ADDED LICENSE-by-nc-sa Index: LICENSE-by-nc-sa ================================================================== --- LICENSE-by-nc-sa +++ LICENSE-by-nc-sa @@ -0,0 +1,439 @@ +Copyright (C) 2021 Xyzzy Apps, + +Attribution-NonCommercial-ShareAlike 4.0 International +======================================================= + +Creative Commons Corporation ("Creative Commons") is not a law firm and +does not provide legal services or legal advice. Distribution of +Creative Commons public licenses does not create a lawyer-client or +other relationship. Creative Commons makes its licenses and related +information available on an "as-is" basis. Creative Commons gives no +warranties regarding its licenses, any material licensed under their +terms and conditions, or any related information. Creative Commons +disclaims all liability for damages resulting from their use to the +fullest extent possible. + +Using Creative Commons Public Licenses + +Creative Commons public licenses provide a standard set of terms and +conditions that creators and other rights holders may use to share +original works of authorship and other material subject to copyright +and certain other rights specified in the public license below. The +following considerations are for informational purposes only, are not +exhaustive, and do not form part of our licenses. + + Considerations for licensors: Our public licenses are + intended for use by those authorized to give the public + permission to use material in ways otherwise restricted by + copyright and certain other rights. Our licenses are + irrevocable. Licensors should read and understand the terms + and conditions of the license they choose before applying it. + Licensors should also secure all rights necessary before + applying our licenses so that the public can reuse the + material as expected. Licensors should clearly mark any + material not subject to the license. This includes other CC- + licensed material, or material used under an exception or + limitation to copyright. More considerations for licensors: + wiki.creativecommons.org/Considerations_for_licensors + + Considerations for the public: By using one of our public + licenses, a licensor grants the public permission to use the + licensed material under specified terms and conditions. If + the licensor's permission is not necessary for any reason--for + example, because of any applicable exception or limitation to + copyright--then that use is not regulated by the license. Our + licenses grant only permissions under copyright and certain + other rights that a licensor has authority to grant. Use of + the licensed material may still be restricted for other + reasons, including because others have copyright or other + rights in the material. A licensor may make special requests, + such as asking that all changes be marked or described. + Although not required by our licenses, you are encouraged to + respect those requests where reasonable. More considerations + for the public: + wiki.creativecommons.org/Considerations_for_licensees + +======================================================================= + +Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International +Public License + +By exercising the Licensed Rights (defined below), You accept and agree +to be bound by the terms and conditions of this Creative Commons +Attribution-NonCommercial-ShareAlike 4.0 International Public License +("Public License"). To the extent this Public License may be +interpreted as a contract, You are granted the Licensed Rights in +consideration of Your acceptance of these terms and conditions, and the +Licensor grants You such rights in consideration of benefits the +Licensor receives from making the Licensed Material available under +these terms and conditions. + + +Section 1 -- Definitions. + + a. Adapted Material means material subject to Copyright and Similar + Rights that is derived from or based upon the Licensed Material + and in which the Licensed Material is translated, altered, + arranged, transformed, or otherwise modified in a manner requiring + permission under the Copyright and Similar Rights held by the + Licensor. For purposes of this Public License, where the Licensed + Material is a musical work, performance, or sound recording, + Adapted Material is always produced where the Licensed Material is + synched in timed relation with a moving image. + + b. Adapter's License means the license You apply to Your Copyright + and Similar Rights in Your contributions to Adapted Material in + accordance with the terms and conditions of this Public License. + + c. BY-NC-SA Compatible License means a license listed at + creativecommons.org/compatiblelicenses, approved by Creative + Commons as essentially the equivalent of this Public License. + + d. Copyright and Similar Rights means copyright and/or similar rights + closely related to copyright including, without limitation, + performance, broadcast, sound recording, and Sui Generis Database + Rights, without regard to how the rights are labeled or + categorized. For purposes of this Public License, the rights + specified in Section 2(b)(1)-(2) are not Copyright and Similar + Rights. + + e. Effective Technological Measures means those measures that, in the + absence of proper authority, may not be circumvented under laws + fulfilling obligations under Article 11 of the WIPO Copyright + Treaty adopted on December 20, 1996, and/or similar international + agreements. + + f. Exceptions and Limitations means fair use, fair dealing, and/or + any other exception or limitation to Copyright and Similar Rights + that applies to Your use of the Licensed Material. + + g. License Elements means the license attributes listed in the name + of a Creative Commons Public License. The License Elements of this + Public License are Attribution, NonCommercial, and ShareAlike. + + h. Licensed Material means the artistic or literary work, database, + or other material to which the Licensor applied this Public + License. + + i. Licensed Rights means the rights granted to You subject to the + terms and conditions of this Public License, which are limited to + all Copyright and Similar Rights that apply to Your use of the + Licensed Material and that the Licensor has authority to license. + + j. Licensor means the individual(s) or entity(ies) granting rights + under this Public License. + + k. NonCommercial means not primarily intended for or directed towards + commercial advantage or monetary compensation. For purposes of + this Public License, the exchange of the Licensed Material for + other material subject to Copyright and Similar Rights by digital + file-sharing or similar means is NonCommercial provided there is + no payment of monetary compensation in connection with the + exchange. + + l. Share means to provide material to the public by any means or + process that requires permission under the Licensed Rights, such + as reproduction, public display, public performance, distribution, + dissemination, communication, or importation, and to make material + available to the public including in ways that members of the + public may access the material from a place and at a time + individually chosen by them. + + m. Sui Generis Database Rights means rights other than copyright + resulting from Directive 96/9/EC of the European Parliament and of + the Council of 11 March 1996 on the legal protection of databases, + as amended and/or succeeded, as well as other essentially + equivalent rights anywhere in the world. + + n. You means the individual or entity exercising the Licensed Rights + under this Public License. Your has a corresponding meaning. + + +Section 2 -- Scope. + + a. License grant. + + 1. Subject to the terms and conditions of this Public License, + the Licensor hereby grants You a worldwide, royalty-free, + non-sublicensable, non-exclusive, irrevocable license to + exercise the Licensed Rights in the Licensed Material to: + + a. reproduce and Share the Licensed Material, in whole or + in part, for NonCommercial purposes only; and + + b. produce, reproduce, and Share Adapted Material for + NonCommercial purposes only. + + 2. Exceptions and Limitations. For the avoidance of doubt, where + Exceptions and Limitations apply to Your use, this Public + License does not apply, and You do not need to comply with + its terms and conditions. + + 3. Term. The term of this Public License is specified in Section + 6(a). + + 4. Media and formats; technical modifications allowed. The + Licensor authorizes You to exercise the Licensed Rights in + all media and formats whether now known or hereafter created, + and to make technical modifications necessary to do so. The + Licensor waives and/or agrees not to assert any right or + authority to forbid You from making technical modifications + necessary to exercise the Licensed Rights, including + technical modifications necessary to circumvent Effective + Technological Measures. For purposes of this Public License, + simply making modifications authorized by this Section 2(a) + (4) never produces Adapted Material. + + 5. Downstream recipients. + + a. Offer from the Licensor -- Licensed Material. Every + recipient of the Licensed Material automatically + receives an offer from the Licensor to exercise the + Licensed Rights under the terms and conditions of this + Public License. + + b. Additional offer from the Licensor -- Adapted Material. + Every recipient of Adapted Material from You + automatically receives an offer from the Licensor to + exercise the Licensed Rights in the Adapted Material + under the conditions of the Adapter's License You apply. + + c. No downstream restrictions. You may not offer or impose + any additional or different terms or conditions on, or + apply any Effective Technological Measures to, the + Licensed Material if doing so restricts exercise of the + Licensed Rights by any recipient of the Licensed + Material. + + 6. No endorsement. Nothing in this Public License constitutes or + may be construed as permission to assert or imply that You + are, or that Your use of the Licensed Material is, connected + with, or sponsored, endorsed, or granted official status by, + the Licensor or others designated to receive attribution as + provided in Section 3(a)(1)(A)(i). + + b. Other rights. + + 1. Moral rights, such as the right of integrity, are not + licensed under this Public License, nor are publicity, + privacy, and/or other similar personality rights; however, to + the extent possible, the Licensor waives and/or agrees not to + assert any such rights held by the Licensor to the limited + extent necessary to allow You to exercise the Licensed + Rights, but not otherwise. + + 2. Patent and trademark rights are not licensed under this + Public License. + + 3. To the extent possible, the Licensor waives any right to + collect royalties from You for the exercise of the Licensed + Rights, whether directly or through a collecting society + under any voluntary or waivable statutory or compulsory + licensing scheme. In all other cases the Licensor expressly + reserves any right to collect such royalties, including when + the Licensed Material is used other than for NonCommercial + purposes. + + +Section 3 -- License Conditions. + +Your exercise of the Licensed Rights is expressly made subject to the +following conditions. + + a. Attribution. + + 1. If You Share the Licensed Material (including in modified + form), You must: + + a. retain the following if it is supplied by the Licensor + with the Licensed Material: + + i. identification of the creator(s) of the Licensed + Material and any others designated to receive + attribution, in any reasonable manner requested by + the Licensor (including by pseudonym if + designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of + warranties; + + v. a URI or hyperlink to the Licensed Material to the + extent reasonably practicable; + + b. indicate if You modified the Licensed Material and + retain an indication of any previous modifications; and + + c. indicate the Licensed Material is licensed under this + Public License, and include the text of, or the URI or + hyperlink to, this Public License. + + 2. You may satisfy the conditions in Section 3(a)(1) in any + reasonable manner based on the medium, means, and context in + which You Share the Licensed Material. For example, it may be + reasonable to satisfy the conditions by providing a URI or + hyperlink to a resource that includes the required + information. + 3. If requested by the Licensor, You must remove any of the + information required by Section 3(a)(1)(A) to the extent + reasonably practicable. + + b. ShareAlike. + + In addition to the conditions in Section 3(a), if You Share + Adapted Material You produce, the following conditions also apply. + + 1. The Adapter's License You apply must be a Creative Commons + license with the same License Elements, this version or + later, or a BY-NC-SA Compatible License. + + 2. You must include the text of, or the URI or hyperlink to, the + Adapter's License You apply. You may satisfy this condition + in any reasonable manner based on the medium, means, and + context in which You Share Adapted Material. + + 3. You may not offer or impose any additional or different terms + or conditions on, or apply any Effective Technological + Measures to, Adapted Material that restrict exercise of the + rights granted under the Adapter's License You apply. + + +Section 4 -- Sui Generis Database Rights. + +Where the Licensed Rights include Sui Generis Database Rights that +apply to Your use of the Licensed Material: + + a. for the avoidance of doubt, Section 2(a)(1) grants You the right + to extract, reuse, reproduce, and Share all or a substantial + portion of the contents of the database for NonCommercial purposes + only; + + b. if You include all or a substantial portion of the database + contents in a database in which You have Sui Generis Database + Rights, then the database in which You have Sui Generis Database + Rights (but not its individual contents) is Adapted Material, + including for purposes of Section 3(b); and + + c. You must comply with the conditions in Section 3(a) if You Share + all or a substantial portion of the contents of the database. + +For the avoidance of doubt, this Section 4 supplements and does not +replace Your obligations under this Public License where the Licensed +Rights include other Copyright and Similar Rights. + + +Section 5 -- Disclaimer of Warranties and Limitation of Liability. + + a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE + EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS + AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF + ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, + IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, + WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, + ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT + KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT + ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. + + b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE + TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, + NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, + INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, + COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR + USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR + DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR + IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. + + c. The disclaimer of warranties and limitation of liability provided + above shall be interpreted in a manner that, to the extent + possible, most closely approximates an absolute disclaimer and + waiver of all liability. + + +Section 6 -- Term and Termination. + + a. This Public License applies for the term of the Copyright and + Similar Rights licensed here. However, if You fail to comply with + this Public License, then Your rights under this Public License + terminate automatically. + + b. Where Your right to use the Licensed Material has terminated under + Section 6(a), it reinstates: + + 1. automatically as of the date the violation is cured, provided + it is cured within 30 days of Your discovery of the + violation; or + + 2. upon express reinstatement by the Licensor. + + For the avoidance of doubt, this Section 6(b) does not affect any + right the Licensor may have to seek remedies for Your violations + of this Public License. + + c. For the avoidance of doubt, the Licensor may also offer the + Licensed Material under separate terms or conditions or stop + distributing the Licensed Material at any time; however, doing so + will not terminate this Public License. + + d. Sections 1, 5, 6, 7, and 8 survive termination of this Public + License. + + +Section 7 -- Other Terms and Conditions. + + a. The Licensor shall not be bound by any additional or different + terms or conditions communicated by You unless expressly agreed. + + b. Any arrangements, understandings, or agreements regarding the + Licensed Material not stated herein are separate from and + independent of the terms and conditions of this Public License. + + +Section 8 -- Interpretation. + + a. For the avoidance of doubt, this Public License does not, and + shall not be interpreted to, reduce, limit, restrict, or impose + conditions on any use of the Licensed Material that could lawfully + be made without permission under this Public License. + + b. To the extent possible, if any provision of this Public License is + deemed unenforceable, it shall be automatically reformed to the + minimum extent necessary to make it enforceable. If the provision + cannot be reformed, it shall be severed from this Public License + without affecting the enforceability of the remaining terms and + conditions. + + c. No term or condition of this Public License will be waived and no + failure to comply consented to unless expressly agreed to by the + Licensor. + + d. Nothing in this Public License constitutes or may be interpreted + as a limitation upon, or waiver of, any privileges and immunities + that apply to the Licensor or You, including from the legal + processes of any jurisdiction or authority. + +======================================================================= + +Creative Commons is not a party to its public +licenses. Notwithstanding, Creative Commons may elect to apply one of +its public licenses to material it publishes and in those instances +will be considered the “Licensor.” The text of the Creative Commons +public licenses is dedicated to the public domain under the CC0 Public +Domain Dedication. Except for the limited purpose of indicating that +material is shared under a Creative Commons public license or as +otherwise permitted by the Creative Commons policies published at +creativecommons.org/policies, Creative Commons does not authorize the +use of the trademark "Creative Commons" or any other trademark or logo +of Creative Commons without its prior written consent including, +without limitation, in connection with any unauthorized modifications +to any of its public licenses or any other arrangements, +understandings, or agreements concerning use of licensed material. For +the avoidance of doubt, this paragraph does not form part of the +public licenses. + +Creative Commons may be contacted at creativecommons.org. + ADDED Makefile Index: Makefile ================================================================== --- Makefile +++ Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) ADDED bitrhythm.hy Index: bitrhythm.hy ================================================================== --- bitrhythm.hy +++ bitrhythm.hy @@ -0,0 +1,56 @@ + +(import [sanic [Sanic response]]) +(import [sanic.response [json text]]) +(import [sanic.exceptions [NotFound abort]]) +(import [jinja2 [Environment FileSystemLoader]]) +(import re) +(import ipdb) +(import sys) +(import traceback) +(import json) +(import datetime) +(import [email.utils [format_datetime]]) +(import [urllib.parse [urlparse]]) +(import base64) + +(setv file-loader (FileSystemLoader "templates")) +(setv env (Environment :loader file-loader)) + +(setv app (Sanic "Bitrhythm")) + +(with-decorator + (app.exception NotFound) + (defn/a ignore_404s [request exception] + (return (text (+ "Yep, I totally found the page " request.url))) + ) +) + +(with-decorator + (app.route "/song/") + (defn/a get-index [request name] + (setv template (env.get_template "index.html")) + (return (response.html (template.render {"data" name}))) + ) +) + +(with-decorator + (app.route "/") + (defn/a get-index [request] + (setv template (env.get_template "index.html")) + (return (response.html (template.render {"data" ""}))) + ) +) + +(with-decorator + (app.route "/issue") + (defn/a get-index [request] + (setv template (env.get_template "page.html")) + (return (response.html (template.render))) + ) +) + +(app.static "/" "./public") + +(defmain [&rest args] + (app.run :host "0.0.0.0" :port 8015) +) ADDED build/html/_static/analytics.js Index: build/html/_static/analytics.js ================================================================== --- build/html/_static/analytics.js +++ build/html/_static/analytics.js @@ -0,0 +1,3 @@ +window.goatcounter = { + path: function(p) { return location.host + p } +} ADDED build/html/_static/basic.css Index: build/html/_static/basic.css ================================================================== --- build/html/_static/basic.css +++ build/html/_static/basic.css @@ -0,0 +1,861 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 270px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li div.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 450px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +a.brackets:before, +span.brackets > a:before{ + content: "["; +} + +a.brackets:after, +span.brackets > a:after { + content: "]"; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +table.footnote td, table.footnote th { + border: 0 !important; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +dl.footnote > dt, +dl.citation > dt { + float: left; + margin-right: 0.5em; +} + +dl.footnote > dd, +dl.citation > dd { + margin-bottom: 0em; +} + +dl.footnote > dd:after, +dl.citation > dd:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dt:after { + content: ":"; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0.5em; + content: ":"; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.doctest > div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.descname { + background-color: transparent; + font-weight: bold; + font-size: 1.2em; +} + +code.descclassname { + background-color: transparent; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} ADDED build/html/_static/css/index.c5995385ac14fb8791e8eb36b4908be2.css Index: build/html/_static/css/index.c5995385ac14fb8791e8eb36b4908be2.css ================================================================== --- build/html/_static/css/index.c5995385ac14fb8791e8eb36b4908be2.css +++ build/html/_static/css/index.c5995385ac14fb8791e8eb36b4908be2.css cannot compute difference between binary files ADDED build/html/_static/css/theme.css Index: build/html/_static/css/theme.css ================================================================== --- build/html/_static/css/theme.css +++ build/html/_static/css/theme.css @@ -0,0 +1,117 @@ +:root { + /***************************************************************************** + * Theme config + **/ + --pst-header-height: 60px; + + /***************************************************************************** + * Font size + **/ + --pst-font-size-base: 15px; /* base font size - applied at body / html level */ + + /* heading font sizes */ + --pst-font-size-h1: 36px; + --pst-font-size-h2: 32px; + --pst-font-size-h3: 26px; + --pst-font-size-h4: 21px; + --pst-font-size-h5: 18px; + --pst-font-size-h6: 16px; + + /* smaller then heading font sizes*/ + --pst-font-size-milli: 12px; + + --pst-sidebar-font-size: .9em; + --pst-sidebar-caption-font-size: .9em; + + /***************************************************************************** + * Font family + **/ + /* These are adapted from https://systemfontstack.com/ */ + --pst-font-family-base-system: -apple-system, BlinkMacSystemFont, Segoe UI, "Helvetica Neue", + Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol; + --pst-font-family-monospace-system: "SFMono-Regular", Menlo, Consolas, Monaco, + Liberation Mono, Lucida Console, monospace; + + --pst-font-family-base: var(--pst-font-family-base-system); + --pst-font-family-heading: var(--pst-font-family-base); + --pst-font-family-monospace: var(--pst-font-family-monospace-system); + + /***************************************************************************** + * Color + * + * Colors are defined in rgb string way, "red, green, blue" + **/ + --pst-color-primary: 19, 6, 84; + --pst-color-success: 40, 167, 69; + --pst-color-info: 0, 123, 255; /*23, 162, 184;*/ + --pst-color-warning: 255, 193, 7; + --pst-color-danger: 220, 53, 69; + --pst-color-text-base: 51, 51, 51; + + --pst-color-h1: var(--pst-color-primary); + --pst-color-h2: var(--pst-color-primary); + --pst-color-h3: var(--pst-color-text-base); + --pst-color-h4: var(--pst-color-text-base); + --pst-color-h5: var(--pst-color-text-base); + --pst-color-h6: var(--pst-color-text-base); + --pst-color-paragraph: var(--pst-color-text-base); + --pst-color-link: 0, 91, 129; + --pst-color-link-hover: 227, 46, 0; + --pst-color-headerlink: 198, 15, 15; + --pst-color-headerlink-hover: 255, 255, 255; + --pst-color-preformatted-text: 34, 34, 34; + --pst-color-preformatted-background: 250, 250, 250; + --pst-color-inline-code: 232, 62, 140; + + --pst-color-active-navigation: 19, 6, 84; + --pst-color-navbar-link: 77, 77, 77; + --pst-color-navbar-link-hover: var(--pst-color-active-navigation); + --pst-color-navbar-link-active: var(--pst-color-active-navigation); + --pst-color-sidebar-link: 77, 77, 77; + --pst-color-sidebar-link-hover: var(--pst-color-active-navigation); + --pst-color-sidebar-link-active: var(--pst-color-active-navigation); + --pst-color-sidebar-expander-background-hover: 244, 244, 244; + --pst-color-sidebar-caption: 77, 77, 77; + --pst-color-toc-link: 119, 117, 122; + --pst-color-toc-link-hover: var(--pst-color-active-navigation); + --pst-color-toc-link-active: var(--pst-color-active-navigation); + + /***************************************************************************** + * Icon + **/ + + /* font awesome icons*/ + --pst-icon-check-circle: '\f058'; + --pst-icon-info-circle: '\f05a'; + --pst-icon-exclamation-triangle: '\f071'; + --pst-icon-exclamation-circle: '\f06a'; + --pst-icon-times-circle: '\f057'; + --pst-icon-lightbulb: '\f0eb'; + + /***************************************************************************** + * Admonitions + **/ + + --pst-color-admonition-default: var(--pst-color-info); + --pst-color-admonition-note: var(--pst-color-info); + --pst-color-admonition-attention: var(--pst-color-warning); + --pst-color-admonition-caution: var(--pst-color-warning); + --pst-color-admonition-warning: var(--pst-color-warning); + --pst-color-admonition-danger: var(--pst-color-danger); + --pst-color-admonition-error: var(--pst-color-danger); + --pst-color-admonition-hint: var(--pst-color-success); + --pst-color-admonition-tip: var(--pst-color-success); + --pst-color-admonition-important: var(--pst-color-success); + + --pst-icon-admonition-default: var(--pst-icon-info-circle); + --pst-icon-admonition-note: var(--pst-icon-info-circle); + --pst-icon-admonition-attention: var(--pst-icon-exclamation-circle); + --pst-icon-admonition-caution: var(--pst-icon-exclamation-triangle); + --pst-icon-admonition-warning: var(--pst-icon-exclamation-triangle); + --pst-icon-admonition-danger: var(--pst-icon-exclamation-triangle); + --pst-icon-admonition-error: var(--pst-icon-times-circle); + --pst-icon-admonition-hint: var(--pst-icon-lightbulb); + --pst-icon-admonition-tip: var(--pst-icon-lightbulb); + --pst-icon-admonition-important: var(--pst-icon-exclamation-circle); + +} ADDED build/html/_static/custom.css Index: build/html/_static/custom.css ================================================================== --- build/html/_static/custom.css +++ build/html/_static/custom.css @@ -0,0 +1,3 @@ +.custom-nav-footer { + margin-top: 8em; +} ADDED build/html/_static/doctools.js Index: build/html/_static/doctools.js ================================================================== --- build/html/_static/doctools.js +++ build/html/_static/doctools.js @@ -0,0 +1,321 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for all documentation. + * + * :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/** + * select a different prefix for underscore + */ +$u = _.noConflict(); + +/** + * make the code below compatible with browsers without + * an installed firebug like debugger +if (!window.console || !console.firebug) { + var names = ["log", "debug", "info", "warn", "error", "assert", "dir", + "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", + "profile", "profileEnd"]; + window.console = {}; + for (var i = 0; i < names.length; ++i) + window.console[names[i]] = function() {}; +} + */ + +/** + * small helper function to urldecode strings + * + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL + */ +jQuery.urldecode = function(x) { + if (!x) { + return x + } + return decodeURIComponent(x.replace(/\+/g, ' ')); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + var bbox = node.parentElement.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute('class', className); + addItems.push({ + "parent": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} + +/** + * Small JavaScript module for the documentation. + */ +var Documentation = { + + init : function() { + this.fixFirefoxAnchorBug(); + this.highlightSearchWords(); + this.initIndexTable(); + if (DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) { + this.initOnKeyListeners(); + } + }, + + /** + * i18n support + */ + TRANSLATIONS : {}, + PLURAL_EXPR : function(n) { return n === 1 ? 0 : 1; }, + LOCALE : 'unknown', + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext : function(string) { + var translated = Documentation.TRANSLATIONS[string]; + if (typeof translated === 'undefined') + return string; + return (typeof translated === 'string') ? translated : translated[0]; + }, + + ngettext : function(singular, plural, n) { + var translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated === 'undefined') + return (n == 1) ? singular : plural; + return translated[Documentation.PLURALEXPR(n)]; + }, + + addTranslations : function(catalog) { + for (var key in catalog.messages) + this.TRANSLATIONS[key] = catalog.messages[key]; + this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); + this.LOCALE = catalog.locale; + }, + + /** + * add context elements like header anchor links + */ + addContextElements : function() { + $('div[id] > :header:first').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this headline')). + appendTo(this); + }); + $('dt[id]').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this definition')). + appendTo(this); + }); + }, + + /** + * workaround a firefox stupidity + * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075 + */ + fixFirefoxAnchorBug : function() { + if (document.location.hash && $.browser.mozilla) + window.setTimeout(function() { + document.location.href += ''; + }, 10); + }, + + /** + * highlight the search words provided in the url in the text + */ + highlightSearchWords : function() { + var params = $.getQueryParameters(); + var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; + if (terms.length) { + var body = $('div.body'); + if (!body.length) { + body = $('body'); + } + window.setTimeout(function() { + $.each(terms, function() { + body.highlightText(this.toLowerCase(), 'highlighted'); + }); + }, 10); + $('') + .appendTo($('#searchbox')); + } + }, + + /** + * init the domain index toggle buttons + */ + initIndexTable : function() { + var togglers = $('img.toggler').click(function() { + var src = $(this).attr('src'); + var idnum = $(this).attr('id').substr(7); + $('tr.cg-' + idnum).toggle(); + if (src.substr(-9) === 'minus.png') + $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); + else + $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); + }).css('display', ''); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { + togglers.click(); + } + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords : function() { + $('#searchbox .highlight-link').fadeOut(300); + $('span.highlighted').removeClass('highlighted'); + }, + + /** + * make the url absolute + */ + makeURL : function(relativeURL) { + return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; + }, + + /** + * get the current relative url + */ + getCurrentURL : function() { + var path = document.location.pathname; + var parts = path.split(/\//); + $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { + if (this === '..') + parts.pop(); + }); + var url = parts.join('/'); + return path.substring(url.lastIndexOf('/') + 1, path.length - 1); + }, + + initOnKeyListeners: function() { + $(document).keydown(function(event) { + var activeElementType = document.activeElement.tagName; + // don't navigate when in search box, textarea, dropdown or button + if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT' + && activeElementType !== 'BUTTON' && !event.altKey && !event.ctrlKey && !event.metaKey + && !event.shiftKey) { + switch (event.keyCode) { + case 37: // left + var prevHref = $('link[rel="prev"]').prop('href'); + if (prevHref) { + window.location.href = prevHref; + return false; + } + case 39: // right + var nextHref = $('link[rel="next"]').prop('href'); + if (nextHref) { + window.location.href = nextHref; + return false; + } + } + } + }); + } +}; + +// quick alias for translations +_ = Documentation.gettext; + +$(document).ready(function() { + Documentation.init(); +}); ADDED build/html/_static/documentation_options.js Index: build/html/_static/documentation_options.js ================================================================== --- build/html/_static/documentation_options.js +++ build/html/_static/documentation_options.js @@ -0,0 +1,12 @@ +var DOCUMENTATION_OPTIONS = { + URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), + VERSION: '', + LANGUAGE: 'None', + COLLAPSE_INDEX: false, + BUILDER: 'html', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: true +}; ADDED build/html/_static/file.png Index: build/html/_static/file.png ================================================================== --- build/html/_static/file.png +++ build/html/_static/file.png cannot compute difference between binary files ADDED build/html/_static/images/logo_binder.svg Index: build/html/_static/images/logo_binder.svg ================================================================== --- build/html/_static/images/logo_binder.svg +++ build/html/_static/images/logo_binder.svg @@ -0,0 +1,19 @@ + + + + +logo + + + + + + + + ADDED build/html/_static/images/logo_colab.png Index: build/html/_static/images/logo_colab.png ================================================================== --- build/html/_static/images/logo_colab.png +++ build/html/_static/images/logo_colab.png cannot compute difference between binary files ADDED build/html/_static/images/logo_jupyterhub.svg Index: build/html/_static/images/logo_jupyterhub.svg ================================================================== --- build/html/_static/images/logo_jupyterhub.svg +++ build/html/_static/images/logo_jupyterhub.svg @@ -0,0 +1,1 @@ +logo_jupyterhubHub ADDED build/html/_static/jquery-3.5.1.js Index: build/html/_static/jquery-3.5.1.js ================================================================== --- build/html/_static/jquery-3.5.1.js +++ build/html/_static/jquery-3.5.1.js @@ -0,0 +1,10872 @@ +/*! + * jQuery JavaScript Library v3.5.1 + * https://jquery.com/ + * + * Includes Sizzle.js + * https://sizzlejs.com/ + * + * Copyright JS Foundation and other contributors + * Released under the MIT license + * https://jquery.org/license + * + * Date: 2020-05-04T22:49Z + */ +( function( global, factory ) { + + "use strict"; + + if ( typeof module === "object" && typeof module.exports === "object" ) { + + // For CommonJS and CommonJS-like environments where a proper `window` + // is present, execute the factory and get jQuery. + // For environments that do not have a `window` with a `document` + // (such as Node.js), expose a factory as module.exports. + // This accentuates the need for the creation of a real `window`. + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info. + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + +// Pass this if window is not defined yet +} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + +// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 +// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode +// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common +// enough that all such attempts are guarded in a try block. +"use strict"; + +var arr = []; + +var getProto = Object.getPrototypeOf; + +var slice = arr.slice; + +var flat = arr.flat ? function( array ) { + return arr.flat.call( array ); +} : function( array ) { + return arr.concat.apply( [], array ); +}; + + +var push = arr.push; + +var indexOf = arr.indexOf; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var fnToString = hasOwn.toString; + +var ObjectFunctionString = fnToString.call( Object ); + +var support = {}; + +var isFunction = function isFunction( obj ) { + + // Support: Chrome <=57, Firefox <=52 + // In some browsers, typeof returns "function" for HTML elements + // (i.e., `typeof document.createElement( "object" ) === "function"`). + // We don't want to classify *any* DOM node as a function. + return typeof obj === "function" && typeof obj.nodeType !== "number"; + }; + + +var isWindow = function isWindow( obj ) { + return obj != null && obj === obj.window; + }; + + +var document = window.document; + + + + var preservedScriptAttributes = { + type: true, + src: true, + nonce: true, + noModule: true + }; + + function DOMEval( code, node, doc ) { + doc = doc || document; + + var i, val, + script = doc.createElement( "script" ); + + script.text = code; + if ( node ) { + for ( i in preservedScriptAttributes ) { + + // Support: Firefox 64+, Edge 18+ + // Some browsers don't support the "nonce" property on scripts. + // On the other hand, just using `getAttribute` is not enough as + // the `nonce` attribute is reset to an empty string whenever it + // becomes browsing-context connected. + // See https://github.com/whatwg/html/issues/2369 + // See https://html.spec.whatwg.org/#nonce-attributes + // The `node.getAttribute` check was added for the sake of + // `jQuery.globalEval` so that it can fake a nonce-containing node + // via an object. + val = node[ i ] || node.getAttribute && node.getAttribute( i ); + if ( val ) { + script.setAttribute( i, val ); + } + } + } + doc.head.appendChild( script ).parentNode.removeChild( script ); + } + + +function toType( obj ) { + if ( obj == null ) { + return obj + ""; + } + + // Support: Android <=2.3 only (functionish RegExp) + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call( obj ) ] || "object" : + typeof obj; +} +/* global Symbol */ +// Defining this global in .eslintrc.json would create a danger of using the global +// unguarded in another place, it seems safer to define global only for this module + + + +var + version = "3.5.1", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }; + +jQuery.fn = jQuery.prototype = { + + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + + // Return all the elements in a clean array + if ( num == null ) { + return slice.call( this ); + } + + // Return just the one element from the set + return num < 0 ? this[ num + this.length ] : this[ num ]; + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + each: function( callback ) { + return jQuery.each( this, callback ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map( this, function( elem, i ) { + return callback.call( elem, i, elem ); + } ) ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + even: function() { + return this.pushStack( jQuery.grep( this, function( _elem, i ) { + return ( i + 1 ) % 2; + } ) ); + }, + + odd: function() { + return this.pushStack( jQuery.grep( this, function( _elem, i ) { + return i % 2; + } ) ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); + }, + + end: function() { + return this.prevObject || this.constructor(); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: arr.sort, + splice: arr.splice +}; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[ 0 ] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // Skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !isFunction( target ) ) { + target = {}; + } + + // Extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + + // Only deal with non-null/undefined values + if ( ( options = arguments[ i ] ) != null ) { + + // Extend the base object + for ( name in options ) { + copy = options[ name ]; + + // Prevent Object.prototype pollution + // Prevent never-ending loop + if ( name === "__proto__" || target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject( copy ) || + ( copyIsArray = Array.isArray( copy ) ) ) ) { + src = target[ name ]; + + // Ensure proper type for the source value + if ( copyIsArray && !Array.isArray( src ) ) { + clone = []; + } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { + clone = {}; + } else { + clone = src; + } + copyIsArray = false; + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend( { + + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + isPlainObject: function( obj ) { + var proto, Ctor; + + // Detect obvious negatives + // Use toString instead of jQuery.type to catch host objects + if ( !obj || toString.call( obj ) !== "[object Object]" ) { + return false; + } + + proto = getProto( obj ); + + // Objects with no prototype (e.g., `Object.create( null )`) are plain + if ( !proto ) { + return true; + } + + // Objects with prototype are plain iff they were constructed by a global Object function + Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; + return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; + }, + + isEmptyObject: function( obj ) { + var name; + + for ( name in obj ) { + return false; + } + return true; + }, + + // Evaluates a script in a provided context; falls back to the global one + // if not specified. + globalEval: function( code, options, doc ) { + DOMEval( code, { nonce: options && options.nonce }, doc ); + }, + + each: function( obj, callback ) { + var length, i = 0; + + if ( isArrayLike( obj ) ) { + length = obj.length; + for ( ; i < length; i++ ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } else { + for ( i in obj ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } + + return obj; + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArrayLike( Object( arr ) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + return arr == null ? -1 : indexOf.call( arr, elem, i ); + }, + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + for ( ; j < len; j++ ) { + first[ i++ ] = second[ j ]; + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var length, value, + i = 0, + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArrayLike( elems ) ) { + length = elems.length; + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return flat( ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +} ); + +if ( typeof Symbol === "function" ) { + jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; +} + +// Populate the class2type map +jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), +function( _i, name ) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +} ); + +function isArrayLike( obj ) { + + // Support: real iOS 8.2 only (not reproducible in simulator) + // `in` check used to prevent JIT error (gh-2145) + // hasOwn isn't used here due to false negatives + // regarding Nodelist length in IE + var length = !!obj && "length" in obj && obj.length, + type = toType( obj ); + + if ( isFunction( obj ) || isWindow( obj ) ) { + return false; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v2.3.5 + * https://sizzlejs.com/ + * + * Copyright JS Foundation and other contributors + * Released under the MIT license + * https://js.foundation/ + * + * Date: 2020-03-14 + */ +( function( window ) { +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + 1 * new Date(), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + nonnativeSelectorCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // Instance methods + hasOwn = ( {} ).hasOwnProperty, + arr = [], + pop = arr.pop, + pushNative = arr.push, + push = arr.push, + slice = arr.slice, + + // Use a stripped-down indexOf as it's faster than native + // https://jsperf.com/thor-indexof-vs-for/5 + indexOf = function( list, elem ) { + var i = 0, + len = list.length; + for ( ; i < len; i++ ) { + if ( list[ i ] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" + + "ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + + // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram + identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + + "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+", + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + + // "Attribute values must be CSS identifiers [capture 5] + // or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + + whitespace + "*\\]", + + pseudos = ":(" + identifier + ")(?:\\((" + + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rwhitespace = new RegExp( whitespace + "+", "g" ), + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + + "*" ), + rdescend = new RegExp( whitespace + "|>" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + identifier + ")" ), + "CLASS": new RegExp( "^\\.(" + identifier + ")" ), + "TAG": new RegExp( "^(" + identifier + "|[*])" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + + whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + + whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rhtml = /HTML$/i, + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + + // CSS escapes + // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ), + funescape = function( escape, nonHex ) { + var high = "0x" + escape.slice( 1 ) - 0x10000; + + return nonHex ? + + // Strip the backslash prefix from a non-hex escape sequence + nonHex : + + // Replace a hexadecimal escape sequence with the encoded Unicode code point + // Support: IE <=11+ + // For values outside the Basic Multilingual Plane (BMP), manually construct a + // surrogate pair + high < 0 ? + String.fromCharCode( high + 0x10000 ) : + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }, + + // CSS string/identifier serialization + // https://drafts.csswg.org/cssom/#common-serializing-idioms + rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, + fcssescape = function( ch, asCodePoint ) { + if ( asCodePoint ) { + + // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER + if ( ch === "\0" ) { + return "\uFFFD"; + } + + // Control characters and (dependent upon position) numbers get escaped as code points + return ch.slice( 0, -1 ) + "\\" + + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; + } + + // Other potentially-special ASCII characters get backslash-escaped + return "\\" + ch; + }, + + // Used for iframes + // See setDocument() + // Removing the function wrapper causes a "Permission Denied" + // error in IE + unloadHandler = function() { + setDocument(); + }, + + inDisabledFieldset = addCombinator( + function( elem ) { + return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset"; + }, + { dir: "parentNode", next: "legend" } + ); + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + ( arr = slice.call( preferredDoc.childNodes ) ), + preferredDoc.childNodes + ); + + // Support: Android<4.0 + // Detect silently failing push.apply + // eslint-disable-next-line no-unused-expressions + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + pushNative.apply( target, slice.call( els ) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + + // Can't trust NodeList.length + while ( ( target[ j++ ] = els[ i++ ] ) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var m, i, elem, nid, match, groups, newSelector, + newContext = context && context.ownerDocument, + + // nodeType defaults to 9, since context defaults to document + nodeType = context ? context.nodeType : 9; + + results = results || []; + + // Return early from calls with invalid selector or context + if ( typeof selector !== "string" || !selector || + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { + + return results; + } + + // Try to shortcut find operations (as opposed to filters) in HTML documents + if ( !seed ) { + setDocument( context ); + context = context || document; + + if ( documentIsHTML ) { + + // If the selector is sufficiently simple, try using a "get*By*" DOM method + // (excepting DocumentFragment context, where the methods don't exist) + if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) { + + // ID selector + if ( ( m = match[ 1 ] ) ) { + + // Document context + if ( nodeType === 9 ) { + if ( ( elem = context.getElementById( m ) ) ) { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + + // Element context + } else { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( newContext && ( elem = newContext.getElementById( m ) ) && + contains( context, elem ) && + elem.id === m ) { + + results.push( elem ); + return results; + } + } + + // Type selector + } else if ( match[ 2 ] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Class selector + } else if ( ( m = match[ 3 ] ) && support.getElementsByClassName && + context.getElementsByClassName ) { + + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // Take advantage of querySelectorAll + if ( support.qsa && + !nonnativeSelectorCache[ selector + " " ] && + ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) && + + // Support: IE 8 only + // Exclude object elements + ( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) { + + newSelector = selector; + newContext = context; + + // qSA considers elements outside a scoping root when evaluating child or + // descendant combinators, which is not what we want. + // In such cases, we work around the behavior by prefixing every selector in the + // list with an ID selector referencing the scope context. + // The technique has to be used as well when a leading combinator is used + // as such selectors are not recognized by querySelectorAll. + // Thanks to Andrew Dupont for this technique. + if ( nodeType === 1 && + ( rdescend.test( selector ) || rcombinators.test( selector ) ) ) { + + // Expand context for sibling selectors + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || + context; + + // We can use :scope instead of the ID hack if the browser + // supports it & if we're not changing the context. + if ( newContext !== context || !support.scope ) { + + // Capture the context ID, setting it first if necessary + if ( ( nid = context.getAttribute( "id" ) ) ) { + nid = nid.replace( rcssescape, fcssescape ); + } else { + context.setAttribute( "id", ( nid = expando ) ); + } + } + + // Prefix every selector in the list + groups = tokenize( selector ); + i = groups.length; + while ( i-- ) { + groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " + + toSelector( groups[ i ] ); + } + newSelector = groups.join( "," ); + } + + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch ( qsaError ) { + nonnativeSelectorCache( selector, true ); + } finally { + if ( nid === expando ) { + context.removeAttribute( "id" ); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {function(string, object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return ( cache[ key + " " ] = value ); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created element and returns a boolean result + */ +function assert( fn ) { + var el = document.createElement( "fieldset" ); + + try { + return !!fn( el ); + } catch ( e ) { + return false; + } finally { + + // Remove from its parent by default + if ( el.parentNode ) { + el.parentNode.removeChild( el ); + } + + // release memory in IE + el = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split( "|" ), + i = arr.length; + + while ( i-- ) { + Expr.attrHandle[ arr[ i ] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + a.sourceIndex - b.sourceIndex; + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( ( cur = cur.nextSibling ) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return ( name === "input" || name === "button" ) && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for :enabled/:disabled + * @param {Boolean} disabled true for :disabled; false for :enabled + */ +function createDisabledPseudo( disabled ) { + + // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable + return function( elem ) { + + // Only certain elements can match :enabled or :disabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled + if ( "form" in elem ) { + + // Check for inherited disabledness on relevant non-disabled elements: + // * listed form-associated elements in a disabled fieldset + // https://html.spec.whatwg.org/multipage/forms.html#category-listed + // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled + // * option elements in a disabled optgroup + // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled + // All such elements have a "form" property. + if ( elem.parentNode && elem.disabled === false ) { + + // Option elements defer to a parent optgroup if present + if ( "label" in elem ) { + if ( "label" in elem.parentNode ) { + return elem.parentNode.disabled === disabled; + } else { + return elem.disabled === disabled; + } + } + + // Support: IE 6 - 11 + // Use the isDisabled shortcut property to check for disabled fieldset ancestors + return elem.isDisabled === disabled || + + // Where there is no isDisabled, check manually + /* jshint -W018 */ + elem.isDisabled !== !disabled && + inDisabledFieldset( elem ) === disabled; + } + + return elem.disabled === disabled; + + // Try to winnow out elements that can't be disabled before trusting the disabled property. + // Some victims get caught in our net (label, legend, menu, track), but it shouldn't + // even exist on them, let alone have a boolean value. + } else if ( "label" in elem ) { + return elem.disabled === disabled; + } + + // Remaining elements are neither :enabled nor :disabled + return false; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction( function( argument ) { + argument = +argument; + return markFunction( function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ ( j = matchIndexes[ i ] ) ] ) { + seed[ j ] = !( matches[ j ] = seed[ j ] ); + } + } + } ); + } ); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== "undefined" && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + var namespace = elem.namespaceURI, + docElem = ( elem.ownerDocument || elem ).documentElement; + + // Support: IE <=8 + // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes + // https://bugs.jquery.com/ticket/4833 + return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" ); +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, subWindow, + doc = node ? node.ownerDocument || node : preferredDoc; + + // Return early if doc is invalid or already selected + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Update global variables + document = doc; + docElem = document.documentElement; + documentIsHTML = !isXML( document ); + + // Support: IE 9 - 11+, Edge 12 - 18+ + // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( preferredDoc != document && + ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) { + + // Support: IE 11, Edge + if ( subWindow.addEventListener ) { + subWindow.addEventListener( "unload", unloadHandler, false ); + + // Support: IE 9 - 10 only + } else if ( subWindow.attachEvent ) { + subWindow.attachEvent( "onunload", unloadHandler ); + } + } + + // Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only, + // Safari 4 - 5 only, Opera <=11.6 - 12.x only + // IE/Edge & older browsers don't support the :scope pseudo-class. + // Support: Safari 6.0 only + // Safari 6.0 supports :scope but it's an alias of :root there. + support.scope = assert( function( el ) { + docElem.appendChild( el ).appendChild( document.createElement( "div" ) ); + return typeof el.querySelectorAll !== "undefined" && + !el.querySelectorAll( ":scope fieldset div" ).length; + } ); + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties + // (excepting IE8 booleans) + support.attributes = assert( function( el ) { + el.className = "i"; + return !el.getAttribute( "className" ); + } ); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert( function( el ) { + el.appendChild( document.createComment( "" ) ); + return !el.getElementsByTagName( "*" ).length; + } ); + + // Support: IE<9 + support.getElementsByClassName = rnative.test( document.getElementsByClassName ); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programmatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert( function( el ) { + docElem.appendChild( el ).id = expando; + return !document.getElementsByName || !document.getElementsByName( expando ).length; + } ); + + // ID filter and find + if ( support.getById ) { + Expr.filter[ "ID" ] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute( "id" ) === attrId; + }; + }; + Expr.find[ "ID" ] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var elem = context.getElementById( id ); + return elem ? [ elem ] : []; + } + }; + } else { + Expr.filter[ "ID" ] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== "undefined" && + elem.getAttributeNode( "id" ); + return node && node.value === attrId; + }; + }; + + // Support: IE 6 - 7 only + // getElementById is not reliable as a find shortcut + Expr.find[ "ID" ] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var node, i, elems, + elem = context.getElementById( id ); + + if ( elem ) { + + // Verify the id attribute + node = elem.getAttributeNode( "id" ); + if ( node && node.value === id ) { + return [ elem ]; + } + + // Fall back on getElementsByName + elems = context.getElementsByName( id ); + i = 0; + while ( ( elem = elems[ i++ ] ) ) { + node = elem.getAttributeNode( "id" ); + if ( node && node.value === id ) { + return [ elem ]; + } + } + } + + return []; + } + }; + } + + // Tag + Expr.find[ "TAG" ] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( tag ); + + // DocumentFragment nodes don't have gEBTN + } else if ( support.qsa ) { + return context.querySelectorAll( tag ); + } + } : + + function( tag, context ) { + var elem, + tmp = [], + i = 0, + + // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( ( elem = results[ i++ ] ) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See https://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) { + + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert( function( el ) { + + var input; + + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // https://bugs.jquery.com/ticket/12359 + docElem.appendChild( el ).innerHTML = "" + + ""; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !el.querySelectorAll( "[selected]" ).length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ + if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { + rbuggyQSA.push( "~=" ); + } + + // Support: IE 11+, Edge 15 - 18+ + // IE 11/Edge don't find elements on a `[name='']` query in some cases. + // Adding a temporary attribute to the document before the selection works + // around the issue. + // Interestingly, IE 10 & older don't seem to have the issue. + input = document.createElement( "input" ); + input.setAttribute( "name", "" ); + el.appendChild( input ); + if ( !el.querySelectorAll( "[name='']" ).length ) { + rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" + + whitespace + "*(?:''|\"\")" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !el.querySelectorAll( ":checked" ).length ) { + rbuggyQSA.push( ":checked" ); + } + + // Support: Safari 8+, iOS 8+ + // https://bugs.webkit.org/show_bug.cgi?id=136851 + // In-page `selector#id sibling-combinator selector` fails + if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { + rbuggyQSA.push( ".#.+[+~]" ); + } + + // Support: Firefox <=3.6 - 5 only + // Old Firefox doesn't throw on a badly-escaped identifier. + el.querySelectorAll( "\\\f" ); + rbuggyQSA.push( "[\\r\\n\\f]" ); + } ); + + assert( function( el ) { + el.innerHTML = "" + + ""; + + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = document.createElement( "input" ); + input.setAttribute( "type", "hidden" ); + el.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( el.querySelectorAll( "[name=d]" ).length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( el.querySelectorAll( ":enabled" ).length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: IE9-11+ + // IE's :disabled selector does not pick up the children of disabled fieldsets + docElem.appendChild( el ).disabled = true; + if ( el.querySelectorAll( ":disabled" ).length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: Opera 10 - 11 only + // Opera 10-11 does not throw on post-comma invalid pseudos + el.querySelectorAll( "*,:x" ); + rbuggyQSA.push( ",.*:" ); + } ); + } + + if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector ) ) ) ) { + + assert( function( el ) { + + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( el, "*" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( el, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + } ); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully self-exclusive + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + ) ); + } : + function( a, b ) { + if ( b ) { + while ( ( b = b.parentNode ) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + ( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) { + + // Choose the first element that is related to our preferred document + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( a == document || a.ownerDocument == preferredDoc && + contains( preferredDoc, a ) ) { + return -1; + } + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( b == document || b.ownerDocument == preferredDoc && + contains( preferredDoc, b ) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + /* eslint-disable eqeqeq */ + return a == document ? -1 : + b == document ? 1 : + /* eslint-enable eqeqeq */ + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( ( cur = cur.parentNode ) ) { + ap.unshift( cur ); + } + cur = b; + while ( ( cur = cur.parentNode ) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[ i ] === bp[ i ] ) { + i++; + } + + return i ? + + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[ i ], bp[ i ] ) : + + // Otherwise nodes in our document sort first + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + /* eslint-disable eqeqeq */ + ap[ i ] == preferredDoc ? -1 : + bp[ i ] == preferredDoc ? 1 : + /* eslint-enable eqeqeq */ + 0; + }; + + return document; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + setDocument( elem ); + + if ( support.matchesSelector && documentIsHTML && + !nonnativeSelectorCache[ expr + " " ] && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch ( e ) { + nonnativeSelectorCache( expr, true ); + } + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + + // Set document vars if needed + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( ( context.ownerDocument || context ) != document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + + // Set document vars if needed + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( ( elem.ownerDocument || elem ) != document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + ( val = elem.getAttributeNode( name ) ) && val.specified ? + val.value : + null; +}; + +Sizzle.escape = function( sel ) { + return ( sel + "" ).replace( rcssescape, fcssescape ); +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( ( elem = results[ i++ ] ) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + + // If no nodeType, this is expected to be an array + while ( ( node = elem[ i++ ] ) ) { + + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[ 1 ] = match[ 1 ].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[ 3 ] = ( match[ 3 ] || match[ 4 ] || + match[ 5 ] || "" ).replace( runescape, funescape ); + + if ( match[ 2 ] === "~=" ) { + match[ 3 ] = " " + match[ 3 ] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[ 1 ] = match[ 1 ].toLowerCase(); + + if ( match[ 1 ].slice( 0, 3 ) === "nth" ) { + + // nth-* requires argument + if ( !match[ 3 ] ) { + Sizzle.error( match[ 0 ] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[ 4 ] = +( match[ 4 ] ? + match[ 5 ] + ( match[ 6 ] || 1 ) : + 2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) ); + match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" ); + + // other types prohibit arguments + } else if ( match[ 3 ] ) { + Sizzle.error( match[ 0 ] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[ 6 ] && match[ 2 ]; + + if ( matchExpr[ "CHILD" ].test( match[ 0 ] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[ 3 ] ) { + match[ 2 ] = match[ 4 ] || match[ 5 ] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + + // Get excess from tokenize (recursively) + ( excess = tokenize( unquoted, true ) ) && + + // advance to the next closing parenthesis + ( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) { + + // excess is a negative index + match[ 0 ] = match[ 0 ].slice( 0, excess ); + match[ 2 ] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { + return true; + } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + ( pattern = new RegExp( "(^|" + whitespace + + ")" + className + "(" + whitespace + "|$)" ) ) && classCache( + className, function( elem ) { + return pattern.test( + typeof elem.className === "string" && elem.className || + typeof elem.getAttribute !== "undefined" && + elem.getAttribute( "class" ) || + "" + ); + } ); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + /* eslint-disable max-len */ + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + /* eslint-enable max-len */ + + }; + }, + + "CHILD": function( type, what, _argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, _context, xml ) { + var cache, uniqueCache, outerCache, node, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType, + diff = false; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( ( node = node[ dir ] ) ) { + if ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) { + + return false; + } + } + + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + + // Seek `elem` from a previously-cached index + + // ...in a gzip-friendly way + node = parent; + outerCache = node[ expando ] || ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex && cache[ 2 ]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( ( node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + ( diff = nodeIndex = 0 ) || start.pop() ) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + } else { + + // Use previously-cached element index if available + if ( useCache ) { + + // ...in a gzip-friendly way + node = elem; + outerCache = node[ expando ] || ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex; + } + + // xml :nth-child(...) + // or :nth-last-child(...) or :nth(-last)?-of-type(...) + if ( diff === false ) { + + // Use the same loop as above to seek `elem` from the start + while ( ( node = ++nodeIndex && node && node[ dir ] || + ( diff = nodeIndex = 0 ) || start.pop() ) ) { + + if ( ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) && + ++diff ) { + + // Cache the index of each encountered element + if ( useCache ) { + outerCache = node[ expando ] || + ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + uniqueCache[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction( function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf( seed, matched[ i ] ); + seed[ idx ] = !( matches[ idx ] = matched[ i ] ); + } + } ) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + + // Potentially complex pseudos + "not": markFunction( function( selector ) { + + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction( function( seed, matches, _context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( ( elem = unmatched[ i ] ) ) { + seed[ i ] = !( matches[ i ] = elem ); + } + } + } ) : + function( elem, _context, xml ) { + input[ 0 ] = elem; + matcher( input, null, xml, results ); + + // Don't keep the element (issue #299) + input[ 0 ] = null; + return !results.pop(); + }; + } ), + + "has": markFunction( function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + } ), + + "contains": markFunction( function( text ) { + text = text.replace( runescape, funescape ); + return function( elem ) { + return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1; + }; + } ), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + + // lang value must be a valid identifier + if ( !ridentifier.test( lang || "" ) ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( ( elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( ( elem = elem.parentNode ) && elem.nodeType === 1 ); + return false; + }; + } ), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && + ( !document.hasFocus || document.hasFocus() ) && + !!( elem.type || elem.href || ~elem.tabIndex ); + }, + + // Boolean properties + "enabled": createDisabledPseudo( false ), + "disabled": createDisabledPseudo( true ), + + "checked": function( elem ) { + + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return ( nodeName === "input" && !!elem.checked ) || + ( nodeName === "option" && !!elem.selected ); + }, + + "selected": function( elem ) { + + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + // eslint-disable-next-line no-unused-expressions + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos[ "empty" ]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( ( attr = elem.getAttribute( "type" ) ) == null || + attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo( function() { + return [ 0 ]; + } ), + + "last": createPositionalPseudo( function( _matchIndexes, length ) { + return [ length - 1 ]; + } ), + + "eq": createPositionalPseudo( function( _matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + } ), + + "even": createPositionalPseudo( function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "odd": createPositionalPseudo( function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "lt": createPositionalPseudo( function( matchIndexes, length, argument ) { + var i = argument < 0 ? + argument + length : + argument > length ? + length : + argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "gt": createPositionalPseudo( function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ) + } +}; + +Expr.pseudos[ "nth" ] = Expr.pseudos[ "eq" ]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +tokenize = Sizzle.tokenize = function( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || ( match = rcomma.exec( soFar ) ) ) { + if ( match ) { + + // Don't consume trailing commas as valid + soFar = soFar.slice( match[ 0 ].length ) || soFar; + } + groups.push( ( tokens = [] ) ); + } + + matched = false; + + // Combinators + if ( ( match = rcombinators.exec( soFar ) ) ) { + matched = match.shift(); + tokens.push( { + value: matched, + + // Cast descendant combinators to space + type: match[ 0 ].replace( rtrim, " " ) + } ); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] || + ( match = preFilters[ type ]( match ) ) ) ) { + matched = match.shift(); + tokens.push( { + value: matched, + type: type, + matches: match + } ); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +}; + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[ i ].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + skip = combinator.next, + key = skip || dir, + checkNonElements = base && key === "parentNode", + doneName = done++; + + return combinator.first ? + + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + return false; + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, uniqueCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching + if ( xml ) { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || ( elem[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ elem.uniqueID ] || + ( outerCache[ elem.uniqueID ] = {} ); + + if ( skip && skip === elem.nodeName.toLowerCase() ) { + elem = elem[ dir ] || elem; + } else if ( ( oldCache = uniqueCache[ key ] ) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return ( newCache[ 2 ] = oldCache[ 2 ] ); + } else { + + // Reuse newcache so results back-propagate to previous elements + uniqueCache[ key ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) { + return true; + } + } + } + } + } + return false; + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[ i ]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[ 0 ]; +} + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[ i ], results ); + } + return results; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( ( elem = unmatched[ i ] ) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction( function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( + selector || "*", + context.nodeType ? [ context ] : context, + [] + ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( ( elem = temp[ i ] ) ) { + matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem ); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( ( elem = matcherOut[ i ] ) ) { + + // Restore matcherIn since elem is not yet a final match + temp.push( ( matcherIn[ i ] = elem ) ); + } + } + postFinder( null, ( matcherOut = [] ), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( ( elem = matcherOut[ i ] ) && + ( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) { + + seed[ temp ] = !( results[ temp ] = elem ); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + } ); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[ 0 ].type ], + implicitRelative = leadingRelative || Expr.relative[ " " ], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + ( checkContext = context ).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + + // Avoid hanging onto element (issue #299) + checkContext = null; + return ret; + } ]; + + for ( ; i < len; i++ ) { + if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) { + matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; + } else { + matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[ j ].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens + .slice( 0, i - 1 ) + .concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } ) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find[ "TAG" ]( "*", outermost ), + + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ), + len = elems.length; + + if ( outermost ) { + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + outermostContext = context == document || context || outermost; + } + + // Add elements passing elementMatchers directly to results + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id + for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( !context && elem.ownerDocument != document ) { + setDocument( elem ); + xml = !documentIsHTML; + } + while ( ( matcher = elementMatchers[ j++ ] ) ) { + if ( matcher( elem, context || document, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + + // They will have gone through all possible matchers + if ( ( elem = !matcher && elem ) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // `i` is now the count of elements visited above, and adding it to `matchedCount` + // makes the latter nonnegative. + matchedCount += i; + + // Apply set filters to unmatched elements + // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` + // equals `i`), unless we didn't visit _any_ elements in the above loop because we have + // no element matchers and no seed. + // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that + // case, which will result in a "00" `matchedCount` that differs from `i` but is also + // numerically zero. + if ( bySet && i !== matchedCount ) { + j = 0; + while ( ( matcher = setMatchers[ j++ ] ) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !( unmatched[ i ] || setMatched[ i ] ) ) { + setMatched[ i ] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[ i ] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( + selector, + matcherFromGroupMatchers( elementMatchers, setMatchers ) + ); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; +}; + +/** + * A low-level selection function that works with Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ +select = Sizzle.select = function( selector, context, results, seed ) { + var i, tokens, token, type, find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize( ( selector = compiled.selector || selector ) ); + + results = results || []; + + // Try to minimize operations if there is only one selector in the list and no seed + // (the latter of which guarantees us context) + if ( match.length === 1 ) { + + // Reduce context if the leading compound selector is an ID + tokens = match[ 0 ] = match[ 0 ].slice( 0 ); + if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" && + context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) { + + context = ( Expr.find[ "ID" ]( token.matches[ 0 ] + .replace( runescape, funescape ), context ) || [] )[ 0 ]; + if ( !context ) { + return results; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr[ "needsContext" ].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[ i ]; + + // Abort if we hit a combinator + if ( Expr.relative[ ( type = token.type ) ] ) { + break; + } + if ( ( find = Expr.find[ type ] ) ) { + + // Search, expanding context for leading sibling combinators + if ( ( seed = find( + token.matches[ 0 ].replace( runescape, funescape ), + rsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) || + context + ) ) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + !context || rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; +}; + +// One-time assignments + +// Sort stability +support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando; + +// Support: Chrome 14-35+ +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = !!hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert( function( el ) { + + // Should return 1, but returns 4 (following) + return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1; +} ); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert( function( el ) { + el.innerHTML = ""; + return el.firstChild.getAttribute( "href" ) === "#"; +} ) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + } ); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert( function( el ) { + el.innerHTML = ""; + el.firstChild.setAttribute( "value", "" ); + return el.firstChild.getAttribute( "value" ) === ""; +} ) ) { + addHandle( "value", function( elem, _name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + } ); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert( function( el ) { + return el.getAttribute( "disabled" ) == null; +} ) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + ( val = elem.getAttributeNode( name ) ) && val.specified ? + val.value : + null; + } + } ); +} + +return Sizzle; + +} )( window ); + + + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; + +// Deprecated +jQuery.expr[ ":" ] = jQuery.expr.pseudos; +jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; +jQuery.escapeSelector = Sizzle.escape; + + + + +var dir = function( elem, dir, until ) { + var matched = [], + truncate = until !== undefined; + + while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { + if ( elem.nodeType === 1 ) { + if ( truncate && jQuery( elem ).is( until ) ) { + break; + } + matched.push( elem ); + } + } + return matched; +}; + + +var siblings = function( n, elem ) { + var matched = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + matched.push( n ); + } + } + + return matched; +}; + + +var rneedsContext = jQuery.expr.match.needsContext; + + + +function nodeName( elem, name ) { + + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + +}; +var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); + + + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + return !!qualifier.call( elem, i, elem ) !== not; + } ); + } + + // Single element + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + } ); + } + + // Arraylike of elements (jQuery, arguments, Array) + if ( typeof qualifier !== "string" ) { + return jQuery.grep( elements, function( elem ) { + return ( indexOf.call( qualifier, elem ) > -1 ) !== not; + } ); + } + + // Filtered directly for both simple and complex selectors + return jQuery.filter( qualifier, elements, not ); +} + +jQuery.filter = function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + if ( elems.length === 1 && elem.nodeType === 1 ) { + return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; + } + + return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + } ) ); +}; + +jQuery.fn.extend( { + find: function( selector ) { + var i, ret, + len = this.length, + self = this; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter( function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + } ) ); + } + + ret = this.pushStack( [] ); + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + return len > 1 ? jQuery.uniqueSort( ret ) : ret; + }, + filter: function( selector ) { + return this.pushStack( winnow( this, selector || [], false ) ); + }, + not: function( selector ) { + return this.pushStack( winnow( this, selector || [], true ) ); + }, + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } +} ); + + +// Initialize a jQuery object + + +// A central reference to the root jQuery(document) +var rootjQuery, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + // Shortcut simple #id case for speed + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, + + init = jQuery.fn.init = function( selector, context, root ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Method init() accepts an alternate rootjQuery + // so migrate can support jQuery.sub (gh-2101) + root = root || rootjQuery; + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector[ 0 ] === "<" && + selector[ selector.length - 1 ] === ">" && + selector.length >= 3 ) { + + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && ( match[ 1 ] || !context ) ) { + + // HANDLE: $(html) -> $(array) + if ( match[ 1 ] ) { + context = context instanceof jQuery ? context[ 0 ] : context; + + // Option to run scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[ 1 ], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + + // Properties of context are called as methods if possible + if ( isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[ 2 ] ); + + if ( elem ) { + + // Inject the element directly into the jQuery object + this[ 0 ] = elem; + this.length = 1; + } + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || root ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this[ 0 ] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( isFunction( selector ) ) { + return root.ready !== undefined ? + root.ready( selector ) : + + // Execute immediately if ready is not present + selector( jQuery ); + } + + return jQuery.makeArray( selector, this ); + }; + +// Give the init function the jQuery prototype for later instantiation +init.prototype = jQuery.fn; + +// Initialize central reference +rootjQuery = jQuery( document ); + + +var rparentsprev = /^(?:parents|prev(?:Until|All))/, + + // Methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend( { + has: function( target ) { + var targets = jQuery( target, this ), + l = targets.length; + + return this.filter( function() { + var i = 0; + for ( ; i < l; i++ ) { + if ( jQuery.contains( this, targets[ i ] ) ) { + return true; + } + } + } ); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + matched = [], + targets = typeof selectors !== "string" && jQuery( selectors ); + + // Positional selectors never match, since there's no _selection_ context + if ( !rneedsContext.test( selectors ) ) { + for ( ; i < l; i++ ) { + for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { + + // Always skip document fragments + if ( cur.nodeType < 11 && ( targets ? + targets.index( cur ) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector( cur, selectors ) ) ) { + + matched.push( cur ); + break; + } + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); + }, + + // Determine the position of an element within the set + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; + } + + // Index in selector + if ( typeof elem === "string" ) { + return indexOf.call( jQuery( elem ), this[ 0 ] ); + } + + // Locate the position of the desired element + return indexOf.call( this, + + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[ 0 ] : elem + ); + }, + + add: function( selector, context ) { + return this.pushStack( + jQuery.uniqueSort( + jQuery.merge( this.get(), jQuery( selector, context ) ) + ) + ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter( selector ) + ); + } +} ); + +function sibling( cur, dir ) { + while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} + return cur; +} + +jQuery.each( { + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, _i, until ) { + return dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, _i, until ) { + return dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, _i, until ) { + return dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return siblings( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return siblings( elem.firstChild ); + }, + contents: function( elem ) { + if ( elem.contentDocument != null && + + // Support: IE 11+ + // elements with no `data` attribute has an object + // `contentDocument` with a `null` prototype. + getProto( elem.contentDocument ) ) { + + return elem.contentDocument; + } + + // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only + // Treat the template element as a regular one in browsers that + // don't support it. + if ( nodeName( elem, "template" ) ) { + elem = elem.content || elem; + } + + return jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var matched = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + matched = jQuery.filter( selector, matched ); + } + + if ( this.length > 1 ) { + + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + jQuery.uniqueSort( matched ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + matched.reverse(); + } + } + + return this.pushStack( matched ); + }; +} ); +var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); + + + +// Convert String-formatted options into Object-formatted ones +function createOptions( options ) { + var object = {}; + jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { + object[ flag ] = true; + } ); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + createOptions( options ) : + jQuery.extend( {}, options ); + + var // Flag to know if list is currently firing + firing, + + // Last fire value for non-forgettable lists + memory, + + // Flag to know if list was already fired + fired, + + // Flag to prevent firing + locked, + + // Actual callback list + list = [], + + // Queue of execution data for repeatable lists + queue = [], + + // Index of currently firing callback (modified by add/remove as needed) + firingIndex = -1, + + // Fire callbacks + fire = function() { + + // Enforce single-firing + locked = locked || options.once; + + // Execute callbacks for all pending executions, + // respecting firingIndex overrides and runtime changes + fired = firing = true; + for ( ; queue.length; firingIndex = -1 ) { + memory = queue.shift(); + while ( ++firingIndex < list.length ) { + + // Run callback and check for early termination + if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && + options.stopOnFalse ) { + + // Jump to end and forget the data so .add doesn't re-fire + firingIndex = list.length; + memory = false; + } + } + } + + // Forget the data if we're done with it + if ( !options.memory ) { + memory = false; + } + + firing = false; + + // Clean up if we're done firing for good + if ( locked ) { + + // Keep an empty list if we have data for future add calls + if ( memory ) { + list = []; + + // Otherwise, this object is spent + } else { + list = ""; + } + } + }, + + // Actual Callbacks object + self = { + + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + + // If we have memory from a past run, we should fire after adding + if ( memory && !firing ) { + firingIndex = list.length - 1; + queue.push( memory ); + } + + ( function add( args ) { + jQuery.each( args, function( _, arg ) { + if ( isFunction( arg ) ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && toType( arg ) !== "string" ) { + + // Inspect recursively + add( arg ); + } + } ); + } )( arguments ); + + if ( memory && !firing ) { + fire(); + } + } + return this; + }, + + // Remove a callback from the list + remove: function() { + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + + // Handle firing indexes + if ( index <= firingIndex ) { + firingIndex--; + } + } + } ); + return this; + }, + + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? + jQuery.inArray( fn, list ) > -1 : + list.length > 0; + }, + + // Remove all callbacks from the list + empty: function() { + if ( list ) { + list = []; + } + return this; + }, + + // Disable .fire and .add + // Abort any current/pending executions + // Clear all callbacks and values + disable: function() { + locked = queue = []; + list = memory = ""; + return this; + }, + disabled: function() { + return !list; + }, + + // Disable .fire + // Also disable .add unless we have memory (since it would have no effect) + // Abort any pending executions + lock: function() { + locked = queue = []; + if ( !memory && !firing ) { + list = memory = ""; + } + return this; + }, + locked: function() { + return !!locked; + }, + + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( !locked ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + queue.push( args ); + if ( !firing ) { + fire(); + } + } + return this; + }, + + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + +function Identity( v ) { + return v; +} +function Thrower( ex ) { + throw ex; +} + +function adoptValue( value, resolve, reject, noValue ) { + var method; + + try { + + // Check for promise aspect first to privilege synchronous behavior + if ( value && isFunction( ( method = value.promise ) ) ) { + method.call( value ).done( resolve ).fail( reject ); + + // Other thenables + } else if ( value && isFunction( ( method = value.then ) ) ) { + method.call( value, resolve, reject ); + + // Other non-thenables + } else { + + // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: + // * false: [ value ].slice( 0 ) => resolve( value ) + // * true: [ value ].slice( 1 ) => resolve() + resolve.apply( undefined, [ value ].slice( noValue ) ); + } + + // For Promises/A+, convert exceptions into rejections + // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in + // Deferred#then to conditionally suppress rejection. + } catch ( value ) { + + // Support: Android 4.0 only + // Strict mode functions invoked without .call/.apply get global-object context + reject.apply( undefined, [ value ] ); + } +} + +jQuery.extend( { + + Deferred: function( func ) { + var tuples = [ + + // action, add listener, callbacks, + // ... .then handlers, argument index, [final state] + [ "notify", "progress", jQuery.Callbacks( "memory" ), + jQuery.Callbacks( "memory" ), 2 ], + [ "resolve", "done", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 0, "resolved" ], + [ "reject", "fail", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 1, "rejected" ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + "catch": function( fn ) { + return promise.then( null, fn ); + }, + + // Keep pipe for back-compat + pipe: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + + return jQuery.Deferred( function( newDefer ) { + jQuery.each( tuples, function( _i, tuple ) { + + // Map tuples (progress, done, fail) to arguments (done, fail, progress) + var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; + + // deferred.progress(function() { bind to newDefer or newDefer.notify }) + // deferred.done(function() { bind to newDefer or newDefer.resolve }) + // deferred.fail(function() { bind to newDefer or newDefer.reject }) + deferred[ tuple[ 1 ] ]( function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && isFunction( returned.promise ) ) { + returned.promise() + .progress( newDefer.notify ) + .done( newDefer.resolve ) + .fail( newDefer.reject ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( + this, + fn ? [ returned ] : arguments + ); + } + } ); + } ); + fns = null; + } ).promise(); + }, + then: function( onFulfilled, onRejected, onProgress ) { + var maxDepth = 0; + function resolve( depth, deferred, handler, special ) { + return function() { + var that = this, + args = arguments, + mightThrow = function() { + var returned, then; + + // Support: Promises/A+ section 2.3.3.3.3 + // https://promisesaplus.com/#point-59 + // Ignore double-resolution attempts + if ( depth < maxDepth ) { + return; + } + + returned = handler.apply( that, args ); + + // Support: Promises/A+ section 2.3.1 + // https://promisesaplus.com/#point-48 + if ( returned === deferred.promise() ) { + throw new TypeError( "Thenable self-resolution" ); + } + + // Support: Promises/A+ sections 2.3.3.1, 3.5 + // https://promisesaplus.com/#point-54 + // https://promisesaplus.com/#point-75 + // Retrieve `then` only once + then = returned && + + // Support: Promises/A+ section 2.3.4 + // https://promisesaplus.com/#point-64 + // Only check objects and functions for thenability + ( typeof returned === "object" || + typeof returned === "function" ) && + returned.then; + + // Handle a returned thenable + if ( isFunction( then ) ) { + + // Special processors (notify) just wait for resolution + if ( special ) { + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ) + ); + + // Normal processors (resolve) also hook into progress + } else { + + // ...and disregard older resolution values + maxDepth++; + + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ), + resolve( maxDepth, deferred, Identity, + deferred.notifyWith ) + ); + } + + // Handle all other returned values + } else { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Identity ) { + that = undefined; + args = [ returned ]; + } + + // Process the value(s) + // Default process is resolve + ( special || deferred.resolveWith )( that, args ); + } + }, + + // Only normal processors (resolve) catch and reject exceptions + process = special ? + mightThrow : + function() { + try { + mightThrow(); + } catch ( e ) { + + if ( jQuery.Deferred.exceptionHook ) { + jQuery.Deferred.exceptionHook( e, + process.stackTrace ); + } + + // Support: Promises/A+ section 2.3.3.3.4.1 + // https://promisesaplus.com/#point-61 + // Ignore post-resolution exceptions + if ( depth + 1 >= maxDepth ) { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Thrower ) { + that = undefined; + args = [ e ]; + } + + deferred.rejectWith( that, args ); + } + } + }; + + // Support: Promises/A+ section 2.3.3.3.1 + // https://promisesaplus.com/#point-57 + // Re-resolve promises immediately to dodge false rejection from + // subsequent errors + if ( depth ) { + process(); + } else { + + // Call an optional hook to record the stack, in case of exception + // since it's otherwise lost when execution goes async + if ( jQuery.Deferred.getStackHook ) { + process.stackTrace = jQuery.Deferred.getStackHook(); + } + window.setTimeout( process ); + } + }; + } + + return jQuery.Deferred( function( newDefer ) { + + // progress_handlers.add( ... ) + tuples[ 0 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onProgress ) ? + onProgress : + Identity, + newDefer.notifyWith + ) + ); + + // fulfilled_handlers.add( ... ) + tuples[ 1 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onFulfilled ) ? + onFulfilled : + Identity + ) + ); + + // rejected_handlers.add( ... ) + tuples[ 2 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onRejected ) ? + onRejected : + Thrower + ) + ); + } ).promise(); + }, + + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 5 ]; + + // promise.progress = list.add + // promise.done = list.add + // promise.fail = list.add + promise[ tuple[ 1 ] ] = list.add; + + // Handle state + if ( stateString ) { + list.add( + function() { + + // state = "resolved" (i.e., fulfilled) + // state = "rejected" + state = stateString; + }, + + // rejected_callbacks.disable + // fulfilled_callbacks.disable + tuples[ 3 - i ][ 2 ].disable, + + // rejected_handlers.disable + // fulfilled_handlers.disable + tuples[ 3 - i ][ 3 ].disable, + + // progress_callbacks.lock + tuples[ 0 ][ 2 ].lock, + + // progress_handlers.lock + tuples[ 0 ][ 3 ].lock + ); + } + + // progress_handlers.fire + // fulfilled_handlers.fire + // rejected_handlers.fire + list.add( tuple[ 3 ].fire ); + + // deferred.notify = function() { deferred.notifyWith(...) } + // deferred.resolve = function() { deferred.resolveWith(...) } + // deferred.reject = function() { deferred.rejectWith(...) } + deferred[ tuple[ 0 ] ] = function() { + deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); + return this; + }; + + // deferred.notifyWith = list.fireWith + // deferred.resolveWith = list.fireWith + // deferred.rejectWith = list.fireWith + deferred[ tuple[ 0 ] + "With" ] = list.fireWith; + } ); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( singleValue ) { + var + + // count of uncompleted subordinates + remaining = arguments.length, + + // count of unprocessed arguments + i = remaining, + + // subordinate fulfillment data + resolveContexts = Array( i ), + resolveValues = slice.call( arguments ), + + // the master Deferred + master = jQuery.Deferred(), + + // subordinate callback factory + updateFunc = function( i ) { + return function( value ) { + resolveContexts[ i ] = this; + resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( !( --remaining ) ) { + master.resolveWith( resolveContexts, resolveValues ); + } + }; + }; + + // Single- and empty arguments are adopted like Promise.resolve + if ( remaining <= 1 ) { + adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject, + !remaining ); + + // Use .then() to unwrap secondary thenables (cf. gh-3000) + if ( master.state() === "pending" || + isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { + + return master.then(); + } + } + + // Multiple arguments are aggregated like Promise.all array elements + while ( i-- ) { + adoptValue( resolveValues[ i ], updateFunc( i ), master.reject ); + } + + return master.promise(); + } +} ); + + +// These usually indicate a programmer mistake during development, +// warn about them ASAP rather than swallowing them by default. +var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; + +jQuery.Deferred.exceptionHook = function( error, stack ) { + + // Support: IE 8 - 9 only + // Console exists when dev tools are open, which can happen at any time + if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { + window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); + } +}; + + + + +jQuery.readyException = function( error ) { + window.setTimeout( function() { + throw error; + } ); +}; + + + + +// The deferred used on DOM ready +var readyList = jQuery.Deferred(); + +jQuery.fn.ready = function( fn ) { + + readyList + .then( fn ) + + // Wrap jQuery.readyException in a function so that the lookup + // happens at the time of error handling instead of callback + // registration. + .catch( function( error ) { + jQuery.readyException( error ); + } ); + + return this; +}; + +jQuery.extend( { + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + } +} ); + +jQuery.ready.then = readyList.then; + +// The ready event handler and self cleanup method +function completed() { + document.removeEventListener( "DOMContentLoaded", completed ); + window.removeEventListener( "load", completed ); + jQuery.ready(); +} + +// Catch cases where $(document).ready() is called +// after the browser event has already occurred. +// Support: IE <=9 - 10 only +// Older IE sometimes signals "interactive" too soon +if ( document.readyState === "complete" || + ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { + + // Handle it asynchronously to allow scripts the opportunity to delay ready + window.setTimeout( jQuery.ready ); + +} else { + + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed ); +} + + + + +// Multifunctional method to get and set values of a collection +// The value/s can optionally be executed if it's a function +var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + len = elems.length, + bulk = key == null; + + // Sets many values + if ( toType( key ) === "object" ) { + chainable = true; + for ( i in key ) { + access( elems, fn, i, key[ i ], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, _key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < len; i++ ) { + fn( + elems[ i ], key, raw ? + value : + value.call( elems[ i ], i, fn( elems[ i ], key ) ) + ); + } + } + } + + if ( chainable ) { + return elems; + } + + // Gets + if ( bulk ) { + return fn.call( elems ); + } + + return len ? fn( elems[ 0 ], key ) : emptyGet; +}; + + +// Matches dashed string for camelizing +var rmsPrefix = /^-ms-/, + rdashAlpha = /-([a-z])/g; + +// Used by camelCase as callback to replace() +function fcamelCase( _all, letter ) { + return letter.toUpperCase(); +} + +// Convert dashed to camelCase; used by the css and data modules +// Support: IE <=9 - 11, Edge 12 - 15 +// Microsoft forgot to hump their vendor prefix (#9572) +function camelCase( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); +} +var acceptData = function( owner ) { + + // Accepts only: + // - Node + // - Node.ELEMENT_NODE + // - Node.DOCUMENT_NODE + // - Object + // - Any + return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); +}; + + + + +function Data() { + this.expando = jQuery.expando + Data.uid++; +} + +Data.uid = 1; + +Data.prototype = { + + cache: function( owner ) { + + // Check if the owner object already has a cache + var value = owner[ this.expando ]; + + // If not, create one + if ( !value ) { + value = {}; + + // We can accept data for non-element nodes in modern browsers, + // but we should not, see #8335. + // Always return an empty object. + if ( acceptData( owner ) ) { + + // If it is a node unlikely to be stringify-ed or looped over + // use plain assignment + if ( owner.nodeType ) { + owner[ this.expando ] = value; + + // Otherwise secure it in a non-enumerable property + // configurable must be true to allow the property to be + // deleted when data is removed + } else { + Object.defineProperty( owner, this.expando, { + value: value, + configurable: true + } ); + } + } + } + + return value; + }, + set: function( owner, data, value ) { + var prop, + cache = this.cache( owner ); + + // Handle: [ owner, key, value ] args + // Always use camelCase key (gh-2257) + if ( typeof data === "string" ) { + cache[ camelCase( data ) ] = value; + + // Handle: [ owner, { properties } ] args + } else { + + // Copy the properties one-by-one to the cache object + for ( prop in data ) { + cache[ camelCase( prop ) ] = data[ prop ]; + } + } + return cache; + }, + get: function( owner, key ) { + return key === undefined ? + this.cache( owner ) : + + // Always use camelCase key (gh-2257) + owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; + }, + access: function( owner, key, value ) { + + // In cases where either: + // + // 1. No key was specified + // 2. A string key was specified, but no value provided + // + // Take the "read" path and allow the get method to determine + // which value to return, respectively either: + // + // 1. The entire cache object + // 2. The data stored at the key + // + if ( key === undefined || + ( ( key && typeof key === "string" ) && value === undefined ) ) { + + return this.get( owner, key ); + } + + // When the key is not a string, or both a key and value + // are specified, set or extend (existing objects) with either: + // + // 1. An object of properties + // 2. A key and value + // + this.set( owner, key, value ); + + // Since the "set" path can have two possible entry points + // return the expected data based on which path was taken[*] + return value !== undefined ? value : key; + }, + remove: function( owner, key ) { + var i, + cache = owner[ this.expando ]; + + if ( cache === undefined ) { + return; + } + + if ( key !== undefined ) { + + // Support array or space separated string of keys + if ( Array.isArray( key ) ) { + + // If key is an array of keys... + // We always set camelCase keys, so remove that. + key = key.map( camelCase ); + } else { + key = camelCase( key ); + + // If a key with the spaces exists, use it. + // Otherwise, create an array by matching non-whitespace + key = key in cache ? + [ key ] : + ( key.match( rnothtmlwhite ) || [] ); + } + + i = key.length; + + while ( i-- ) { + delete cache[ key[ i ] ]; + } + } + + // Remove the expando if there's no more data + if ( key === undefined || jQuery.isEmptyObject( cache ) ) { + + // Support: Chrome <=35 - 45 + // Webkit & Blink performance suffers when deleting properties + // from DOM nodes, so set to undefined instead + // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) + if ( owner.nodeType ) { + owner[ this.expando ] = undefined; + } else { + delete owner[ this.expando ]; + } + } + }, + hasData: function( owner ) { + var cache = owner[ this.expando ]; + return cache !== undefined && !jQuery.isEmptyObject( cache ); + } +}; +var dataPriv = new Data(); + +var dataUser = new Data(); + + + +// Implementation Summary +// +// 1. Enforce API surface and semantic compatibility with 1.9.x branch +// 2. Improve the module's maintainability by reducing the storage +// paths to a single mechanism. +// 3. Use the same single mechanism to support "private" and "user" data. +// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) +// 5. Avoid exposing implementation details on user objects (eg. expando properties) +// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 + +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /[A-Z]/g; + +function getData( data ) { + if ( data === "true" ) { + return true; + } + + if ( data === "false" ) { + return false; + } + + if ( data === "null" ) { + return null; + } + + // Only convert to a number if it doesn't change the string + if ( data === +data + "" ) { + return +data; + } + + if ( rbrace.test( data ) ) { + return JSON.parse( data ); + } + + return data; +} + +function dataAttr( elem, key, data ) { + var name; + + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = getData( data ); + } catch ( e ) {} + + // Make sure we set the data so it isn't changed later + dataUser.set( elem, key, data ); + } else { + data = undefined; + } + } + return data; +} + +jQuery.extend( { + hasData: function( elem ) { + return dataUser.hasData( elem ) || dataPriv.hasData( elem ); + }, + + data: function( elem, name, data ) { + return dataUser.access( elem, name, data ); + }, + + removeData: function( elem, name ) { + dataUser.remove( elem, name ); + }, + + // TODO: Now that all calls to _data and _removeData have been replaced + // with direct calls to dataPriv methods, these can be deprecated. + _data: function( elem, name, data ) { + return dataPriv.access( elem, name, data ); + }, + + _removeData: function( elem, name ) { + dataPriv.remove( elem, name ); + } +} ); + +jQuery.fn.extend( { + data: function( key, value ) { + var i, name, data, + elem = this[ 0 ], + attrs = elem && elem.attributes; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = dataUser.get( elem ); + + if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { + i = attrs.length; + while ( i-- ) { + + // Support: IE 11 only + // The attrs elements can be null (#14894) + if ( attrs[ i ] ) { + name = attrs[ i ].name; + if ( name.indexOf( "data-" ) === 0 ) { + name = camelCase( name.slice( 5 ) ); + dataAttr( elem, name, data[ name ] ); + } + } + } + dataPriv.set( elem, "hasDataAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each( function() { + dataUser.set( this, key ); + } ); + } + + return access( this, function( value ) { + var data; + + // The calling jQuery object (element matches) is not empty + // (and therefore has an element appears at this[ 0 ]) and the + // `value` parameter was not undefined. An empty jQuery object + // will result in `undefined` for elem = this[ 0 ] which will + // throw an exception if an attempt to read a data cache is made. + if ( elem && value === undefined ) { + + // Attempt to get data from the cache + // The key will always be camelCased in Data + data = dataUser.get( elem, key ); + if ( data !== undefined ) { + return data; + } + + // Attempt to "discover" the data in + // HTML5 custom data-* attrs + data = dataAttr( elem, key ); + if ( data !== undefined ) { + return data; + } + + // We tried really hard, but the data doesn't exist. + return; + } + + // Set the data... + this.each( function() { + + // We always store the camelCased key + dataUser.set( this, key, value ); + } ); + }, null, value, arguments.length > 1, null, true ); + }, + + removeData: function( key ) { + return this.each( function() { + dataUser.remove( this, key ); + } ); + } +} ); + + +jQuery.extend( { + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = dataPriv.get( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || Array.isArray( data ) ) { + queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // Clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // Not public - generate a queueHooks object, or return the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { + empty: jQuery.Callbacks( "once memory" ).add( function() { + dataPriv.remove( elem, [ type + "queue", key ] ); + } ) + } ); + } +} ); + +jQuery.fn.extend( { + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[ 0 ], type ); + } + + return data === undefined ? + this : + this.each( function() { + var queue = jQuery.queue( this, type, data ); + + // Ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + } ); + }, + dequeue: function( type ) { + return this.each( function() { + jQuery.dequeue( this, type ); + } ); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while ( i-- ) { + tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +} ); +var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; + +var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); + + +var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; + +var documentElement = document.documentElement; + + + + var isAttached = function( elem ) { + return jQuery.contains( elem.ownerDocument, elem ); + }, + composed = { composed: true }; + + // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only + // Check attachment across shadow DOM boundaries when possible (gh-3504) + // Support: iOS 10.0-10.2 only + // Early iOS 10 versions support `attachShadow` but not `getRootNode`, + // leading to errors. We need to check for `getRootNode`. + if ( documentElement.getRootNode ) { + isAttached = function( elem ) { + return jQuery.contains( elem.ownerDocument, elem ) || + elem.getRootNode( composed ) === elem.ownerDocument; + }; + } +var isHiddenWithinTree = function( elem, el ) { + + // isHiddenWithinTree might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + + // Inline style trumps all + return elem.style.display === "none" || + elem.style.display === "" && + + // Otherwise, check computed style + // Support: Firefox <=43 - 45 + // Disconnected elements can have computed display: none, so first confirm that elem is + // in the document. + isAttached( elem ) && + + jQuery.css( elem, "display" ) === "none"; + }; + + + +function adjustCSS( elem, prop, valueParts, tween ) { + var adjusted, scale, + maxIterations = 20, + currentValue = tween ? + function() { + return tween.cur(); + } : + function() { + return jQuery.css( elem, prop, "" ); + }, + initial = currentValue(), + unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), + + // Starting value computation is required for potential unit mismatches + initialInUnit = elem.nodeType && + ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && + rcssNum.exec( jQuery.css( elem, prop ) ); + + if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { + + // Support: Firefox <=54 + // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) + initial = initial / 2; + + // Trust units reported by jQuery.css + unit = unit || initialInUnit[ 3 ]; + + // Iteratively approximate from a nonzero starting point + initialInUnit = +initial || 1; + + while ( maxIterations-- ) { + + // Evaluate and update our best guess (doubling guesses that zero out). + // Finish if the scale equals or crosses 1 (making the old*new product non-positive). + jQuery.style( elem, prop, initialInUnit + unit ); + if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { + maxIterations = 0; + } + initialInUnit = initialInUnit / scale; + + } + + initialInUnit = initialInUnit * 2; + jQuery.style( elem, prop, initialInUnit + unit ); + + // Make sure we update the tween properties later on + valueParts = valueParts || []; + } + + if ( valueParts ) { + initialInUnit = +initialInUnit || +initial || 0; + + // Apply relative offset (+=/-=) if specified + adjusted = valueParts[ 1 ] ? + initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : + +valueParts[ 2 ]; + if ( tween ) { + tween.unit = unit; + tween.start = initialInUnit; + tween.end = adjusted; + } + } + return adjusted; +} + + +var defaultDisplayMap = {}; + +function getDefaultDisplay( elem ) { + var temp, + doc = elem.ownerDocument, + nodeName = elem.nodeName, + display = defaultDisplayMap[ nodeName ]; + + if ( display ) { + return display; + } + + temp = doc.body.appendChild( doc.createElement( nodeName ) ); + display = jQuery.css( temp, "display" ); + + temp.parentNode.removeChild( temp ); + + if ( display === "none" ) { + display = "block"; + } + defaultDisplayMap[ nodeName ] = display; + + return display; +} + +function showHide( elements, show ) { + var display, elem, + values = [], + index = 0, + length = elements.length; + + // Determine new display value for elements that need to change + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + + display = elem.style.display; + if ( show ) { + + // Since we force visibility upon cascade-hidden elements, an immediate (and slow) + // check is required in this first loop unless we have a nonempty display value (either + // inline or about-to-be-restored) + if ( display === "none" ) { + values[ index ] = dataPriv.get( elem, "display" ) || null; + if ( !values[ index ] ) { + elem.style.display = ""; + } + } + if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { + values[ index ] = getDefaultDisplay( elem ); + } + } else { + if ( display !== "none" ) { + values[ index ] = "none"; + + // Remember what we're overwriting + dataPriv.set( elem, "display", display ); + } + } + } + + // Set the display of the elements in a second loop to avoid constant reflow + for ( index = 0; index < length; index++ ) { + if ( values[ index ] != null ) { + elements[ index ].style.display = values[ index ]; + } + } + + return elements; +} + +jQuery.fn.extend( { + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state ) { + if ( typeof state === "boolean" ) { + return state ? this.show() : this.hide(); + } + + return this.each( function() { + if ( isHiddenWithinTree( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + } ); + } +} ); +var rcheckableType = ( /^(?:checkbox|radio)$/i ); + +var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i ); + +var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); + + + +( function() { + var fragment = document.createDocumentFragment(), + div = fragment.appendChild( document.createElement( "div" ) ), + input = document.createElement( "input" ); + + // Support: Android 4.0 - 4.3 only + // Check state lost if the name is set (#11217) + // Support: Windows Web Apps (WWA) + // `name` and `type` must use .setAttribute for WWA (#14901) + input.setAttribute( "type", "radio" ); + input.setAttribute( "checked", "checked" ); + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + + // Support: Android <=4.1 only + // Older WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE <=11 only + // Make sure textarea (and checkbox) defaultValue is properly cloned + div.innerHTML = ""; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; + + // Support: IE <=9 only + // IE <=9 replaces "; + support.option = !!div.lastChild; +} )(); + + +// We have to close these tags to support XHTML (#13200) +var wrapMap = { + + // XHTML parsers do not magically insert elements in the + // same way that tag soup parsers do. So we cannot shorten + // this by omitting or other required elements. + thead: [ 1, "", "
" ], + col: [ 2, "", "
" ], + tr: [ 2, "", "
" ], + td: [ 3, "", "
" ], + + _default: [ 0, "", "" ] +}; + +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// Support: IE <=9 only +if ( !support.option ) { + wrapMap.optgroup = wrapMap.option = [ 1, "" ]; +} + + +function getAll( context, tag ) { + + // Support: IE <=9 - 11 only + // Use typeof to avoid zero-argument method invocation on host objects (#15151) + var ret; + + if ( typeof context.getElementsByTagName !== "undefined" ) { + ret = context.getElementsByTagName( tag || "*" ); + + } else if ( typeof context.querySelectorAll !== "undefined" ) { + ret = context.querySelectorAll( tag || "*" ); + + } else { + ret = []; + } + + if ( tag === undefined || tag && nodeName( context, tag ) ) { + return jQuery.merge( [ context ], ret ); + } + + return ret; +} + + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + dataPriv.set( + elems[ i ], + "globalEval", + !refElements || dataPriv.get( refElements[ i ], "globalEval" ) + ); + } +} + + +var rhtml = /<|&#?\w+;/; + +function buildFragment( elems, context, scripts, selection, ignored ) { + var elem, tmp, tag, wrap, attached, j, + fragment = context.createDocumentFragment(), + nodes = [], + i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( toType( elem ) === "object" ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; + + // Descend through wrappers to the right content + j = wrap[ 0 ]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, tmp.childNodes ); + + // Remember the top-level container + tmp = fragment.firstChild; + + // Ensure the created nodes are orphaned (#12392) + tmp.textContent = ""; + } + } + } + + // Remove wrapper from fragment + fragment.textContent = ""; + + i = 0; + while ( ( elem = nodes[ i++ ] ) ) { + + // Skip elements already in the context collection (trac-4087) + if ( selection && jQuery.inArray( elem, selection ) > -1 ) { + if ( ignored ) { + ignored.push( elem ); + } + continue; + } + + attached = isAttached( elem ); + + // Append to fragment + tmp = getAll( fragment.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( attached ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( ( elem = tmp[ j++ ] ) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + return fragment; +} + + +var + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +// Support: IE <=9 - 11+ +// focus() and blur() are asynchronous, except when they are no-op. +// So expect focus to be synchronous when the element is already active, +// and blur to be synchronous when the element is not already active. +// (focus and blur are always synchronous in other supported browsers, +// this just defines when we can count on it). +function expectSync( elem, type ) { + return ( elem === safeActiveElement() ) === ( type === "focus" ); +} + +// Support: IE <=9 only +// Accessing document.activeElement can throw unexpectedly +// https://bugs.jquery.com/ticket/13393 +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +function on( elem, types, selector, data, fn, one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + on( elem, type, selector, data, types[ type ], one ); + } + return elem; + } + + if ( data == null && fn == null ) { + + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return elem; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return elem.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + } ); +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + + var handleObjIn, eventHandle, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.get( elem ); + + // Only attach events to objects that accept data + if ( !acceptData( elem ) ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Ensure that invalid selectors throw exceptions at attach time + // Evaluate against documentElement in case elem is a non-element node (e.g., document) + if ( selector ) { + jQuery.find.matchesSelector( documentElement, selector ); + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !( events = elemData.events ) ) { + events = elemData.events = Object.create( null ); + } + if ( !( eventHandle = elemData.handle ) ) { + eventHandle = elemData.handle = function( e ) { + + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? + jQuery.event.dispatch.apply( elem, arguments ) : undefined; + }; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend( { + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join( "." ) + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !( handlers = events[ type ] ) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener if the special events handler returns false + if ( !special.setup || + special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var j, origCount, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); + + if ( !elemData || !( events = elemData.events ) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[ 2 ] && + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || + selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || + special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove data and the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + dataPriv.remove( elem, "handle events" ); + } + }, + + dispatch: function( nativeEvent ) { + + var i, j, ret, matched, handleObj, handlerQueue, + args = new Array( arguments.length ), + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( nativeEvent ), + + handlers = ( + dataPriv.get( this, "events" ) || Object.create( null ) + )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[ 0 ] = event; + + for ( i = 1; i < arguments.length; i++ ) { + args[ i ] = arguments[ i ]; + } + + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( ( handleObj = matched.handlers[ j++ ] ) && + !event.isImmediatePropagationStopped() ) { + + // If the event is namespaced, then each handler is only invoked if it is + // specially universal or its namespaces are a superset of the event's. + if ( !event.rnamespace || handleObj.namespace === false || + event.rnamespace.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || + handleObj.handler ).apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( ( event.result = ret ) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var i, handleObj, sel, matchedHandlers, matchedSelectors, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + if ( delegateCount && + + // Support: IE <=9 + // Black-hole SVG instance trees (trac-13180) + cur.nodeType && + + // Support: Firefox <=42 + // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) + // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click + // Support: IE 11 only + // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) + !( event.type === "click" && event.button >= 1 ) ) { + + for ( ; cur !== this; cur = cur.parentNode || this ) { + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { + matchedHandlers = []; + matchedSelectors = {}; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matchedSelectors[ sel ] === undefined ) { + matchedSelectors[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) > -1 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matchedSelectors[ sel ] ) { + matchedHandlers.push( handleObj ); + } + } + if ( matchedHandlers.length ) { + handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); + } + } + } + } + + // Add the remaining (directly-bound) handlers + cur = this; + if ( delegateCount < handlers.length ) { + handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); + } + + return handlerQueue; + }, + + addProp: function( name, hook ) { + Object.defineProperty( jQuery.Event.prototype, name, { + enumerable: true, + configurable: true, + + get: isFunction( hook ) ? + function() { + if ( this.originalEvent ) { + return hook( this.originalEvent ); + } + } : + function() { + if ( this.originalEvent ) { + return this.originalEvent[ name ]; + } + }, + + set: function( value ) { + Object.defineProperty( this, name, { + enumerable: true, + configurable: true, + writable: true, + value: value + } ); + } + } ); + }, + + fix: function( originalEvent ) { + return originalEvent[ jQuery.expando ] ? + originalEvent : + new jQuery.Event( originalEvent ); + }, + + special: { + load: { + + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + click: { + + // Utilize native event to ensure correct state for checkable inputs + setup: function( data ) { + + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; + + // Claim the first handler + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + // dataPriv.set( el, "click", ... ) + leverageNative( el, "click", returnTrue ); + } + + // Return false to allow normal processing in the caller + return false; + }, + trigger: function( data ) { + + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; + + // Force setup before triggering a click + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + leverageNative( el, "click" ); + } + + // Return non-false to allow normal event-path propagation + return true; + }, + + // For cross-browser consistency, suppress native .click() on links + // Also prevent it if we're currently inside a leveraged native-event stack + _default: function( event ) { + var target = event.target; + return rcheckableType.test( target.type ) && + target.click && nodeName( target, "input" ) && + dataPriv.get( target, "click" ) || + nodeName( target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if ( event.result !== undefined && event.originalEvent ) { + event.originalEvent.returnValue = event.result; + } + } + } + } +}; + +// Ensure the presence of an event listener that handles manually-triggered +// synthetic events by interrupting progress until reinvoked in response to +// *native* events that it fires directly, ensuring that state changes have +// already occurred before other listeners are invoked. +function leverageNative( el, type, expectSync ) { + + // Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add + if ( !expectSync ) { + if ( dataPriv.get( el, type ) === undefined ) { + jQuery.event.add( el, type, returnTrue ); + } + return; + } + + // Register the controller as a special universal handler for all event namespaces + dataPriv.set( el, type, false ); + jQuery.event.add( el, type, { + namespace: false, + handler: function( event ) { + var notAsync, result, + saved = dataPriv.get( this, type ); + + if ( ( event.isTrigger & 1 ) && this[ type ] ) { + + // Interrupt processing of the outer synthetic .trigger()ed event + // Saved data should be false in such cases, but might be a leftover capture object + // from an async native handler (gh-4350) + if ( !saved.length ) { + + // Store arguments for use when handling the inner native event + // There will always be at least one argument (an event object), so this array + // will not be confused with a leftover capture object. + saved = slice.call( arguments ); + dataPriv.set( this, type, saved ); + + // Trigger the native event and capture its result + // Support: IE <=9 - 11+ + // focus() and blur() are asynchronous + notAsync = expectSync( this, type ); + this[ type ](); + result = dataPriv.get( this, type ); + if ( saved !== result || notAsync ) { + dataPriv.set( this, type, false ); + } else { + result = {}; + } + if ( saved !== result ) { + + // Cancel the outer synthetic event + event.stopImmediatePropagation(); + event.preventDefault(); + return result.value; + } + + // If this is an inner synthetic event for an event with a bubbling surrogate + // (focus or blur), assume that the surrogate already propagated from triggering the + // native event and prevent that from happening again here. + // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the + // bubbling surrogate propagates *after* the non-bubbling base), but that seems + // less bad than duplication. + } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) { + event.stopPropagation(); + } + + // If this is a native event triggered above, everything is now in order + // Fire an inner synthetic event with the original arguments + } else if ( saved.length ) { + + // ...and capture the result + dataPriv.set( this, type, { + value: jQuery.event.trigger( + + // Support: IE <=9 - 11+ + // Extend with the prototype to reset the above stopImmediatePropagation() + jQuery.extend( saved[ 0 ], jQuery.Event.prototype ), + saved.slice( 1 ), + this + ) + } ); + + // Abort handling of the native event + event.stopImmediatePropagation(); + } + } + } ); +} + +jQuery.removeEvent = function( elem, type, handle ) { + + // This "if" is needed for plain objects + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle ); + } +}; + +jQuery.Event = function( src, props ) { + + // Allow instantiation without the 'new' keyword + if ( !( this instanceof jQuery.Event ) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && + + // Support: Android <=2.3 only + src.returnValue === false ? + returnTrue : + returnFalse; + + // Create target properties + // Support: Safari <=6 - 7 only + // Target should not be a text node (#504, #13143) + this.target = ( src.target && src.target.nodeType === 3 ) ? + src.target.parentNode : + src.target; + + this.currentTarget = src.currentTarget; + this.relatedTarget = src.relatedTarget; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || Date.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + constructor: jQuery.Event, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + isSimulated: false, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + + if ( e && !this.isSimulated ) { + e.preventDefault(); + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopPropagation(); + } + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } +}; + +// Includes all common event props including KeyEvent and MouseEvent specific props +jQuery.each( { + altKey: true, + bubbles: true, + cancelable: true, + changedTouches: true, + ctrlKey: true, + detail: true, + eventPhase: true, + metaKey: true, + pageX: true, + pageY: true, + shiftKey: true, + view: true, + "char": true, + code: true, + charCode: true, + key: true, + keyCode: true, + button: true, + buttons: true, + clientX: true, + clientY: true, + offsetX: true, + offsetY: true, + pointerId: true, + pointerType: true, + screenX: true, + screenY: true, + targetTouches: true, + toElement: true, + touches: true, + + which: function( event ) { + var button = event.button; + + // Add which for key events + if ( event.which == null && rkeyEvent.test( event.type ) ) { + return event.charCode != null ? event.charCode : event.keyCode; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) { + if ( button & 1 ) { + return 1; + } + + if ( button & 2 ) { + return 3; + } + + if ( button & 4 ) { + return 2; + } + + return 0; + } + + return event.which; + } +}, jQuery.event.addProp ); + +jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { + jQuery.event.special[ type ] = { + + // Utilize native event if possible so blur/focus sequence is correct + setup: function() { + + // Claim the first handler + // dataPriv.set( this, "focus", ... ) + // dataPriv.set( this, "blur", ... ) + leverageNative( this, type, expectSync ); + + // Return false to allow normal processing in the caller + return false; + }, + trigger: function() { + + // Force setup before trigger + leverageNative( this, type ); + + // Return non-false to allow normal event-path propagation + return true; + }, + + delegateType: delegateType + }; +} ); + +// Create mouseenter/leave events using mouseover/out and event-time checks +// so that event delegation works in jQuery. +// Do the same for pointerenter/pointerleave and pointerover/pointerout +// +// Support: Safari 7 only +// Safari sends mouseenter too often; see: +// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 +// for the description of the bug (it existed in older Chrome versions as well). +jQuery.each( { + mouseenter: "mouseover", + mouseleave: "mouseout", + pointerenter: "pointerover", + pointerleave: "pointerout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mouseenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +} ); + +jQuery.fn.extend( { + + on: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn ); + }, + one: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? + handleObj.origType + "." + handleObj.namespace : + handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each( function() { + jQuery.event.remove( this, types, fn, selector ); + } ); + } +} ); + + +var + + // Support: IE <=10 - 11, Edge 12 - 13 only + // In IE/Edge using regex groups here causes severe slowdowns. + // See https://connect.microsoft.com/IE/feedback/details/1736512/ + rnoInnerhtml = /\s*$/g; + +// Prefer a tbody over its parent table for containing new rows +function manipulationTarget( elem, content ) { + if ( nodeName( elem, "table" ) && + nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { + + return jQuery( elem ).children( "tbody" )[ 0 ] || elem; + } + + return elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { + elem.type = elem.type.slice( 5 ); + } else { + elem.removeAttribute( "type" ); + } + + return elem; +} + +function cloneCopyEvent( src, dest ) { + var i, l, type, pdataOld, udataOld, udataCur, events; + + if ( dest.nodeType !== 1 ) { + return; + } + + // 1. Copy private data: events, handlers, etc. + if ( dataPriv.hasData( src ) ) { + pdataOld = dataPriv.get( src ); + events = pdataOld.events; + + if ( events ) { + dataPriv.remove( dest, "handle events" ); + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + } + + // 2. Copy user data + if ( dataUser.hasData( src ) ) { + udataOld = dataUser.access( src ); + udataCur = jQuery.extend( {}, udataOld ); + + dataUser.set( dest, udataCur ); + } +} + +// Fix IE bugs, see support tests +function fixInput( src, dest ) { + var nodeName = dest.nodeName.toLowerCase(); + + // Fails to persist the checked state of a cloned checkbox or radio button. + if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + dest.checked = src.checked; + + // Fails to return the selected option to the default selected state when cloning options + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +function domManip( collection, args, callback, ignored ) { + + // Flatten any nested arrays + args = flat( args ); + + var fragment, first, scripts, hasScripts, node, doc, + i = 0, + l = collection.length, + iNoClone = l - 1, + value = args[ 0 ], + valueIsFunction = isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( valueIsFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return collection.each( function( index ) { + var self = collection.eq( index ); + if ( valueIsFunction ) { + args[ 0 ] = value.call( this, index, self.html() ); + } + domManip( self, args, callback, ignored ); + } ); + } + + if ( l ) { + fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + // Require either new content or an interest in ignored elements to invoke the callback + if ( first || ignored ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item + // instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( collection[ i ], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !dataPriv.access( node, "globalEval" ) && + jQuery.contains( doc, node ) ) { + + if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { + + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl && !node.noModule ) { + jQuery._evalUrl( node.src, { + nonce: node.nonce || node.getAttribute( "nonce" ) + }, doc ); + } + } else { + DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); + } + } + } + } + } + } + + return collection; +} + +function remove( elem, selector, keepData ) { + var node, + nodes = selector ? jQuery.filter( selector, elem ) : elem, + i = 0; + + for ( ; ( node = nodes[ i ] ) != null; i++ ) { + if ( !keepData && node.nodeType === 1 ) { + jQuery.cleanData( getAll( node ) ); + } + + if ( node.parentNode ) { + if ( keepData && isAttached( node ) ) { + setGlobalEval( getAll( node, "script" ) ); + } + node.parentNode.removeChild( node ); + } + } + + return elem; +} + +jQuery.extend( { + htmlPrefilter: function( html ) { + return html; + }, + + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var i, l, srcElements, destElements, + clone = elem.cloneNode( true ), + inPage = isAttached( elem ); + + // Fix IE cloning issues + if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && + !jQuery.isXMLDoc( elem ) ) { + + // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + fixInput( srcElements[ i ], destElements[ i ] ); + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + cloneCopyEvent( srcElements[ i ], destElements[ i ] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + // Return the cloned set + return clone; + }, + + cleanData: function( elems ) { + var data, elem, type, + special = jQuery.event.special, + i = 0; + + for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { + if ( acceptData( elem ) ) { + if ( ( data = elem[ dataPriv.expando ] ) ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataPriv.expando ] = undefined; + } + if ( elem[ dataUser.expando ] ) { + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataUser.expando ] = undefined; + } + } + } + } +} ); + +jQuery.fn.extend( { + detach: function( selector ) { + return remove( this, selector, true ); + }, + + remove: function( selector ) { + return remove( this, selector ); + }, + + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().each( function() { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + this.textContent = value; + } + } ); + }, null, value, arguments.length ); + }, + + append: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + } ); + }, + + prepend: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + } ); + }, + + before: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + } ); + }, + + after: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + } ); + }, + + empty: function() { + var elem, + i = 0; + + for ( ; ( elem = this[ i ] ) != null; i++ ) { + if ( elem.nodeType === 1 ) { + + // Prevent memory leaks + jQuery.cleanData( getAll( elem, false ) ); + + // Remove any remaining nodes + elem.textContent = ""; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + } ); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined && elem.nodeType === 1 ) { + return elem.innerHTML; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { + + value = jQuery.htmlPrefilter( value ); + + try { + for ( ; i < l; i++ ) { + elem = this[ i ] || {}; + + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch ( e ) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var ignored = []; + + // Make the changes, replacing each non-ignored context element with the new content + return domManip( this, arguments, function( elem ) { + var parent = this.parentNode; + + if ( jQuery.inArray( this, ignored ) < 0 ) { + jQuery.cleanData( getAll( this ) ); + if ( parent ) { + parent.replaceChild( elem, this ); + } + } + + // Force callback invocation + }, ignored ); + } +} ); + +jQuery.each( { + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1, + i = 0; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone( true ); + jQuery( insert[ i ] )[ original ]( elems ); + + // Support: Android <=4.0 only, PhantomJS 1 only + // .get() because push.apply(_, arraylike) throws on ancient WebKit + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +} ); +var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); + +var getStyles = function( elem ) { + + // Support: IE <=11 only, Firefox <=30 (#15098, #14150) + // IE throws on elements created in popups + // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" + var view = elem.ownerDocument.defaultView; + + if ( !view || !view.opener ) { + view = window; + } + + return view.getComputedStyle( elem ); + }; + +var swap = function( elem, options, callback ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.call( elem ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; +}; + + +var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); + + + +( function() { + + // Executing both pixelPosition & boxSizingReliable tests require only one layout + // so they're executed at the same time to save the second computation. + function computeStyleTests() { + + // This is a singleton, we need to execute it only once + if ( !div ) { + return; + } + + container.style.cssText = "position:absolute;left:-11111px;width:60px;" + + "margin-top:1px;padding:0;border:0"; + div.style.cssText = + "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + + "margin:auto;border:1px;padding:1px;" + + "width:60%;top:1%"; + documentElement.appendChild( container ).appendChild( div ); + + var divStyle = window.getComputedStyle( div ); + pixelPositionVal = divStyle.top !== "1%"; + + // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 + reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; + + // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 + // Some styles come back with percentage values, even though they shouldn't + div.style.right = "60%"; + pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; + + // Support: IE 9 - 11 only + // Detect misreporting of content dimensions for box-sizing:border-box elements + boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; + + // Support: IE 9 only + // Detect overflow:scroll screwiness (gh-3699) + // Support: Chrome <=64 + // Don't get tricked when zoom affects offsetWidth (gh-4029) + div.style.position = "absolute"; + scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12; + + documentElement.removeChild( container ); + + // Nullify the div so it wouldn't be stored in the memory and + // it will also be a sign that checks already performed + div = null; + } + + function roundPixelMeasures( measure ) { + return Math.round( parseFloat( measure ) ); + } + + var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, + reliableTrDimensionsVal, reliableMarginLeftVal, + container = document.createElement( "div" ), + div = document.createElement( "div" ); + + // Finish early in limited (non-browser) environments + if ( !div.style ) { + return; + } + + // Support: IE <=9 - 11 only + // Style of cloned element affects source element cloned (#8908) + div.style.backgroundClip = "content-box"; + div.cloneNode( true ).style.backgroundClip = ""; + support.clearCloneStyle = div.style.backgroundClip === "content-box"; + + jQuery.extend( support, { + boxSizingReliable: function() { + computeStyleTests(); + return boxSizingReliableVal; + }, + pixelBoxStyles: function() { + computeStyleTests(); + return pixelBoxStylesVal; + }, + pixelPosition: function() { + computeStyleTests(); + return pixelPositionVal; + }, + reliableMarginLeft: function() { + computeStyleTests(); + return reliableMarginLeftVal; + }, + scrollboxSize: function() { + computeStyleTests(); + return scrollboxSizeVal; + }, + + // Support: IE 9 - 11+, Edge 15 - 18+ + // IE/Edge misreport `getComputedStyle` of table rows with width/height + // set in CSS while `offset*` properties report correct values. + // Behavior in IE 9 is more subtle than in newer versions & it passes + // some versions of this test; make sure not to make it pass there! + reliableTrDimensions: function() { + var table, tr, trChild, trStyle; + if ( reliableTrDimensionsVal == null ) { + table = document.createElement( "table" ); + tr = document.createElement( "tr" ); + trChild = document.createElement( "div" ); + + table.style.cssText = "position:absolute;left:-11111px"; + tr.style.height = "1px"; + trChild.style.height = "9px"; + + documentElement + .appendChild( table ) + .appendChild( tr ) + .appendChild( trChild ); + + trStyle = window.getComputedStyle( tr ); + reliableTrDimensionsVal = parseInt( trStyle.height ) > 3; + + documentElement.removeChild( table ); + } + return reliableTrDimensionsVal; + } + } ); +} )(); + + +function curCSS( elem, name, computed ) { + var width, minWidth, maxWidth, ret, + + // Support: Firefox 51+ + // Retrieving style before computed somehow + // fixes an issue with getting wrong values + // on detached elements + style = elem.style; + + computed = computed || getStyles( elem ); + + // getPropertyValue is needed for: + // .css('filter') (IE 9 only, #12537) + // .css('--customProperty) (#3144) + if ( computed ) { + ret = computed.getPropertyValue( name ) || computed[ name ]; + + if ( ret === "" && !isAttached( elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Android Browser returns percentage for some values, + // but width seems to be reliably pixels. + // This is against the CSSOM draft spec: + // https://drafts.csswg.org/cssom/#resolved-values + if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { + + // Remember the original values + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + // Put in the new values to get a computed value out + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + // Revert the changed values + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret !== undefined ? + + // Support: IE <=9 - 11 only + // IE returns zIndex value as an integer. + ret + "" : + ret; +} + + +function addGetHookIf( conditionFn, hookFn ) { + + // Define the hook, we'll check on the first run if it's really needed. + return { + get: function() { + if ( conditionFn() ) { + + // Hook not needed (or it's not possible to use it due + // to missing dependency), remove it. + delete this.get; + return; + } + + // Hook needed; redefine it so that the support test is not executed again. + return ( this.get = hookFn ).apply( this, arguments ); + } + }; +} + + +var cssPrefixes = [ "Webkit", "Moz", "ms" ], + emptyStyle = document.createElement( "div" ).style, + vendorProps = {}; + +// Return a vendor-prefixed property or undefined +function vendorPropName( name ) { + + // Check for vendor prefixed names + var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in emptyStyle ) { + return name; + } + } +} + +// Return a potentially-mapped jQuery.cssProps or vendor prefixed property +function finalPropName( name ) { + var final = jQuery.cssProps[ name ] || vendorProps[ name ]; + + if ( final ) { + return final; + } + if ( name in emptyStyle ) { + return name; + } + return vendorProps[ name ] = vendorPropName( name ) || name; +} + + +var + + // Swappable if display is none or starts with table + // except "table", "table-cell", or "table-caption" + // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rcustomProp = /^--/, + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: "0", + fontWeight: "400" + }; + +function setPositiveNumber( _elem, value, subtract ) { + + // Any relative (+/-) values have already been + // normalized at this point + var matches = rcssNum.exec( value ); + return matches ? + + // Guard against undefined "subtract", e.g., when used as in cssHooks + Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : + value; +} + +function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { + var i = dimension === "width" ? 1 : 0, + extra = 0, + delta = 0; + + // Adjustment may not be necessary + if ( box === ( isBorderBox ? "border" : "content" ) ) { + return 0; + } + + for ( ; i < 4; i += 2 ) { + + // Both box models exclude margin + if ( box === "margin" ) { + delta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); + } + + // If we get here with a content-box, we're seeking "padding" or "border" or "margin" + if ( !isBorderBox ) { + + // Add padding + delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + + // For "border" or "margin", add border + if ( box !== "padding" ) { + delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + + // But still keep track of it otherwise + } else { + extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + + // If we get here with a border-box (content + padding + border), we're seeking "content" or + // "padding" or "margin" + } else { + + // For "content", subtract padding + if ( box === "content" ) { + delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + } + + // For "content" or "padding", subtract border + if ( box !== "margin" ) { + delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } + } + + // Account for positive content-box scroll gutter when requested by providing computedVal + if ( !isBorderBox && computedVal >= 0 ) { + + // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border + // Assuming integer scroll gutter, subtract the rest and round down + delta += Math.max( 0, Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + computedVal - + delta - + extra - + 0.5 + + // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter + // Use an explicit zero to avoid NaN (gh-3964) + ) ) || 0; + } + + return delta; +} + +function getWidthOrHeight( elem, dimension, extra ) { + + // Start with computed style + var styles = getStyles( elem ), + + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). + // Fake content-box until we know it's needed to know the true value. + boxSizingNeeded = !support.boxSizingReliable() || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + valueIsBorderBox = isBorderBox, + + val = curCSS( elem, dimension, styles ), + offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); + + // Support: Firefox <=54 + // Return a confounding non-pixel value or feign ignorance, as appropriate. + if ( rnumnonpx.test( val ) ) { + if ( !extra ) { + return val; + } + val = "auto"; + } + + + // Support: IE 9 - 11 only + // Use offsetWidth/offsetHeight for when box sizing is unreliable. + // In those cases, the computed value can be trusted to be border-box. + if ( ( !support.boxSizingReliable() && isBorderBox || + + // Support: IE 10 - 11+, Edge 15 - 18+ + // IE/Edge misreport `getComputedStyle` of table rows with width/height + // set in CSS while `offset*` properties report correct values. + // Interestingly, in some cases IE 9 doesn't suffer from this issue. + !support.reliableTrDimensions() && nodeName( elem, "tr" ) || + + // Fall back to offsetWidth/offsetHeight when value is "auto" + // This happens for inline elements with no explicit setting (gh-3571) + val === "auto" || + + // Support: Android <=4.1 - 4.3 only + // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) + !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && + + // Make sure the element is visible & connected + elem.getClientRects().length ) { + + isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; + + // Where available, offsetWidth/offsetHeight approximate border box dimensions. + // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the + // retrieved value as a content box dimension. + valueIsBorderBox = offsetProp in elem; + if ( valueIsBorderBox ) { + val = elem[ offsetProp ]; + } + } + + // Normalize "" and auto + val = parseFloat( val ) || 0; + + // Adjust for the element's box model + return ( val + + boxModelAdjustment( + elem, + dimension, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox, + styles, + + // Provide the current computed size to request scroll gutter calculation (gh-3589) + val + ) + ) + "px"; +} + +jQuery.extend( { + + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + } + } + } + }, + + // Don't automatically add "px" to these possibly-unitless properties + cssNumber: { + "animationIterationCount": true, + "columnCount": true, + "fillOpacity": true, + "flexGrow": true, + "flexShrink": true, + "fontWeight": true, + "gridArea": true, + "gridColumn": true, + "gridColumnEnd": true, + "gridColumnStart": true, + "gridRow": true, + "gridRowEnd": true, + "gridRowStart": true, + "lineHeight": true, + "opacity": true, + "order": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: {}, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ), + style = elem.style; + + // Make sure that we're working with the right name. We don't + // want to query the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Gets hook for the prefixed version, then unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // Convert "+=" or "-=" to relative numbers (#7345) + if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { + value = adjustCSS( elem, name, ret ); + + // Fixes bug #9237 + type = "number"; + } + + // Make sure that null and NaN values aren't set (#7116) + if ( value == null || value !== value ) { + return; + } + + // If a number was passed in, add the unit (except for certain CSS properties) + // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append + // "px" to a few hardcoded values. + if ( type === "number" && !isCustomProp ) { + value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); + } + + // background-* props affect original clone's values + if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { + style[ name ] = "inherit"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !( "set" in hooks ) || + ( value = hooks.set( elem, value, extra ) ) !== undefined ) { + + if ( isCustomProp ) { + style.setProperty( name, value ); + } else { + style[ name ] = value; + } + } + + } else { + + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && + ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { + + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, extra, styles ) { + var val, num, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ); + + // Make sure that we're working with the right name. We don't + // want to modify the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Try prefixed name followed by the unprefixed name + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name, styles ); + } + + // Convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Make numeric if forced or a qualifier was provided and val looks numeric + if ( extra === "" || extra ) { + num = parseFloat( val ); + return extra === true || isFinite( num ) ? num || 0 : val; + } + + return val; + } +} ); + +jQuery.each( [ "height", "width" ], function( _i, dimension ) { + jQuery.cssHooks[ dimension ] = { + get: function( elem, computed, extra ) { + if ( computed ) { + + // Certain elements can have dimension info if we invisibly show them + // but it must have a current display style that would benefit + return rdisplayswap.test( jQuery.css( elem, "display" ) ) && + + // Support: Safari 8+ + // Table columns in Safari have non-zero offsetWidth & zero + // getBoundingClientRect().width unless display is changed. + // Support: IE <=11 only + // Running getBoundingClientRect on a disconnected node + // in IE throws an error. + ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? + swap( elem, cssShow, function() { + return getWidthOrHeight( elem, dimension, extra ); + } ) : + getWidthOrHeight( elem, dimension, extra ); + } + }, + + set: function( elem, value, extra ) { + var matches, + styles = getStyles( elem ), + + // Only read styles.position if the test has a chance to fail + // to avoid forcing a reflow. + scrollboxSizeBuggy = !support.scrollboxSize() && + styles.position === "absolute", + + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) + boxSizingNeeded = scrollboxSizeBuggy || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + subtract = extra ? + boxModelAdjustment( + elem, + dimension, + extra, + isBorderBox, + styles + ) : + 0; + + // Account for unreliable border-box dimensions by comparing offset* to computed and + // faking a content-box to get border and padding (gh-3699) + if ( isBorderBox && scrollboxSizeBuggy ) { + subtract -= Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + parseFloat( styles[ dimension ] ) - + boxModelAdjustment( elem, dimension, "border", false, styles ) - + 0.5 + ); + } + + // Convert to pixels if value adjustment is needed + if ( subtract && ( matches = rcssNum.exec( value ) ) && + ( matches[ 3 ] || "px" ) !== "px" ) { + + elem.style[ dimension ] = value; + value = jQuery.css( elem, dimension ); + } + + return setPositiveNumber( elem, value, subtract ); + } + }; +} ); + +jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, + function( elem, computed ) { + if ( computed ) { + return ( parseFloat( curCSS( elem, "marginLeft" ) ) || + elem.getBoundingClientRect().left - + swap( elem, { marginLeft: 0 }, function() { + return elem.getBoundingClientRect().left; + } ) + ) + "px"; + } + } +); + +// These hooks are used by animate to expand properties +jQuery.each( { + margin: "", + padding: "", + border: "Width" +}, function( prefix, suffix ) { + jQuery.cssHooks[ prefix + suffix ] = { + expand: function( value ) { + var i = 0, + expanded = {}, + + // Assumes a single number if not a string + parts = typeof value === "string" ? value.split( " " ) : [ value ]; + + for ( ; i < 4; i++ ) { + expanded[ prefix + cssExpand[ i ] + suffix ] = + parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; + } + + return expanded; + } + }; + + if ( prefix !== "margin" ) { + jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; + } +} ); + +jQuery.fn.extend( { + css: function( name, value ) { + return access( this, function( elem, name, value ) { + var styles, len, + map = {}, + i = 0; + + if ( Array.isArray( name ) ) { + styles = getStyles( elem ); + len = name.length; + + for ( ; i < len; i++ ) { + map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); + } + + return map; + } + + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + } +} ); + + +function Tween( elem, options, prop, end, easing ) { + return new Tween.prototype.init( elem, options, prop, end, easing ); +} +jQuery.Tween = Tween; + +Tween.prototype = { + constructor: Tween, + init: function( elem, options, prop, end, easing, unit ) { + this.elem = elem; + this.prop = prop; + this.easing = easing || jQuery.easing._default; + this.options = options; + this.start = this.now = this.cur(); + this.end = end; + this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + }, + cur: function() { + var hooks = Tween.propHooks[ this.prop ]; + + return hooks && hooks.get ? + hooks.get( this ) : + Tween.propHooks._default.get( this ); + }, + run: function( percent ) { + var eased, + hooks = Tween.propHooks[ this.prop ]; + + if ( this.options.duration ) { + this.pos = eased = jQuery.easing[ this.easing ]( + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } else { + this.pos = eased = percent; + } + this.now = ( this.end - this.start ) * eased + this.start; + + if ( this.options.step ) { + this.options.step.call( this.elem, this.now, this ); + } + + if ( hooks && hooks.set ) { + hooks.set( this ); + } else { + Tween.propHooks._default.set( this ); + } + return this; + } +}; + +Tween.prototype.init.prototype = Tween.prototype; + +Tween.propHooks = { + _default: { + get: function( tween ) { + var result; + + // Use a property on the element directly when it is not a DOM element, + // or when there is no matching style property that exists. + if ( tween.elem.nodeType !== 1 || + tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { + return tween.elem[ tween.prop ]; + } + + // Passing an empty string as a 3rd parameter to .css will automatically + // attempt a parseFloat and fallback to a string if the parse fails. + // Simple values such as "10px" are parsed to Float; + // complex values such as "rotate(1rad)" are returned as-is. + result = jQuery.css( tween.elem, tween.prop, "" ); + + // Empty strings, null, undefined and "auto" are converted to 0. + return !result || result === "auto" ? 0 : result; + }, + set: function( tween ) { + + // Use step hook for back compat. + // Use cssHook if its there. + // Use .style if available and use plain properties where available. + if ( jQuery.fx.step[ tween.prop ] ) { + jQuery.fx.step[ tween.prop ]( tween ); + } else if ( tween.elem.nodeType === 1 && ( + jQuery.cssHooks[ tween.prop ] || + tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) { + jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); + } else { + tween.elem[ tween.prop ] = tween.now; + } + } + } +}; + +// Support: IE <=9 only +// Panic based approach to setting things on disconnected nodes +Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { + set: function( tween ) { + if ( tween.elem.nodeType && tween.elem.parentNode ) { + tween.elem[ tween.prop ] = tween.now; + } + } +}; + +jQuery.easing = { + linear: function( p ) { + return p; + }, + swing: function( p ) { + return 0.5 - Math.cos( p * Math.PI ) / 2; + }, + _default: "swing" +}; + +jQuery.fx = Tween.prototype.init; + +// Back compat <1.8 extension point +jQuery.fx.step = {}; + + + + +var + fxNow, inProgress, + rfxtypes = /^(?:toggle|show|hide)$/, + rrun = /queueHooks$/; + +function schedule() { + if ( inProgress ) { + if ( document.hidden === false && window.requestAnimationFrame ) { + window.requestAnimationFrame( schedule ); + } else { + window.setTimeout( schedule, jQuery.fx.interval ); + } + + jQuery.fx.tick(); + } +} + +// Animations created synchronously will run synchronously +function createFxNow() { + window.setTimeout( function() { + fxNow = undefined; + } ); + return ( fxNow = Date.now() ); +} + +// Generate parameters to create a standard animation +function genFx( type, includeWidth ) { + var which, + i = 0, + attrs = { height: type }; + + // If we include width, step value is 1 to do all cssExpand values, + // otherwise step value is 2 to skip over Left and Right + includeWidth = includeWidth ? 1 : 0; + for ( ; i < 4; i += 2 - includeWidth ) { + which = cssExpand[ i ]; + attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; + } + + if ( includeWidth ) { + attrs.opacity = attrs.width = type; + } + + return attrs; +} + +function createTween( value, prop, animation ) { + var tween, + collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), + index = 0, + length = collection.length; + for ( ; index < length; index++ ) { + if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { + + // We're done with this property + return tween; + } + } +} + +function defaultPrefilter( elem, props, opts ) { + var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, + isBox = "width" in props || "height" in props, + anim = this, + orig = {}, + style = elem.style, + hidden = elem.nodeType && isHiddenWithinTree( elem ), + dataShow = dataPriv.get( elem, "fxshow" ); + + // Queue-skipping animations hijack the fx hooks + if ( !opts.queue ) { + hooks = jQuery._queueHooks( elem, "fx" ); + if ( hooks.unqueued == null ) { + hooks.unqueued = 0; + oldfire = hooks.empty.fire; + hooks.empty.fire = function() { + if ( !hooks.unqueued ) { + oldfire(); + } + }; + } + hooks.unqueued++; + + anim.always( function() { + + // Ensure the complete handler is called before this completes + anim.always( function() { + hooks.unqueued--; + if ( !jQuery.queue( elem, "fx" ).length ) { + hooks.empty.fire(); + } + } ); + } ); + } + + // Detect show/hide animations + for ( prop in props ) { + value = props[ prop ]; + if ( rfxtypes.test( value ) ) { + delete props[ prop ]; + toggle = toggle || value === "toggle"; + if ( value === ( hidden ? "hide" : "show" ) ) { + + // Pretend to be hidden if this is a "show" and + // there is still data from a stopped show/hide + if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { + hidden = true; + + // Ignore all other no-op show/hide data + } else { + continue; + } + } + orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); + } + } + + // Bail out if this is a no-op like .hide().hide() + propTween = !jQuery.isEmptyObject( props ); + if ( !propTween && jQuery.isEmptyObject( orig ) ) { + return; + } + + // Restrict "overflow" and "display" styles during box animations + if ( isBox && elem.nodeType === 1 ) { + + // Support: IE <=9 - 11, Edge 12 - 15 + // Record all 3 overflow attributes because IE does not infer the shorthand + // from identically-valued overflowX and overflowY and Edge just mirrors + // the overflowX value there. + opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; + + // Identify a display type, preferring old show/hide data over the CSS cascade + restoreDisplay = dataShow && dataShow.display; + if ( restoreDisplay == null ) { + restoreDisplay = dataPriv.get( elem, "display" ); + } + display = jQuery.css( elem, "display" ); + if ( display === "none" ) { + if ( restoreDisplay ) { + display = restoreDisplay; + } else { + + // Get nonempty value(s) by temporarily forcing visibility + showHide( [ elem ], true ); + restoreDisplay = elem.style.display || restoreDisplay; + display = jQuery.css( elem, "display" ); + showHide( [ elem ] ); + } + } + + // Animate inline elements as inline-block + if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { + if ( jQuery.css( elem, "float" ) === "none" ) { + + // Restore the original display value at the end of pure show/hide animations + if ( !propTween ) { + anim.done( function() { + style.display = restoreDisplay; + } ); + if ( restoreDisplay == null ) { + display = style.display; + restoreDisplay = display === "none" ? "" : display; + } + } + style.display = "inline-block"; + } + } + } + + if ( opts.overflow ) { + style.overflow = "hidden"; + anim.always( function() { + style.overflow = opts.overflow[ 0 ]; + style.overflowX = opts.overflow[ 1 ]; + style.overflowY = opts.overflow[ 2 ]; + } ); + } + + // Implement show/hide animations + propTween = false; + for ( prop in orig ) { + + // General show/hide setup for this element animation + if ( !propTween ) { + if ( dataShow ) { + if ( "hidden" in dataShow ) { + hidden = dataShow.hidden; + } + } else { + dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); + } + + // Store hidden/visible for toggle so `.stop().toggle()` "reverses" + if ( toggle ) { + dataShow.hidden = !hidden; + } + + // Show elements before animating them + if ( hidden ) { + showHide( [ elem ], true ); + } + + /* eslint-disable no-loop-func */ + + anim.done( function() { + + /* eslint-enable no-loop-func */ + + // The final step of a "hide" animation is actually hiding the element + if ( !hidden ) { + showHide( [ elem ] ); + } + dataPriv.remove( elem, "fxshow" ); + for ( prop in orig ) { + jQuery.style( elem, prop, orig[ prop ] ); + } + } ); + } + + // Per-property setup + propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); + if ( !( prop in dataShow ) ) { + dataShow[ prop ] = propTween.start; + if ( hidden ) { + propTween.end = propTween.start; + propTween.start = 0; + } + } + } +} + +function propFilter( props, specialEasing ) { + var index, name, easing, value, hooks; + + // camelCase, specialEasing and expand cssHook pass + for ( index in props ) { + name = camelCase( index ); + easing = specialEasing[ name ]; + value = props[ index ]; + if ( Array.isArray( value ) ) { + easing = value[ 1 ]; + value = props[ index ] = value[ 0 ]; + } + + if ( index !== name ) { + props[ name ] = value; + delete props[ index ]; + } + + hooks = jQuery.cssHooks[ name ]; + if ( hooks && "expand" in hooks ) { + value = hooks.expand( value ); + delete props[ name ]; + + // Not quite $.extend, this won't overwrite existing keys. + // Reusing 'index' because we have the correct "name" + for ( index in value ) { + if ( !( index in props ) ) { + props[ index ] = value[ index ]; + specialEasing[ index ] = easing; + } + } + } else { + specialEasing[ name ] = easing; + } + } +} + +function Animation( elem, properties, options ) { + var result, + stopped, + index = 0, + length = Animation.prefilters.length, + deferred = jQuery.Deferred().always( function() { + + // Don't match elem in the :animated selector + delete tick.elem; + } ), + tick = function() { + if ( stopped ) { + return false; + } + var currentTime = fxNow || createFxNow(), + remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), + + // Support: Android 2.3 only + // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) + temp = remaining / animation.duration || 0, + percent = 1 - temp, + index = 0, + length = animation.tweens.length; + + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( percent ); + } + + deferred.notifyWith( elem, [ animation, percent, remaining ] ); + + // If there's more to do, yield + if ( percent < 1 && length ) { + return remaining; + } + + // If this was an empty animation, synthesize a final progress notification + if ( !length ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + } + + // Resolve the animation and report its conclusion + deferred.resolveWith( elem, [ animation ] ); + return false; + }, + animation = deferred.promise( { + elem: elem, + props: jQuery.extend( {}, properties ), + opts: jQuery.extend( true, { + specialEasing: {}, + easing: jQuery.easing._default + }, options ), + originalProperties: properties, + originalOptions: options, + startTime: fxNow || createFxNow(), + duration: options.duration, + tweens: [], + createTween: function( prop, end ) { + var tween = jQuery.Tween( elem, animation.opts, prop, end, + animation.opts.specialEasing[ prop ] || animation.opts.easing ); + animation.tweens.push( tween ); + return tween; + }, + stop: function( gotoEnd ) { + var index = 0, + + // If we are going to the end, we want to run all the tweens + // otherwise we skip this part + length = gotoEnd ? animation.tweens.length : 0; + if ( stopped ) { + return this; + } + stopped = true; + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( 1 ); + } + + // Resolve when we played the last frame; otherwise, reject + if ( gotoEnd ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + deferred.resolveWith( elem, [ animation, gotoEnd ] ); + } else { + deferred.rejectWith( elem, [ animation, gotoEnd ] ); + } + return this; + } + } ), + props = animation.props; + + propFilter( props, animation.opts.specialEasing ); + + for ( ; index < length; index++ ) { + result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); + if ( result ) { + if ( isFunction( result.stop ) ) { + jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = + result.stop.bind( result ); + } + return result; + } + } + + jQuery.map( props, createTween, animation ); + + if ( isFunction( animation.opts.start ) ) { + animation.opts.start.call( elem, animation ); + } + + // Attach callbacks from options + animation + .progress( animation.opts.progress ) + .done( animation.opts.done, animation.opts.complete ) + .fail( animation.opts.fail ) + .always( animation.opts.always ); + + jQuery.fx.timer( + jQuery.extend( tick, { + elem: elem, + anim: animation, + queue: animation.opts.queue + } ) + ); + + return animation; +} + +jQuery.Animation = jQuery.extend( Animation, { + + tweeners: { + "*": [ function( prop, value ) { + var tween = this.createTween( prop, value ); + adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); + return tween; + } ] + }, + + tweener: function( props, callback ) { + if ( isFunction( props ) ) { + callback = props; + props = [ "*" ]; + } else { + props = props.match( rnothtmlwhite ); + } + + var prop, + index = 0, + length = props.length; + + for ( ; index < length; index++ ) { + prop = props[ index ]; + Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; + Animation.tweeners[ prop ].unshift( callback ); + } + }, + + prefilters: [ defaultPrefilter ], + + prefilter: function( callback, prepend ) { + if ( prepend ) { + Animation.prefilters.unshift( callback ); + } else { + Animation.prefilters.push( callback ); + } + } +} ); + +jQuery.speed = function( speed, easing, fn ) { + var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { + complete: fn || !fn && easing || + isFunction( speed ) && speed, + duration: speed, + easing: fn && easing || easing && !isFunction( easing ) && easing + }; + + // Go to the end state if fx are off + if ( jQuery.fx.off ) { + opt.duration = 0; + + } else { + if ( typeof opt.duration !== "number" ) { + if ( opt.duration in jQuery.fx.speeds ) { + opt.duration = jQuery.fx.speeds[ opt.duration ]; + + } else { + opt.duration = jQuery.fx.speeds._default; + } + } + } + + // Normalize opt.queue - true/undefined/null -> "fx" + if ( opt.queue == null || opt.queue === true ) { + opt.queue = "fx"; + } + + // Queueing + opt.old = opt.complete; + + opt.complete = function() { + if ( isFunction( opt.old ) ) { + opt.old.call( this ); + } + + if ( opt.queue ) { + jQuery.dequeue( this, opt.queue ); + } + }; + + return opt; +}; + +jQuery.fn.extend( { + fadeTo: function( speed, to, easing, callback ) { + + // Show any hidden elements after setting opacity to 0 + return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() + + // Animate to the value specified + .end().animate( { opacity: to }, speed, easing, callback ); + }, + animate: function( prop, speed, easing, callback ) { + var empty = jQuery.isEmptyObject( prop ), + optall = jQuery.speed( speed, easing, callback ), + doAnimation = function() { + + // Operate on a copy of prop so per-property easing won't be lost + var anim = Animation( this, jQuery.extend( {}, prop ), optall ); + + // Empty animations, or finishing resolves immediately + if ( empty || dataPriv.get( this, "finish" ) ) { + anim.stop( true ); + } + }; + doAnimation.finish = doAnimation; + + return empty || optall.queue === false ? + this.each( doAnimation ) : + this.queue( optall.queue, doAnimation ); + }, + stop: function( type, clearQueue, gotoEnd ) { + var stopQueue = function( hooks ) { + var stop = hooks.stop; + delete hooks.stop; + stop( gotoEnd ); + }; + + if ( typeof type !== "string" ) { + gotoEnd = clearQueue; + clearQueue = type; + type = undefined; + } + if ( clearQueue ) { + this.queue( type || "fx", [] ); + } + + return this.each( function() { + var dequeue = true, + index = type != null && type + "queueHooks", + timers = jQuery.timers, + data = dataPriv.get( this ); + + if ( index ) { + if ( data[ index ] && data[ index ].stop ) { + stopQueue( data[ index ] ); + } + } else { + for ( index in data ) { + if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { + stopQueue( data[ index ] ); + } + } + } + + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && + ( type == null || timers[ index ].queue === type ) ) { + + timers[ index ].anim.stop( gotoEnd ); + dequeue = false; + timers.splice( index, 1 ); + } + } + + // Start the next in the queue if the last step wasn't forced. + // Timers currently will call their complete callbacks, which + // will dequeue but only if they were gotoEnd. + if ( dequeue || !gotoEnd ) { + jQuery.dequeue( this, type ); + } + } ); + }, + finish: function( type ) { + if ( type !== false ) { + type = type || "fx"; + } + return this.each( function() { + var index, + data = dataPriv.get( this ), + queue = data[ type + "queue" ], + hooks = data[ type + "queueHooks" ], + timers = jQuery.timers, + length = queue ? queue.length : 0; + + // Enable finishing flag on private data + data.finish = true; + + // Empty the queue first + jQuery.queue( this, type, [] ); + + if ( hooks && hooks.stop ) { + hooks.stop.call( this, true ); + } + + // Look for any active animations, and finish them + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && timers[ index ].queue === type ) { + timers[ index ].anim.stop( true ); + timers.splice( index, 1 ); + } + } + + // Look for any animations in the old queue and finish them + for ( index = 0; index < length; index++ ) { + if ( queue[ index ] && queue[ index ].finish ) { + queue[ index ].finish.call( this ); + } + } + + // Turn off finishing flag + delete data.finish; + } ); + } +} ); + +jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) { + var cssFn = jQuery.fn[ name ]; + jQuery.fn[ name ] = function( speed, easing, callback ) { + return speed == null || typeof speed === "boolean" ? + cssFn.apply( this, arguments ) : + this.animate( genFx( name, true ), speed, easing, callback ); + }; +} ); + +// Generate shortcuts for custom animations +jQuery.each( { + slideDown: genFx( "show" ), + slideUp: genFx( "hide" ), + slideToggle: genFx( "toggle" ), + fadeIn: { opacity: "show" }, + fadeOut: { opacity: "hide" }, + fadeToggle: { opacity: "toggle" } +}, function( name, props ) { + jQuery.fn[ name ] = function( speed, easing, callback ) { + return this.animate( props, speed, easing, callback ); + }; +} ); + +jQuery.timers = []; +jQuery.fx.tick = function() { + var timer, + i = 0, + timers = jQuery.timers; + + fxNow = Date.now(); + + for ( ; i < timers.length; i++ ) { + timer = timers[ i ]; + + // Run the timer and safely remove it when done (allowing for external removal) + if ( !timer() && timers[ i ] === timer ) { + timers.splice( i--, 1 ); + } + } + + if ( !timers.length ) { + jQuery.fx.stop(); + } + fxNow = undefined; +}; + +jQuery.fx.timer = function( timer ) { + jQuery.timers.push( timer ); + jQuery.fx.start(); +}; + +jQuery.fx.interval = 13; +jQuery.fx.start = function() { + if ( inProgress ) { + return; + } + + inProgress = true; + schedule(); +}; + +jQuery.fx.stop = function() { + inProgress = null; +}; + +jQuery.fx.speeds = { + slow: 600, + fast: 200, + + // Default speed + _default: 400 +}; + + +// Based off of the plugin by Clint Helfers, with permission. +// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ +jQuery.fn.delay = function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = window.setTimeout( next, time ); + hooks.stop = function() { + window.clearTimeout( timeout ); + }; + } ); +}; + + +( function() { + var input = document.createElement( "input" ), + select = document.createElement( "select" ), + opt = select.appendChild( document.createElement( "option" ) ); + + input.type = "checkbox"; + + // Support: Android <=4.3 only + // Default value for a checkbox should be "on" + support.checkOn = input.value !== ""; + + // Support: IE <=11 only + // Must access selectedIndex to make default options select + support.optSelected = opt.selected; + + // Support: IE <=11 only + // An input loses its value after becoming a radio + input = document.createElement( "input" ); + input.value = "t"; + input.type = "radio"; + support.radioValue = input.value === "t"; +} )(); + + +var boolHook, + attrHandle = jQuery.expr.attrHandle; + +jQuery.fn.extend( { + attr: function( name, value ) { + return access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each( function() { + jQuery.removeAttr( this, name ); + } ); + } +} ); + +jQuery.extend( { + attr: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set attributes on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + // Attribute hooks are determined by the lowercase version + // Grab necessary hook if one is defined + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + hooks = jQuery.attrHooks[ name.toLowerCase() ] || + ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); + } + + if ( value !== undefined ) { + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + } + + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + elem.setAttribute( name, value + "" ); + return value; + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + ret = jQuery.find.attr( elem, name ); + + // Non-existent attributes return null, we normalize to undefined + return ret == null ? undefined : ret; + }, + + attrHooks: { + type: { + set: function( elem, value ) { + if ( !support.radioValue && value === "radio" && + nodeName( elem, "input" ) ) { + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + } + }, + + removeAttr: function( elem, value ) { + var name, + i = 0, + + // Attribute names can contain non-HTML whitespace characters + // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 + attrNames = value && value.match( rnothtmlwhite ); + + if ( attrNames && elem.nodeType === 1 ) { + while ( ( name = attrNames[ i++ ] ) ) { + elem.removeAttribute( name ); + } + } + } +} ); + +// Hooks for boolean attributes +boolHook = { + set: function( elem, value, name ) { + if ( value === false ) { + + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + elem.setAttribute( name, name ); + } + return name; + } +}; + +jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) { + var getter = attrHandle[ name ] || jQuery.find.attr; + + attrHandle[ name ] = function( elem, name, isXML ) { + var ret, handle, + lowercaseName = name.toLowerCase(); + + if ( !isXML ) { + + // Avoid an infinite loop by temporarily removing this function from the getter + handle = attrHandle[ lowercaseName ]; + attrHandle[ lowercaseName ] = ret; + ret = getter( elem, name, isXML ) != null ? + lowercaseName : + null; + attrHandle[ lowercaseName ] = handle; + } + return ret; + }; +} ); + + + + +var rfocusable = /^(?:input|select|textarea|button)$/i, + rclickable = /^(?:a|area)$/i; + +jQuery.fn.extend( { + prop: function( name, value ) { + return access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + return this.each( function() { + delete this[ jQuery.propFix[ name ] || name ]; + } ); + } +} ); + +jQuery.extend( { + prop: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set properties on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + return ( elem[ name ] = value ); + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + return elem[ name ]; + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + + // Support: IE <=9 - 11 only + // elem.tabIndex doesn't always return the + // correct value when it hasn't been explicitly set + // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + // Use proper attribute retrieval(#12072) + var tabindex = jQuery.find.attr( elem, "tabindex" ); + + if ( tabindex ) { + return parseInt( tabindex, 10 ); + } + + if ( + rfocusable.test( elem.nodeName ) || + rclickable.test( elem.nodeName ) && + elem.href + ) { + return 0; + } + + return -1; + } + } + }, + + propFix: { + "for": "htmlFor", + "class": "className" + } +} ); + +// Support: IE <=11 only +// Accessing the selectedIndex property +// forces the browser to respect setting selected +// on the option +// The getter ensures a default option is selected +// when in an optgroup +// eslint rule "no-unused-expressions" is disabled for this code +// since it considers such accessions noop +if ( !support.optSelected ) { + jQuery.propHooks.selected = { + get: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent && parent.parentNode ) { + parent.parentNode.selectedIndex; + } + return null; + }, + set: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent ) { + parent.selectedIndex; + + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + } + }; +} + +jQuery.each( [ + "tabIndex", + "readOnly", + "maxLength", + "cellSpacing", + "cellPadding", + "rowSpan", + "colSpan", + "useMap", + "frameBorder", + "contentEditable" +], function() { + jQuery.propFix[ this.toLowerCase() ] = this; +} ); + + + + + // Strip and collapse whitespace according to HTML spec + // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace + function stripAndCollapse( value ) { + var tokens = value.match( rnothtmlwhite ) || []; + return tokens.join( " " ); + } + + +function getClass( elem ) { + return elem.getAttribute && elem.getAttribute( "class" ) || ""; +} + +function classesToArray( value ) { + if ( Array.isArray( value ) ) { + return value; + } + if ( typeof value === "string" ) { + return value.match( rnothtmlwhite ) || []; + } + return []; +} + +jQuery.fn.extend( { + addClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + if ( cur.indexOf( " " + clazz + " " ) < 0 ) { + cur += clazz + " "; + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + if ( !arguments.length ) { + return this.attr( "class", "" ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + + // This expression is here for better compressibility (see addClass) + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + + // Remove *all* instances + while ( cur.indexOf( " " + clazz + " " ) > -1 ) { + cur = cur.replace( " " + clazz + " ", " " ); + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isValidValue = type === "string" || Array.isArray( value ); + + if ( typeof stateVal === "boolean" && isValidValue ) { + return stateVal ? this.addClass( value ) : this.removeClass( value ); + } + + if ( isFunction( value ) ) { + return this.each( function( i ) { + jQuery( this ).toggleClass( + value.call( this, i, getClass( this ), stateVal ), + stateVal + ); + } ); + } + + return this.each( function() { + var className, i, self, classNames; + + if ( isValidValue ) { + + // Toggle individual class names + i = 0; + self = jQuery( this ); + classNames = classesToArray( value ); + + while ( ( className = classNames[ i++ ] ) ) { + + // Check each className given, space separated list + if ( self.hasClass( className ) ) { + self.removeClass( className ); + } else { + self.addClass( className ); + } + } + + // Toggle whole class name + } else if ( value === undefined || type === "boolean" ) { + className = getClass( this ); + if ( className ) { + + // Store className if set + dataPriv.set( this, "__className__", className ); + } + + // If the element has a class name or if we're passed `false`, + // then remove the whole classname (if there was one, the above saved it). + // Otherwise bring back whatever was previously saved (if anything), + // falling back to the empty string if nothing was stored. + if ( this.setAttribute ) { + this.setAttribute( "class", + className || value === false ? + "" : + dataPriv.get( this, "__className__" ) || "" + ); + } + } + } ); + }, + + hasClass: function( selector ) { + var className, elem, + i = 0; + + className = " " + selector + " "; + while ( ( elem = this[ i++ ] ) ) { + if ( elem.nodeType === 1 && + ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { + return true; + } + } + + return false; + } +} ); + + + + +var rreturn = /\r/g; + +jQuery.fn.extend( { + val: function( value ) { + var hooks, ret, valueIsFunction, + elem = this[ 0 ]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || + jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && + "get" in hooks && + ( ret = hooks.get( elem, "value" ) ) !== undefined + ) { + return ret; + } + + ret = elem.value; + + // Handle most common string cases + if ( typeof ret === "string" ) { + return ret.replace( rreturn, "" ); + } + + // Handle cases where value is null/undef or number + return ret == null ? "" : ret; + } + + return; + } + + valueIsFunction = isFunction( value ); + + return this.each( function( i ) { + var val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( valueIsFunction ) { + val = value.call( this, i, jQuery( this ).val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + + } else if ( typeof val === "number" ) { + val += ""; + + } else if ( Array.isArray( val ) ) { + val = jQuery.map( val, function( value ) { + return value == null ? "" : value + ""; + } ); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + } ); + } +} ); + +jQuery.extend( { + valHooks: { + option: { + get: function( elem ) { + + var val = jQuery.find.attr( elem, "value" ); + return val != null ? + val : + + // Support: IE <=10 - 11 only + // option.text throws exceptions (#14686, #14858) + // Strip and collapse whitespace + // https://html.spec.whatwg.org/#strip-and-collapse-whitespace + stripAndCollapse( jQuery.text( elem ) ); + } + }, + select: { + get: function( elem ) { + var value, option, i, + options = elem.options, + index = elem.selectedIndex, + one = elem.type === "select-one", + values = one ? null : [], + max = one ? index + 1 : options.length; + + if ( index < 0 ) { + i = max; + + } else { + i = one ? index : 0; + } + + // Loop through all the selected options + for ( ; i < max; i++ ) { + option = options[ i ]; + + // Support: IE <=9 only + // IE8-9 doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + + // Don't return options that are disabled or in a disabled optgroup + !option.disabled && + ( !option.parentNode.disabled || + !nodeName( option.parentNode, "optgroup" ) ) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + }, + + set: function( elem, value ) { + var optionSet, option, + options = elem.options, + values = jQuery.makeArray( value ), + i = options.length; + + while ( i-- ) { + option = options[ i ]; + + /* eslint-disable no-cond-assign */ + + if ( option.selected = + jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 + ) { + optionSet = true; + } + + /* eslint-enable no-cond-assign */ + } + + // Force browsers to behave consistently when non-matching value is set + if ( !optionSet ) { + elem.selectedIndex = -1; + } + return values; + } + } + } +} ); + +// Radios and checkboxes getter/setter +jQuery.each( [ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + set: function( elem, value ) { + if ( Array.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); + } + } + }; + if ( !support.checkOn ) { + jQuery.valHooks[ this ].get = function( elem ) { + return elem.getAttribute( "value" ) === null ? "on" : elem.value; + }; + } +} ); + + + + +// Return jQuery for attributes-only inclusion + + +support.focusin = "onfocusin" in window; + + +var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + stopPropagationCallback = function( e ) { + e.stopPropagation(); + }; + +jQuery.extend( jQuery.event, { + + trigger: function( event, data, elem, onlyHandlers ) { + + var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, + eventPath = [ elem || document ], + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; + + cur = lastElement = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "." ) > -1 ) { + + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split( "." ); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf( ":" ) < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join( "." ); + event.rnamespace = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === ( elem.ownerDocument || document ) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { + lastElement = cur; + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( + dataPriv.get( cur, "events" ) || Object.create( null ) + )[ event.type ] && + dataPriv.get( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && handle.apply && acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( ( !special._default || + special._default.apply( eventPath.pop(), data ) === false ) && + acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name as the event. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + + if ( event.isPropagationStopped() ) { + lastElement.addEventListener( type, stopPropagationCallback ); + } + + elem[ type ](); + + if ( event.isPropagationStopped() ) { + lastElement.removeEventListener( type, stopPropagationCallback ); + } + + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + // Piggyback on a donor event to simulate a different one + // Used only for `focus(in | out)` events + simulate: function( type, elem, event ) { + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true + } + ); + + jQuery.event.trigger( e, null, elem ); + } + +} ); + +jQuery.fn.extend( { + + trigger: function( type, data ) { + return this.each( function() { + jQuery.event.trigger( type, data, this ); + } ); + }, + triggerHandler: function( type, data ) { + var elem = this[ 0 ]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +} ); + + +// Support: Firefox <=44 +// Firefox doesn't have focus(in | out) events +// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 +// +// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 +// focus(in | out) events fire after focus & blur events, +// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order +// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 +if ( !support.focusin ) { + jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler on the document while someone wants focusin/focusout + var handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + + // Handle: regular nodes (via `this.ownerDocument`), window + // (via `this.document`) & document (via `this`). + var doc = this.ownerDocument || this.document || this, + attaches = dataPriv.access( doc, fix ); + + if ( !attaches ) { + doc.addEventListener( orig, handler, true ); + } + dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); + }, + teardown: function() { + var doc = this.ownerDocument || this.document || this, + attaches = dataPriv.access( doc, fix ) - 1; + + if ( !attaches ) { + doc.removeEventListener( orig, handler, true ); + dataPriv.remove( doc, fix ); + + } else { + dataPriv.access( doc, fix, attaches ); + } + } + }; + } ); +} +var location = window.location; + +var nonce = { guid: Date.now() }; + +var rquery = ( /\?/ ); + + + +// Cross-browser xml parsing +jQuery.parseXML = function( data ) { + var xml; + if ( !data || typeof data !== "string" ) { + return null; + } + + // Support: IE 9 - 11 only + // IE throws on parseFromString with invalid input. + try { + xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); + } catch ( e ) { + xml = undefined; + } + + if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; +}; + + +var + rbracket = /\[\]$/, + rCRLF = /\r?\n/g, + rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, + rsubmittable = /^(?:input|select|textarea|keygen)/i; + +function buildParams( prefix, obj, traditional, add ) { + var name; + + if ( Array.isArray( obj ) ) { + + // Serialize array item. + jQuery.each( obj, function( i, v ) { + if ( traditional || rbracket.test( prefix ) ) { + + // Treat each array item as a scalar. + add( prefix, v ); + + } else { + + // Item is non-scalar (array or object), encode its numeric index. + buildParams( + prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", + v, + traditional, + add + ); + } + } ); + + } else if ( !traditional && toType( obj ) === "object" ) { + + // Serialize object item. + for ( name in obj ) { + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); + } + + } else { + + // Serialize scalar item. + add( prefix, obj ); + } +} + +// Serialize an array of form elements or a set of +// key/values into a query string +jQuery.param = function( a, traditional ) { + var prefix, + s = [], + add = function( key, valueOrFunction ) { + + // If value is a function, invoke it and use its return value + var value = isFunction( valueOrFunction ) ? + valueOrFunction() : + valueOrFunction; + + s[ s.length ] = encodeURIComponent( key ) + "=" + + encodeURIComponent( value == null ? "" : value ); + }; + + if ( a == null ) { + return ""; + } + + // If an array was passed in, assume that it is an array of form elements. + if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { + + // Serialize the form elements + jQuery.each( a, function() { + add( this.name, this.value ); + } ); + + } else { + + // If traditional, encode the "old" way (the way 1.3.2 or older + // did it), otherwise encode params recursively. + for ( prefix in a ) { + buildParams( prefix, a[ prefix ], traditional, add ); + } + } + + // Return the resulting serialization + return s.join( "&" ); +}; + +jQuery.fn.extend( { + serialize: function() { + return jQuery.param( this.serializeArray() ); + }, + serializeArray: function() { + return this.map( function() { + + // Can add propHook for "elements" to filter or add form elements + var elements = jQuery.prop( this, "elements" ); + return elements ? jQuery.makeArray( elements ) : this; + } ) + .filter( function() { + var type = this.type; + + // Use .is( ":disabled" ) so that fieldset[disabled] works + return this.name && !jQuery( this ).is( ":disabled" ) && + rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && + ( this.checked || !rcheckableType.test( type ) ); + } ) + .map( function( _i, elem ) { + var val = jQuery( this ).val(); + + if ( val == null ) { + return null; + } + + if ( Array.isArray( val ) ) { + return jQuery.map( val, function( val ) { + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ); + } + + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ).get(); + } +} ); + + +var + r20 = /%20/g, + rhash = /#.*$/, + rantiCache = /([?&])_=[^&]*/, + rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, + + // #7653, #8125, #8152: local protocol detection + rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, + rnoContent = /^(?:GET|HEAD)$/, + rprotocol = /^\/\//, + + /* Prefilters + * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) + * 2) These are called: + * - BEFORE asking for a transport + * - AFTER param serialization (s.data is a string if s.processData is true) + * 3) key is the dataType + * 4) the catchall symbol "*" can be used + * 5) execution will start with transport dataType and THEN continue down to "*" if needed + */ + prefilters = {}, + + /* Transports bindings + * 1) key is the dataType + * 2) the catchall symbol "*" can be used + * 3) selection will start with transport dataType and THEN go to "*" if needed + */ + transports = {}, + + // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression + allTypes = "*/".concat( "*" ), + + // Anchor tag for parsing the document origin + originAnchor = document.createElement( "a" ); + originAnchor.href = location.href; + +// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport +function addToPrefiltersOrTransports( structure ) { + + // dataTypeExpression is optional and defaults to "*" + return function( dataTypeExpression, func ) { + + if ( typeof dataTypeExpression !== "string" ) { + func = dataTypeExpression; + dataTypeExpression = "*"; + } + + var dataType, + i = 0, + dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; + + if ( isFunction( func ) ) { + + // For each dataType in the dataTypeExpression + while ( ( dataType = dataTypes[ i++ ] ) ) { + + // Prepend if requested + if ( dataType[ 0 ] === "+" ) { + dataType = dataType.slice( 1 ) || "*"; + ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); + + // Otherwise append + } else { + ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); + } + } + } + }; +} + +// Base inspection function for prefilters and transports +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { + + var inspected = {}, + seekingTransport = ( structure === transports ); + + function inspect( dataType ) { + var selected; + inspected[ dataType ] = true; + jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { + var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); + if ( typeof dataTypeOrTransport === "string" && + !seekingTransport && !inspected[ dataTypeOrTransport ] ) { + + options.dataTypes.unshift( dataTypeOrTransport ); + inspect( dataTypeOrTransport ); + return false; + } else if ( seekingTransport ) { + return !( selected = dataTypeOrTransport ); + } + } ); + return selected; + } + + return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); +} + +// A special extend for ajax options +// that takes "flat" options (not to be deep extended) +// Fixes #9887 +function ajaxExtend( target, src ) { + var key, deep, + flatOptions = jQuery.ajaxSettings.flatOptions || {}; + + for ( key in src ) { + if ( src[ key ] !== undefined ) { + ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; + } + } + if ( deep ) { + jQuery.extend( true, target, deep ); + } + + return target; +} + +/* Handles responses to an ajax request: + * - finds the right dataType (mediates between content-type and expected dataType) + * - returns the corresponding response + */ +function ajaxHandleResponses( s, jqXHR, responses ) { + + var ct, type, finalDataType, firstDataType, + contents = s.contents, + dataTypes = s.dataTypes; + + // Remove auto dataType and get content-type in the process + while ( dataTypes[ 0 ] === "*" ) { + dataTypes.shift(); + if ( ct === undefined ) { + ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); + } + } + + // Check if we're dealing with a known content-type + if ( ct ) { + for ( type in contents ) { + if ( contents[ type ] && contents[ type ].test( ct ) ) { + dataTypes.unshift( type ); + break; + } + } + } + + // Check to see if we have a response for the expected dataType + if ( dataTypes[ 0 ] in responses ) { + finalDataType = dataTypes[ 0 ]; + } else { + + // Try convertible dataTypes + for ( type in responses ) { + if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { + finalDataType = type; + break; + } + if ( !firstDataType ) { + firstDataType = type; + } + } + + // Or just use first one + finalDataType = finalDataType || firstDataType; + } + + // If we found a dataType + // We add the dataType to the list if needed + // and return the corresponding response + if ( finalDataType ) { + if ( finalDataType !== dataTypes[ 0 ] ) { + dataTypes.unshift( finalDataType ); + } + return responses[ finalDataType ]; + } +} + +/* Chain conversions given the request and the original response + * Also sets the responseXXX fields on the jqXHR instance + */ +function ajaxConvert( s, response, jqXHR, isSuccess ) { + var conv2, current, conv, tmp, prev, + converters = {}, + + // Work with a copy of dataTypes in case we need to modify it for conversion + dataTypes = s.dataTypes.slice(); + + // Create converters map with lowercased keys + if ( dataTypes[ 1 ] ) { + for ( conv in s.converters ) { + converters[ conv.toLowerCase() ] = s.converters[ conv ]; + } + } + + current = dataTypes.shift(); + + // Convert to each sequential dataType + while ( current ) { + + if ( s.responseFields[ current ] ) { + jqXHR[ s.responseFields[ current ] ] = response; + } + + // Apply the dataFilter if provided + if ( !prev && isSuccess && s.dataFilter ) { + response = s.dataFilter( response, s.dataType ); + } + + prev = current; + current = dataTypes.shift(); + + if ( current ) { + + // There's only work to do if current dataType is non-auto + if ( current === "*" ) { + + current = prev; + + // Convert response if prev dataType is non-auto and differs from current + } else if ( prev !== "*" && prev !== current ) { + + // Seek a direct converter + conv = converters[ prev + " " + current ] || converters[ "* " + current ]; + + // If none found, seek a pair + if ( !conv ) { + for ( conv2 in converters ) { + + // If conv2 outputs current + tmp = conv2.split( " " ); + if ( tmp[ 1 ] === current ) { + + // If prev can be converted to accepted input + conv = converters[ prev + " " + tmp[ 0 ] ] || + converters[ "* " + tmp[ 0 ] ]; + if ( conv ) { + + // Condense equivalence converters + if ( conv === true ) { + conv = converters[ conv2 ]; + + // Otherwise, insert the intermediate dataType + } else if ( converters[ conv2 ] !== true ) { + current = tmp[ 0 ]; + dataTypes.unshift( tmp[ 1 ] ); + } + break; + } + } + } + } + + // Apply converter (if not an equivalence) + if ( conv !== true ) { + + // Unless errors are allowed to bubble, catch and return them + if ( conv && s.throws ) { + response = conv( response ); + } else { + try { + response = conv( response ); + } catch ( e ) { + return { + state: "parsererror", + error: conv ? e : "No conversion from " + prev + " to " + current + }; + } + } + } + } + } + } + + return { state: "success", data: response }; +} + +jQuery.extend( { + + // Counter for holding the number of active queries + active: 0, + + // Last-Modified header cache for next request + lastModified: {}, + etag: {}, + + ajaxSettings: { + url: location.href, + type: "GET", + isLocal: rlocalProtocol.test( location.protocol ), + global: true, + processData: true, + async: true, + contentType: "application/x-www-form-urlencoded; charset=UTF-8", + + /* + timeout: 0, + data: null, + dataType: null, + username: null, + password: null, + cache: null, + throws: false, + traditional: false, + headers: {}, + */ + + accepts: { + "*": allTypes, + text: "text/plain", + html: "text/html", + xml: "application/xml, text/xml", + json: "application/json, text/javascript" + }, + + contents: { + xml: /\bxml\b/, + html: /\bhtml/, + json: /\bjson\b/ + }, + + responseFields: { + xml: "responseXML", + text: "responseText", + json: "responseJSON" + }, + + // Data converters + // Keys separate source (or catchall "*") and destination types with a single space + converters: { + + // Convert anything to text + "* text": String, + + // Text to html (true = no transformation) + "text html": true, + + // Evaluate text as a json expression + "text json": JSON.parse, + + // Parse text as xml + "text xml": jQuery.parseXML + }, + + // For options that shouldn't be deep extended: + // you can add your own custom options here if + // and when you create one that shouldn't be + // deep extended (see ajaxExtend) + flatOptions: { + url: true, + context: true + } + }, + + // Creates a full fledged settings object into target + // with both ajaxSettings and settings fields. + // If target is omitted, writes into ajaxSettings. + ajaxSetup: function( target, settings ) { + return settings ? + + // Building a settings object + ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : + + // Extending ajaxSettings + ajaxExtend( jQuery.ajaxSettings, target ); + }, + + ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), + ajaxTransport: addToPrefiltersOrTransports( transports ), + + // Main method + ajax: function( url, options ) { + + // If url is an object, simulate pre-1.5 signature + if ( typeof url === "object" ) { + options = url; + url = undefined; + } + + // Force options to be an object + options = options || {}; + + var transport, + + // URL without anti-cache param + cacheURL, + + // Response headers + responseHeadersString, + responseHeaders, + + // timeout handle + timeoutTimer, + + // Url cleanup var + urlAnchor, + + // Request state (becomes false upon send and true upon completion) + completed, + + // To know if global events are to be dispatched + fireGlobals, + + // Loop variable + i, + + // uncached part of the url + uncached, + + // Create the final options object + s = jQuery.ajaxSetup( {}, options ), + + // Callbacks context + callbackContext = s.context || s, + + // Context for global events is callbackContext if it is a DOM node or jQuery collection + globalEventContext = s.context && + ( callbackContext.nodeType || callbackContext.jquery ) ? + jQuery( callbackContext ) : + jQuery.event, + + // Deferreds + deferred = jQuery.Deferred(), + completeDeferred = jQuery.Callbacks( "once memory" ), + + // Status-dependent callbacks + statusCode = s.statusCode || {}, + + // Headers (they are sent all at once) + requestHeaders = {}, + requestHeadersNames = {}, + + // Default abort message + strAbort = "canceled", + + // Fake xhr + jqXHR = { + readyState: 0, + + // Builds headers hashtable if needed + getResponseHeader: function( key ) { + var match; + if ( completed ) { + if ( !responseHeaders ) { + responseHeaders = {}; + while ( ( match = rheaders.exec( responseHeadersString ) ) ) { + responseHeaders[ match[ 1 ].toLowerCase() + " " ] = + ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] ) + .concat( match[ 2 ] ); + } + } + match = responseHeaders[ key.toLowerCase() + " " ]; + } + return match == null ? null : match.join( ", " ); + }, + + // Raw string + getAllResponseHeaders: function() { + return completed ? responseHeadersString : null; + }, + + // Caches the header + setRequestHeader: function( name, value ) { + if ( completed == null ) { + name = requestHeadersNames[ name.toLowerCase() ] = + requestHeadersNames[ name.toLowerCase() ] || name; + requestHeaders[ name ] = value; + } + return this; + }, + + // Overrides response content-type header + overrideMimeType: function( type ) { + if ( completed == null ) { + s.mimeType = type; + } + return this; + }, + + // Status-dependent callbacks + statusCode: function( map ) { + var code; + if ( map ) { + if ( completed ) { + + // Execute the appropriate callbacks + jqXHR.always( map[ jqXHR.status ] ); + } else { + + // Lazy-add the new callbacks in a way that preserves old ones + for ( code in map ) { + statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; + } + } + } + return this; + }, + + // Cancel the request + abort: function( statusText ) { + var finalText = statusText || strAbort; + if ( transport ) { + transport.abort( finalText ); + } + done( 0, finalText ); + return this; + } + }; + + // Attach deferreds + deferred.promise( jqXHR ); + + // Add protocol if not provided (prefilters might expect it) + // Handle falsy url in the settings object (#10093: consistency with old signature) + // We also use the url parameter if available + s.url = ( ( url || s.url || location.href ) + "" ) + .replace( rprotocol, location.protocol + "//" ); + + // Alias method option to type as per ticket #12004 + s.type = options.method || options.type || s.method || s.type; + + // Extract dataTypes list + s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; + + // A cross-domain request is in order when the origin doesn't match the current origin. + if ( s.crossDomain == null ) { + urlAnchor = document.createElement( "a" ); + + // Support: IE <=8 - 11, Edge 12 - 15 + // IE throws exception on accessing the href property if url is malformed, + // e.g. http://example.com:80x/ + try { + urlAnchor.href = s.url; + + // Support: IE <=8 - 11 only + // Anchor's host property isn't correctly set when s.url is relative + urlAnchor.href = urlAnchor.href; + s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== + urlAnchor.protocol + "//" + urlAnchor.host; + } catch ( e ) { + + // If there is an error parsing the URL, assume it is crossDomain, + // it can be rejected by the transport if it is invalid + s.crossDomain = true; + } + } + + // Convert data if not already a string + if ( s.data && s.processData && typeof s.data !== "string" ) { + s.data = jQuery.param( s.data, s.traditional ); + } + + // Apply prefilters + inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); + + // If request was aborted inside a prefilter, stop there + if ( completed ) { + return jqXHR; + } + + // We can fire global events as of now if asked to + // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) + fireGlobals = jQuery.event && s.global; + + // Watch for a new set of requests + if ( fireGlobals && jQuery.active++ === 0 ) { + jQuery.event.trigger( "ajaxStart" ); + } + + // Uppercase the type + s.type = s.type.toUpperCase(); + + // Determine if request has content + s.hasContent = !rnoContent.test( s.type ); + + // Save the URL in case we're toying with the If-Modified-Since + // and/or If-None-Match header later on + // Remove hash to simplify url manipulation + cacheURL = s.url.replace( rhash, "" ); + + // More options handling for requests with no content + if ( !s.hasContent ) { + + // Remember the hash so we can put it back + uncached = s.url.slice( cacheURL.length ); + + // If data is available and should be processed, append data to url + if ( s.data && ( s.processData || typeof s.data === "string" ) ) { + cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; + + // #9682: remove data so that it's not used in an eventual retry + delete s.data; + } + + // Add or update anti-cache param if needed + if ( s.cache === false ) { + cacheURL = cacheURL.replace( rantiCache, "$1" ); + uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) + + uncached; + } + + // Put hash and anti-cache on the URL that will be requested (gh-1732) + s.url = cacheURL + uncached; + + // Change '%20' to '+' if this is encoded form body content (gh-2658) + } else if ( s.data && s.processData && + ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { + s.data = s.data.replace( r20, "+" ); + } + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + if ( jQuery.lastModified[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); + } + if ( jQuery.etag[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); + } + } + + // Set the correct header, if data is being sent + if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { + jqXHR.setRequestHeader( "Content-Type", s.contentType ); + } + + // Set the Accepts header for the server, depending on the dataType + jqXHR.setRequestHeader( + "Accept", + s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? + s.accepts[ s.dataTypes[ 0 ] ] + + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : + s.accepts[ "*" ] + ); + + // Check for headers option + for ( i in s.headers ) { + jqXHR.setRequestHeader( i, s.headers[ i ] ); + } + + // Allow custom headers/mimetypes and early abort + if ( s.beforeSend && + ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { + + // Abort if not done already and return + return jqXHR.abort(); + } + + // Aborting is no longer a cancellation + strAbort = "abort"; + + // Install callbacks on deferreds + completeDeferred.add( s.complete ); + jqXHR.done( s.success ); + jqXHR.fail( s.error ); + + // Get transport + transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); + + // If no transport, we auto-abort + if ( !transport ) { + done( -1, "No Transport" ); + } else { + jqXHR.readyState = 1; + + // Send global event + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); + } + + // If request was aborted inside ajaxSend, stop there + if ( completed ) { + return jqXHR; + } + + // Timeout + if ( s.async && s.timeout > 0 ) { + timeoutTimer = window.setTimeout( function() { + jqXHR.abort( "timeout" ); + }, s.timeout ); + } + + try { + completed = false; + transport.send( requestHeaders, done ); + } catch ( e ) { + + // Rethrow post-completion exceptions + if ( completed ) { + throw e; + } + + // Propagate others as results + done( -1, e ); + } + } + + // Callback for when everything is done + function done( status, nativeStatusText, responses, headers ) { + var isSuccess, success, error, response, modified, + statusText = nativeStatusText; + + // Ignore repeat invocations + if ( completed ) { + return; + } + + completed = true; + + // Clear timeout if it exists + if ( timeoutTimer ) { + window.clearTimeout( timeoutTimer ); + } + + // Dereference transport for early garbage collection + // (no matter how long the jqXHR object will be used) + transport = undefined; + + // Cache response headers + responseHeadersString = headers || ""; + + // Set readyState + jqXHR.readyState = status > 0 ? 4 : 0; + + // Determine if successful + isSuccess = status >= 200 && status < 300 || status === 304; + + // Get response data + if ( responses ) { + response = ajaxHandleResponses( s, jqXHR, responses ); + } + + // Use a noop converter for missing script + if ( !isSuccess && jQuery.inArray( "script", s.dataTypes ) > -1 ) { + s.converters[ "text script" ] = function() {}; + } + + // Convert no matter what (that way responseXXX fields are always set) + response = ajaxConvert( s, response, jqXHR, isSuccess ); + + // If successful, handle type chaining + if ( isSuccess ) { + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + modified = jqXHR.getResponseHeader( "Last-Modified" ); + if ( modified ) { + jQuery.lastModified[ cacheURL ] = modified; + } + modified = jqXHR.getResponseHeader( "etag" ); + if ( modified ) { + jQuery.etag[ cacheURL ] = modified; + } + } + + // if no content + if ( status === 204 || s.type === "HEAD" ) { + statusText = "nocontent"; + + // if not modified + } else if ( status === 304 ) { + statusText = "notmodified"; + + // If we have data, let's convert it + } else { + statusText = response.state; + success = response.data; + error = response.error; + isSuccess = !error; + } + } else { + + // Extract error from statusText and normalize for non-aborts + error = statusText; + if ( status || !statusText ) { + statusText = "error"; + if ( status < 0 ) { + status = 0; + } + } + } + + // Set data for the fake xhr object + jqXHR.status = status; + jqXHR.statusText = ( nativeStatusText || statusText ) + ""; + + // Success/Error + if ( isSuccess ) { + deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); + } else { + deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); + } + + // Status-dependent callbacks + jqXHR.statusCode( statusCode ); + statusCode = undefined; + + if ( fireGlobals ) { + globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", + [ jqXHR, s, isSuccess ? success : error ] ); + } + + // Complete + completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); + + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); + + // Handle the global AJAX counter + if ( !( --jQuery.active ) ) { + jQuery.event.trigger( "ajaxStop" ); + } + } + } + + return jqXHR; + }, + + getJSON: function( url, data, callback ) { + return jQuery.get( url, data, callback, "json" ); + }, + + getScript: function( url, callback ) { + return jQuery.get( url, undefined, callback, "script" ); + } +} ); + +jQuery.each( [ "get", "post" ], function( _i, method ) { + jQuery[ method ] = function( url, data, callback, type ) { + + // Shift arguments if data argument was omitted + if ( isFunction( data ) ) { + type = type || callback; + callback = data; + data = undefined; + } + + // The url can be an options object (which then must have .url) + return jQuery.ajax( jQuery.extend( { + url: url, + type: method, + dataType: type, + data: data, + success: callback + }, jQuery.isPlainObject( url ) && url ) ); + }; +} ); + +jQuery.ajaxPrefilter( function( s ) { + var i; + for ( i in s.headers ) { + if ( i.toLowerCase() === "content-type" ) { + s.contentType = s.headers[ i ] || ""; + } + } +} ); + + +jQuery._evalUrl = function( url, options, doc ) { + return jQuery.ajax( { + url: url, + + // Make this explicit, since user can override this through ajaxSetup (#11264) + type: "GET", + dataType: "script", + cache: true, + async: false, + global: false, + + // Only evaluate the response if it is successful (gh-4126) + // dataFilter is not invoked for failure responses, so using it instead + // of the default converter is kludgy but it works. + converters: { + "text script": function() {} + }, + dataFilter: function( response ) { + jQuery.globalEval( response, options, doc ); + } + } ); +}; + + +jQuery.fn.extend( { + wrapAll: function( html ) { + var wrap; + + if ( this[ 0 ] ) { + if ( isFunction( html ) ) { + html = html.call( this[ 0 ] ); + } + + // The elements to wrap the target around + wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); + + if ( this[ 0 ].parentNode ) { + wrap.insertBefore( this[ 0 ] ); + } + + wrap.map( function() { + var elem = this; + + while ( elem.firstElementChild ) { + elem = elem.firstElementChild; + } + + return elem; + } ).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( isFunction( html ) ) { + return this.each( function( i ) { + jQuery( this ).wrapInner( html.call( this, i ) ); + } ); + } + + return this.each( function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + } ); + }, + + wrap: function( html ) { + var htmlIsFunction = isFunction( html ); + + return this.each( function( i ) { + jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); + } ); + }, + + unwrap: function( selector ) { + this.parent( selector ).not( "body" ).each( function() { + jQuery( this ).replaceWith( this.childNodes ); + } ); + return this; + } +} ); + + +jQuery.expr.pseudos.hidden = function( elem ) { + return !jQuery.expr.pseudos.visible( elem ); +}; +jQuery.expr.pseudos.visible = function( elem ) { + return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); +}; + + + + +jQuery.ajaxSettings.xhr = function() { + try { + return new window.XMLHttpRequest(); + } catch ( e ) {} +}; + +var xhrSuccessStatus = { + + // File protocol always yields status code 0, assume 200 + 0: 200, + + // Support: IE <=9 only + // #1450: sometimes IE returns 1223 when it should be 204 + 1223: 204 + }, + xhrSupported = jQuery.ajaxSettings.xhr(); + +support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); +support.ajax = xhrSupported = !!xhrSupported; + +jQuery.ajaxTransport( function( options ) { + var callback, errorCallback; + + // Cross domain only allowed if supported through XMLHttpRequest + if ( support.cors || xhrSupported && !options.crossDomain ) { + return { + send: function( headers, complete ) { + var i, + xhr = options.xhr(); + + xhr.open( + options.type, + options.url, + options.async, + options.username, + options.password + ); + + // Apply custom fields if provided + if ( options.xhrFields ) { + for ( i in options.xhrFields ) { + xhr[ i ] = options.xhrFields[ i ]; + } + } + + // Override mime type if needed + if ( options.mimeType && xhr.overrideMimeType ) { + xhr.overrideMimeType( options.mimeType ); + } + + // X-Requested-With header + // For cross-domain requests, seeing as conditions for a preflight are + // akin to a jigsaw puzzle, we simply never set it to be sure. + // (it can always be set on a per-request basis or even using ajaxSetup) + // For same-domain requests, won't change header if already provided. + if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { + headers[ "X-Requested-With" ] = "XMLHttpRequest"; + } + + // Set headers + for ( i in headers ) { + xhr.setRequestHeader( i, headers[ i ] ); + } + + // Callback + callback = function( type ) { + return function() { + if ( callback ) { + callback = errorCallback = xhr.onload = + xhr.onerror = xhr.onabort = xhr.ontimeout = + xhr.onreadystatechange = null; + + if ( type === "abort" ) { + xhr.abort(); + } else if ( type === "error" ) { + + // Support: IE <=9 only + // On a manual native abort, IE9 throws + // errors on any property access that is not readyState + if ( typeof xhr.status !== "number" ) { + complete( 0, "error" ); + } else { + complete( + + // File: protocol always yields status 0; see #8605, #14207 + xhr.status, + xhr.statusText + ); + } + } else { + complete( + xhrSuccessStatus[ xhr.status ] || xhr.status, + xhr.statusText, + + // Support: IE <=9 only + // IE9 has no XHR2 but throws on binary (trac-11426) + // For XHR2 non-text, let the caller handle it (gh-2498) + ( xhr.responseType || "text" ) !== "text" || + typeof xhr.responseText !== "string" ? + { binary: xhr.response } : + { text: xhr.responseText }, + xhr.getAllResponseHeaders() + ); + } + } + }; + }; + + // Listen to events + xhr.onload = callback(); + errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); + + // Support: IE 9 only + // Use onreadystatechange to replace onabort + // to handle uncaught aborts + if ( xhr.onabort !== undefined ) { + xhr.onabort = errorCallback; + } else { + xhr.onreadystatechange = function() { + + // Check readyState before timeout as it changes + if ( xhr.readyState === 4 ) { + + // Allow onerror to be called first, + // but that will not handle a native abort + // Also, save errorCallback to a variable + // as xhr.onerror cannot be accessed + window.setTimeout( function() { + if ( callback ) { + errorCallback(); + } + } ); + } + }; + } + + // Create the abort callback + callback = callback( "abort" ); + + try { + + // Do send the request (this may raise an exception) + xhr.send( options.hasContent && options.data || null ); + } catch ( e ) { + + // #14683: Only rethrow if this hasn't been notified as an error yet + if ( callback ) { + throw e; + } + } + }, + + abort: function() { + if ( callback ) { + callback(); + } + } + }; + } +} ); + + + + +// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) +jQuery.ajaxPrefilter( function( s ) { + if ( s.crossDomain ) { + s.contents.script = false; + } +} ); + +// Install script dataType +jQuery.ajaxSetup( { + accepts: { + script: "text/javascript, application/javascript, " + + "application/ecmascript, application/x-ecmascript" + }, + contents: { + script: /\b(?:java|ecma)script\b/ + }, + converters: { + "text script": function( text ) { + jQuery.globalEval( text ); + return text; + } + } +} ); + +// Handle cache's special case and crossDomain +jQuery.ajaxPrefilter( "script", function( s ) { + if ( s.cache === undefined ) { + s.cache = false; + } + if ( s.crossDomain ) { + s.type = "GET"; + } +} ); + +// Bind script tag hack transport +jQuery.ajaxTransport( "script", function( s ) { + + // This transport only deals with cross domain or forced-by-attrs requests + if ( s.crossDomain || s.scriptAttrs ) { + var script, callback; + return { + send: function( _, complete ) { + script = jQuery( " +{% endmacro %} ADDED build/html/bookmarks.html Index: build/html/bookmarks.html ================================================================== --- build/html/bookmarks.html +++ build/html/bookmarks.html @@ -0,0 +1,306 @@ + + + + + + + + Bookmarks — Bitrhythm's literate documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + +
+ +
+
+ +
+ + + + + + + + + + + + +
+ + +
+ +
+ Contents +
+ +
+
+
+
+
+ +
+ +
+

Bookmarks

+ + +
+

Visuals

+

https://compform.net/turtles/
+https://github.com/capnmidnight/Primrose

+

The code editor borrows some CSS styles from this project +https://github.com/htor/repeat-editor

+
+ + +
+ + +
+ + + + +
+
+
+
+

+ + By Xyzzy Apps
+ + © Copyright (c) Xyzzy Apps, 2021.
+

+
+
+
+ + +
+
+ + + + + + ADDED build/html/changelog.html Index: build/html/changelog.html ================================================================== --- build/html/changelog.html +++ build/html/changelog.html @@ -0,0 +1,259 @@ + + + + + + + + Changelog — Bitrhythm's literate documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + +
+ +
+
+ +
+ + + + + + + + + + + + +
+ + +
+ +
+
+
+
+
+ +
+ +
+

Changelog

+

June - July 2019 ~ First prototype

+
Eval, tone.js and an checkoxbased input visualization for rhythm
+
+
+

Feb ~ May 2021 ~ Second Prototype

+
    Save feature
+    Added Samples
+    Moving to riot javascript
+    Fix for not mounting
+    Refactoring codebase
+    Added sphinx
+    Added number and monitoring for knob
+    Added clock
+    Changed Theme
+    Visuals
+    Observers and Misc Libraries
+    New sections
+    Fix for crackling
+    Docs
+
+
+

June - July 2021 - Demo

+
    Theme changes
+    Lots of Docs
+    Tutorials
+    Working visuals
+    Code Mirror Issue
+
+
+
+ + +
+ + + + +
+
+
+
+

+ + By Xyzzy Apps
+ + © Copyright (c) Xyzzy Apps, 2021.
+

+
+
+
+ + +
+
+ + + + + + ADDED build/html/demo.html Index: build/html/demo.html ================================================================== --- build/html/demo.html +++ build/html/demo.html @@ -0,0 +1,789 @@ + + + + + + + + Demo and Tutorial — Bitrhythm's literate documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + +
+ +
+
+ +
+ + + + + + + + + + + + +
+ + +
+ +
+ Contents +
+ +
+
+
+
+
+ +
+ +
+

Demo and Tutorial

+
+

Video

+ +

Postprocessed using Reaper with EQ and Surround effects to add some sparkle. +Video is recorded with the help of Blackhole and Kap and rendered by Reaper.

+

Samples taken from Deep Techno and Dub Techno collections from splice. Sadly I can’t distribute the song itself as I would also have to distribute the samples with it.

+
+
+

Demo Song 1 // Techno

+

Code for the Demo Song. The visualisation was disabled in the Demo as it was causing a huge lag while recording on both windows and mac.

+
volume_guard1 = guard([-20,15])
+volume_guard2 = guard([-20,15])
+Tone.Master.volume.value = volume_guard1(Math.round(dials[0]["cell"]() * 30) -20);
+ //mem["stab_channel"].volume.value = volume_guard2(-2);
+ //mem["stab_filter"].frequency.value = Math.round(dials[1]["cell"]() * 10000);
+//mem["l_filter"].frequency.value = Math.round(dials[1]["cell"]() * 1000);
+
+
+scene1 = [
+    cellx("p 1000 1000 1000 1000"),
+    cellx("p x000 0000 0000 0000"),
+    cellx("p 0x00 0000 0x00 x000"),
+    cellx("p 0000 x000 0000 x000"),
+    cellx("p x000 00x0 0x00 x0xx"),
+    cellx("p 00x0 00x0 0000 00x0"),
+    cellx("p 00x0 00x0 00x0 00x0"),
+]
+
+patterns = scene1
+
+always();
+
+function Sample(name, no, filter, volume) {
+    name = name
+    filter = filter || 10000
+    volume = volume || 0
+    mem[name + "_filter"] = new Tone.Filter(filter, 'lowpass', -96);
+    mem[name + "_channel"] = new Tone.Channel({channelCount: 2, volume: volume}).chain(mem[name + "_filter"], mem.master)
+    samples[no].connect(mem[name + "_channel"]);
+}
+
+function p(s, note, len) {
+    note = note || "C3"
+    len = len || "16n"
+    samples[s].triggerAttackRelease(note, len, time);
+}
+
+function once () {
+    
+	var vis = initWinamp("Cope - The Neverending Explosion of Red Liquid Fire");
+    render_loop = function () {
+       vis.render();
+    }
+
+    Tone.Master.volume.value = -30
+    mem.master = new Tone.Channel({channelCount: 2, volume: -10}).chain(Tone.Destination);
+
+    Sample("k", 0, 20000, 5);
+    Sample("h", 1, 20000, -5);
+    Sample("sn",2, 6000, -3);
+    Sample("c", 3, 1200, -10);
+    Sample("stab", 4, 420, 10);
+    Sample("l", 5, 20000, 8);
+    Sample("o", 6, 20000, -8);
+
+
+    handlers["1"] = function (val) {
+        if (val > 0.5) {
+            mem["start_snare"] = true;
+        }
+    }
+
+    dials[1]["cell"].onChange(function (e) {
+        var val = parseFloat(e["data"].value);
+        handlers["1"](val);
+    })
+
+}
+
+function tweak () {
+	mem.k1 = knob({initial : 0.42, ramp : [0.42, 0.525, 0.8, 0.4, 1, 0.65, 0.75, 1, 0.8], "number": dials[2]["cell"] });
+    always = function () {
+        mem["stab_filter"].frequency.value = mem.k1.move() * 1000;
+    }
+}
+
+function sampleTest () {
+    Sample("l", 4, 10000, -5);
+
+}
+
+if (bars <= 3 ) {
+	transition = once;
+} else {
+	transition = tweak;
+}
+
+if (isHit) {
+    if (track_no == 1) {
+   		 if (bars > 4 ) {
+       		 p(0);
+        }
+    }
+    if (track_no == 2) {
+        if (bars > 8 ) {
+       	 	p(1,  "C3", "1n");
+        }	
+    }
+    if (track_no == 3) {
+        if (bars > 0 ) {
+    		p(4, "C3", "1n");
+        }
+        if (bars == 15) {
+        	transition();
+        }
+    }
+    if (track_no == 4) {
+		  if( mem["start_snare"]) {
+           p(2);
+        }
+ 
+    }
+    if (track_no == 5) {
+    }
+    if (track_no == 6) {
+       if (bars > 12) {
+	       p(5, "F2", "16n")
+       } 
+    }
+	if (track_no == 7) {
+       if (bars > 48) {
+
+     		p(6, "C3", "48n")
+       }
+    }
+
+}
+
+
+
+
+

Example1

+

This illustrates the core concepts of bitrhythm.

+
    +
  1. Samples (Tone.Sampler)

  2. +
  3. Dials (use cellx internally)

  4. +
  5. Observers (cellx)

  6. +
+

See https://tonejs.github.io/ for more notes.

+

For an understanding of the global variables see the concepts and code walkthrough section.

+
- patterns and track_no
+- isHit, current_bit
+- samples
+- Tone
+- cellx
+- window and any thing included with the script tag is available here
+
+
+

mem is short for memory. All instruments and effects are saved here so that they can be accessed everywhere.

+

Step to create the basic song.

+
    +
  1. Click on Add Sample URL to add the following URLs

    +
      +
    • /Kick01.wav

    • +
    • /Snare19.wav

    • +
    • /Closedhat01.wav

    • +
    • /MiscSynthStab04.wav

    • +
    +
  2. +
  3. Click on Add Dial

  4. +
  5. Enter the following into the window

  6. +
+
scene1 = [
+    cellx("p 1000 1000 1000 1000"),
+    cellx("p 00x0 00x0 00x0 00x0"),
+    cellx("p 0000 x000 0000 x000"),
+]
+
+scene2 = [
+    cellx("p 1011 1001 1000 1000"),
+    cellx("p 00x0 00x0 00x0 00x0"),
+    cellx("p 0000 x000 0000 x000"),
+]
+
+patterns = scene1
+
+function Sample(name, no) {
+    name = name || "sample"
+    name += no
+    mem[name + "_filter"] = new Tone.Filter(10000, 'lowpass', -96);
+    mem[name + "_channel"] = new Tone.Channel({channelCount: 2, volume:0}).chain(mem[name + "_filter"], mem.master)
+    samples[no].connect(mem[name + "_channel"]);
+}
+
+function p(s, note) {
+    note = note || "C3"
+    samples[s].triggerAttack(note, time);
+}
+
+var once = function () {
+    Tone.Master.volume.value = -30
+    mem.master = new Tone.Channel({channelCount: 2, volume: -10}).chain( Tone.Destination);
+    mem.volume_guard = guard([-20,-10]);
+
+    Sample("k", 0);
+    Sample("h", 1);
+    Sample("sn", 2);
+
+    handlers["ex"] = function (val) {
+        if (val > 0.5) {
+            mem["start_snare"] = true;
+        }
+    }
+
+    dials[0]["cell"].onChange(function (e) {
+        var val = parseFloat(e["data"].value);
+        handlers["ex"](val);
+    })
+
+}
+
+if (bars <= 3 ) {
+	transition = once;
+} else {
+	transition = tweak;
+}
+
+if (isHit) {
+    if (track_no == 1) {
+        p(0);
+    }
+    if (track_no == 2) {
+        p(1);
+    }
+    if (track_no == 3) {
+		if (mem["start_snare"]) {
+            p(2);
+        };
+    }
+}
+
+
+
+
+

Now try changing the code.

+
patterns = scene2
+
+
+

Increase the dial to see the addition of the snare. This is how you can use observers to trigger unrelated changes. I call them sideevents, as the logic is similar to sidechain, which typically observers the volume.

+

Comment and Uncomment lines in the if (isHit) block. To mute and unmute sections.

+

Note: mem["k0_channel"].solo = true; is not working.

+

Visuals

+

Change the once function to this and click + Execute Once

+

Code is taken from butterchurn. Try changing presets to get different visuals.

+
var tweak = function() {
+    var can = document.getElementById("visual");
+    var can_container = document.getElementById("canvas-container");
+    can.width = window.innerWidth;
+    can.height = window.innerHeight;
+    can_container.width = window.innerWidth;
+    window.visualizer = window.butterchurn.default.createVisualizer(Tone.getContext().rawContext, can, {
+        width: window.innerWidth,
+        height: window.innerHeight,
+    });
+    window.visualizer.connectAudio(Tone.getContext().destination);
+    const presets = butterchurnPresets.getPresets();
+    const preset = presets["_Aderrasi - Wanderer in Curved Space - mash0000 - faclempt kibitzing meshuggana schmaltz (Geiss color mix)"]
+    window.visualizer.loadPreset(preset, 0.0); // 2nd argument is the number of seconds to blend presets
+
+    render_loop = function () {
+        window.visualizer.render();
+    }
+}
+
+
+

Tweaking

+

First click + Number. This is useful to check if the knob function is actually working. And click + Execute Once

+
var tweak = function () {
+    mem.k1 = knob({ramp : [0.09,1.8, 0.4, 2, 1.5, 1, 0.5, 3, 5, 8, 2], "number": numbers[0]["v"] });
+    always = function () {
+        mem["k0_filter"].frequency.value = mem.k1.move() * 1000;
+    }
+}
+
+
+

As you can sere numbers and dials will be available as a global array.

+

There is no way to remove them so be careful about the order in which you add them.

+

The following code will always be executed as its at the top level. As you can see this code implies that the first dial is connected to the master volume. Use guards to avoid going deaf as sometimes editing can created bad frequency numbers.

+
Tone.Master.volume.value = volume_guard((1 - dials[0]["cell"]()) * -30);
+
+
+
+
+

Example2

+
    +
  • Kick + Filter

  • +
  • Snare + Filter

  • +
  • Snare + Filter + Delay

  • +
  • High Hat

  • +
  • Lead + Filter

  • +
  • Dub Stab + Filter + Reverb

  • +
+

Tip: In Tone.js you can’t call connect one after another, you need to use chain.

+

TODO: Add glide to Lead to make it more 303 sounding

+

Master is connected with Surround and Volume Limiter. +Use Gates and Limiters to avoid going deaf.

+

Tone.MultiInstrument gave lots of glitches, so custom voices are written in the voice function

+

Channels provide

+
    +
  • Mute

  • +
  • Solo

  • +
+

More improvements for the Stab

+
- Chorus or Phaser
+- Compressor
+- Decay in envelope
+- Separate filters
+- EQ
+- Sends for more delay
+- LFO for filters
+
+
+

Freeverb does not work and also needs Mono to function properly

+
var reverb = new Tone.Freeverb().toDestination();
+var reverb_mono = new Tone.Mono().connect(reverb);
+reverb.dampening = 100;
+reverb.roomSize = 0.9;
+
+
+
+
+

Full Code

+
volume_guard1 = guard([-20,15])
+volume_guard2 = guard([-20,15])
+Tone.Master.volume.value = volume_guard1(Math.round(dials[0]["cell"]() * 30) -20);
+ //mem["stab_channel"].volume.value = volume_guard2(-2);
+// mem["stab_filter"].frequency.value = Math.round(dials[1]["cell"]() * 10000);
+// mem["l_filter"].frequency.value = Math.round(dials[1]["cell"]() * 1000);
+
+
+scene1 = [
+    cellx("p 1000 1000 1000 1000"),
+    cellx("p 00x0 00x0 00x0 00x0"),
+    cellx("p 0x00 0000 0000 x000"),
+    cellx("p 0000 x000 0000 x000"),
+    cellx("p xx0x x0x0 x0x0 0xxx"),
+    cellx("p x000 x0x0 0000 x0x0"),
+]
+
+patterns = scene1
+
+always();
+
+function NoiseSynth (name) {
+    name = name || "wf";
+    mem[name + "_stereo"] = new Tone.StereoWidener({width: 1});
+    mem[name] =  new Tone.Noise("pink").start();
+    mem[name + "_filter"] = new Tone.Filter(400, 'lowpass', -96);
+    mem[name + "_channel"] = new Tone.Channel({channelCount: 2, volume: -10, pan: -0.8}).chain(mem[name + "_filter"], mem[name + "_stereo"], mem.master);
+    mem[name].connect(mem[name + "_channel"])
+}
+
+
+function Sample(name, no, filter, volume) {
+    name = name
+    filter = filter || 10000
+    volume = volume || 0
+    mem[name + "_filter"] = new Tone.Filter(filter, 'lowpass', -96);
+    mem[name + "_channel"] = new Tone.Channel({channelCount: 2, volume: volume}).chain(mem[name + "_filter"], mem.master)
+    samples[no].connect(mem[name + "_channel"]);
+}
+
+function Stab(name) {
+    name = name || "stab";
+
+    mem[name + "_filter"] = new Tone.Filter(5250, 'lowpass', -96);
+    mem[name + "_hfilter"] = new Tone.Filter(80, 'highpass', -96);
+    mem[name + "_reverb"] = new Tone.Reverb(0.1);
+    mem[name + "_delay"] = new Tone.FeedbackDelay("4n", 0.4);
+    // mem[name + "_pdelay"] = new Tone.PingPongDelay("2n", 0.1);
+     mem[name + "_stereo"] = new Tone.StereoWidener({width: 0.25});
+     mem[name + "_channel"] = new Tone.Channel({channelCount: 2, volume: -2}).chain(mem[name + "_filter"] ,   mem[name + "_delay"], mem[name + "_reverb"],  mem[name + "_hfilter"] ,mem[name + "_stereo"], mem.master)
+
+
+    function voice(no, type) {
+        mem[name + "_synth" + no] = new Tone.MonoSynth({
+            oscillator: {
+                type: type
+            }
+        })
+        mem[name + "_synth" + no].connect(mem[name + "_channel"]);
+    }
+
+    voice(1, "sawtooth")
+    voice(2, "sawtooth")
+    voice(3, "sawtooth")
+    voice(4, "pwm")
+    voice(5, "pwm")
+    voice(6, "pwm")
+}
+
+
+function p(s, note, len) {
+    note = note || "C3"
+    len = len || "16n"
+    samples[s].triggerAttackRelease(note, len, time);
+}
+
+
+function s(vel, notes, duration) {
+    vel = vel || 1.0;
+    duration = duration || "2n";
+    notes = notes ||  ["E2", "B2", "G2"];
+    mem["stab_synth1"].triggerAttackRelease(notes[0], duration, time, vel);
+    mem["stab_synth2"].triggerAttackRelease(notes[1], duration, time, vel);
+    mem["stab_synth3"].triggerAttackRelease(notes[2], duration, time, vel);
+
+    mem["stab_synth4"].triggerAttackRelease(notes[0], duration, time, vel);
+    mem["stab_synth5"].triggerAttackRelease(notes[1], duration, time, vel);
+   mem["stab_synth6"].triggerAttackRelease(notes[2], duration, time, vel);
+}
+
+
+
+
+function once () {
+    
+	// var vis = initWinamp("Unchained - Rewop");
+    render_loop = function () {
+       // vis.render();
+    }
+
+    Tone.Master.volume.value = -30
+    mem.master = new Tone.Channel({channelCount: 2, volume: -10}).chain(Tone.Destination);
+
+    // NoiseSynth();
+    Stab();
+    Sample("k", 0, 3000, 3);
+    Sample("h", 1, 7000, -15);
+    Sample("sn",2, 6000, -15);
+    Sample("c", 3, 800, -10);
+    Sample("l", 4, 420, -15);
+
+
+    handlers["1"] = function (val) {
+        if (val > 0.5) {
+            mem["start_snare"] = true;
+        } else {
+            mem["start_snare"] = false;
+        }
+        mem["stab_filter"].Q.value = Math.round(val * 5);
+    }
+
+    dials[1]["cell"].onChange(function (e) {
+        var val = parseFloat(e["data"].value);
+        handlers["1"](val);
+    })
+    
+    
+
+}
+
+
+function tweak () {
+	mem.k1 = knob({ramp : [0.525, 0.8, 0.4, 1, 0.25, 0.75, 1, 0.25, 0.1], "number": dials[2]["cell"] });
+    always = function () {
+        mem["stab_filter"].frequency.value = mem.k1.move() * 10000;
+    }
+}
+
+
+
+
+function sampleTest () {
+    Sample("l", 4, 10000, -5);
+
+}
+
+
+
+if (bars <= 3 ) {
+	transition = once;
+} else {
+	transition = tweak;
+}
+
+if (isHit) {
+    if (track_no == 1) {
+   		 if (bars > 0 ) {
+       		 p(0);
+        }
+    }
+    if (track_no == 2) {
+        if (bars > 8 ) {
+       	 	p(1);
+        }	
+    }
+    if (track_no == 3) {
+        if (bars > 4 ) {
+    		s();
+        }
+        if (bars == 6) {
+        	transition();
+        }
+    }
+    if (track_no == 4) {
+        // Uncomment for snare
+      //  if (mem["start_snare"]) {
+            p(2);
+      //  }
+
+    }
+    if (track_no == 5) {
+         if (bars > 12) {
+	  		p(3)
+        }
+       // a();
+    }
+    if (track_no == 6) {
+      // p(4, "B3", "8n")
+    }
+
+}
+
+
+
+
+ + +
+ + + + +
+
+
+
+

+ + By Xyzzy Apps
+ + © Copyright (c) Xyzzy Apps, 2021.
+

+
+
+
+ + +
+
+ + + + + + ADDED build/html/early-attempts.html Index: build/html/early-attempts.html ================================================================== --- build/html/early-attempts.html +++ build/html/early-attempts.html @@ -0,0 +1,307 @@ + + + + + + + + Early Attempts — Bitrhythm's literate documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + +
+ +
+
+ +
+ + + + + + + + + + + + +
+ + +
+ +
+
+
+
+
+ +
+ +
+

Early Attempts

+

My first attempt at this project was called bang256 ~ 2016, meant to mess with Renoise’s OSC. Its still usable.

+

The music loop for OSC sequencing. You need to install osc and nanotimer. Alternatively you can use portmidi

+
var fs = require("fs");
+var osc = require("osc");
+var NanoTimer = require('nanotimer');
+var timer = new NanoTimer();
+
+function bang256(host, port, tempo, lines_per_beat, measure, tracks, title) {
+
+    var udpPort = new osc.UDPPort({
+        remoteAddress: host,
+        remotePort: port
+    });
+
+    udpPort.open();
+
+    var beat = 60.0 / tempo;
+    var lines_per_measure = lines_per_beat * measure;
+    var tick = beat / lines_per_beat;
+    var bangs = 0;
+    var count = 0;
+
+    timer.setInterval(function() {
+        var bang = (bangs % lines_per_measure);
+        if (bang == 0) {
+            count++;
+        }
+        for (var t = 1; t <= tracks; t++) {
+            var path = title + "/" + t;
+            if (fs.existsSync(path)) {
+                var code = fs.readFileSync(path, {encoding: 'utf-8'});
+                var f = eval(code);
+                f(udpPort, bang, count, bangs);
+            }
+        }
+
+        bangs++;
+
+    }, '', tick + "s");
+
+}
+
+var argv = require('minimist')(process.argv.slice(2));
+var bang256 = require("bang256").bang256;
+
+var host = argv["host"] || "127.0.0.1";
+var port = argv["port"] || 8000;
+var tempo = argv["tempo"];
+var lines_per_beat = argv["lpb"] || 4;
+var measure = argv["measure"] || 4;
+var tracks = argv["tracks"] || 4;
+var title = argv["title"];
+
+bang256(host, port, tempo, lines_per_beat, measure, tracks, title);
+
+
+

To run,

+
node ./bang256 -host "127.0.0.1" --tempo=120 --lpb=4 --measure=4 --tracks=4 --title=foo
+
+
+

Edit files in foo/1 and foo/2 and foo/3 and foo/4 to create live music with an OSC compatible synthesizer.

+

Inside the file foo/1

+
(function (osc, bang, count, bangs, thread) {
+
+    if ([4, 12].indexOf(bang) != -1) {
+        var msg = {
+            address: "/renoise/trigger/note_on",
+            args: [ 1, 1, 38, 127],
+        };
+        osc.send(msg);
+    }
+
+})
+
+
+

https://www.perl.com/pub/2004/08/31/livecode.html/ also uses the ticks approach but uses a message bus for events.
+https://github.com/psenough/teach_yourself_demoscene_in_14_days

+
+ + +
+ + +
+ + Samples + Changelog + +
+ +
+
+
+
+

+ + By Xyzzy Apps
+ + © Copyright (c) Xyzzy Apps, 2021.
+

+
+
+
+ + +
+
+ + + + + + ADDED build/html/genindex.html Index: build/html/genindex.html ================================================================== --- build/html/genindex.html +++ build/html/genindex.html @@ -0,0 +1,229 @@ + + + + + + + + Index — Bitrhythm's literate documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + +
+ +
+
+ +
+ + + + + + + + + + + + +
+ + +
+ +
+
+
+
+
+ +
+ + +

Index

+ +
+ +
+ + +
+ + +
+ + +
+ +
+
+
+
+

+ + By Xyzzy Apps
+ + © Copyright (c) Xyzzy Apps, 2021.
+

+
+
+
+ + +
+
+ + + + + + ADDED build/html/index.html Index: build/html/index.html ================================================================== --- build/html/index.html +++ build/html/index.html @@ -0,0 +1,295 @@ + + + + + + + + + + Welcome to Bitrhythm’s documentation! — Bitrhythm's literate documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ADDED build/html/limitations.html Index: build/html/limitations.html ================================================================== --- build/html/limitations.html +++ build/html/limitations.html @@ -0,0 +1,237 @@ + + + + + + + + Limitations and Recording — Bitrhythm's literate documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + +
+ +
+
+ +
+ + + + + + + + + + + + +
+ + +
+ +
+
+
+
+
+ +
+ +
+

Limitations and Recording

+
    +
  • Opening developer tools might slow down the execution a bit

  • +
  • Using excessive delays and reverbs seems to cause some glitches

  • +
  • Mobile browsers don’t work properly

  • +
  • Firefox does not seem to work well with tone.js

  • +
+

I use BlackHole to record audio from the browser window to Reaper. You can use any screenrecording software to record the screen. Have a distinct sound to match both audio and video.

+
+ + +
+ + + + +
+
+
+
+

+ + By Xyzzy Apps
+ + © Copyright (c) Xyzzy Apps, 2021.
+

+
+
+
+ + +
+
+ + + + + + ADDED build/html/main.html Index: build/html/main.html ================================================================== --- build/html/main.html +++ build/html/main.html @@ -0,0 +1,1446 @@ + + + + + + + + Concepts and Code Walkthrough — Bitrhythm's literate documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + +
+ +
+
+ +
+ + + + + + + + + + + + +
+ + + +
+
+
+
+ +
+ +
+

Concepts and Code Walkthrough

+
+

Running

+

ls source/main.cog | entr -r runserver.sh -b

+
+
+

Core Tracker Loop

+

In bitrhythm code is evaluated for every cycle.

+

1 beat = 60 / tempo +1 cycle = 1 beat / ticks

+

For every cycle visual and audio code is evaluated.

+

The edit checkbox allows you to perform long edits, where only old code is evaluated. Once you disable it, all the new edit changes are applied in the next cycle.

+

If there is any syntax error, previous working code is used.

+

If the click the execute transition is selected, the transition function is run. Use this progressing the song from initializing to tweaking.

+

Patterns is an array of strings, each string can be hexadecimal, decimal or something like “x000 x000 x000 x000”. +isHit and track_no can be used to identify the layer in the live editor. Hexadecimal uses `0 `1 `2 `3 `4 `5 instead of the Roman numerals abcde for 10, 11, 12 …

+

Scheduled Time as signified by the variable time is crucial when calling note triggers. This is used by Tone.js to schedule notes to play in the future.

+
+

Observers

+

Sidechain compression is a simple algorithm which observes amplitude of another instrument but you can generalise it to anything. By attaching observers to time or other instruments you can create sections within the song that can trigger others with conditional logic. This is similar to pure data’s bangs - see this. In future this will be referred to as side events. You could decrease the volume of the drums to have the snares drop automatically for example.

+

This is something that you can’t do in DAWs.

+
async play() {
+    var self = this;
+    var cellx = window.cellx.cellx;
+
+    await Tone.start();
+    Tone.Transport.start();
+    Tone.Transport.bpm.value = this.state.tempo;
+    Tone.Transport.swing.value = 0;
+
+    var transition = function () {
+    }
+
+    var always = function () {
+    }
+
+
+    var render_loop = function () {
+    }
+
+    var animation = function () {
+        render_loop();
+        window.requestAnimationFrame(animation)
+    }
+
+    Tone.Master.mute = false;
+    document.getElementById('tempo-value').disabled = true;
+    document.getElementById('tick-value').disabled = true;
+
+    var mem = self.state.mem;
+    var handlers = {};
+    var count = -1;
+
+    var text = editor.getValue();
+    editor.on("change", function () {
+            text = editor.getValue();
+    });
+
+    var patterns = [ cellx("0000") ]; // need this for first eval
+
+    var bars = 0;
+    var tick = 0;
+
+    loop = new Tone.ToneEvent((time, chord) => {
+        count = count + 1;
+        tick = (count % this.state.ticks);
+        if (tick === 0) ++bars;
+
+        $("#duration").html("" + bars + "." + tick + " / " + count + " / " + window.roundTo(Tone.Transport.seconds, 2));
+
+        for (var i = 0; i < patterns.length; i++) {
+            var samples = this.state.samples;
+            var dials = self.state.dials;
+            var numbers = self.state.numbers;
+
+            if (document.getElementById('edit-mode').checked) {
+                p = oldPatterns[i];
+            } else {
+                var p = patterns[i];
+                oldPatterns[i] = p;
+            }
+            if (p && p.length !== 0) {
+                var track_no = i + 1;
+                var pattern = pattern_clean(p());
+                var isHit = (pattern.split('')[tick] == "1") ? true : false;
+
+                try {
+                    if (document.getElementById('edit-mode').checked) {
+                        eval(oldCode);
+                    } else {
+                        eval(text);
+                        if (document.getElementById('load-mode').checked) {
+                            document.getElementById('load-mode').checked = false;
+                            transition();
+                        }
+                        oldCode = text;
+                    }
+                    $("#error").html("");
+                } catch (ex) {
+                    $("#error").html(ex);
+                    eval(oldCode);
+                }
+            }
+        }
+    }, []);
+    loop.loop = true;
+    loop.loopEnd = this.state.ticks + "n";
+    loop.start();
+
+   window.requestAnimationFrame(animation)
+
+}
+
+
+
+
+
+

Dials

+

Bitrhythm provides custom dials. These dials can be mapped to any aspects of Tone.js. All dials are available as an array dials in the live code editor.

+
<dial>
+    <vbox>
+        <div class="ml-4">
+            <hstack>
+                <div id={"knob" + props.ti}></div>
+                <div class="mt-1" style="height: 22px" id={"knob-value" + props.ti}></div>
+                <span class="cursor-pointer" id={"sample" + this.props.ti} onclick={remove(this.props.ti -1)}>(x)</span>
+            </hstack>
+        </div>
+    </vbox>
+
+    <script>
+
+this.props = opts;
+
+remove(index) {
+    return () => {
+        this.props.rmdial(index);
+    }
+}
+
+this.on("mount", () => {
+    if (opts.v) {
+
+        Nexus.colors.accent = "#000000"
+        Nexus.colors.fill = "#ffffff"
+
+        var cell = window.cellx.cellx(0.5);
+        var dial = new Nexus.Dial('#knob' + this.props.ti, {
+            'size': [45, 45],
+            'value': 0.5
+        });
+        cell.onChange(evt => {
+            if (evt.data.prevValue !== evt.data.value) {
+                dial.value = evt.data.value;
+            }
+        });
+        dial.colorize("accent","#000")
+        dial.on('change', (val) => {
+            val = window.roundTo(val, 4);
+            $('#knob-value' + this.props.ti).html(val);
+            cell(val);
+        });
+       this.props.v["cell"] = cell;
+    }
+});
+   </script>
+
+</dial>
+
+
+
+
+

Numbers

+

These numbers can be mapped to any aspect of Tone.js. All number boxes are available as an array numbers in the live code editor. Useful for debugging purposes.

+
<number>
+    <vbox>
+        <div  class="ml-4">
+            <hstack>
+            <div id={"number" + props.ti}></div>
+            <div class="mt-1" style="height: 22px" id={"number-value" + props.ti}></div>
+            <span class="cursor-pointer" onclick={remove(this.props.ti -1)}>(x)</span>
+        </hstack>
+        </div>
+    </vbox>
+
+    <script>
+
+this.props = opts;
+
+    remove(index) {
+        return () => {
+            this.props.rmnumber(index);
+        }
+    }
+
+this.on("mount", () => {
+    if (opts.v) {
+
+        Nexus.colors.accent = "#000000"
+        Nexus.colors.fill = "#ffffff"
+
+        var cell = window.cellx.cellx(0)
+        var number = new Nexus.Number('#number' + this.props.ti, {
+            'value': 0,
+            'step': 0.01
+        });
+        cell.onChange(evt => {
+            if (evt.data.prevValue !== evt.data.value) {
+                number.value = evt.data.value;
+            }
+        });
+
+        this.props.v["v"] = cell;
+    }
+});
+   </script>
+
+</number>
+
+
+
+
+

AutoKnob

+

AutoKnob enables programmatic automation in Bitrhythm

+

x -> [1, 2.5, 4, 3.2] | by 0.3

+

x will go from 1 to 2.5 to 4 to 3.2 in increments of 0.3 for every tick. While x will increase till 4 … it will decrease once it reaches 4 and drop down to 3.2. After reaching 3.2 you can stay there or reverse back. At any point during live editing, you can add an extra element to the array. If you add 5 for example, the loop will continue from 3.2 to 5.

+

You can think of each element in the array as the “final knob position” and in each cycle we are moving to the next knob position in increments of 0.3

+

An alternate to AutoKnob is to use TimedKnob. In the endless acid banger project, the basic code was using a simple timer to randomly move the knob position along with note collections and weighted random choice on note collections for generating rhythms.

+

TimedKnobs can be used to add small variations in volume to make the drums sounds more natural.

+
function knob(options) {
+    options = options || {};
+    var context = {};
+    context.ramp = options.ramp || [0 , 1];
+    context.count_skip = options.speed || 4;
+    context.step = options.step || 0.01;
+    context.reverse = options.reverse || true;
+    context.number = options.number || null;
+
+    context.current_count = 0;
+    context.index = 0;
+    context.val = window.cellx.cellx(options.initial || 0.5)
+
+    function changeContext() {
+        context.next_val = context.ramp[context.index + 1];
+
+        context.val(context.ramp[context.index]);
+        if (context.val() > context.next_val) {
+            context.direction = -1;
+        } else {
+            context.direction = 1;
+        }
+    }
+
+    changeContext();
+
+    return {
+        "cell": context.val,
+        "push": function (val) {
+            context.ramp.push(val);
+        },
+        "replace": function (val) {
+            context.ramp = val;
+        },
+        "speed": function (val) {
+            context.count_skip = val;
+        },
+        "step": function (val) {
+            context.step = val;
+        },
+        "up": function (val) {
+            val = val || 0.1;
+            context.ramp.push(context.ramp[context.ramp.length - 1] + val);
+        },
+        "down": function (val) {
+            val = val || -0.1;
+            context.ramp.push(context.ramp[context.ramp.length - 1] + val);
+        },
+       "move": function () {
+            if (context.current_count >= context.count_skip) {
+                context.current_count = 1;
+
+                if (context.direction == 1) {
+                    var cmp = function () {
+                        return (context.val() >= context.next_val);
+                    };
+                } else {
+                    var cmp = function () {
+                        return (context.next_val >= context.val());
+                    };
+                }
+
+                if (cmp()) {
+                    context.val(context.next_val);
+                    context.index = context.index + 1;
+                    if (context.index === context.ramp.length -1) {
+                        if (context.reverse) {
+                            context.index = 0;
+                            context.ramp = context.ramp.reverse();
+                        } else {
+                            context.index = context.index - 1;
+                        }
+                    }
+                    changeContext();
+                    context.val(context.val() + context.step * context.direction);
+                    if (context.number) context.number(context.val());
+                } else {
+                    context.val(context.val() + context.step * context.direction);
+                    if (context.number) context.number(context.val());
+                }
+            } else {
+                context.current_count += 1;
+            }
+
+           return context.val();
+        }
+    }
+}
+
+function timedKnob(options) {
+    options = options || {};
+    var context = {};
+    context.interval = options.interval || 100;
+    context.knob = knob(options);
+
+    context.timer = setInterval(function () {
+       context.knob.move();
+    }, context.interval);
+
+    context.knob["clear"] = function () {
+        clearInterval(context.timer);
+    }
+
+    return context.knob;
+}
+
+
+
+
+

Main UI

+
// Not working
+
+.CodeMirror-selected,
+.CodeMirror-focused,
+.CodeMirror-activeline,
+.CodeMirror-activeline-background {
+    background: transparent;
+    color: #882d2d;
+    z-index: 5 !important;
+}
+
+
+
<bitrhythm>
+
+<div>
+    <vstack id="header-playback">
+        <hstack>
+            <div class="ml-2">
+                <button type="button" class="btn btn-primary w-1/10 ml-2 mt-1" onclick={addDial}>+ Dial</button>
+                <button type="button" class="btn btn-primary w-1/10 ml-2 mt-1" onclick={addNumber}>+ Number</button>
+                <!-- <button type="button" class="btn btn-primary w-1/10 ml-2 mt-1" onclick={addSample}>+ Sample File</button> -->
+                <button type="button" class="btn btn-primary w-1/10 ml-2 mt-1" onclick={addSampleURL}>+ Sample URL</button>
+            </div>
+
+            <div class="ml-2" >
+                <label for="tempo-value">Tempo / Ticks</label><br>
+                <input type="text" id="tempo-value" value={state.tempo} style="width: 150px" onkeyup={ editTempo }/>
+                <input type="text"  class="mt-2" id="tick-value" value={state.ticks} style="width: 150px" onkeyup={editTicks}/>
+            </div>
+            <div class="ml-2" style="min-width: 250px;">
+                <label for="duration">Bars / Ticks / Seconds</label><br>
+                <div id="duration" ></div>
+            </div>
+        </hstack>
+
+        <div class="mt-2 ml-2" >
+            <button type="button" class="btn btn-primary w-1/10 ml-2 mt-1"  onclick={play}>Play</button>
+            <button type="button" class="btn btn-primary ml-2" onclick={save}>Save</button>
+            <button type="button" class="btn btn-primary ml-2" onclick={reset}>Reset</button>
+            <button type="button" class="btn btn-primary ml-2" onclick={reload}>Window Reload</button>
+
+            <input class="ml-1" name="edit-mode" id="edit-mode" type="checkbox"/>
+            <label for="edit-mode">Edit</label>
+            <input class="ml-1" name="load-mode" id="load-mode" type="checkbox"/>
+            <label for="load-mode">Execute Transition</label>
+        </div>
+
+        <hstack>
+            <div each={ key, index in state.samples} >
+                <div if={ state.samples && state.samples[index] }>
+                    <sample  setsample={setSample} rmsample={rmSample} samples={state.samples} ti={index + 1}></sample>
+                </div>
+            </div>
+        </hstack>
+
+        <hstack>
+            <div each={ key, index in state.dials}>
+                <dial rmdial={rmDial}  v={state.dials[index]} ti={index + 1}></dial>
+            </div>
+        </hstack>
+
+        <hstack>
+            <div each={ key, index in state.numbers}>
+                <number rmnumber={rmNumber} v={state.numbers[index]} ti={index + 1}></number>
+            </div>
+        </hstack>
+
+    </vstack>
+
+    <div id="error" class="p-2" style="color: yellow !important; height: 32px; font-size: 12px;"></div>
+    <div id="canvas-container" style="position: relative;">
+        <div id="p5" style="position: absolute; width: 100%; background: black"></div>
+        <canvas id="visual" style="position: absolute; width: 100%; background: black;"></canvas>
+        <div id="code" style="position: absolute;"></div>
+    </div>
+    
+</div>
+
+<style>
+:host {
+    margin-top: 4vh;
+}
+</style>
+
+<script>
+var oldCode = "";
+var oldPatterns = [];
+
+// var audio = new Audio();
+// audio.loop = true;
+const actx = Tone.context;
+const dest = actx.createMediaStreamDestination();
+const recorder = new MediaRecorder(dest.stream);
+let chunks = [];
+var sampleURL = "";
+var sam;
+var loop;
+this.props = opts;
+
+this.state = {
+    mem: {},
+    dials: [],
+    numbers: [],
+    samples: [],
+    tempo: 120,
+    ticks: 16,
+}
+
+async function copyTextToClipboard(text) {
+    try { await navigator.clipboard.writeText(text); }
+    catch(err) {
+        alert('Error in copying text: ', err);
+    }
+}
+
+shouldUpdate(data, nextOpts) {
+    return true;
+}
+
+this.on('mount', function() {
+    var self = this;
+    $("#load-mode").click();
+    editor = CodeMirror(document.getElementById("code"), {
+        mode: "null",
+        spellcheck: false,
+        autocorrect: false,
+        scrollbarStyle: "null",
+        lineWrapping: false,
+        lineNumbers: false,
+        styleActiveLine: false,
+        matchBrackets: false,
+        value: `// track_no, pattern, current_bit, samples, sample and Tone are available as globals`
+    });
+
+    editor.setSize(null, window.innerHeight - document.getElementById("header-playback").clientHeight - 160);
+
+    if (this.props.song) {
+        const lib = window.JsonUrl('lzma');
+        lib.decompress(this.props.song).then(data => {
+            var sample_names = data["sample_names"];
+            var dial_count = data["dial_count"];
+            var numbers_count = data["numbers_count"];
+            delete data["sample_names"];
+            delete data["dial_count"];
+            delete data["numbers_count"];
+            this.state.tempo = data.tempo;
+            this.state.ticks = data.ticks;
+            this.state.code = data.code;
+            sample_names.map(function (url) {
+                self.addURL(url);
+            });
+            for (var i = 0; i < dial_count; i++) {
+                this.state.dials.push({});
+            }
+            for (var i = 0; i < numbers_count; i++) {
+                this.state.numbers.push({});
+            }
+            editor.setValue(this.state.code);
+            this.update();
+            riot.mount('');
+        })
+    }
+
+
+});
+
+
+pattern_clean(p) {
+    return window.pattern_clean(p);
+}
+
+save() {
+    this.state.code = editor.getValue();
+    var text = {
+        tempo: this.state.tempo,
+        dial_count: this.state.dials.length,
+        numbers_count: this.state.numbers.length,
+        sample_names: this.state.samples.map(function (item) {return item["__url"]}),
+        ticks: 16,
+        code: this.state.code,
+    };
+    const lib = window.JsonUrl('lzma');
+	lib.compress(text).then(encodedData => {
+        var link = "/song/" + encodedData;
+        window.open(link, "_blank");
+    });
+}
+
+reload() {
+    window.location.replace( "//" + window.location.host)
+}
+
+reset() {
+
+    Tone.Master.mute = true;
+    if (loop) {
+        loop.stop();
+        loop.cancel();
+        loop.dispose();
+        Tone.Master.mute = false;
+    }
+    document.getElementById('tempo-value').disabled = false;
+    document.getElementById('tick-value').disabled = false;
+    editor.setValue("");
+
+    this.state = {
+        mem: {},
+        dials: [],
+        samples: [],
+        tempo: 120,
+        ticks: 16,
+    }
+
+    this.update();
+    riot.mount('bitrhythm', {
+        song: this.props.song
+    })
+
+
+}
+
+editTempo(e) {
+    this.update({
+        tempo: e.target.value
+    })
+}
+
+editTicks(e) {
+    this.update({
+        ticks: e.target.value
+    })
+}
+
+${core_loop}
+
+start() {
+    recorder.start();
+}
+
+stop() {
+    recorder.stop();
+}
+
+addDial() {
+    this.state.dials.push({});
+    this.update();
+}
+
+addNumber() {
+    this.state.numbers.push({});
+    this.update();
+}
+
+addURL(value) {
+    var self = this;
+    this.state.samples.push({"__name": value});
+    var sam;
+    sam = new Tone.Sampler({
+        urls:  {
+            "C3": value,
+        }
+    });
+    sam["__name"] = value;
+    sam["__url"] = value;
+    self.setSample(sam, self.state.samples.length - 1);
+}
+
+addSampleURL() {
+    var self = this;
+    alertify.prompt( 'Enter Sample URL', '', ''
+        , function(evt, value) {
+            self.addURL(value);
+        }
+        , function() {
+            alertify.error('Cancel')
+        });
+}
+
+addSample() {
+    this.state.samples.push({});
+    this.update();
+}
+
+rmSample(index) {
+   this.state.samples.splice(index, 1);
+   this.update();
+}
+
+rmDial(index) {
+   this.state.dials.splice(index, 1);
+   this.update();
+}
+
+rmNumber(index) {
+   this.state.numbers.splice(index, 1);
+   this.update();
+}
+
+setSample(e, i) {
+    this.state.samples[i] = e;
+    this.update();
+}
+
+</script>
+
+</bitrhythm>
+
+
+
+
+

Sample

+

You can add samples using the file upload. All samples are available as an array – samples. Initialise samples, global variables and synthesisers using the transition function and change the sample parameters using the same during live coding.

+
<sample>
+    <vbox class="ml-2">
+        <vstack class="ml-2">
+        <!-- <input type="file" id={"sample-file" + this.props.ti} style="width: 120px;"/> -->
+        <div style="max-width: 120px;text-overflow: ellipsis; white-space: nowrap;overflow: hidden;">
+            <span>{ getLast(this.props.ti -1)} </span>
+            <span class="cursor-pointer" id={"sample" + this.props.ti} onclick={remove(this.props.ti -1)}>(x)</span>
+        </div>
+        </vstack>
+    </vbox>
+
+    <script>
+    this.props = opts;
+
+    remove(index) {
+        return () => {
+            this.props.rmsample(index);
+        }
+    }
+
+    getLast (index) {
+        if (this.props.samples && this.props.samples[index] && this.props.samples[index]["__name"]) {
+            var e = this.props.samples[index]["__name"];
+            var elems = e.split("/");
+            var name = elems[elems.length - 1];
+            return name;
+        } else {
+            console.log(this.props)
+            return "";
+        }
+    }
+
+
+    this.on("mount", function () {
+
+        var self = this;
+/*
+        var sample_file = $("#sample-file" + this.props.ti).get(0);
+        var sam;
+
+        sample_file.addEventListener('change', (event) => {
+            var file = event.srcElement.files[0];
+            var a = new Audio();
+            a.onloadedmetadata = (e) => {
+                sam = new Tone.Sampler({
+                    urls:  {
+                        "C3": URL.createObjectURL(file),
+                    },
+                    onload: () => {
+                        this.update();
+                        sam.triggerAttackRelease("C3", 0.5);
+                    }
+                });
+
+                sam["__name"] = file.name;
+                sam["__url"] = "";
+                // riot doesn't allow camelcase ?
+                self.props.setsample(sam, self.props.ti - 1);
+            }
+            a.src = URL.createObjectURL(file);
+        });
+        */
+
+    });
+   </script>
+</sample>
+
+
+
+
+

App

+
(import [sanic [Sanic response]])
+(import [sanic.response [json text]])
+(import [sanic.exceptions [NotFound abort]])
+(import [jinja2 [Environment FileSystemLoader]])
+(import re)
+(import ipdb)
+(import sys)
+(import traceback)
+(import json)
+(import datetime)
+(import [email.utils [format_datetime]])
+(import [urllib.parse [urlparse]])
+(import base64)
+
+(setv file-loader (FileSystemLoader "templates"))
+(setv env (Environment :loader file-loader))
+
+(setv app (Sanic "Bitrhythm"))
+
+(with-decorator
+  (app.exception NotFound)
+  (defn/a ignore_404s [request exception]
+    (return (text (+ "Yep, I totally found the page " request.url)))
+  )
+)
+
+(with-decorator
+  (app.route "/song/<name>")
+  (defn/a get-index [request name]
+    (setv template (env.get_template "index.html"))
+    (return (response.html (template.render {"data" name})))
+  )
+)
+
+(with-decorator
+  (app.route "/")
+  (defn/a get-index [request]
+    (setv template (env.get_template "index.html"))
+    (return (response.html (template.render {"data" ""})))
+  )
+)
+
+(with-decorator
+  (app.route "/issue")
+  (defn/a get-index [request]
+    (setv template (env.get_template "page.html"))
+    (return (response.html (template.render)))
+  )
+)
+
+(app.static "/" "./public")
+
+(defmain [&rest args]
+    (app.run :host "0.0.0.0" :port 8015)
+)
+
+
+
+
+

Index

+
<!DOCTYPE html>
+<html lang="en">
+
+    <head>
+        <meta charset="utf-8">
+
+        <title>Bitrhythm</title>
+
+        <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
+        <meta http-equiv="Pragma" content="no-cache" />
+        <meta http-equiv="Expires" content="0" />
+
+        <meta content="Bitrhythm" name="description" xml:lang="en" lang="en">
+        <meta content="literate programming, p5, live coding, algorave, demoscene, creative programming, music, techno, programming, webaudio, webgl, p5, improvising">
+
+       ${common_scripts}
+
+        <link rel="preconnect" href="https://fonts.gstatic.com">
+        <link href="https://fonts.googleapis.com/css2?family=Roboto+Mono:ital,wght@0,100;0,200;0,300;0,400;0,500;0,700;1,100;1,200;1,300;1,400;1,500;1,700&display=swap" rel="stylesheet">
+        <link href="https://fonts.googleapis.com/css2?family=Major+Mono+Display&family=Roboto+Mono:ital,wght@0,100;0,200;0,300;0,400;0,500;0,700;1,100;1,200;1,300;1,400;1,500;1,700&display=swap" rel="stylesheet">
+
+        <script src="https://code.jquery.com/ui/1.12.0/jquery-ui.min.js"></script>
+        <link rel="stylesheet" href="https://code.jquery.com/ui/1.12.0/themes/smoothness/jquery-ui.css">
+        <script src="https://cdnjs.cloudflare.com/ajax/libs/micromodal/0.4.6/micromodal.min.js" integrity="sha512-RMMh+IHzfZLsVFo1rX9PBoysxrJJqjyOS31HYWftobWtv2At6KBTqKpvVDIWAjL5aiV+LjFqkQ6e53Rdw3VOBg==" crossorigin="anonymous"></script>
+        <script src="https://cdn.jsdelivr.net/npm/whenipress@1.8.0/dist/whenipress.js"></script>
+
+        <script src="https://cdnjs.cloudflare.com/ajax/libs/AlertifyJS/1.13.1/alertify.min.js" integrity="sha512-JnjG+Wt53GspUQXQhc+c4j8SBERsgJAoHeehagKHlxQN+MtCCmFDghX9/AcbkkNRZptyZU4zC8utK59M5L45Iw==" crossorigin="anonymous"></script>
+        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/AlertifyJS/1.13.1/css/alertify.min.css" integrity="sha512-IXuoq1aFd2wXs4NqGskwX2Vb+I8UJ+tGJEu/Dc0zwLNKeQ7CW3Sr6v0yU3z5OQWe3eScVIkER4J9L7byrgR/fA==" crossorigin="anonymous" />
+        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/AlertifyJS/1.13.1/css/themes/default.min.css" integrity="sha512-RgUjDpwjEDzAb7nkShizCCJ+QTSLIiJO1ldtuxzs0UIBRH4QpOjUU9w47AF9ZlviqV/dOFGWF6o7l3lttEFb6g==" crossorigin="anonymous" />
+
+        <script src="/json-url-master/dist/browser/json-url.js"></script>
+        <script src="/riot-3.13.2/riot+compiler.js"></script>
+
+        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.1.2/tailwind.min.css" integrity="sha512-RntatPOhEcQEA81gC/esYoCkGkL7AYV7TeTPoU+R9zE44/yWxVvLIBfBSaMu78rhoDd73ZeRHXRJN5+aPEK53Q==" crossorigin="anonymous" />
+        <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
+
+        <link rel="stylesheet" href="https://esironal.github.io/cmtouch/lib/codemirror.css">
+        <link rel="stylesheet" href="https://esironal.github.io/cmtouch/addon/hint/show-hint.css">
+        <script src="https://esironal.github.io/cmtouch/lib/codemirror.js"></script>
+        <script src="https://esironal.github.io/cmtouch/addon/hint/show-hint.js"></script>
+        <script src="http://esironal.github.io/cmtouch/addon/hint/xml-hint.js"></script>
+        <script src="https://esironal.github.io/cmtouch/addon/hint/html-hint.js"></script>
+        <script src="https://esironal.github.io/cmtouch/mode/xml/xml.js"></script>
+        <script src="https://esironal.github.io/cmtouch/mode/javascript/javascript.js"></script>
+        <script src="https://esironal.github.io/cmtouch/mode/css/css.js"></script>
+        <script src="https://esironal.github.io/cmtouch/mode/htmlmixed/htmlmixed.js"></script>
+        <script src="https://esironal.github.io/cmtouch/addon/selection/active-line.js"></script>
+        <script src="https://esironal.github.io/cmtouch/addon/edit/matchbrackets.js"></script>
+        <link rel="stylesheet" href="https://esironal.github.io/cmtouch/theme/neonsyntax.css">
+        <link rel="stylesheet" href="https://unpkg.com/pyloncss@latest/css/pylon.css"/>
+
+
+        <script src="/tune.js"></script>
+        <script src="/misc.js"></script>
+
+        <style type="text/css">
+body {
+    background: black;
+    color: white;
+    font-family: 'Roboto Mono', monospace;
+}
+
+a {
+    color: white;
+}
+
+input {
+    color: black;
+}
+
+.btn {
+    background: white;
+    color: black;
+    padding: 4px;
+}
+
+.CodeMirror {
+    font-size: 12px;
+    width: 100%;
+    padding-left: 4px;
+    line-height: 1;
+    background: transparent !important;
+    color: white !important;
+    font-family: 'Roboto Mono', monospace !important;
+}
+
+.CodeMirror-vscrollbar, .CodeMirror-hscrollbar {
+    overflow-x: hidden !important;
+    overflow-y: hidden !important;
+}
+
+.CodeMirror-cursor {
+  border-left: 2px solid white !important;
+}
+
+.CodeMirror pre,
+.CodeMirror-line > span,
+.CodeMirror-lines {
+  padding: 0 !important;
+}
+
+
+        </style>
+
+        <script type="riot/tag" src="/components/bitrhythm.tag"></script>
+        <script type="riot/tag" src="/components/dial.tag"></script>
+        <script type="riot/tag" src="/components/sample.tag" ></script>
+        <script type="riot/tag" src="/components/number.tag" ></script>
+
+        <script>
+            window.goatcounter = {
+                path: function(p) { return location.host + p }
+            }
+        </script>
+	    <script data-goatcounter="https://analytics.xyzzyapps.link/count" async src="//analytics.xyzzyapps.link/count.js"></script>
+    </head>
+
+    <body>
+        <div class="containera-full">
+            <hstack class="mb-2">
+                <h5 class="ml-4"><a href="/docs/index.html" target="_blank">Docs</a></h5>
+                <h5 class="ml-4"><a target="_blank" href="/issue">Report bugs / Feedback</a></h5>
+                <h5 class="ml-4"><a href="/song/XQAAAALHCwAAAAAAAABDKUqGU5vI8Eygv8VLc6H1NFIzdYQ4SmT-79BTKosH6Xje2IYnNRgEOpeuhg9Ej9Iz-_uEg-npGX0y9CmzyyVpwgaOUrKNlF-pzVXf3YmslEqBloRY0JslK5KapeSFSSH9ScweRgAPu9a4t1L0-t71Xb9Eb3KJ-lezPo7xcmK9xCnNGorm__kixtPuM_8L3YNc30OA3GMBPHu5pAH__cKjLF6k5mCGKsNp8WFWYQACckBR03VaZGhfZv946NYyFQlw6boXQuVis292UUboEkaCJ0CV5wGurbJUA7il2uX-okyMSjx7WVseVG-zDQ0wBjbMLNYnXzoT0kYxI_6-GOAOVamJJHTrkulVfd1k0AgzCHByI6zCNtWyBa3i_2ks4ncMec8vqsjAy8BhwFAbKAP1RDKh7MUxwsecBuzyLR0hKGddivZmPn-xyYB-p8-Xru_Min2-3Z_3YZal2_wv8s6cIcqPAJ4wf5DH29U7le-eRLcUN6lhK77651_xeU--z7A6E3NDQ6WEb6UPc-brxTz-L-wZwFwy95QkwAZw4bWR2LNW78DVdCSnMC8zf-DVWgFkKP9SU9iGQj6yk6E8qBAlZfd3YavthZBdwhs2mtzsvIL8qcBTBRhy2Fxx5n5tLq2lXuPkH19-cqIoJCHJUjiuGKWh3PqOAnTj9n2PejvNlp1GUMMixR7YMUofcLeA5oQCQpMSuIEP8sUshtk3zY35vG4xr3FfPj7OZiOQx5jRtMaw7l8xqFVm_PZ-kEgxoIVFtpZFcgsACnuBeJF1yZ2ss1GN95XEt9BsF3UY_UM1x8ePgY8BL4WH7BcHZRCOV2YZeRXZ6sYLNjKBjGVD_FAR_ZL6yd6l_1wqpQJPb3lL1fhBecNTcaXAn61RhySOvokAJ5TcrTtqdhsGEBUnaQOGRIfKU0NV4zPmgTm9TLASz5gs1VRoUZ06htWirfNfjiWNrbw8I9ggo8KMKwDZ2v4CnfqyL4eCpFNZjVIYOEWGGktLAadafQjdjOkWHWF8KIdr3uPBt1kXY_-IEkn11gjmn1q9ybgMLxriz7kWqzyawAEpqM27wzIwET2smzbJ-zHcx01rdHu3AqLMHk-AliQLGvGknluJNjWmK-WFwZUR8ZokJ6cVYW70a6X1dYWncQsPwyC3AOplDyUChlC_Rmgvz9fqeMs-fXub0odr01b7PFrraLWJ02Xk7trVq_Gqh8V2A2LATUKewJT05dG0bVJTBdM9n86C-mgyLf7s7JeNf9ul97CsS3BalNZ--N0hfkPbT_VPU9heFko9goG_mkF7Ky6FbtVpERCqw7UbvPgdFdIOEkoqPYEwAmjwzva2U-7cLo3g3uEQq1NBV3C8LijP10-1Avqu2df_R8XtykOk4H8yitylcxka4vSq1Jo2fv-wp74EiJi6Tn6T3epZJYXAMBRXRxozyl1r4lbOqRjDfqjWRTRrr8l9U2iKbAiIz6Ssy74Ic9sQABR9F4UahwsDQuJgjOHKdaLXmBHoPuD7nX_9mMYV">Example1</a></h5>
+                <h5 class="ml-4"><a href="/song/XQAAAALYEwAAAAAAAABDKUqGU5vI8Eygv8VLc6H1NFIzdYQe5mT-79BTKosH6Xje2IYnNRgEOpeuhg9NTfIT-_uEg-npGX0y9CmzyyVpwgaOUrKNlF-pzVXf3YnQ2gSfpzY3zlYLujavQRq73hSEM-RaGxTxuud9naok9rMpYn-UCaNiF2zrnnqUB61s_22pYOE_9KuFo7vEJMCtU2bkxyNdgSXzwmIDuo8OyxcIh9HQP59UZbNRixlBnmw73PnywS5DJBoH8NEIAnlLpL4rqaokfN9Cfte0Id3929n26IjA7zVZF75ovX37KO1xT9iBa8gt-w8cvYBdIdVL5JUOrbf0ccVJSoXGFoM0U4GXoEDThw00FdKnfsq1WeJjEQt4Qn8f90TkkQgkpSajR9dA0AJBqKDuVeEgDoFsbVI-ZZVvJW2dD_9GIm5PpQSTzpuBslzD7ZJQSI3XA1g2F_QP4w6U4rOrTMZUQSr___s22d8Plp0FbffDCq8dri0C8kUYPqS_np_Nnr7sDY9KsxgNZJmUxYkt1XBTO3iWmR6RZ7OFk6PZ8R44NXwhvxbUEikMoboPSW1XPiV4xtCfZb4qE4yCP2xHPlEniUhcNrWc5608hrNkVfpQUmYLFvXFTyUHA4aOkRDoHf0jHwGzyBV-YanP65YlZpupZC4oW3bjhO01tfh_qYWNA_ZpDVCCXRoGZJfrBjkmaYom9Gd6mvGVzillbk6LD0_Amu_Zublb4_AZ1SAxKSWlMfbmbXQfW16RSMidtmTCKAMmF9LCONKcjTR_1P2vU3fPR7hBhRtbtNR0xNEfRstXJ81ZcyC5YTK8dnpMwMXKk5uoaBMDbochbAKXaswgZKIn2usyi5Z4pyQf8xCSheQawyYSA031ZHA3wRuq_7rjhn0bXZrEGnB0QFzxgM-dYsY7CUojKr8ziZGXGb9zoVHvGDI0SIFyFIrMs6kEzpZAq_CnJyqJi4nbbqfoHlE3nDyLNKFk1e4OHqPsU9G1LRNnHBwSjiJCnvZO_xv_VQbtWmQwLrT7j6PZeXvNOz-yKWQFcE-0RXn6-EuqT7LNTF1GSo2o9AFS5Z2PJqIXioD9ebr9xjFXNrfTdIe32dgcgQHVHNyjEIH22AABUQWYtHRvZQpcfsUjJQM140MJ8nmpjmxlhtAMEstPzbGYUKZdjhF1LkeePxXD46zniN9cFEtRPTNR9luP4W2rhfHnvP4_tRAipmQiB_6RSRvLaiVYfkYYXdzMkX_M5blfwCKQ-DyDFy0hTw3mYZ-SbYT11RVO-5dEm_YntYmgQOI1FI7AhMxpmyE27Lwb73oDO0SeS-SDj4T6nbfltfHdWDPFaeUWd12KRmI-E8AQCcnmJayoBnMXyXNw3muX0319WhuitTtab3n3vwZM1e7ku11q1rNoaA3VXLbBJdyS1Vxvdvm8Tled56S54siOsEYGRqmdiC3gO2ZGaBq68SJZ9zxe9yttNFEXFFgWYFnIn_EMSTNj1ILB0wkOQPzsjFXEEa3W6esXTujFuoHK05q4rrfYicKZkq01hfaoZcovIbDFNyGtpgEzn-BFPJXKWwqn5gkgrvZiYxVxG7a449Gjj_R2HqNbbiTmd1la0MKDnVLWv9yXXRdRLQrKC4Z2kAJIOdwxluk6fRBFzRWT_o046yjM-nvgp3KLJU-n_CWu3mgfmQi5vCbNxRczEeyaJGg3DJL-anxXk0A2CFsFCXRLccmhHV7MjQdh4sdvnvl3JO1Ypt1_nsBXQJqXvahwkjpEC5jzduvTd0rIHgDBAzO3PA7YNjWF_r1EmagtsB_1VFSRqAQdXjbEep8SLKNqv8N7ILkix2NeTM30r9xyXtXcGOOmoQK4AMk1tHBmQ4m6YYNalWXJ_aGIjdBgx4jgsRYjWp1H9qRr0wMkmG75zOSbuOy_lg5-C-xbszvp7B5YELZblpjnpXCW8AhXMWCLM_iG16lkgw24Z40VWh4Q9DCXoMgZmOXm-98WidEFfkMP_8L7sdQjWRxMAodkLhUkHnsBRlYNChmAexNvzKW3xiiDhC_k6qKRfldVgCGSBFfpldJF_8e7EyQ">Example2</a></h5>
+                <h5 class="ml-4"><a href="/docs/demo.html">See Demo Song // Techno</a></h5>
+            </hstack>
+
+            <bitrhythm song="{{data}}"></bitrhythm>
+        </div>
+
+    <script>
+        riot.compile(function() {
+            var bitrhythm = riot.mount('bitrhythm');
+            window.bitrhythm = bitrhythm[0];
+            var dial = riot.mount('dial');
+            var number = riot.mount('number');
+            var sample = riot.mount('sample');
+        })
+    </script>
+
+
+    </body>
+
+</html>
+
+
+
+
+

Page

+
<!DOCTYPE html>
+<html lang="en">
+    <head>
+        <meta charset="utf-8">
+        <meta name="viewport" content="width=device-width, initial-scale=1">
+        <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
+        <meta http-equiv="Pragma" content="no-cache" />
+        <meta http-equiv="Expires" content="0" />
+        <title>About birthythm</title>
+        <link rel="icon" href="favicon.ico">
+        <style>
+        html, body {
+            margin: 0;
+            width: 100%;
+            height: 100%;
+            padding: 0;
+        }
+        iframe {
+            position:fixed;
+            top:0;
+            left:0;
+            bottom:0;
+            right:0;
+            width:100%;
+            height:100%;
+            border:none;
+            margin:0;
+            padding:0;
+            overflow:hidden;
+            z-index:999999;
+        }
+        </style>
+        <link href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel="stylesheet">
+        <script>
+            window.goatcounter = {
+                path: function(p) { return location.host + p }
+            }
+        </script>
+        <script data-goatcounter="https://analytics.xyzzyapps.link/count" async src="//analytics.xyzzyapps.link/count.js"></script>
+    </head>
+    <body>
+        <iframe src="https://blog.xyzzyapps.link/bitrhythm-submit-issue-feedback" frameborder="0"></iframe>
+    </body>
+</html>
+
+
+
+
+

Javascript

+
function initWinamp(preset) {
+    var can = document.getElementById("visual");
+    can.height = window.innerHeight - document.getElementById("header-playback").clientHeight - 75;
+    can.width = window.innerWidth;
+    var can_container = document.getElementById("canvas-container");
+    can_container.width = window.innerWidth;
+    var visualizer = window.butterchurn.default.createVisualizer(Tone.getContext().rawContext, can, {
+        height: window.innerHeight - document.getElementById("header-playback").clientHeight - 75,
+        width: window.innerWidth,
+        meshWidth: 24,
+        meshHeight: 18,
+    });
+    visualizer.connectAudio(Tone.getContext().destination);
+    const presets = window.butterchurnPresets.getPresets();
+    const presetParam = presets[preset];
+    visualizer.loadPreset(presetParam, 0.0); // 2nd argument is the number of seconds to blend presets
+    return visualizer;
+}
+
+function guard(range) {
+    var state = null;
+    return function (val) {
+        if ((val >= range[0]) && (val <= range[1])) {
+            state = val;
+            return val;
+        } else {
+            return state;
+        }
+    }
+}
+
+function hex2bin(hex) {
+    var letters = hex.replace('`1','a');
+    letters = hex.replace('`2','b');
+    letters = hex.replace('`3','c');
+    letters = hex.replace('`4','d');
+    letters = hex.replace('`5','e');
+    letters = hex.replace('`6','f');
+    letters = letters.split('');
+    var bin = "";
+    letters.map(function(letter) {
+        if (letter == "0") {
+            bin += "0000";
+        }
+        if (letter == "1") {
+            bin += "0001";
+        }
+        else if (letter == "2") {
+            bin += "0010";
+        }
+        else if (letter == "3") {
+            bin += "0011";
+        }
+        else if (letter == "4") {
+            bin += "0100";
+        }
+        else if (letter == "5") {
+            bin += "0101";
+        }
+        else if (letter == "6") {
+            bin += "0110";
+        }
+        else if (letter == "7") {
+            bin += "0111";
+        }
+        else if (letter == "8") {
+            bin += "1000";
+        }
+        else if (letter == "9") {
+            bin += "1001";
+        }
+        else if (letter == "a") {
+            bin += "1010";
+        }
+        else if (letter == "b") {
+            bin += "1011";
+        }
+        else if (letter == "c") {
+            bin += "1100";
+        }
+        else if (letter == "d") {
+            bin += "1101";
+        }
+        else if (letter == "e") {
+            bin += "1110";
+        }
+        else if (letter == "f") {
+            bin += "1111";
+        }
+
+    })
+    return bin;
+}
+
+
+function pattern_clean(p) {
+    if (!p) {
+        return "";
+    }
+    p = p.replace(/ /g, "");
+    var fc = p.split('')[0];
+    if (fc== "p") {
+        var ptype = "xo";
+        var l = (p.length - 1);
+    }
+    else if (fc== "b") {
+        var l = (p.length - 1);
+        var ptype = "bin";
+    }
+    else {
+        var ptype = "hex";
+        var l = (p.length) * 4;
+    }
+
+    if (ptype == "bin") {
+        var fp =  p.substring(1);
+    } else if (ptype == "xo") {
+        var fp = p.substr(1);
+        fp = fp.replace(/x/g, "1");
+    } else {
+        var fp = hex2bin(p);
+    }
+
+    return fp;
+}
+
+function download(data, filename, type) {
+    var file = new Blob([data], { type: type });
+    if (window.navigator.msSaveOrOpenBlob) // IE10+
+        window.navigator.msSaveOrOpenBlob(file, filename);
+    else { // Others
+        var a = document.createElement("a"),
+            url = URL.createObjectURL(file);
+        a.href = url;
+        a.download = filename;
+        document.body.appendChild(a);
+        a.click();
+        setTimeout(function () {
+            document.body.removeChild(a);
+            window.URL.revokeObjectURL(url);
+        }, 0);
+    }
+}
+
+// https://stackoverflow.com/questions/15762768/javascript-math-round-to-two-decimal-places
+function roundTo(n, digits) {
+    var negative = false;
+    if (digits === undefined) {
+        digits = 0;
+    }
+    if (n < 0) {
+        negative = true;
+        n = n * -1;
+    }
+    var multiplicator = Math.pow(10, digits);
+    n = parseFloat((n * multiplicator).toFixed(11));
+    n = (Math.round(n) / multiplicator).toFixed(digits);
+    if (negative) {
+        n = (n * -1).toFixed(digits);
+    }
+    return n;
+}
+
+${knob_code}
+
+
+
+
+ + +
+ + + + +
+
+
+
+

+ + By Xyzzy Apps
+ + © Copyright (c) Xyzzy Apps, 2021.
+

+
+
+
+ + +
+
+ + + + + + ADDED build/html/midi.html Index: build/html/midi.html ================================================================== --- build/html/midi.html +++ build/html/midi.html @@ -0,0 +1,393 @@ + + + + + + + + MIDI and DAW Terms — Bitrhythm's literate documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + +
+ +
+
+ +
+ + + + + + + + + + + + +
+ + +
+ +
+ Contents +
+ +
+
+
+
+
+ +
+ +
+

MIDI and DAW Terms

+
+

MIDI

+

MIDI changed music.

+

Consider what a classically trained Musician needs to do, to make his +music heard.

+

He needs to,

+
    +
  1. Write it

  2. +
  3. Get a bunch of musicians

  4. +
  5. Practice

  6. +
  7. Play

  8. +
  9. goto 1

  10. +
  11. Record the Final Cut in a Studio

  12. +
+

With MIDI,

+
    +
  1. Write it. Save it, with a Software

  2. +
  3. Get the electronic instruments to play it for him +-or- +Get a computer Software to play it for him

  4. +
  5. Tweak

  6. +
  7. Record the Final Cut in Software or a Studio

  8. +
+

MIDI is - Musical Instrument Digital Interface.

+

It abstracts Music Notation into bytes. +Since its bytes, you can replay it with software.

+

MIDI made production,

+
    +
  • Dirt Cheap

  • +
  • Made Producers more efficient

  • +
+

How about Audio Quality ?

+
    +
  • A Classical Ensemble still has its place. Panning is unique there.

  • +
  • But MIDI + Electronic Instrument increased the Range. It helped form whole new genres in Music like EDM, IDM, SynthPunk …

  • +
+

Limitations ?

+
    +
  • MIDI is limited to 16 instruments.

  • +
  • Integers.

  • +
  • 16 is a big number.

  • +
  • OSC overcomes these.

  • +
+
+
+
+

Usage

+

To use MIDI you need,

+
    +
  1. A Sequencer

    +

    This generates MIDI messages like,

    +
    Command param1 param2 param3
    +Command param1 param2
    +Command param1 param2 param3
    +Command param1 param2
    +...
    +
    +
    +

    Important messages are,

    +
      +
    1. Note On => Channel [1-16]**, Pitch[0-127], Volume[0-127]

    2. +
    3. Note Off “

    4. +
    5. Controller => No [0-127], Value[0-127]

    6. +
    +

    ** Channel 10 is reserved for Drums.

    +

    Note On and Note Off are typically sent by keys, buttons. +Controller Messages are typically sent by knobs and pedals.

    +
  2. +
  3. A Synthesizer

    +

    This accepts MIDI data. +It Maps channels to DSP. +It Maps knobs** to effects like distortion and reverb.

    +

    ** The positions of the knob are called patches.

    +
  4. +
  5. A Sampler.

    +

    This accepts MIDI data. +It Maps channels to sound recordings. +It Maps knobs to effects like distortion and reverb.

    +
  6. +
+

If you buy Music Hardware you have both 1 and 2. The sequencing capabilities are limited in a synth, so you can’t Edit MIDI data in the instrument.

+

Some notes,

+
    +
  1. You can buy hardware and get a Synthesizer + a limited Sequencer.

  2. +
  3. You can buy A Sequencer and use a Computer as a Synthesizer

  4. +
+

or

+
    +
  1. Use a Software Sequencer to Program your Synthesizer

  2. +
+

or

+
    +
  1. Forget Hardware and go complete nuts with Software

  2. +
+ +

Also, Robots love it.

+

+

Terms

+

Instruments used in Electronic Music

+
    +
  • Tr 909

  • +
  • Tr 303

  • +
  • Tr 808

  • +
+

Instruments commonly used in Disco, Synth Wave and Funk

+
    +
  • Samplers

  • +
  • FM Synthesiser

  • +
+

Rock Pedals used in

+
    +
  • Reverb (sludge)

  • +
  • Delay (slow rock)

  • +
  • Distortion (metal)

  • +
+

DAW Terms

+
    +
  • track

  • +
  • sequencer

  • +
  • piano roll

  • +
  • OSC

  • +
  • sampler

  • +
  • soundfont

  • +
  • synthesizer (DSP, FM, AM, AS, SS, PM)

  • +
  • effect

  • +
  • mixer, LFO

  • +
  • automation, equalizer

  • +
  • filter

  • +
  • arpegiator

  • +
+
+
+ + +
+ + + + +
+
+
+
+

+ + By Xyzzy Apps
+ + © Copyright (c) Xyzzy Apps, 2021.
+

+
+
+
+ + +
+
+ + + + + + ADDED build/html/samples.html Index: build/html/samples.html ================================================================== --- build/html/samples.html +++ build/html/samples.html @@ -0,0 +1,242 @@ + + + + + + + + Samples — Bitrhythm's literate documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + +
+ +
+
+ +
+ + + + + + + + + + + + +
+ + +
+ +
+
+
+
+
+ +
+ +
+

Samples

+

You can use Sample URL to add samples from anywhere. Currently there are three samples available from the main site for use in the demos.

+
    +
  • /Kick01.wav

  • +
  • /Snare19.wav

  • +
  • /Closedhat01.wav

  • +
  • /MiscSynthStab04.wav

  • +
  • /Perc11.wav

  • +
  • /PianoStab03.wav

  • +
  • /Snare06.wav

  • +
  • /Snare12.wav

  • +
  • /Snare09.wav

  • +
+
+ + +
+ + + + +
+
+
+
+

+ + By Xyzzy Apps
+ + © Copyright (c) Xyzzy Apps, 2021.
+

+
+
+
+ + +
+
+ + + + + + ADDED build/html/saving.html Index: build/html/saving.html ================================================================== --- build/html/saving.html +++ build/html/saving.html @@ -0,0 +1,232 @@ + + + + + + + + Saving and Sharing — Bitrhythm's literate documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + +
+ +
+
+ +
+ + + + + + + + + + + + +
+ + +
+ +
+
+
+
+
+ +
+ +
+

Saving and Sharing

+

There is a save button that converts the state of bitrhythm into a url paramter. This means there is an upper limit on how much code you can write, making it useful for demoscene like situations. You can share the url with tinyurl.

+

To make a complete song use bars to trigger multiple transitions.

+
+ + +
+ + + + +
+
+
+
+

+ + By Xyzzy Apps
+ + © Copyright (c) Xyzzy Apps, 2021.
+

+
+
+
+ + +
+
+ + + + + + ADDED build/html/search.html Index: build/html/search.html ================================================================== --- build/html/search.html +++ build/html/search.html @@ -0,0 +1,249 @@ + + + + + + + + Search — Bitrhythm's literate documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + +
+ +
+
+ +
+ + + + + + + + + + + + +
+ + +
+ +
+
+
+
+
+ +
+ +

Search

+
+ +

+ Please activate JavaScript to enable the search + functionality. +

+
+

+ Searching for multiple words only shows matches that contain + all words. +

+
+ + + +
+ +
+ +
+ +
+ + +
+ + +
+ +
+
+
+
+

+ + By Xyzzy Apps
+ + © Copyright (c) Xyzzy Apps, 2021.
+

+
+
+
+ + +
+
+ + + + + + ADDED build/html/source-code.html Index: build/html/source-code.html ================================================================== --- build/html/source-code.html +++ build/html/source-code.html @@ -0,0 +1,239 @@ + + + + + + + + Source Code and License — Bitrhythm's literate documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + +
+ +
+
+ +
+ + + + + + + + + + + + +
+ + +
+ +
+
+
+
+
+ +
+ +
+

Source Code and License

+

The literate code framework wheel uses extensively in this project is available here.

+

The documentation, demo code and the source code in the following webpages is distributed under creative commons, attribution-noncommercial-sharealike license. The source code is self-hosted using fossil here. You can report issues, browse and download the source code from fossil. An Iframe is provided below. You can also get the latest source code here.

+ +

Coding conventions

+
    +
  1. 4 Spaces

  2. +
  3. EcmaScript5

  4. +
+

Written using the Vim editor.

+
+ + +
+ + + + +
+
+
+
+

+ + By Xyzzy Apps
+ + © Copyright (c) Xyzzy Apps, 2021.
+

+
+
+
+ + +
+
+ + + + + + ADDED build/html/tweaking.html Index: build/html/tweaking.html ================================================================== --- build/html/tweaking.html +++ build/html/tweaking.html @@ -0,0 +1,364 @@ + + + + + + + + What exactly is Tweaking ? — Bitrhythm's literate documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + +
+ +
+
+ +
+ + + + + + + + + + + + +
+ + + +
+
+
+
+ +
+ +
+

What exactly is Tweaking ?

+

For that you need some context.

+

Historically speaking, music was an accompaniment for theatrical plays. A typical song has a Theme and develops Exposition / Conflict / Resolution through time. Its not a coincidence that the sonata and the dramatic structure share the same form. In a typical play you have scenes, transitions, sets in the background and characters in the foreground. While the play progresses and characters clash you get music alongside each of these elements. Every song has a title that guides the listener to what the song is about. Typical Scenes include intro, bridge, buildup, section, breakdown and climax. What is the intro about ? What is the bridge about ? What is the verse about ? What is the chorus about ? What are the sections about ? The essential question driving any story is how to be ? In a drama this question is answered with doubts, emotion, circularity, warnings from the chorus, exposition, rises, falls, reprisals, conclusions, contradictions, denouncements, confrontations, mistakes, reversals, recognition, revelation resolution, statements and breakdowns.

+

Modern music has evolved to be standalone but it retains elements of theatrical story telling. You can divide a song into verses and sections. In the documentation, we will use the terms from plays. Within each musical scene you typically have,

+
    +
  • Background: You use layers of rhythm and groove to set the mood.

  • +
  • Foreground: Lead (Soliloquy), Counterpoint (Character Conflict), Call Response(Dialogues), Motif, Ornaments (Exposition)

  • +
+

In Electronic Music, the foreground is mainly developed using Layers(polyrhythms) and Tweaking. Tweaking and Layers effectively function for the purposes of Exposition and Conflict. Chorus, Fade, Drop are used for transitions typically in electronic music. Tweaking is also called knob-twisting by hardware users. To compare the foreground in others,

+

Classical Music: Counterpoint and Harmony
+Rock: Call Response

+

Now EDM - Dub, Techno and Jungle - are distinct musical genres. What could they possibly share ?

+
    +
  1. All three uphold the primacy of Rhythm for start.

  2. +
  3. All three are instrumental.

  4. +
  5. Voices are used sparingly as samples.

  6. +
  7. All three have a tradition of live acts.

  8. +
  9. Dub Plates are common for these genres.

  10. +
  11. Melody is nothing but a repeating stab (motif)

  12. +
+

If you want to add a solo to EDM, you typically add a live instrument.

+

Dub Music is made by messing with the Recording Engineer’s Mixing desk. A prime example of tweaking.

+ +

Techno is made by messing with Hardware or Hardware + Software. Tweaking + Layering.

+ +

Jungle is used as a catch all for Breakbeat, Hardcore as well. Jungle Music is made by messing with Hardware + Software combo. Complex Layering is used here.

+ +

Bitrhythm only supports rhythmic notations and is geared towards electronic music. My current goal is to produce an IDM track and Chiptune with it with complex rhythmic patterns. As for techno the current setup seems alright. Support will be added in the future for pitch manipulation in a different module or a different project. There is a piano module in the code with midi support but its currently deactivated.

+

You can treat a musical scale as no different than a drumset. The pentatanic scale approximately maps to a drumset and you can use techniques from melodic drumming with multiple samples. This is typically how drummers approach guitars.

+
+

Is Bitrhythm Maths heavy ?

+

You will need some basic maths operations to understand and use bitrhythm effectively. These operations are about working with lists of numbers and lists of strings.

+

Some common operations on lists include

+
    +
  • Rotate

  • +
  • Invert

  • +
  • Slicing

  • +
  • Choose

  • +
  • Reverse

  • +
  • Shuffle

  • +
  • Filter

  • +
  • Map

  • +
+

Other math operations are useful for working with envelope ranges,

+
    +
  • Clamp

  • +
  • Ramp

  • +
  • Waves

  • +
+

Programming is not that difficult. Programming is about organising reactions to events. A typical event comes from

+
    +
  1. The timer

  2. +
  3. User interface elements like sliders and dials

  4. +
  5. Data change

  6. +
+

A typical reaction to an event (often called a handler) either changes data or displays data. A data change triggers more events. Other programming concepts needed for birthythm

+

As Tone.js provides the bulk of sound generation in Bitrhythm you should make youself comfortable with its APIs.

+

You will also need to understand

+
    +
  • Conditions

  • +
  • Loops

  • +
  • Functions

  • +
  • Javascript Math.random

  • +
  • Modulo Arithmetic

  • +
  • SetInterval Timers

  • +
+

What comes next - This is the pertinent question when composing music. If you are feeling adventurous you can try to use,

+
    +
  1. Mathematical patterns like fibonacci series, geometric series, +pi, fractals …

  2. +
  3. Neo-Riemannian_theory, Combinatory theory

  4. +
  5. Sacred Geometry

  6. +
  7. Circle of fifths, chord progressions

  8. +
  9. Set transformations like inversion on Scales

  10. +
  11. Licks from books

  12. +
  13. Randomness, I Ching, Playing Cards

  14. +
+
+
+

DJ Controls

+
+

Todo

+

Expand

+
+

Essentially a DJ is like a conductor. Loops are like individual instrumentalists.

+
    +
  1. Cueing -> Mute / Solo

  2. +
  3. Dynamics -> Volume

  4. +
  5. Ornamentation -> Cutoff

  6. +
  7. Tempo, Beat Counting -> Beat Matching

  8. +
+
+
+

Music is arrangement

+ +
+
+

See Also

+

In screenplays you also have a setup / payoff dynamic.

+

Setup

+
    +
  • Obstacles

  • +
  • Challenges

  • +
  • Forces

  • +
  • Context

  • +
+
+
+ + +
+ + + + +
+
+
+
+

+ + By Xyzzy Apps
+ + © Copyright (c) Xyzzy Apps, 2021.
+

+
+
+
+ + +
+
+ + + + + + ADDED build/html/what.html Index: build/html/what.html ================================================================== --- build/html/what.html +++ build/html/what.html @@ -0,0 +1,339 @@ + + + + + + + + What is bitrhythm about ? — Bitrhythm's literate documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + +
+ +
+
+ +
+ + + + + + + + + + + + +
+ + +
+ +
+ Contents +
+ +
+
+
+
+
+ +
+ +
+

What is bitrhythm about ?

+

Currently this is how you can use code with music,

+
    +
  1. VST plugins

  2. +
  3. DAW scripting

  4. +
  5. Embedded code to interact with electronics

  6. +
  7. ML approaches

  8. +
  9. Live coding

  10. +
  11. Use some weird algorithms / number sequences / hardcoded chords / random numbers

  12. +
  13. Web Audio / Audio Programming languages

  14. +
+

Bitrhythm offers 4-7. In Bitrhythm you get a coding playground to explore and learn webaudio and webgl apis for the purposes of

+
    +
  1. live visual programming

  2. +
  3. live audio programming

  4. +
  5. music sequencing

  6. +
  7. interactive music

  8. +
  9. audio visualisation

  10. +
  11. music learning

  12. +
+

Apart from the core html apis, you can also use the following libraries

+
    +
  1. Tuna

  2. +
  3. Timbral

  4. +
  5. Tone.js

  6. +
  7. Underscore / Rambda

  8. +
  9. cellx

  10. +
  11. Magenta.js (Machine Learning)

  12. +
  13. Three.js / P5.js / D3 / Paper.js

  14. +
  15. Winamp Visualisations (butterchurn)

  16. +
+
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
+<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore-min.js"></script>
+
+<script src="https://cdnjs.cloudflare.com/ajax/libs/tensorflow/1.2.8/tf.min.js"></script>
+<script src="https://cdn.jsdelivr.net/npm/@magenta/music@^1.0.0/es6/core.js"></script>
+<script src="https://cdn.jsdelivr.net/npm/@magenta/music@^1.0.0/es6/music_vae.js"></script>
+
+<script sec="https://mohayonao.github.io/timbre.js/timbre.js"></script>
+<script src="https://cdnjs.cloudflare.com/ajax/libs/tunajs/1.0.1/tuna-min.js" type="text/javascript"></script>
+<script src="https://cdnjs.cloudflare.com/ajax/libs/tone/14.7.77/Tone.js" integrity="sha512-gwSDP1iEKl4KG0wi3N89RAJU91s78jb/TGC6lsbF5IyR2c19Rn7Jl1icK4K4kUiJNwQUEPI7o98T+GJVWNuvIQ==" crossorigin="anonymous"></script>
+<script src="/teoria-master/teoria.js"></script>
+
+<script src="https://cdn.jsdelivr.net/npm/p5@1.3.1/lib/p5.js"></script>
+<script src="https://cdn.jsdelivr.net/npm/d3@5.7.0/dist/d3.min.js"></script>
+<script src="https://threejs.org/build/three.js"></script>
+<script src="https://cdnjs.cloudflare.com/ajax/libs/paper.js/0.12.11/paper-full.min.js"></script>
+
+<script src="https://cdn.jsdelivr.net/npm/butterchurn@2.6.7/lib/butterchurn.min.js"></script>
+<script src="https://cdn.jsdelivr.net/npm/butterchurn-presets@2.4.7/lib/butterchurnPresets.min.js"></script>
+
+<script src="https://cdn.jsdelivr.net/npm/webmidi@2.0.0"></script>
+<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
+<script src="/nexus-js/dist/NexusUI.js"></script>
+<script src="https://cdnjs.cloudflare.com/ajax/libs/cellx/1.10.19/cellx.umd.min.js" integrity="sha512-ojEcAP3e6N+n5MDKPW6CexXzuLDahDPkNZmzyRV4t2zqh9nwljJNuV8JGa+xjpnAaGB/FhsAU7P6IHEP0dtJQA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
+
+
+
+

About Author

+

I make web apps apps for a living. I started messing with algorithmic composition using pure data around 2011. Although nothing much came out of it musically, it transformed the way I view programming. The unix pipes concept is identical to the data flow model in pure data; albeit with more connections.

+

For my music I moved onto Electribe, Renoise, Reaper and live looping with my guitar. I started exploring sonic pi in 2019 but TBH none of the live coding tools were doing what I wanted - basically tweaking /knob-twisting in techno so I started my work on this project. This library in sonic pi comes close to what I am trying todo with this project. In bitrhythm time is divided into ticks like renoise tracker.

+

After my initial work on the project in 2019, the project got sidetracked. After seeing endless acid banger I had an epiphany to work on this project again. I was able to compose an endless and interactive dubtechno demo track. In March 2021, I also picked up on literate programming so this document will have both code and documentation intertwined.

+

The documentation for the literate programming project - wheel is available here.

+
+
+

Support this project

+

My goal is to make bitrhythm easy for both professionals and music learners. Support my work to get regular updates. Supporters will also get free accounts when I add pro features! Also get notified on latest developments and tutorials in the web audio world.

+

Support Bitrhythm

+

You can find me on theaudioprogrammer and algorave discord as @xyzzy.

+
+
+

Future Features

+
    +
  • Saving Songs

  • +
  • More Synths with Presets

  • +
  • Visualisation Presets

  • +
  • Autocomplete Rhythms and Chords

  • +
  • Automation Recording

  • +
  • Version Control

  • +
  • Record

  • +
  • Midi Support

  • +
  • More tutorials and examples on Web APIs

  • +
  • Synthesizer

  • +
  • Collaboration

  • +
  • Adding DJ Transition / Hints support

  • +
+
+
+ + +
+ + + + +
+
+
+
+

+ + By Xyzzy Apps
+ + © Copyright (c) Xyzzy Apps, 2021.
+

+
+
+
+ + +
+
+ + + + + + ADDED pidfile Index: pidfile ================================================================== --- pidfile +++ pidfile @@ -0,0 +1,1 @@ +%1 ADDED public/Clap05.wav Index: public/Clap05.wav ================================================================== --- public/Clap05.wav +++ public/Clap05.wav cannot compute difference between binary files ADDED public/Closedhat01.wav Index: public/Closedhat01.wav ================================================================== --- public/Closedhat01.wav +++ public/Closedhat01.wav cannot compute difference between binary files ADDED public/Kick01.wav Index: public/Kick01.wav ================================================================== --- public/Kick01.wav +++ public/Kick01.wav cannot compute difference between binary files ADDED public/MiscSynthStab04.wav Index: public/MiscSynthStab04.wav ================================================================== --- public/MiscSynthStab04.wav +++ public/MiscSynthStab04.wav cannot compute difference between binary files ADDED public/Perc11.wav Index: public/Perc11.wav ================================================================== --- public/Perc11.wav +++ public/Perc11.wav cannot compute difference between binary files ADDED public/PianoStab03.wav Index: public/PianoStab03.wav ================================================================== --- public/PianoStab03.wav +++ public/PianoStab03.wav cannot compute difference between binary files ADDED public/Snare06.wav Index: public/Snare06.wav ================================================================== --- public/Snare06.wav +++ public/Snare06.wav cannot compute difference between binary files ADDED public/Snare09.wav Index: public/Snare09.wav ================================================================== --- public/Snare09.wav +++ public/Snare09.wav cannot compute difference between binary files ADDED public/Snare12.wav Index: public/Snare12.wav ================================================================== --- public/Snare12.wav +++ public/Snare12.wav cannot compute difference between binary files ADDED public/Snare19.wav Index: public/Snare19.wav ================================================================== --- public/Snare19.wav +++ public/Snare19.wav cannot compute difference between binary files ADDED public/bootstrap-colorpicker/LICENSE Index: public/bootstrap-colorpicker/LICENSE ================================================================== --- public/bootstrap-colorpicker/LICENSE +++ public/bootstrap-colorpicker/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 Javi Aguilar + +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. ADDED public/bootstrap-colorpicker/README.md Index: public/bootstrap-colorpicker/README.md ================================================================== --- public/bootstrap-colorpicker/README.md +++ public/bootstrap-colorpicker/README.md @@ -0,0 +1,127 @@ + + +# Bootstrap Colorpicker + + + +[Bootstrap Colorpicker](https://github.com/farbelous/bootstrap-colorpicker/) is a modular color picker plugin for Bootstrap 4. + +[![Build Status](https://img.shields.io/travis/farbelous/bootstrap-colorpicker/master.svg?style=flat-square)](https://travis-ci.org/farbelous/bootstrap-colorpicker) +[![npm](https://img.shields.io/npm/v/bootstrap-colorpicker.svg?style=flat-square)](https://www.npmjs.com/package/bootstrap-colorpicker) + +## Install +You can get the latest version in many different ways: + +- Downloading [a ZIP file from the releases](https://github.com/farbelous/bootstrap-colorpicker/releases) +- Cloning using Git: `git clone https://github.com/farbelous/bootstrap-colorpicker.git` +- Installing via NPM: `npm install bootstrap-colorpicker` +- Installing via Yarn: `yarn add bootstrap-colorpicker` +- Installing via Composer: `composer require itsjavi/bootstrap-colorpicker` + +Note that the `dist` files are only distributed via the NPM and Yarn installations. + +For the rest methods, you will need to generate the files initializing the project with `yarn install` +and then building the code using `npm run build`. + +## Versions + + + + + + + + + + + + + + + + + + + + + +
Colorpicker versionCompatible Bootstrap versionDependencies
+ v2.x
+ Documentation +
(any) +
    +
  • jQuery >= 1.10
  • +
  • Bootstrap CSS (input addon)
  • +
+
+ v3.x
+ Documentation +
Bootstrap 4 +
    +
  • jQuery >= 2.1.0
  • +
  • Bootstrap CSS (input addon, popover)
  • +
  • Bootstrap JS Bundle (popover)
  • +
+
+ + +Note that the plugin may work without Bootstrap if your code is not using any of the mentioned Bootstrap +dependencies. + + +## Basic example + +```html + + + + + + + + +
+

Bootstrap Colorpicker Demo

+ +
+ + + + + +``` + +## Contributions +* [Issues](https://github.com/farbelous/bootstrap-colorpicker/issues) +* [Pull Requests](https://github.com/farbelous/bootstrap-colorpicker/pulls) +* [Milestones](https://github.com/farbelous/bootstrap-colorpicker/milestones) +* [Planned Features](https://github.com/farbelous/bootstrap-colorpicker/projects) + +This project exists thanks to all the [people who contribute](https://github.com/farbelous/bootstrap-colorpicker/graphs/contributors). + +Please read [CONTRIBUTING](https://github.com/farbelous/bootstrap-colorpicker/blob/master/.github/CONTRIBUTING.md) +before sending a pull request or issue. + +## License +The MIT License (MIT). +Please see the [License File](https://github.com/farbelous/bootstrap-colorpicker/blob/master/LICENSE) for more information. + +## Credits + +Written and maintained by [Javi Aguilar](https://itsjavi.com) and all other contributors. + +*Based on Stefan Petre's color picker (2013).* + +*Thanks to JetBrains for supporting this project.* ADDED public/bootstrap-colorpicker/dist/LICENSE Index: public/bootstrap-colorpicker/dist/LICENSE ================================================================== --- public/bootstrap-colorpicker/dist/LICENSE +++ public/bootstrap-colorpicker/dist/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 Javi Aguilar + +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. ADDED public/bootstrap-colorpicker/dist/README.md Index: public/bootstrap-colorpicker/dist/README.md ================================================================== --- public/bootstrap-colorpicker/dist/README.md +++ public/bootstrap-colorpicker/dist/README.md @@ -0,0 +1,127 @@ + + +# Bootstrap Colorpicker + + + +[Bootstrap Colorpicker](https://github.com/farbelous/bootstrap-colorpicker/) is a modular color picker plugin for Bootstrap 4. + +[![Build Status](https://img.shields.io/travis/farbelous/bootstrap-colorpicker/master.svg?style=flat-square)](https://travis-ci.org/farbelous/bootstrap-colorpicker) +[![npm](https://img.shields.io/npm/v/bootstrap-colorpicker.svg?style=flat-square)](https://www.npmjs.com/package/bootstrap-colorpicker) + +## Install +You can get the latest version in many different ways: + +- Downloading [a ZIP file from the releases](https://github.com/farbelous/bootstrap-colorpicker/releases) +- Cloning using Git: `git clone https://github.com/farbelous/bootstrap-colorpicker.git` +- Installing via NPM: `npm install bootstrap-colorpicker` +- Installing via Yarn: `yarn add bootstrap-colorpicker` +- Installing via Composer: `composer require itsjavi/bootstrap-colorpicker` + +Note that the `dist` files are only distributed via the NPM and Yarn installations. + +For the rest methods, you will need to generate the files initializing the project with `yarn install` +and then building the code using `npm run build`. + +## Versions + + + + + + + + + + + + + + + + + + + + + +
Colorpicker versionCompatible Bootstrap versionDependencies
+ v2.x
+ Documentation +
(any) +
    +
  • jQuery >= 1.10
  • +
  • Bootstrap CSS (input addon)
  • +
+
+ v3.x
+ Documentation +
Bootstrap 4 +
    +
  • jQuery >= 2.1.0
  • +
  • Bootstrap CSS (input addon, popover)
  • +
  • Bootstrap JS Bundle (popover)
  • +
+
+ + +Note that the plugin may work without Bootstrap if your code is not using any of the mentioned Bootstrap +dependencies. + + +## Basic example + +```html + + + + + + + + +
+

Bootstrap Colorpicker Demo

+ +
+ + + + + +``` + +## Contributions +* [Issues](https://github.com/farbelous/bootstrap-colorpicker/issues) +* [Pull Requests](https://github.com/farbelous/bootstrap-colorpicker/pulls) +* [Milestones](https://github.com/farbelous/bootstrap-colorpicker/milestones) +* [Planned Features](https://github.com/farbelous/bootstrap-colorpicker/projects) + +This project exists thanks to all the [people who contribute](https://github.com/farbelous/bootstrap-colorpicker/graphs/contributors). + +Please read [CONTRIBUTING](https://github.com/farbelous/bootstrap-colorpicker/blob/master/.github/CONTRIBUTING.md) +before sending a pull request or issue. + +## License +The MIT License (MIT). +Please see the [License File](https://github.com/farbelous/bootstrap-colorpicker/blob/master/LICENSE) for more information. + +## Credits + +Written and maintained by [Javi Aguilar](https://itsjavi.com) and all other contributors. + +*Based on Stefan Petre's color picker (2013).* + +*Thanks to JetBrains for supporting this project.* ADDED public/bootstrap-colorpicker/dist/css/bootstrap-colorpicker.css Index: public/bootstrap-colorpicker/dist/css/bootstrap-colorpicker.css ================================================================== --- public/bootstrap-colorpicker/dist/css/bootstrap-colorpicker.css +++ public/bootstrap-colorpicker/dist/css/bootstrap-colorpicker.css @@ -0,0 +1,399 @@ +/*! + * Bootstrap Colorpicker - Bootstrap Colorpicker is a modular color picker plugin for Bootstrap 4. + * @package bootstrap-colorpicker + * @version v3.1.2 + * @license MIT + * @link https://farbelous.github.io/bootstrap-colorpicker/ + * @link https://github.com/farbelous/bootstrap-colorpicker.git + */ +.colorpicker { + position: relative; + display: none; + font-size: inherit; + color: inherit; + text-align: left; + list-style: none; + background-color: #ffffff; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, 0.2); + padding: .75rem .75rem; + width: 148px; + border-radius: 4px; + -webkit-box-sizing: content-box; + box-sizing: content-box; } + +.colorpicker.colorpicker-disabled, +.colorpicker.colorpicker-disabled * { + cursor: default !important; } + +.colorpicker div { + position: relative; } + +.colorpicker-popup { + position: absolute; + top: 100%; + left: 0; + float: left; + margin-top: 1px; + z-index: 1060; } + +.colorpicker-popup.colorpicker-bs-popover-content { + position: relative; + top: auto; + left: auto; + float: none; + margin: 0; + z-index: initial; + border: none; + padding: 0.25rem 0; + border-radius: 0; + background: none; + -webkit-box-shadow: none; + box-shadow: none; } + +.colorpicker:before, +.colorpicker:after { + content: ""; + display: table; + clear: both; + line-height: 0; } + +.colorpicker-clear { + clear: both; + display: block; } + +.colorpicker:before { + content: ''; + display: inline-block; + border-left: 7px solid transparent; + border-right: 7px solid transparent; + border-bottom: 7px solid #ccc; + border-bottom-color: rgba(0, 0, 0, 0.2); + position: absolute; + top: -7px; + left: auto; + right: 6px; } + +.colorpicker:after { + content: ''; + display: inline-block; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-bottom: 6px solid #ffffff; + position: absolute; + top: -6px; + left: auto; + right: 7px; } + +.colorpicker.colorpicker-with-alpha { + width: 170px; } + +.colorpicker.colorpicker-with-alpha .colorpicker-alpha { + display: block; } + +.colorpicker-saturation { + position: relative; + width: 126px; + height: 126px; + /* FF3.6+ */ + /* Chrome,Safari4+ */ + /* Chrome10+,Safari5.1+ */ + /* Opera 11.10+ */ + /* IE10+ */ + background: -webkit-gradient(linear, left top, left bottom, from(transparent), to(black)), -webkit-gradient(linear, left top, right top, from(white), to(rgba(255, 255, 255, 0))); + background: linear-gradient(to bottom, transparent 0%, black 100%), linear-gradient(to right, white 0%, rgba(255, 255, 255, 0) 100%); + /* W3C */ + cursor: crosshair; + float: left; + -webkit-box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.2); + box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.2); + margin-bottom: 6px; } + .colorpicker-saturation .colorpicker-guide { + display: block; + height: 6px; + width: 6px; + border-radius: 6px; + border: 1px solid #000; + -webkit-box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.8); + box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.8); + position: absolute; + top: 0; + left: 0; + margin: -3px 0 0 -3px; } + +.colorpicker-hue, +.colorpicker-alpha { + position: relative; + width: 16px; + height: 126px; + float: left; + cursor: row-resize; + margin-left: 6px; + margin-bottom: 6px; } + +.colorpicker-alpha-color { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; } + +.colorpicker-hue, +.colorpicker-alpha-color { + -webkit-box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.2); + box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.2); } + +.colorpicker-hue .colorpicker-guide, +.colorpicker-alpha .colorpicker-guide { + display: block; + height: 4px; + background: rgba(255, 255, 255, 0.8); + border: 1px solid rgba(0, 0, 0, 0.4); + position: absolute; + top: 0; + left: 0; + margin-left: -2px; + margin-top: -2px; + right: -2px; + z-index: 1; } + +.colorpicker-hue { + /* FF3.6+ */ + /* Chrome,Safari4+ */ + /* Chrome10+,Safari5.1+ */ + /* Opera 11.10+ */ + /* IE10+ */ + background: -webkit-gradient(linear, left bottom, left top, from(red), color-stop(8%, #ff8000), color-stop(17%, yellow), color-stop(25%, #80ff00), color-stop(33%, lime), color-stop(42%, #00ff80), color-stop(50%, cyan), color-stop(58%, #0080ff), color-stop(67%, blue), color-stop(75%, #8000ff), color-stop(83%, magenta), color-stop(92%, #ff0080), to(red)); + background: linear-gradient(to top, red 0%, #ff8000 8%, yellow 17%, #80ff00 25%, lime 33%, #00ff80 42%, cyan 50%, #0080ff 58%, blue 67%, #8000ff 75%, magenta 83%, #ff0080 92%, red 100%); + /* W3C */ } + +.colorpicker-alpha { + background: linear-gradient(45deg, rgba(0, 0, 0, 0.1) 25%, transparent 25%, transparent 75%, rgba(0, 0, 0, 0.1) 75%, rgba(0, 0, 0, 0.1) 0), linear-gradient(45deg, rgba(0, 0, 0, 0.1) 25%, transparent 25%, transparent 75%, rgba(0, 0, 0, 0.1) 75%, rgba(0, 0, 0, 0.1) 0), white; + background-size: 10px 10px; + background-position: 0 0, 5px 5px; + display: none; } + +.colorpicker-bar { + min-height: 16px; + margin: 6px 0 0 0; + clear: both; + text-align: center; + font-size: 10px; + line-height: normal; + max-width: 100%; + -webkit-box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.2); + box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.2); } + .colorpicker-bar:before { + content: ""; + display: table; + clear: both; } + +.colorpicker-bar.colorpicker-bar-horizontal { + height: 126px; + width: 16px; + margin: 0 0 6px 0; + float: left; } + +.colorpicker-input-addon { + position: relative; } + +.colorpicker-input-addon i { + display: inline-block; + cursor: pointer; + vertical-align: text-top; + height: 16px; + width: 16px; + position: relative; } + +.colorpicker-input-addon:before { + content: ""; + position: absolute; + width: 16px; + height: 16px; + display: inline-block; + vertical-align: text-top; + background: linear-gradient(45deg, rgba(0, 0, 0, 0.1) 25%, transparent 25%, transparent 75%, rgba(0, 0, 0, 0.1) 75%, rgba(0, 0, 0, 0.1) 0), linear-gradient(45deg, rgba(0, 0, 0, 0.1) 25%, transparent 25%, transparent 75%, rgba(0, 0, 0, 0.1) 75%, rgba(0, 0, 0, 0.1) 0), white; + background-size: 10px 10px; + background-position: 0 0, 5px 5px; } + +.colorpicker.colorpicker-inline { + position: relative; + display: inline-block; + float: none; + z-index: auto; + vertical-align: text-bottom; } + +.colorpicker.colorpicker-horizontal { + width: 126px; + height: auto; } + +.colorpicker.colorpicker-horizontal .colorpicker-bar { + width: 126px; } + +.colorpicker.colorpicker-horizontal .colorpicker-saturation { + float: none; + margin-bottom: 0; } + +.colorpicker.colorpicker-horizontal .colorpicker-hue, +.colorpicker.colorpicker-horizontal .colorpicker-alpha { + float: none; + width: 126px; + height: 16px; + cursor: col-resize; + margin-left: 0; + margin-top: 6px; + margin-bottom: 0; } + +.colorpicker.colorpicker-horizontal .colorpicker-hue .colorpicker-guide, +.colorpicker.colorpicker-horizontal .colorpicker-alpha .colorpicker-guide { + position: absolute; + display: block; + bottom: -2px; + left: 0; + right: auto; + height: auto; + width: 4px; } + +.colorpicker.colorpicker-horizontal .colorpicker-hue { + /* FF3.6+ */ + /* Chrome,Safari4+ */ + /* Chrome10+,Safari5.1+ */ + /* Opera 11.10+ */ + /* IE10+ */ + background: -webkit-gradient(linear, right top, left top, from(red), color-stop(8%, #ff8000), color-stop(17%, yellow), color-stop(25%, #80ff00), color-stop(33%, lime), color-stop(42%, #00ff80), color-stop(50%, cyan), color-stop(58%, #0080ff), color-stop(67%, blue), color-stop(75%, #8000ff), color-stop(83%, magenta), color-stop(92%, #ff0080), to(red)); + background: linear-gradient(to left, red 0%, #ff8000 8%, yellow 17%, #80ff00 25%, lime 33%, #00ff80 42%, cyan 50%, #0080ff 58%, blue 67%, #8000ff 75%, magenta 83%, #ff0080 92%, red 100%); + /* W3C */ } + +.colorpicker.colorpicker-horizontal .colorpicker-alpha { + background: linear-gradient(45deg, rgba(0, 0, 0, 0.1) 25%, transparent 25%, transparent 75%, rgba(0, 0, 0, 0.1) 75%, rgba(0, 0, 0, 0.1) 0), linear-gradient(45deg, rgba(0, 0, 0, 0.1) 25%, transparent 25%, transparent 75%, rgba(0, 0, 0, 0.1) 75%, rgba(0, 0, 0, 0.1) 0), white; + background-size: 10px 10px; + background-position: 0 0, 5px 5px; } + +.colorpicker-inline:before, +.colorpicker-no-arrow:before, +.colorpicker-popup.colorpicker-bs-popover-content:before { + content: none; + display: none; } + +.colorpicker-inline:after, +.colorpicker-no-arrow:after, +.colorpicker-popup.colorpicker-bs-popover-content:after { + content: none; + display: none; } + +.colorpicker-alpha, +.colorpicker-saturation, +.colorpicker-hue { + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; } + +.colorpicker.colorpicker-visible, +.colorpicker-alpha.colorpicker-visible, +.colorpicker-saturation.colorpicker-visible, +.colorpicker-hue.colorpicker-visible, +.colorpicker-bar.colorpicker-visible { + display: block; } + +.colorpicker.colorpicker-hidden, +.colorpicker-alpha.colorpicker-hidden, +.colorpicker-saturation.colorpicker-hidden, +.colorpicker-hue.colorpicker-hidden, +.colorpicker-bar.colorpicker-hidden { + display: none; } + +.colorpicker-inline.colorpicker-visible { + display: inline-block; } + +.colorpicker.colorpicker-disabled:after { + border: none; + content: ''; + display: block; + width: 100%; + height: 100%; + background: rgba(233, 236, 239, 0.33); + top: 0; + left: 0; + right: auto; + z-index: 2; + position: absolute; } + +.colorpicker.colorpicker-disabled .colorpicker-guide { + display: none; } + +/** EXTENSIONS **/ +.colorpicker-preview { + background: linear-gradient(45deg, rgba(0, 0, 0, 0.1) 25%, transparent 25%, transparent 75%, rgba(0, 0, 0, 0.1) 75%, rgba(0, 0, 0, 0.1) 0), linear-gradient(45deg, rgba(0, 0, 0, 0.1) 25%, transparent 25%, transparent 75%, rgba(0, 0, 0, 0.1) 75%, rgba(0, 0, 0, 0.1) 0), white; + background-size: 10px 10px; + background-position: 0 0, 5px 5px; } + +.colorpicker-preview > div { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; } + +.colorpicker-bar.colorpicker-swatches { + -webkit-box-shadow: none; + box-shadow: none; + height: auto; } + +.colorpicker-swatches--inner { + clear: both; + margin-top: -6px; } + +.colorpicker-swatch { + position: relative; + cursor: pointer; + float: left; + height: 16px; + width: 16px; + margin-right: 6px; + margin-top: 6px; + margin-left: 0; + display: block; + -webkit-box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.2); + box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.2); + background: linear-gradient(45deg, rgba(0, 0, 0, 0.1) 25%, transparent 25%, transparent 75%, rgba(0, 0, 0, 0.1) 75%, rgba(0, 0, 0, 0.1) 0), linear-gradient(45deg, rgba(0, 0, 0, 0.1) 25%, transparent 25%, transparent 75%, rgba(0, 0, 0, 0.1) 75%, rgba(0, 0, 0, 0.1) 0), white; + background-size: 10px 10px; + background-position: 0 0, 5px 5px; } + +.colorpicker-swatch--inner { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; } + +.colorpicker-swatch:nth-of-type(7n+0) { + margin-right: 0; } + +.colorpicker-with-alpha .colorpicker-swatch:nth-of-type(7n+0) { + margin-right: 6px; } + +.colorpicker-with-alpha .colorpicker-swatch:nth-of-type(8n+0) { + margin-right: 0; } + +.colorpicker-horizontal .colorpicker-swatch:nth-of-type(6n+0) { + margin-right: 0; } + +.colorpicker-horizontal .colorpicker-swatch:nth-of-type(7n+0) { + margin-right: 6px; } + +.colorpicker-horizontal .colorpicker-swatch:nth-of-type(8n+0) { + margin-right: 6px; } + +.colorpicker-swatch:last-of-type:after { + content: ""; + display: table; + clear: both; } + +*[dir='rtl'] .colorpicker-element input, +.colorpicker-element[dir='rtl'] input, +.colorpicker-element input[dir='rtl'] { + direction: ltr; + text-align: right; } + +/*# sourceMappingURL=bootstrap-colorpicker.css.map */ ADDED public/bootstrap-colorpicker/dist/css/bootstrap-colorpicker.css.map Index: public/bootstrap-colorpicker/dist/css/bootstrap-colorpicker.css.map ================================================================== --- public/bootstrap-colorpicker/dist/css/bootstrap-colorpicker.css.map +++ public/bootstrap-colorpicker/dist/css/bootstrap-colorpicker.css.map cannot compute difference between binary files ADDED public/bootstrap-colorpicker/dist/css/bootstrap-colorpicker.min.css Index: public/bootstrap-colorpicker/dist/css/bootstrap-colorpicker.min.css ================================================================== --- public/bootstrap-colorpicker/dist/css/bootstrap-colorpicker.min.css +++ public/bootstrap-colorpicker/dist/css/bootstrap-colorpicker.min.css cannot compute difference between binary files ADDED public/bootstrap-colorpicker/dist/css/bootstrap-colorpicker.min.css.map Index: public/bootstrap-colorpicker/dist/css/bootstrap-colorpicker.min.css.map ================================================================== --- public/bootstrap-colorpicker/dist/css/bootstrap-colorpicker.min.css.map +++ public/bootstrap-colorpicker/dist/css/bootstrap-colorpicker.min.css.map cannot compute difference between binary files ADDED public/bootstrap-colorpicker/dist/js/bootstrap-colorpicker.js Index: public/bootstrap-colorpicker/dist/js/bootstrap-colorpicker.js ================================================================== --- public/bootstrap-colorpicker/dist/js/bootstrap-colorpicker.js +++ public/bootstrap-colorpicker/dist/js/bootstrap-colorpicker.js @@ -0,0 +1,6212 @@ +/*! + * Bootstrap Colorpicker - Bootstrap Colorpicker is a modular color picker plugin for Bootstrap 4. + * @package bootstrap-colorpicker + * @version v3.1.2 + * @license MIT + * @link https://farbelous.github.io/bootstrap-colorpicker/ + * @link https://github.com/farbelous/bootstrap-colorpicker.git + */ +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(require("jquery")); + else if(typeof define === 'function' && define.amd) + define("bootstrap-colorpicker", ["jquery"], factory); + else if(typeof exports === 'object') + exports["bootstrap-colorpicker"] = factory(require("jquery")); + else + root["bootstrap-colorpicker"] = factory(root["jQuery"]); +})(typeof self !== 'undefined' ? self : this, function(__WEBPACK_EXTERNAL_MODULE_0__) { +return /******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { +/******/ configurable: false, +/******/ enumerable: true, +/******/ get: getter +/******/ }); +/******/ } +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 7); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ (function(module, exports) { + +module.exports = __WEBPACK_EXTERNAL_MODULE_0__; + +/***/ }), +/* 1 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +/** + * Colorpicker extension class. + */ +var Extension = function () { + /** + * @param {Colorpicker} colorpicker + * @param {Object} options + */ + function Extension(colorpicker) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + _classCallCheck(this, Extension); + + /** + * The colorpicker instance + * @type {Colorpicker} + */ + this.colorpicker = colorpicker; + /** + * Extension options + * + * @type {Object} + */ + this.options = options; + + if (!(this.colorpicker.element && this.colorpicker.element.length)) { + throw new Error('Extension: this.colorpicker.element is not valid'); + } + + this.colorpicker.element.on('colorpickerCreate.colorpicker-ext', _jquery2.default.proxy(this.onCreate, this)); + this.colorpicker.element.on('colorpickerDestroy.colorpicker-ext', _jquery2.default.proxy(this.onDestroy, this)); + this.colorpicker.element.on('colorpickerUpdate.colorpicker-ext', _jquery2.default.proxy(this.onUpdate, this)); + this.colorpicker.element.on('colorpickerChange.colorpicker-ext', _jquery2.default.proxy(this.onChange, this)); + this.colorpicker.element.on('colorpickerInvalid.colorpicker-ext', _jquery2.default.proxy(this.onInvalid, this)); + this.colorpicker.element.on('colorpickerShow.colorpicker-ext', _jquery2.default.proxy(this.onShow, this)); + this.colorpicker.element.on('colorpickerHide.colorpicker-ext', _jquery2.default.proxy(this.onHide, this)); + this.colorpicker.element.on('colorpickerEnable.colorpicker-ext', _jquery2.default.proxy(this.onEnable, this)); + this.colorpicker.element.on('colorpickerDisable.colorpicker-ext', _jquery2.default.proxy(this.onDisable, this)); + } + + /** + * Function called every time a new color needs to be created. + * Return false to skip this resolver and continue with other extensions' ones + * or return anything else to consider the color resolved. + * + * @param {ColorItem|String|*} color + * @param {boolean} realColor if true, the color should resolve into a real (not named) color code + * @return {ColorItem|String|*} + */ + + + _createClass(Extension, [{ + key: 'resolveColor', + value: function resolveColor(color) { + var realColor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + + return false; + } + + /** + * Method called after the colorpicker is created + * + * @listens Colorpicker#colorpickerCreate + * @param {Event} event + */ + + }, { + key: 'onCreate', + value: function onCreate(event) {} + // to be extended + + + /** + * Method called after the colorpicker is destroyed + * + * @listens Colorpicker#colorpickerDestroy + * @param {Event} event + */ + + }, { + key: 'onDestroy', + value: function onDestroy(event) { + this.colorpicker.element.off('.colorpicker-ext'); + } + + /** + * Method called after the colorpicker is updated + * + * @listens Colorpicker#colorpickerUpdate + * @param {Event} event + */ + + }, { + key: 'onUpdate', + value: function onUpdate(event) {} + // to be extended + + + /** + * Method called after the colorpicker color is changed + * + * @listens Colorpicker#colorpickerChange + * @param {Event} event + */ + + }, { + key: 'onChange', + value: function onChange(event) {} + // to be extended + + + /** + * Method called when the colorpicker color is invalid + * + * @listens Colorpicker#colorpickerInvalid + * @param {Event} event + */ + + }, { + key: 'onInvalid', + value: function onInvalid(event) {} + // to be extended + + + /** + * Method called after the colorpicker is hidden + * + * @listens Colorpicker#colorpickerHide + * @param {Event} event + */ + + }, { + key: 'onHide', + value: function onHide(event) {} + // to be extended + + + /** + * Method called after the colorpicker is shown + * + * @listens Colorpicker#colorpickerShow + * @param {Event} event + */ + + }, { + key: 'onShow', + value: function onShow(event) {} + // to be extended + + + /** + * Method called after the colorpicker is disabled + * + * @listens Colorpicker#colorpickerDisable + * @param {Event} event + */ + + }, { + key: 'onDisable', + value: function onDisable(event) {} + // to be extended + + + /** + * Method called after the colorpicker is enabled + * + * @listens Colorpicker#colorpickerEnable + * @param {Event} event + */ + + }, { + key: 'onEnable', + value: function onEnable(event) { + // to be extended + } + }]); + + return Extension; +}(); + +exports.default = Extension; + +/***/ }), +/* 2 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ColorItem = exports.HSVAColor = undefined; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /** + * Color manipulation class, specific for Bootstrap Colorpicker + */ + + +var _color = __webpack_require__(16); + +var _color2 = _interopRequireDefault(_color); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +/** + * HSVA color data class, containing the hue, saturation, value and alpha + * information. + */ +var HSVAColor = function () { + /** + * @param {number|int} h + * @param {number|int} s + * @param {number|int} v + * @param {number|int} a + */ + function HSVAColor(h, s, v, a) { + _classCallCheck(this, HSVAColor); + + this.h = isNaN(h) ? 0 : h; + this.s = isNaN(s) ? 0 : s; + this.v = isNaN(v) ? 0 : v; + this.a = isNaN(h) ? 1 : a; + } + + _createClass(HSVAColor, [{ + key: 'toString', + value: function toString() { + return this.h + ', ' + this.s + '%, ' + this.v + '%, ' + this.a; + } + }]); + + return HSVAColor; +}(); + +/** + * HSVA color manipulation + */ + + +var ColorItem = function () { + _createClass(ColorItem, [{ + key: 'api', + + + /** + * Applies a method of the QixColor API and returns a new Color object or + * the return value of the method call. + * + * If no argument is provided, the internal QixColor object is returned. + * + * @param {String} fn QixColor function name + * @param args QixColor function arguments + * @example let darkerColor = color.api('darken', 0.25); + * @example let luminosity = color.api('luminosity'); + * @example color = color.api('negate'); + * @example let qColor = color.api().negate(); + * @returns {ColorItem|QixColor|*} + */ + value: function api(fn) { + for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + + if (arguments.length === 0) { + return this._color; + } + + var result = this._color[fn].apply(this._color, args); + + if (!(result instanceof _color2.default)) { + // return result of the method call + return result; + } + + return new ColorItem(result, this.format); + } + + /** + * Returns the original ColorItem constructor data, + * plus a 'valid' flag to know if it's valid or not. + * + * @returns {{color: *, format: String, valid: boolean}} + */ + + }, { + key: 'original', + get: function get() { + return this._original; + } + + /** + * @param {ColorItem|HSVAColor|QixColor|String|*|null} color Color data + * @param {String|null} format Color model to convert to by default. Supported: 'rgb', 'hsl', 'hex'. + */ + + }], [{ + key: 'HSVAColor', + + + /** + * Returns the HSVAColor class + * + * @static + * @example let colorData = new ColorItem.HSVAColor(360, 100, 100, 1); + * @returns {HSVAColor} + */ + get: function get() { + return HSVAColor; + } + }]); + + function ColorItem() { + var color = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + var format = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; + + _classCallCheck(this, ColorItem); + + this.replace(color, format); + } + + /** + * Replaces the internal QixColor object with a new one. + * This also replaces the internal original color data. + * + * @param {ColorItem|HSVAColor|QixColor|String|*|null} color Color data to be parsed (if needed) + * @param {String|null} format Color model to convert to by default. Supported: 'rgb', 'hsl', 'hex'. + * @example color.replace('rgb(255,0,0)', 'hsl'); + * @example color.replace(hsvaColorData); + */ + + + _createClass(ColorItem, [{ + key: 'replace', + value: function replace(color) { + var format = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; + + format = ColorItem.sanitizeFormat(format); + + /** + * @type {{color: *, format: String}} + * @private + */ + this._original = { + color: color, + format: format, + valid: true + }; + /** + * @type {QixColor} + * @private + */ + this._color = ColorItem.parse(color); + + if (this._color === null) { + this._color = (0, _color2.default)(); + this._original.valid = false; + return; + } + + /** + * @type {*|string} + * @private + */ + this._format = format ? format : ColorItem.isHex(color) ? 'hex' : this._color.model; + } + + /** + * Parses the color returning a Qix Color object or null if cannot be + * parsed. + * + * @param {ColorItem|HSVAColor|QixColor|String|*|null} color Color data + * @example let qColor = ColorItem.parse('rgb(255,0,0)'); + * @static + * @returns {QixColor|null} + */ + + }, { + key: 'isValid', + + + /** + * Returns true if the color is valid, false if not. + * + * @returns {boolean} + */ + value: function isValid() { + return this._original.valid === true; + } + + /** + * Hue value from 0 to 360 + * + * @returns {int} + */ + + }, { + key: 'setHueRatio', + + + /** + * Sets the hue ratio, where 1.0 is 0, 0.5 is 180 and 0.0 is 360. + * + * @ignore + * @param {number} h Ratio from 1.0 to 0.0 + */ + value: function setHueRatio(h) { + this.hue = (1 - h) * 360; + } + + /** + * Sets the saturation value + * + * @param {int} value Integer from 0 to 100 + */ + + }, { + key: 'setSaturationRatio', + + + /** + * Sets the saturation ratio, where 1.0 is 100 and 0.0 is 0. + * + * @ignore + * @param {number} s Ratio from 0.0 to 1.0 + */ + value: function setSaturationRatio(s) { + this.saturation = s * 100; + } + + /** + * Sets the 'value' channel value + * + * @param {int} value Integer from 0 to 100 + */ + + }, { + key: 'setValueRatio', + + + /** + * Sets the value ratio, where 1.0 is 0 and 0.0 is 100. + * + * @ignore + * @param {number} v Ratio from 1.0 to 0.0 + */ + value: function setValueRatio(v) { + this.value = (1 - v) * 100; + } + + /** + * Sets the alpha value. It will be rounded to 2 decimals. + * + * @param {int} value Float from 0.0 to 1.0 + */ + + }, { + key: 'setAlphaRatio', + + + /** + * Sets the alpha ratio, where 1.0 is 0.0 and 0.0 is 1.0. + * + * @ignore + * @param {number} a Ratio from 1.0 to 0.0 + */ + value: function setAlphaRatio(a) { + this.alpha = 1 - a; + } + + /** + * Sets the default color format + * + * @param {String} value Supported: 'rgb', 'hsl', 'hex' + */ + + }, { + key: 'isDesaturated', + + + /** + * Returns true if the saturation value is zero, false otherwise + * + * @returns {boolean} + */ + value: function isDesaturated() { + return this.saturation === 0; + } + + /** + * Returns true if the alpha value is zero, false otherwise + * + * @returns {boolean} + */ + + }, { + key: 'isTransparent', + value: function isTransparent() { + return this.alpha === 0; + } + + /** + * Returns true if the alpha value is numeric and less than 1, false otherwise + * + * @returns {boolean} + */ + + }, { + key: 'hasTransparency', + value: function hasTransparency() { + return this.hasAlpha() && this.alpha < 1; + } + + /** + * Returns true if the alpha value is numeric, false otherwise + * + * @returns {boolean} + */ + + }, { + key: 'hasAlpha', + value: function hasAlpha() { + return !isNaN(this.alpha); + } + + /** + * Returns a new HSVAColor object, based on the current color + * + * @returns {HSVAColor} + */ + + }, { + key: 'toObject', + value: function toObject() { + return new HSVAColor(this.hue, this.saturation, this.value, this.alpha); + } + + /** + * Alias of toObject() + * + * @returns {HSVAColor} + */ + + }, { + key: 'toHsva', + value: function toHsva() { + return this.toObject(); + } + + /** + * Returns a new HSVAColor object with the ratio values (from 0.0 to 1.0), + * based on the current color. + * + * @ignore + * @returns {HSVAColor} + */ + + }, { + key: 'toHsvaRatio', + value: function toHsvaRatio() { + return new HSVAColor(this.hue / 360, this.saturation / 100, this.value / 100, this.alpha); + } + + /** + * Converts the current color to its string representation, + * using the internal format of this instance. + * + * @returns {String} + */ + + }, { + key: 'toString', + value: function toString() { + return this.string(); + } + + /** + * Converts the current color to its string representation, + * using the given format. + * + * @param {String|null} format Format to convert to. If empty or null, the internal format will be used. + * @returns {String} + */ + + }, { + key: 'string', + value: function string() { + var format = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + + format = ColorItem.sanitizeFormat(format ? format : this.format); + + if (!format) { + return this._color.round().string(); + } + + if (this._color[format] === undefined) { + throw new Error('Unsupported color format: \'' + format + '\''); + } + + var str = this._color[format](); + + return str.round ? str.round().string() : str; + } + + /** + * Returns true if the given color values equals this one, false otherwise. + * The format is not compared. + * If any of the colors is invalid, the result will be false. + * + * @param {ColorItem|HSVAColor|QixColor|String|*|null} color Color data + * + * @returns {boolean} + */ + + }, { + key: 'equals', + value: function equals(color) { + color = color instanceof ColorItem ? color : new ColorItem(color); + + if (!color.isValid() || !this.isValid()) { + return false; + } + + return this.hue === color.hue && this.saturation === color.saturation && this.value === color.value && this.alpha === color.alpha; + } + + /** + * Creates a copy of this instance + * + * @returns {ColorItem} + */ + + }, { + key: 'getClone', + value: function getClone() { + return new ColorItem(this._color, this.format); + } + + /** + * Creates a copy of this instance, only copying the hue value, + * and setting the others to its max value. + * + * @returns {ColorItem} + */ + + }, { + key: 'getCloneHueOnly', + value: function getCloneHueOnly() { + return new ColorItem([this.hue, 100, 100, 1], this.format); + } + + /** + * Creates a copy of this instance setting the alpha to the max. + * + * @returns {ColorItem} + */ + + }, { + key: 'getCloneOpaque', + value: function getCloneOpaque() { + return new ColorItem(this._color.alpha(1), this.format); + } + + /** + * Converts the color to a RGB string + * + * @returns {String} + */ + + }, { + key: 'toRgbString', + value: function toRgbString() { + return this.string('rgb'); + } + + /** + * Converts the color to a Hexadecimal string + * + * @returns {String} + */ + + }, { + key: 'toHexString', + value: function toHexString() { + return this.string('hex'); + } + + /** + * Converts the color to a HSL string + * + * @returns {String} + */ + + }, { + key: 'toHslString', + value: function toHslString() { + return this.string('hsl'); + } + + /** + * Returns true if the color is dark, false otherwhise. + * This is useful to decide a text color. + * + * @returns {boolean} + */ + + }, { + key: 'isDark', + value: function isDark() { + return this._color.isDark(); + } + + /** + * Returns true if the color is light, false otherwhise. + * This is useful to decide a text color. + * + * @returns {boolean} + */ + + }, { + key: 'isLight', + value: function isLight() { + return this._color.isLight(); + } + + /** + * Generates a list of colors using the given hue-based formula or the given array of hue values. + * Hue formulas can be extended using ColorItem.colorFormulas static property. + * + * @param {String|Number[]} formula Examples: 'complementary', 'triad', 'tetrad', 'splitcomplement', [180, 270] + * @example let colors = color.generate('triad'); + * @example let colors = color.generate([45, 80, 112, 200]); + * @returns {ColorItem[]} + */ + + }, { + key: 'generate', + value: function generate(formula) { + var hues = []; + + if (Array.isArray(formula)) { + hues = formula; + } else if (!ColorItem.colorFormulas.hasOwnProperty(formula)) { + throw new Error('No color formula found with the name \'' + formula + '\'.'); + } else { + hues = ColorItem.colorFormulas[formula]; + } + + var colors = [], + mainColor = this._color, + format = this.format; + + hues.forEach(function (hue) { + var levels = [hue ? (mainColor.hue() + hue) % 360 : mainColor.hue(), mainColor.saturationv(), mainColor.value(), mainColor.alpha()]; + + colors.push(new ColorItem(levels, format)); + }); + + return colors; + } + }, { + key: 'hue', + get: function get() { + return this._color.hue(); + } + + /** + * Saturation value from 0 to 100 + * + * @returns {int} + */ + , + + + /** + * Sets the hue value + * + * @param {int} value Integer from 0 to 360 + */ + set: function set(value) { + this._color = this._color.hue(value); + } + }, { + key: 'saturation', + get: function get() { + return this._color.saturationv(); + } + + /** + * Value channel value from 0 to 100 + * + * @returns {int} + */ + , + set: function set(value) { + this._color = this._color.saturationv(value); + } + }, { + key: 'value', + get: function get() { + return this._color.value(); + } + + /** + * Alpha value from 0.0 to 1.0 + * + * @returns {number} + */ + , + set: function set(value) { + this._color = this._color.value(value); + } + }, { + key: 'alpha', + get: function get() { + var a = this._color.alpha(); + + return isNaN(a) ? 1 : a; + } + + /** + * Default color format to convert to when calling toString() or string() + * + * @returns {String} 'rgb', 'hsl', 'hex' or '' + */ + , + set: function set(value) { + // 2 decimals max + this._color = this._color.alpha(Math.round(value * 100) / 100); + } + }, { + key: 'format', + get: function get() { + return this._format ? this._format : this._color.model; + }, + set: function set(value) { + this._format = ColorItem.sanitizeFormat(value); + } + }], [{ + key: 'parse', + value: function parse(color) { + if (color instanceof _color2.default) { + return color; + } + + if (color instanceof ColorItem) { + return color._color; + } + + var format = null; + + if (color instanceof HSVAColor) { + color = [color.h, color.s, color.v, isNaN(color.a) ? 1 : color.a]; + } else { + color = ColorItem.sanitizeString(color); + } + + if (color === null) { + return null; + } + + if (Array.isArray(color)) { + format = 'hsv'; + } + + try { + return (0, _color2.default)(color, format); + } catch (e) { + return null; + } + } + + /** + * Sanitizes a color string, adding missing hash to hexadecimal colors + * and converting 'transparent' to a color code. + * + * @param {String|*} str Color string + * @example let colorStr = ColorItem.sanitizeString('ffaa00'); + * @static + * @returns {String|*} + */ + + }, { + key: 'sanitizeString', + value: function sanitizeString(str) { + if (!(typeof str === 'string' || str instanceof String)) { + return str; + } + + if (str.match(/^[0-9a-f]{2,}$/i)) { + return '#' + str; + } + + if (str.toLowerCase() === 'transparent') { + return '#FFFFFF00'; + } + + return str; + } + + /** + * Detects if a value is a string and a color in hexadecimal format (in any variant). + * + * @param {String} str + * @example ColorItem.isHex('rgba(0,0,0)'); // false + * @example ColorItem.isHex('ffaa00'); // true + * @example ColorItem.isHex('#ffaa00'); // true + * @static + * @returns {boolean} + */ + + }, { + key: 'isHex', + value: function isHex(str) { + if (!(typeof str === 'string' || str instanceof String)) { + return false; + } + + return !!str.match(/^#?[0-9a-f]{2,}$/i); + } + + /** + * Sanitizes a color format to one supported by web browsers. + * Returns an empty string of the format can't be recognised. + * + * @param {String|*} format + * @example ColorItem.sanitizeFormat('rgba'); // 'rgb' + * @example ColorItem.isHex('hex8'); // 'hex' + * @example ColorItem.isHex('invalid'); // '' + * @static + * @returns {String} 'rgb', 'hsl', 'hex' or ''. + */ + + }, { + key: 'sanitizeFormat', + value: function sanitizeFormat(format) { + switch (format) { + case 'hex': + case 'hex3': + case 'hex4': + case 'hex6': + case 'hex8': + return 'hex'; + case 'rgb': + case 'rgba': + case 'keyword': + case 'name': + return 'rgb'; + case 'hsl': + case 'hsla': + case 'hsv': + case 'hsva': + case 'hwb': // HWB this is supported by Qix Color, but not by browsers + case 'hwba': + return 'hsl'; + default: + return ''; + } + } + }]); + + return ColorItem; +}(); + +/** + * List of hue-based color formulas used by ColorItem.prototype.generate() + * + * @static + * @type {{complementary: number[], triad: number[], tetrad: number[], splitcomplement: number[]}} + */ + + +ColorItem.colorFormulas = { + complementary: [180], + triad: [0, 120, 240], + tetrad: [0, 90, 180, 270], + splitcomplement: [0, 72, 216] +}; + +exports.default = ColorItem; +exports.HSVAColor = HSVAColor; +exports.ColorItem = ColorItem; + +/***/ }), +/* 3 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +/** + * @module + */ + +// adjust these values accordingly to the sass vars + +Object.defineProperty(exports, "__esModule", { + value: true +}); +var sassVars = { + 'bar_size_short': 16, + 'base_margin': 6, + 'columns': 6 +}; + +var sliderSize = sassVars.bar_size_short * sassVars.columns + sassVars.base_margin * (sassVars.columns - 1); + +/** + * Colorpicker default options + */ +exports.default = { + /** + * Custom class to be added to the `.colorpicker-element` element + * + * @type {String|null} + * @default null + */ + customClass: null, + /** + * Sets a initial color, ignoring the one from the element/input value or the data-color attribute. + * + * @type {(String|ColorItem|boolean)} + * @default false + */ + color: false, + /** + * Fallback color to use when the given color is invalid. + * If false, the latest valid color will be used as a fallback. + * + * @type {String|ColorItem|boolean} + * @default false + */ + fallbackColor: false, + /** + * Forces an specific color format. If 'auto', it will be automatically detected the first time only, + * but if null it will be always recalculated. + * + * Note that the ending 'a' of the format meaning "alpha" has currently no effect, meaning that rgb is the same as + * rgba excepting if the alpha channel is disabled (see useAlpha). + * + * @type {('rgb'|'hex'|'hsl'|'auto'|null)} + * @default 'auto' + */ + format: 'auto', + /** + * Horizontal mode layout. + * + * If true, the hue and alpha channel bars will be rendered horizontally, above the saturation selector. + * + * @type {boolean} + * @default false + */ + horizontal: false, + /** + * Forces to show the colorpicker as an inline element. + * + * Note that if there is no container specified, the inline element + * will be added to the body, so you may want to set the container option. + * + * @type {boolean} + * @default false + */ + inline: false, + /** + * Container where the colorpicker is appended to in the DOM. + * + * If is a string (CSS selector), the colorpicker will be placed inside this container. + * If true, the `.colorpicker-element` element itself will be used as the container. + * If false, the document body is used as the container, unless it is a popover (in this case it is appended to the + * popover body instead). + * + * @type {String|boolean} + * @default false + */ + container: false, + /** + * Bootstrap Popover options. + * The trigger, content and html options are always ignored. + * + * @type {boolean} + * @default Object + */ + popover: { + animation: true, + placement: 'bottom', + fallbackPlacement: 'flip' + }, + /** + * If true, loads the 'debugger' extension automatically, which logs the events in the console + * @type {boolean} + * @default false + */ + debug: false, + /** + * Child CSS selector for the colorpicker input. + * + * @type {String} + * @default 'input' + */ + input: 'input', + /** + * Child CSS selector for the colorpicker addon. + * If it exists, the child element background will be changed on color change. + * + * @type {String} + * @default '.colorpicker-trigger, .colorpicker-input-addon' + */ + addon: '.colorpicker-input-addon', + /** + * If true, the input content will be replaced always with a valid color, + * if false, the invalid color will be left in the input, + * while the internal color object will still resolve into a valid one. + * + * @type {boolean} + * @default true + */ + autoInputFallback: true, + /** + * If true a hash will be prepended to hexadecimal colors. + * If false, the hash will be removed. + * This only affects the input values in hexadecimal format. + * + * @type {boolean} + * @default true + */ + useHashPrefix: true, + /** + * If true, the alpha channel bar will be displayed no matter what. + * + * If false, it will be always hidden and alpha channel will be disabled also programmatically, meaning that + * the selected or typed color will be always opaque. + * + * If null, the alpha channel will be automatically disabled/enabled depending if the initial color format supports + * alpha or not. + * + * @type {boolean} + * @default true + */ + useAlpha: true, + /** + * Colorpicker widget template + * @type {String} + * @example + * + *
+ *
+ *
+ *
+ *
+ * + *
+ *
+ */ + template: '
\n
\n
\n
\n
\n \n
\n
', + /** + * + * Associative object with the extension class name and its config. + * Colorpicker comes with many bundled extensions: debugger, palette, preview and swatches (a superset of palette). + * + * @type {Object[]} + * @example + * extensions: [ + * { + * name: 'swatches' + * options: { + * colors: { + * 'primary': '#337ab7', + * 'success': '#5cb85c', + * 'info': '#5bc0de', + * 'warning': '#f0ad4e', + * 'danger': '#d9534f' + * }, + * namesAsValues: true + * } + * } + * ] + */ + extensions: [{ + name: 'preview', + options: { + showText: true + } + }], + /** + * Vertical sliders configuration + * @type {Object} + */ + sliders: { + saturation: { + selector: '.colorpicker-saturation', + maxLeft: sliderSize, + maxTop: sliderSize, + callLeft: 'setSaturationRatio', + callTop: 'setValueRatio' + }, + hue: { + selector: '.colorpicker-hue', + maxLeft: 0, + maxTop: sliderSize, + callLeft: false, + callTop: 'setHueRatio' + }, + alpha: { + selector: '.colorpicker-alpha', + childSelector: '.colorpicker-alpha-color', + maxLeft: 0, + maxTop: sliderSize, + callLeft: false, + callTop: 'setAlphaRatio' + } + }, + /** + * Horizontal sliders configuration + * @type {Object} + */ + slidersHorz: { + saturation: { + selector: '.colorpicker-saturation', + maxLeft: sliderSize, + maxTop: sliderSize, + callLeft: 'setSaturationRatio', + callTop: 'setValueRatio' + }, + hue: { + selector: '.colorpicker-hue', + maxLeft: sliderSize, + maxTop: 0, + callLeft: 'setHueRatio', + callTop: false + }, + alpha: { + selector: '.colorpicker-alpha', + childSelector: '.colorpicker-alpha-color', + maxLeft: sliderSize, + maxTop: 0, + callLeft: 'setAlphaRatio', + callTop: false + } + } +}; + +/***/ }), +/* 4 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _Extension2 = __webpack_require__(1); + +var _Extension3 = _interopRequireDefault(_Extension2); + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var defaults = { + /** + * Key-value pairs defining a color alias and its CSS color representation. + * + * They can also be just an array of values. In that case, no special names are used, only the real colors. + * + * @type {Object|Array} + * @default null + * @example + * { + * 'black': '#000000', + * 'white': '#ffffff', + * 'red': '#FF0000', + * 'default': '#777777', + * 'primary': '#337ab7', + * 'success': '#5cb85c', + * 'info': '#5bc0de', + * 'warning': '#f0ad4e', + * 'danger': '#d9534f' + * } + * + * @example ['#f0ad4e', '#337ab7', '#5cb85c'] + */ + colors: null, + /** + * If true, when a color swatch is selected the name (alias) will be used as input value, + * otherwise the swatch real color value will be used. + * + * @type {boolean} + * @default true + */ + namesAsValues: true +}; + +/** + * Palette extension + * @ignore + */ + +var Palette = function (_Extension) { + _inherits(Palette, _Extension); + + _createClass(Palette, [{ + key: 'colors', + + + /** + * @returns {Object|Array} + */ + get: function get() { + return this.options.colors; + } + }]); + + function Palette(colorpicker) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + _classCallCheck(this, Palette); + + var _this = _possibleConstructorReturn(this, (Palette.__proto__ || Object.getPrototypeOf(Palette)).call(this, colorpicker, _jquery2.default.extend(true, {}, defaults, options))); + + if (!Array.isArray(_this.options.colors) && _typeof(_this.options.colors) !== 'object') { + _this.options.colors = null; + } + return _this; + } + + /** + * @returns {int} + */ + + + _createClass(Palette, [{ + key: 'getLength', + value: function getLength() { + if (!this.options.colors) { + return 0; + } + + if (Array.isArray(this.options.colors)) { + return this.options.colors.length; + } + + if (_typeof(this.options.colors) === 'object') { + return Object.keys(this.options.colors).length; + } + + return 0; + } + }, { + key: 'resolveColor', + value: function resolveColor(color) { + var realColor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + + if (this.getLength() <= 0) { + return false; + } + + // Array of colors + if (Array.isArray(this.options.colors)) { + if (this.options.colors.indexOf(color) >= 0) { + return color; + } + if (this.options.colors.indexOf(color.toUpperCase()) >= 0) { + return color.toUpperCase(); + } + if (this.options.colors.indexOf(color.toLowerCase()) >= 0) { + return color.toLowerCase(); + } + return false; + } + + if (_typeof(this.options.colors) !== 'object') { + return false; + } + + // Map of objects + if (!this.options.namesAsValues || realColor) { + return this.getValue(color, false); + } + return this.getName(color, this.getName('#' + color)); + } + + /** + * Given a color value, returns the corresponding color name or defaultValue. + * + * @param {String} value + * @param {*} defaultValue + * @returns {*} + */ + + }, { + key: 'getName', + value: function getName(value) { + var defaultValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + if (!(typeof value === 'string') || !this.options.colors) { + return defaultValue; + } + for (var name in this.options.colors) { + if (!this.options.colors.hasOwnProperty(name)) { + continue; + } + if (this.options.colors[name].toLowerCase() === value.toLowerCase()) { + return name; + } + } + return defaultValue; + } + + /** + * Given a color name, returns the corresponding color value or defaultValue. + * + * @param {String} name + * @param {*} defaultValue + * @returns {*} + */ + + }, { + key: 'getValue', + value: function getValue(name) { + var defaultValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + if (!(typeof name === 'string') || !this.options.colors) { + return defaultValue; + } + if (this.options.colors.hasOwnProperty(name)) { + return this.options.colors[name]; + } + return defaultValue; + } + }]); + + return Palette; +}(_Extension3.default); + +exports.default = Palette; + +/***/ }), +/* 5 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +module.exports = { + "aliceblue": [240, 248, 255], + "antiquewhite": [250, 235, 215], + "aqua": [0, 255, 255], + "aquamarine": [127, 255, 212], + "azure": [240, 255, 255], + "beige": [245, 245, 220], + "bisque": [255, 228, 196], + "black": [0, 0, 0], + "blanchedalmond": [255, 235, 205], + "blue": [0, 0, 255], + "blueviolet": [138, 43, 226], + "brown": [165, 42, 42], + "burlywood": [222, 184, 135], + "cadetblue": [95, 158, 160], + "chartreuse": [127, 255, 0], + "chocolate": [210, 105, 30], + "coral": [255, 127, 80], + "cornflowerblue": [100, 149, 237], + "cornsilk": [255, 248, 220], + "crimson": [220, 20, 60], + "cyan": [0, 255, 255], + "darkblue": [0, 0, 139], + "darkcyan": [0, 139, 139], + "darkgoldenrod": [184, 134, 11], + "darkgray": [169, 169, 169], + "darkgreen": [0, 100, 0], + "darkgrey": [169, 169, 169], + "darkkhaki": [189, 183, 107], + "darkmagenta": [139, 0, 139], + "darkolivegreen": [85, 107, 47], + "darkorange": [255, 140, 0], + "darkorchid": [153, 50, 204], + "darkred": [139, 0, 0], + "darksalmon": [233, 150, 122], + "darkseagreen": [143, 188, 143], + "darkslateblue": [72, 61, 139], + "darkslategray": [47, 79, 79], + "darkslategrey": [47, 79, 79], + "darkturquoise": [0, 206, 209], + "darkviolet": [148, 0, 211], + "deeppink": [255, 20, 147], + "deepskyblue": [0, 191, 255], + "dimgray": [105, 105, 105], + "dimgrey": [105, 105, 105], + "dodgerblue": [30, 144, 255], + "firebrick": [178, 34, 34], + "floralwhite": [255, 250, 240], + "forestgreen": [34, 139, 34], + "fuchsia": [255, 0, 255], + "gainsboro": [220, 220, 220], + "ghostwhite": [248, 248, 255], + "gold": [255, 215, 0], + "goldenrod": [218, 165, 32], + "gray": [128, 128, 128], + "green": [0, 128, 0], + "greenyellow": [173, 255, 47], + "grey": [128, 128, 128], + "honeydew": [240, 255, 240], + "hotpink": [255, 105, 180], + "indianred": [205, 92, 92], + "indigo": [75, 0, 130], + "ivory": [255, 255, 240], + "khaki": [240, 230, 140], + "lavender": [230, 230, 250], + "lavenderblush": [255, 240, 245], + "lawngreen": [124, 252, 0], + "lemonchiffon": [255, 250, 205], + "lightblue": [173, 216, 230], + "lightcoral": [240, 128, 128], + "lightcyan": [224, 255, 255], + "lightgoldenrodyellow": [250, 250, 210], + "lightgray": [211, 211, 211], + "lightgreen": [144, 238, 144], + "lightgrey": [211, 211, 211], + "lightpink": [255, 182, 193], + "lightsalmon": [255, 160, 122], + "lightseagreen": [32, 178, 170], + "lightskyblue": [135, 206, 250], + "lightslategray": [119, 136, 153], + "lightslategrey": [119, 136, 153], + "lightsteelblue": [176, 196, 222], + "lightyellow": [255, 255, 224], + "lime": [0, 255, 0], + "limegreen": [50, 205, 50], + "linen": [250, 240, 230], + "magenta": [255, 0, 255], + "maroon": [128, 0, 0], + "mediumaquamarine": [102, 205, 170], + "mediumblue": [0, 0, 205], + "mediumorchid": [186, 85, 211], + "mediumpurple": [147, 112, 219], + "mediumseagreen": [60, 179, 113], + "mediumslateblue": [123, 104, 238], + "mediumspringgreen": [0, 250, 154], + "mediumturquoise": [72, 209, 204], + "mediumvioletred": [199, 21, 133], + "midnightblue": [25, 25, 112], + "mintcream": [245, 255, 250], + "mistyrose": [255, 228, 225], + "moccasin": [255, 228, 181], + "navajowhite": [255, 222, 173], + "navy": [0, 0, 128], + "oldlace": [253, 245, 230], + "olive": [128, 128, 0], + "olivedrab": [107, 142, 35], + "orange": [255, 165, 0], + "orangered": [255, 69, 0], + "orchid": [218, 112, 214], + "palegoldenrod": [238, 232, 170], + "palegreen": [152, 251, 152], + "paleturquoise": [175, 238, 238], + "palevioletred": [219, 112, 147], + "papayawhip": [255, 239, 213], + "peachpuff": [255, 218, 185], + "peru": [205, 133, 63], + "pink": [255, 192, 203], + "plum": [221, 160, 221], + "powderblue": [176, 224, 230], + "purple": [128, 0, 128], + "rebeccapurple": [102, 51, 153], + "red": [255, 0, 0], + "rosybrown": [188, 143, 143], + "royalblue": [65, 105, 225], + "saddlebrown": [139, 69, 19], + "salmon": [250, 128, 114], + "sandybrown": [244, 164, 96], + "seagreen": [46, 139, 87], + "seashell": [255, 245, 238], + "sienna": [160, 82, 45], + "silver": [192, 192, 192], + "skyblue": [135, 206, 235], + "slateblue": [106, 90, 205], + "slategray": [112, 128, 144], + "slategrey": [112, 128, 144], + "snow": [255, 250, 250], + "springgreen": [0, 255, 127], + "steelblue": [70, 130, 180], + "tan": [210, 180, 140], + "teal": [0, 128, 128], + "thistle": [216, 191, 216], + "tomato": [255, 99, 71], + "turquoise": [64, 224, 208], + "violet": [238, 130, 238], + "wheat": [245, 222, 179], + "white": [255, 255, 255], + "whitesmoke": [245, 245, 245], + "yellow": [255, 255, 0], + "yellowgreen": [154, 205, 50] +}; + + +/***/ }), +/* 6 */ +/***/ (function(module, exports, __webpack_require__) { + +/* MIT license */ +var cssKeywords = __webpack_require__(5); + +// NOTE: conversions should only return primitive values (i.e. arrays, or +// values that give correct `typeof` results). +// do not use box values types (i.e. Number(), String(), etc.) + +var reverseKeywords = {}; +for (var key in cssKeywords) { + if (cssKeywords.hasOwnProperty(key)) { + reverseKeywords[cssKeywords[key]] = key; + } +} + +var convert = module.exports = { + rgb: {channels: 3, labels: 'rgb'}, + hsl: {channels: 3, labels: 'hsl'}, + hsv: {channels: 3, labels: 'hsv'}, + hwb: {channels: 3, labels: 'hwb'}, + cmyk: {channels: 4, labels: 'cmyk'}, + xyz: {channels: 3, labels: 'xyz'}, + lab: {channels: 3, labels: 'lab'}, + lch: {channels: 3, labels: 'lch'}, + hex: {channels: 1, labels: ['hex']}, + keyword: {channels: 1, labels: ['keyword']}, + ansi16: {channels: 1, labels: ['ansi16']}, + ansi256: {channels: 1, labels: ['ansi256']}, + hcg: {channels: 3, labels: ['h', 'c', 'g']}, + apple: {channels: 3, labels: ['r16', 'g16', 'b16']}, + gray: {channels: 1, labels: ['gray']} +}; + +// hide .channels and .labels properties +for (var model in convert) { + if (convert.hasOwnProperty(model)) { + if (!('channels' in convert[model])) { + throw new Error('missing channels property: ' + model); + } + + if (!('labels' in convert[model])) { + throw new Error('missing channel labels property: ' + model); + } + + if (convert[model].labels.length !== convert[model].channels) { + throw new Error('channel and label counts mismatch: ' + model); + } + + var channels = convert[model].channels; + var labels = convert[model].labels; + delete convert[model].channels; + delete convert[model].labels; + Object.defineProperty(convert[model], 'channels', {value: channels}); + Object.defineProperty(convert[model], 'labels', {value: labels}); + } +} + +convert.rgb.hsl = function (rgb) { + var r = rgb[0] / 255; + var g = rgb[1] / 255; + var b = rgb[2] / 255; + var min = Math.min(r, g, b); + var max = Math.max(r, g, b); + var delta = max - min; + var h; + var s; + var l; + + if (max === min) { + h = 0; + } else if (r === max) { + h = (g - b) / delta; + } else if (g === max) { + h = 2 + (b - r) / delta; + } else if (b === max) { + h = 4 + (r - g) / delta; + } + + h = Math.min(h * 60, 360); + + if (h < 0) { + h += 360; + } + + l = (min + max) / 2; + + if (max === min) { + s = 0; + } else if (l <= 0.5) { + s = delta / (max + min); + } else { + s = delta / (2 - max - min); + } + + return [h, s * 100, l * 100]; +}; + +convert.rgb.hsv = function (rgb) { + var rdif; + var gdif; + var bdif; + var h; + var s; + + var r = rgb[0] / 255; + var g = rgb[1] / 255; + var b = rgb[2] / 255; + var v = Math.max(r, g, b); + var diff = v - Math.min(r, g, b); + var diffc = function (c) { + return (v - c) / 6 / diff + 1 / 2; + }; + + if (diff === 0) { + h = s = 0; + } else { + s = diff / v; + rdif = diffc(r); + gdif = diffc(g); + bdif = diffc(b); + + if (r === v) { + h = bdif - gdif; + } else if (g === v) { + h = (1 / 3) + rdif - bdif; + } else if (b === v) { + h = (2 / 3) + gdif - rdif; + } + if (h < 0) { + h += 1; + } else if (h > 1) { + h -= 1; + } + } + + return [ + h * 360, + s * 100, + v * 100 + ]; +}; + +convert.rgb.hwb = function (rgb) { + var r = rgb[0]; + var g = rgb[1]; + var b = rgb[2]; + var h = convert.rgb.hsl(rgb)[0]; + var w = 1 / 255 * Math.min(r, Math.min(g, b)); + + b = 1 - 1 / 255 * Math.max(r, Math.max(g, b)); + + return [h, w * 100, b * 100]; +}; + +convert.rgb.cmyk = function (rgb) { + var r = rgb[0] / 255; + var g = rgb[1] / 255; + var b = rgb[2] / 255; + var c; + var m; + var y; + var k; + + k = Math.min(1 - r, 1 - g, 1 - b); + c = (1 - r - k) / (1 - k) || 0; + m = (1 - g - k) / (1 - k) || 0; + y = (1 - b - k) / (1 - k) || 0; + + return [c * 100, m * 100, y * 100, k * 100]; +}; + +/** + * See https://en.m.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance + * */ +function comparativeDistance(x, y) { + return ( + Math.pow(x[0] - y[0], 2) + + Math.pow(x[1] - y[1], 2) + + Math.pow(x[2] - y[2], 2) + ); +} + +convert.rgb.keyword = function (rgb) { + var reversed = reverseKeywords[rgb]; + if (reversed) { + return reversed; + } + + var currentClosestDistance = Infinity; + var currentClosestKeyword; + + for (var keyword in cssKeywords) { + if (cssKeywords.hasOwnProperty(keyword)) { + var value = cssKeywords[keyword]; + + // Compute comparative distance + var distance = comparativeDistance(rgb, value); + + // Check if its less, if so set as closest + if (distance < currentClosestDistance) { + currentClosestDistance = distance; + currentClosestKeyword = keyword; + } + } + } + + return currentClosestKeyword; +}; + +convert.keyword.rgb = function (keyword) { + return cssKeywords[keyword]; +}; + +convert.rgb.xyz = function (rgb) { + var r = rgb[0] / 255; + var g = rgb[1] / 255; + var b = rgb[2] / 255; + + // assume sRGB + r = r > 0.04045 ? Math.pow(((r + 0.055) / 1.055), 2.4) : (r / 12.92); + g = g > 0.04045 ? Math.pow(((g + 0.055) / 1.055), 2.4) : (g / 12.92); + b = b > 0.04045 ? Math.pow(((b + 0.055) / 1.055), 2.4) : (b / 12.92); + + var x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805); + var y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722); + var z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505); + + return [x * 100, y * 100, z * 100]; +}; + +convert.rgb.lab = function (rgb) { + var xyz = convert.rgb.xyz(rgb); + var x = xyz[0]; + var y = xyz[1]; + var z = xyz[2]; + var l; + var a; + var b; + + x /= 95.047; + y /= 100; + z /= 108.883; + + x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116); + y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116); + z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116); + + l = (116 * y) - 16; + a = 500 * (x - y); + b = 200 * (y - z); + + return [l, a, b]; +}; + +convert.hsl.rgb = function (hsl) { + var h = hsl[0] / 360; + var s = hsl[1] / 100; + var l = hsl[2] / 100; + var t1; + var t2; + var t3; + var rgb; + var val; + + if (s === 0) { + val = l * 255; + return [val, val, val]; + } + + if (l < 0.5) { + t2 = l * (1 + s); + } else { + t2 = l + s - l * s; + } + + t1 = 2 * l - t2; + + rgb = [0, 0, 0]; + for (var i = 0; i < 3; i++) { + t3 = h + 1 / 3 * -(i - 1); + if (t3 < 0) { + t3++; + } + if (t3 > 1) { + t3--; + } + + if (6 * t3 < 1) { + val = t1 + (t2 - t1) * 6 * t3; + } else if (2 * t3 < 1) { + val = t2; + } else if (3 * t3 < 2) { + val = t1 + (t2 - t1) * (2 / 3 - t3) * 6; + } else { + val = t1; + } + + rgb[i] = val * 255; + } + + return rgb; +}; + +convert.hsl.hsv = function (hsl) { + var h = hsl[0]; + var s = hsl[1] / 100; + var l = hsl[2] / 100; + var smin = s; + var lmin = Math.max(l, 0.01); + var sv; + var v; + + l *= 2; + s *= (l <= 1) ? l : 2 - l; + smin *= lmin <= 1 ? lmin : 2 - lmin; + v = (l + s) / 2; + sv = l === 0 ? (2 * smin) / (lmin + smin) : (2 * s) / (l + s); + + return [h, sv * 100, v * 100]; +}; + +convert.hsv.rgb = function (hsv) { + var h = hsv[0] / 60; + var s = hsv[1] / 100; + var v = hsv[2] / 100; + var hi = Math.floor(h) % 6; + + var f = h - Math.floor(h); + var p = 255 * v * (1 - s); + var q = 255 * v * (1 - (s * f)); + var t = 255 * v * (1 - (s * (1 - f))); + v *= 255; + + switch (hi) { + case 0: + return [v, t, p]; + case 1: + return [q, v, p]; + case 2: + return [p, v, t]; + case 3: + return [p, q, v]; + case 4: + return [t, p, v]; + case 5: + return [v, p, q]; + } +}; + +convert.hsv.hsl = function (hsv) { + var h = hsv[0]; + var s = hsv[1] / 100; + var v = hsv[2] / 100; + var vmin = Math.max(v, 0.01); + var lmin; + var sl; + var l; + + l = (2 - s) * v; + lmin = (2 - s) * vmin; + sl = s * vmin; + sl /= (lmin <= 1) ? lmin : 2 - lmin; + sl = sl || 0; + l /= 2; + + return [h, sl * 100, l * 100]; +}; + +// http://dev.w3.org/csswg/css-color/#hwb-to-rgb +convert.hwb.rgb = function (hwb) { + var h = hwb[0] / 360; + var wh = hwb[1] / 100; + var bl = hwb[2] / 100; + var ratio = wh + bl; + var i; + var v; + var f; + var n; + + // wh + bl cant be > 1 + if (ratio > 1) { + wh /= ratio; + bl /= ratio; + } + + i = Math.floor(6 * h); + v = 1 - bl; + f = 6 * h - i; + + if ((i & 0x01) !== 0) { + f = 1 - f; + } + + n = wh + f * (v - wh); // linear interpolation + + var r; + var g; + var b; + switch (i) { + default: + case 6: + case 0: r = v; g = n; b = wh; break; + case 1: r = n; g = v; b = wh; break; + case 2: r = wh; g = v; b = n; break; + case 3: r = wh; g = n; b = v; break; + case 4: r = n; g = wh; b = v; break; + case 5: r = v; g = wh; b = n; break; + } + + return [r * 255, g * 255, b * 255]; +}; + +convert.cmyk.rgb = function (cmyk) { + var c = cmyk[0] / 100; + var m = cmyk[1] / 100; + var y = cmyk[2] / 100; + var k = cmyk[3] / 100; + var r; + var g; + var b; + + r = 1 - Math.min(1, c * (1 - k) + k); + g = 1 - Math.min(1, m * (1 - k) + k); + b = 1 - Math.min(1, y * (1 - k) + k); + + return [r * 255, g * 255, b * 255]; +}; + +convert.xyz.rgb = function (xyz) { + var x = xyz[0] / 100; + var y = xyz[1] / 100; + var z = xyz[2] / 100; + var r; + var g; + var b; + + r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986); + g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415); + b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570); + + // assume sRGB + r = r > 0.0031308 + ? ((1.055 * Math.pow(r, 1.0 / 2.4)) - 0.055) + : r * 12.92; + + g = g > 0.0031308 + ? ((1.055 * Math.pow(g, 1.0 / 2.4)) - 0.055) + : g * 12.92; + + b = b > 0.0031308 + ? ((1.055 * Math.pow(b, 1.0 / 2.4)) - 0.055) + : b * 12.92; + + r = Math.min(Math.max(0, r), 1); + g = Math.min(Math.max(0, g), 1); + b = Math.min(Math.max(0, b), 1); + + return [r * 255, g * 255, b * 255]; +}; + +convert.xyz.lab = function (xyz) { + var x = xyz[0]; + var y = xyz[1]; + var z = xyz[2]; + var l; + var a; + var b; + + x /= 95.047; + y /= 100; + z /= 108.883; + + x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116); + y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116); + z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116); + + l = (116 * y) - 16; + a = 500 * (x - y); + b = 200 * (y - z); + + return [l, a, b]; +}; + +convert.lab.xyz = function (lab) { + var l = lab[0]; + var a = lab[1]; + var b = lab[2]; + var x; + var y; + var z; + + y = (l + 16) / 116; + x = a / 500 + y; + z = y - b / 200; + + var y2 = Math.pow(y, 3); + var x2 = Math.pow(x, 3); + var z2 = Math.pow(z, 3); + y = y2 > 0.008856 ? y2 : (y - 16 / 116) / 7.787; + x = x2 > 0.008856 ? x2 : (x - 16 / 116) / 7.787; + z = z2 > 0.008856 ? z2 : (z - 16 / 116) / 7.787; + + x *= 95.047; + y *= 100; + z *= 108.883; + + return [x, y, z]; +}; + +convert.lab.lch = function (lab) { + var l = lab[0]; + var a = lab[1]; + var b = lab[2]; + var hr; + var h; + var c; + + hr = Math.atan2(b, a); + h = hr * 360 / 2 / Math.PI; + + if (h < 0) { + h += 360; + } + + c = Math.sqrt(a * a + b * b); + + return [l, c, h]; +}; + +convert.lch.lab = function (lch) { + var l = lch[0]; + var c = lch[1]; + var h = lch[2]; + var a; + var b; + var hr; + + hr = h / 360 * 2 * Math.PI; + a = c * Math.cos(hr); + b = c * Math.sin(hr); + + return [l, a, b]; +}; + +convert.rgb.ansi16 = function (args) { + var r = args[0]; + var g = args[1]; + var b = args[2]; + var value = 1 in arguments ? arguments[1] : convert.rgb.hsv(args)[2]; // hsv -> ansi16 optimization + + value = Math.round(value / 50); + + if (value === 0) { + return 30; + } + + var ansi = 30 + + ((Math.round(b / 255) << 2) + | (Math.round(g / 255) << 1) + | Math.round(r / 255)); + + if (value === 2) { + ansi += 60; + } + + return ansi; +}; + +convert.hsv.ansi16 = function (args) { + // optimization here; we already know the value and don't need to get + // it converted for us. + return convert.rgb.ansi16(convert.hsv.rgb(args), args[2]); +}; + +convert.rgb.ansi256 = function (args) { + var r = args[0]; + var g = args[1]; + var b = args[2]; + + // we use the extended greyscale palette here, with the exception of + // black and white. normal palette only has 4 greyscale shades. + if (r === g && g === b) { + if (r < 8) { + return 16; + } + + if (r > 248) { + return 231; + } + + return Math.round(((r - 8) / 247) * 24) + 232; + } + + var ansi = 16 + + (36 * Math.round(r / 255 * 5)) + + (6 * Math.round(g / 255 * 5)) + + Math.round(b / 255 * 5); + + return ansi; +}; + +convert.ansi16.rgb = function (args) { + var color = args % 10; + + // handle greyscale + if (color === 0 || color === 7) { + if (args > 50) { + color += 3.5; + } + + color = color / 10.5 * 255; + + return [color, color, color]; + } + + var mult = (~~(args > 50) + 1) * 0.5; + var r = ((color & 1) * mult) * 255; + var g = (((color >> 1) & 1) * mult) * 255; + var b = (((color >> 2) & 1) * mult) * 255; + + return [r, g, b]; +}; + +convert.ansi256.rgb = function (args) { + // handle greyscale + if (args >= 232) { + var c = (args - 232) * 10 + 8; + return [c, c, c]; + } + + args -= 16; + + var rem; + var r = Math.floor(args / 36) / 5 * 255; + var g = Math.floor((rem = args % 36) / 6) / 5 * 255; + var b = (rem % 6) / 5 * 255; + + return [r, g, b]; +}; + +convert.rgb.hex = function (args) { + var integer = ((Math.round(args[0]) & 0xFF) << 16) + + ((Math.round(args[1]) & 0xFF) << 8) + + (Math.round(args[2]) & 0xFF); + + var string = integer.toString(16).toUpperCase(); + return '000000'.substring(string.length) + string; +}; + +convert.hex.rgb = function (args) { + var match = args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i); + if (!match) { + return [0, 0, 0]; + } + + var colorString = match[0]; + + if (match[0].length === 3) { + colorString = colorString.split('').map(function (char) { + return char + char; + }).join(''); + } + + var integer = parseInt(colorString, 16); + var r = (integer >> 16) & 0xFF; + var g = (integer >> 8) & 0xFF; + var b = integer & 0xFF; + + return [r, g, b]; +}; + +convert.rgb.hcg = function (rgb) { + var r = rgb[0] / 255; + var g = rgb[1] / 255; + var b = rgb[2] / 255; + var max = Math.max(Math.max(r, g), b); + var min = Math.min(Math.min(r, g), b); + var chroma = (max - min); + var grayscale; + var hue; + + if (chroma < 1) { + grayscale = min / (1 - chroma); + } else { + grayscale = 0; + } + + if (chroma <= 0) { + hue = 0; + } else + if (max === r) { + hue = ((g - b) / chroma) % 6; + } else + if (max === g) { + hue = 2 + (b - r) / chroma; + } else { + hue = 4 + (r - g) / chroma + 4; + } + + hue /= 6; + hue %= 1; + + return [hue * 360, chroma * 100, grayscale * 100]; +}; + +convert.hsl.hcg = function (hsl) { + var s = hsl[1] / 100; + var l = hsl[2] / 100; + var c = 1; + var f = 0; + + if (l < 0.5) { + c = 2.0 * s * l; + } else { + c = 2.0 * s * (1.0 - l); + } + + if (c < 1.0) { + f = (l - 0.5 * c) / (1.0 - c); + } + + return [hsl[0], c * 100, f * 100]; +}; + +convert.hsv.hcg = function (hsv) { + var s = hsv[1] / 100; + var v = hsv[2] / 100; + + var c = s * v; + var f = 0; + + if (c < 1.0) { + f = (v - c) / (1 - c); + } + + return [hsv[0], c * 100, f * 100]; +}; + +convert.hcg.rgb = function (hcg) { + var h = hcg[0] / 360; + var c = hcg[1] / 100; + var g = hcg[2] / 100; + + if (c === 0.0) { + return [g * 255, g * 255, g * 255]; + } + + var pure = [0, 0, 0]; + var hi = (h % 1) * 6; + var v = hi % 1; + var w = 1 - v; + var mg = 0; + + switch (Math.floor(hi)) { + case 0: + pure[0] = 1; pure[1] = v; pure[2] = 0; break; + case 1: + pure[0] = w; pure[1] = 1; pure[2] = 0; break; + case 2: + pure[0] = 0; pure[1] = 1; pure[2] = v; break; + case 3: + pure[0] = 0; pure[1] = w; pure[2] = 1; break; + case 4: + pure[0] = v; pure[1] = 0; pure[2] = 1; break; + default: + pure[0] = 1; pure[1] = 0; pure[2] = w; + } + + mg = (1.0 - c) * g; + + return [ + (c * pure[0] + mg) * 255, + (c * pure[1] + mg) * 255, + (c * pure[2] + mg) * 255 + ]; +}; + +convert.hcg.hsv = function (hcg) { + var c = hcg[1] / 100; + var g = hcg[2] / 100; + + var v = c + g * (1.0 - c); + var f = 0; + + if (v > 0.0) { + f = c / v; + } + + return [hcg[0], f * 100, v * 100]; +}; + +convert.hcg.hsl = function (hcg) { + var c = hcg[1] / 100; + var g = hcg[2] / 100; + + var l = g * (1.0 - c) + 0.5 * c; + var s = 0; + + if (l > 0.0 && l < 0.5) { + s = c / (2 * l); + } else + if (l >= 0.5 && l < 1.0) { + s = c / (2 * (1 - l)); + } + + return [hcg[0], s * 100, l * 100]; +}; + +convert.hcg.hwb = function (hcg) { + var c = hcg[1] / 100; + var g = hcg[2] / 100; + var v = c + g * (1.0 - c); + return [hcg[0], (v - c) * 100, (1 - v) * 100]; +}; + +convert.hwb.hcg = function (hwb) { + var w = hwb[1] / 100; + var b = hwb[2] / 100; + var v = 1 - b; + var c = v - w; + var g = 0; + + if (c < 1) { + g = (v - c) / (1 - c); + } + + return [hwb[0], c * 100, g * 100]; +}; + +convert.apple.rgb = function (apple) { + return [(apple[0] / 65535) * 255, (apple[1] / 65535) * 255, (apple[2] / 65535) * 255]; +}; + +convert.rgb.apple = function (rgb) { + return [(rgb[0] / 255) * 65535, (rgb[1] / 255) * 65535, (rgb[2] / 255) * 65535]; +}; + +convert.gray.rgb = function (args) { + return [args[0] / 100 * 255, args[0] / 100 * 255, args[0] / 100 * 255]; +}; + +convert.gray.hsl = convert.gray.hsv = function (args) { + return [0, 0, args[0]]; +}; + +convert.gray.hwb = function (gray) { + return [0, 100, gray[0]]; +}; + +convert.gray.cmyk = function (gray) { + return [0, 0, 0, gray[0]]; +}; + +convert.gray.lab = function (gray) { + return [gray[0], 0, 0]; +}; + +convert.gray.hex = function (gray) { + var val = Math.round(gray[0] / 100 * 255) & 0xFF; + var integer = (val << 16) + (val << 8) + val; + + var string = integer.toString(16).toUpperCase(); + return '000000'.substring(string.length) + string; +}; + +convert.rgb.gray = function (rgb) { + var val = (rgb[0] + rgb[1] + rgb[2]) / 3; + return [val / 255 * 100]; +}; + + +/***/ }), +/* 7 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +var _Colorpicker = __webpack_require__(8); + +var _Colorpicker2 = _interopRequireDefault(_Colorpicker); + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var plugin = 'colorpicker'; + +_jquery2.default[plugin] = _Colorpicker2.default; + +// Colorpicker jQuery Plugin API +_jquery2.default.fn[plugin] = function (option) { + var fnArgs = Array.prototype.slice.call(arguments, 1), + isSingleElement = this.length === 1, + returnValue = null; + + var $elements = this.each(function () { + var $this = (0, _jquery2.default)(this), + inst = $this.data(plugin), + options = (typeof option === 'undefined' ? 'undefined' : _typeof(option)) === 'object' ? option : {}; + + // Create instance if does not exist + if (!inst) { + inst = new _Colorpicker2.default(this, options); + $this.data(plugin, inst); + } + + if (!isSingleElement) { + return; + } + + returnValue = $this; + + if (typeof option === 'string') { + if (option === 'colorpicker') { + // Return colorpicker instance: e.g. .colorpicker('colorpicker') + returnValue = inst; + } else if (_jquery2.default.isFunction(inst[option])) { + // Return method call return value: e.g. .colorpicker('isEnabled') + returnValue = inst[option].apply(inst, fnArgs); + } else { + // Return property value: e.g. .colorpicker('element') + returnValue = inst[option]; + } + } + }); + + return isSingleElement ? returnValue : $elements; +}; + +_jquery2.default.fn[plugin].constructor = _Colorpicker2.default; + +/***/ }), +/* 8 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _Extension = __webpack_require__(1); + +var _Extension2 = _interopRequireDefault(_Extension); + +var _options = __webpack_require__(3); + +var _options2 = _interopRequireDefault(_options); + +var _extensions = __webpack_require__(9); + +var _extensions2 = _interopRequireDefault(_extensions); + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _SliderHandler = __webpack_require__(13); + +var _SliderHandler2 = _interopRequireDefault(_SliderHandler); + +var _PopupHandler = __webpack_require__(14); + +var _PopupHandler2 = _interopRequireDefault(_PopupHandler); + +var _InputHandler = __webpack_require__(15); + +var _InputHandler2 = _interopRequireDefault(_InputHandler); + +var _ColorHandler = __webpack_require__(22); + +var _ColorHandler2 = _interopRequireDefault(_ColorHandler); + +var _PickerHandler = __webpack_require__(23); + +var _PickerHandler2 = _interopRequireDefault(_PickerHandler); + +var _AddonHandler = __webpack_require__(24); + +var _AddonHandler2 = _interopRequireDefault(_AddonHandler); + +var _ColorItem = __webpack_require__(2); + +var _ColorItem2 = _interopRequireDefault(_ColorItem); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var colorPickerIdCounter = 0; +var root = typeof self !== 'undefined' ? self : undefined; // window + +/** + * Colorpicker widget class + */ + +var Colorpicker = function () { + _createClass(Colorpicker, [{ + key: 'color', + + + /** + * Internal color object + * + * @type {Color|null} + */ + get: function get() { + return this.colorHandler.color; + } + + /** + * Internal color format + * + * @type {String|null} + */ + + }, { + key: 'format', + get: function get() { + return this.colorHandler.format; + } + + /** + * Getter of the picker element + * + * @returns {jQuery|HTMLElement} + */ + + }, { + key: 'picker', + get: function get() { + return this.pickerHandler.picker; + } + + /** + * @fires Colorpicker#colorpickerCreate + * @param {Object|String} element + * @param {Object} options + * @constructor + */ + + }], [{ + key: 'Color', + + /** + * Color class + * + * @static + * @type {Color} + */ + get: function get() { + return _ColorItem2.default; + } + + /** + * Extension class + * + * @static + * @type {Extension} + */ + + }, { + key: 'Extension', + get: function get() { + return _Extension2.default; + } + }]); + + function Colorpicker(element, options) { + _classCallCheck(this, Colorpicker); + + colorPickerIdCounter += 1; + /** + * The colorpicker instance number + * @type {number} + */ + this.id = colorPickerIdCounter; + + /** + * Latest colorpicker event + * + * @type {{name: String, e: *}} + */ + this.lastEvent = { + alias: null, + e: null + }; + + /** + * The element that the colorpicker is bound to + * + * @type {*|jQuery} + */ + this.element = (0, _jquery2.default)(element).addClass('colorpicker-element').attr('data-colorpicker-id', this.id); + + /** + * @type {defaults} + */ + this.options = _jquery2.default.extend(true, {}, _options2.default, options, this.element.data()); + + /** + * @type {boolean} + * @private + */ + this.disabled = false; + + /** + * Extensions added to this instance + * + * @type {Extension[]} + */ + this.extensions = []; + + /** + * The element where the + * @type {*|jQuery} + */ + this.container = this.options.container === true || this.options.container !== true && this.options.inline === true ? this.element : this.options.container; + + this.container = this.container !== false ? (0, _jquery2.default)(this.container) : false; + + /** + * @type {InputHandler} + */ + this.inputHandler = new _InputHandler2.default(this); + /** + * @type {ColorHandler} + */ + this.colorHandler = new _ColorHandler2.default(this); + /** + * @type {SliderHandler} + */ + this.sliderHandler = new _SliderHandler2.default(this); + /** + * @type {PopupHandler} + */ + this.popupHandler = new _PopupHandler2.default(this, root); + /** + * @type {PickerHandler} + */ + this.pickerHandler = new _PickerHandler2.default(this); + /** + * @type {AddonHandler} + */ + this.addonHandler = new _AddonHandler2.default(this); + + this.init(); + + // Emit a create event + (0, _jquery2.default)(_jquery2.default.proxy(function () { + /** + * (Colorpicker) When the Colorpicker instance has been created and the DOM is ready. + * + * @event Colorpicker#colorpickerCreate + */ + this.trigger('colorpickerCreate'); + }, this)); + } + + /** + * Initializes the plugin + * @private + */ + + + _createClass(Colorpicker, [{ + key: 'init', + value: function init() { + // Init addon + this.addonHandler.bind(); + + // Init input + this.inputHandler.bind(); + + // Init extensions (before initializing the color) + this.initExtensions(); + + // Init color + this.colorHandler.bind(); + + // Init picker + this.pickerHandler.bind(); + + // Init sliders and popup + this.sliderHandler.bind(); + this.popupHandler.bind(); + + // Inject into the DOM (this may make it visible) + this.pickerHandler.attach(); + + // Update all components + this.update(); + + if (this.inputHandler.isDisabled()) { + this.disable(); + } + } + + /** + * Initializes the plugin extensions + * @private + */ + + }, { + key: 'initExtensions', + value: function initExtensions() { + var _this = this; + + if (!Array.isArray(this.options.extensions)) { + this.options.extensions = []; + } + + if (this.options.debug) { + this.options.extensions.push({ name: 'debugger' }); + } + + // Register and instantiate extensions + this.options.extensions.forEach(function (ext) { + _this.registerExtension(Colorpicker.extensions[ext.name.toLowerCase()], ext.options || {}); + }); + } + + /** + * Creates and registers the given extension + * + * @param {Extension} ExtensionClass The extension class to instantiate + * @param {Object} [config] Extension configuration + * @returns {Extension} + */ + + }, { + key: 'registerExtension', + value: function registerExtension(ExtensionClass) { + var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + var ext = new ExtensionClass(this, config); + + this.extensions.push(ext); + return ext; + } + + /** + * Destroys the current instance + * + * @fires Colorpicker#colorpickerDestroy + */ + + }, { + key: 'destroy', + value: function destroy() { + var color = this.color; + + this.sliderHandler.unbind(); + this.inputHandler.unbind(); + this.popupHandler.unbind(); + this.colorHandler.unbind(); + this.addonHandler.unbind(); + this.pickerHandler.unbind(); + + this.element.removeClass('colorpicker-element').removeData('colorpicker', 'color').off('.colorpicker'); + + /** + * (Colorpicker) When the instance is destroyed with all events unbound. + * + * @event Colorpicker#colorpickerDestroy + */ + this.trigger('colorpickerDestroy', color); + } + + /** + * Shows the colorpicker widget if hidden. + * If the colorpicker is disabled this call will be ignored. + * + * @fires Colorpicker#colorpickerShow + * @param {Event} [e] + */ + + }, { + key: 'show', + value: function show(e) { + this.popupHandler.show(e); + } + + /** + * Hides the colorpicker widget. + * + * @fires Colorpicker#colorpickerHide + * @param {Event} [e] + */ + + }, { + key: 'hide', + value: function hide(e) { + this.popupHandler.hide(e); + } + + /** + * Toggles the colorpicker between visible and hidden. + * + * @fires Colorpicker#colorpickerShow + * @fires Colorpicker#colorpickerHide + * @param {Event} [e] + */ + + }, { + key: 'toggle', + value: function toggle(e) { + this.popupHandler.toggle(e); + } + + /** + * Returns the current color value as string + * + * @param {String|*} [defaultValue] + * @returns {String|*} + */ + + }, { + key: 'getValue', + value: function getValue() { + var defaultValue = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + + var val = this.colorHandler.color; + + val = val instanceof _ColorItem2.default ? val : defaultValue; + + if (val instanceof _ColorItem2.default) { + return val.string(this.format); + } + + return val; + } + + /** + * Sets the color manually + * + * @fires Colorpicker#colorpickerChange + * @param {String|Color} val + */ + + }, { + key: 'setValue', + value: function setValue(val) { + if (this.isDisabled()) { + return; + } + var ch = this.colorHandler; + + if (ch.hasColor() && !!val && ch.color.equals(val) || !ch.hasColor() && !val) { + // same color or still empty + return; + } + + ch.color = val ? ch.createColor(val, this.options.autoInputFallback) : null; + + /** + * (Colorpicker) When the color is set programmatically with setValue(). + * + * @event Colorpicker#colorpickerChange + */ + this.trigger('colorpickerChange', ch.color, val); + + // force update if color has changed to empty + this.update(); + } + + /** + * Updates the UI and the input color according to the internal color. + * + * @fires Colorpicker#colorpickerUpdate + */ + + }, { + key: 'update', + value: function update() { + if (this.colorHandler.hasColor()) { + this.inputHandler.update(); + } else { + this.colorHandler.assureColor(); + } + + this.addonHandler.update(); + this.pickerHandler.update(); + + /** + * (Colorpicker) Fired when the widget is updated. + * + * @event Colorpicker#colorpickerUpdate + */ + this.trigger('colorpickerUpdate'); + } + + /** + * Enables the widget and the input if any + * + * @fires Colorpicker#colorpickerEnable + * @returns {boolean} + */ + + }, { + key: 'enable', + value: function enable() { + this.inputHandler.enable(); + this.disabled = false; + this.picker.removeClass('colorpicker-disabled'); + + /** + * (Colorpicker) When the widget has been enabled. + * + * @event Colorpicker#colorpickerEnable + */ + this.trigger('colorpickerEnable'); + return true; + } + + /** + * Disables the widget and the input if any + * + * @fires Colorpicker#colorpickerDisable + * @returns {boolean} + */ + + }, { + key: 'disable', + value: function disable() { + this.inputHandler.disable(); + this.disabled = true; + this.picker.addClass('colorpicker-disabled'); + + /** + * (Colorpicker) When the widget has been disabled. + * + * @event Colorpicker#colorpickerDisable + */ + this.trigger('colorpickerDisable'); + return true; + } + + /** + * Returns true if this instance is enabled + * @returns {boolean} + */ + + }, { + key: 'isEnabled', + value: function isEnabled() { + return !this.isDisabled(); + } + + /** + * Returns true if this instance is disabled + * @returns {boolean} + */ + + }, { + key: 'isDisabled', + value: function isDisabled() { + return this.disabled === true; + } + + /** + * Triggers a Colorpicker event. + * + * @param eventName + * @param color + * @param value + */ + + }, { + key: 'trigger', + value: function trigger(eventName) { + var color = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; + var value = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; + + this.element.trigger({ + type: eventName, + colorpicker: this, + color: color ? color : this.color, + value: value ? value : this.getValue() + }); + } + }]); + + return Colorpicker; +}(); + +/** + * Colorpicker extension classes, indexed by extension name + * + * @static + * @type {Object} a map between the extension name and its class + */ + + +Colorpicker.extensions = _extensions2.default; + +exports.default = Colorpicker; + +/***/ }), +/* 9 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.Palette = exports.Swatches = exports.Preview = exports.Debugger = undefined; + +var _Debugger = __webpack_require__(10); + +var _Debugger2 = _interopRequireDefault(_Debugger); + +var _Preview = __webpack_require__(11); + +var _Preview2 = _interopRequireDefault(_Preview); + +var _Swatches = __webpack_require__(12); + +var _Swatches2 = _interopRequireDefault(_Swatches); + +var _Palette = __webpack_require__(4); + +var _Palette2 = _interopRequireDefault(_Palette); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +exports.Debugger = _Debugger2.default; +exports.Preview = _Preview2.default; +exports.Swatches = _Swatches2.default; +exports.Palette = _Palette2.default; +exports.default = { + 'debugger': _Debugger2.default, + 'preview': _Preview2.default, + 'swatches': _Swatches2.default, + 'palette': _Palette2.default +}; + +/***/ }), +/* 10 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + +var _Extension2 = __webpack_require__(1); + +var _Extension3 = _interopRequireDefault(_Extension2); + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +/** + * Debugger extension class + * @alias DebuggerExtension + * @ignore + */ +var Debugger = function (_Extension) { + _inherits(Debugger, _Extension); + + function Debugger(colorpicker) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + _classCallCheck(this, Debugger); + + /** + * @type {number} + */ + var _this = _possibleConstructorReturn(this, (Debugger.__proto__ || Object.getPrototypeOf(Debugger)).call(this, colorpicker, options)); + + _this.eventCounter = 0; + if (_this.colorpicker.inputHandler.hasInput()) { + _this.colorpicker.inputHandler.input.on('change.colorpicker-ext', _jquery2.default.proxy(_this.onChangeInput, _this)); + } + return _this; + } + + /** + * @fires DebuggerExtension#colorpickerDebug + * @param {string} eventName + * @param {*} args + */ + + + _createClass(Debugger, [{ + key: 'log', + value: function log(eventName) { + var _console; + + for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + + this.eventCounter += 1; + + var logMessage = '#' + this.eventCounter + ': Colorpicker#' + this.colorpicker.id + ' [' + eventName + ']'; + + (_console = console).debug.apply(_console, [logMessage].concat(args)); + + /** + * Whenever the debugger logs an event, this other event is emitted. + * + * @event DebuggerExtension#colorpickerDebug + * @type {object} The event object + * @property {Colorpicker} colorpicker The Colorpicker instance + * @property {ColorItem} color The color instance + * @property {{debugger: DebuggerExtension, eventName: String, logArgs: Array, logMessage: String}} debug + * The debug info + */ + this.colorpicker.element.trigger({ + type: 'colorpickerDebug', + colorpicker: this.colorpicker, + color: this.color, + value: null, + debug: { + debugger: this, + eventName: eventName, + logArgs: args, + logMessage: logMessage + } + }); + } + }, { + key: 'resolveColor', + value: function resolveColor(color) { + var realColor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + + this.log('resolveColor()', color, realColor); + return false; + } + }, { + key: 'onCreate', + value: function onCreate(event) { + this.log('colorpickerCreate'); + return _get(Debugger.prototype.__proto__ || Object.getPrototypeOf(Debugger.prototype), 'onCreate', this).call(this, event); + } + }, { + key: 'onDestroy', + value: function onDestroy(event) { + this.log('colorpickerDestroy'); + this.eventCounter = 0; + + if (this.colorpicker.inputHandler.hasInput()) { + this.colorpicker.inputHandler.input.off('.colorpicker-ext'); + } + + return _get(Debugger.prototype.__proto__ || Object.getPrototypeOf(Debugger.prototype), 'onDestroy', this).call(this, event); + } + }, { + key: 'onUpdate', + value: function onUpdate(event) { + this.log('colorpickerUpdate'); + } + + /** + * @listens Colorpicker#change + * @param {Event} event + */ + + }, { + key: 'onChangeInput', + value: function onChangeInput(event) { + this.log('input:change.colorpicker', event.value, event.color); + } + }, { + key: 'onChange', + value: function onChange(event) { + this.log('colorpickerChange', event.value, event.color); + } + }, { + key: 'onInvalid', + value: function onInvalid(event) { + this.log('colorpickerInvalid', event.value, event.color); + } + }, { + key: 'onHide', + value: function onHide(event) { + this.log('colorpickerHide'); + this.eventCounter = 0; + } + }, { + key: 'onShow', + value: function onShow(event) { + this.log('colorpickerShow'); + } + }, { + key: 'onDisable', + value: function onDisable(event) { + this.log('colorpickerDisable'); + } + }, { + key: 'onEnable', + value: function onEnable(event) { + this.log('colorpickerEnable'); + } + }]); + + return Debugger; +}(_Extension3.default); + +exports.default = Debugger; + +/***/ }), +/* 11 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + +var _Extension2 = __webpack_require__(1); + +var _Extension3 = _interopRequireDefault(_Extension2); + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +/** + * Color preview extension + * @ignore + */ +var Preview = function (_Extension) { + _inherits(Preview, _Extension); + + function Preview(colorpicker) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + _classCallCheck(this, Preview); + + var _this = _possibleConstructorReturn(this, (Preview.__proto__ || Object.getPrototypeOf(Preview)).call(this, colorpicker, _jquery2.default.extend(true, {}, { + template: '
', + showText: true, + format: colorpicker.format + }, options))); + + _this.element = (0, _jquery2.default)(_this.options.template); + _this.elementInner = _this.element.find('div'); + return _this; + } + + _createClass(Preview, [{ + key: 'onCreate', + value: function onCreate(event) { + _get(Preview.prototype.__proto__ || Object.getPrototypeOf(Preview.prototype), 'onCreate', this).call(this, event); + this.colorpicker.picker.append(this.element); + } + }, { + key: 'onUpdate', + value: function onUpdate(event) { + _get(Preview.prototype.__proto__ || Object.getPrototypeOf(Preview.prototype), 'onUpdate', this).call(this, event); + + if (!event.color) { + this.elementInner.css('backgroundColor', null).css('color', null).html(''); + return; + } + + this.elementInner.css('backgroundColor', event.color.toRgbString()); + + if (this.options.showText) { + this.elementInner.html(event.color.string(this.options.format || this.colorpicker.format)); + + if (event.color.isDark() && event.color.alpha > 0.5) { + this.elementInner.css('color', 'white'); + } else { + this.elementInner.css('color', 'black'); + } + } + } + }]); + + return Preview; +}(_Extension3.default); + +exports.default = Preview; + +/***/ }), +/* 12 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; + +var _Palette2 = __webpack_require__(4); + +var _Palette3 = _interopRequireDefault(_Palette2); + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var defaults = { + barTemplate: '
\n
\n
', + swatchTemplate: '' +}; + +/** + * Color swatches extension + * @ignore + */ + +var Swatches = function (_Palette) { + _inherits(Swatches, _Palette); + + function Swatches(colorpicker) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + _classCallCheck(this, Swatches); + + var _this = _possibleConstructorReturn(this, (Swatches.__proto__ || Object.getPrototypeOf(Swatches)).call(this, colorpicker, _jquery2.default.extend(true, {}, defaults, options))); + + _this.element = null; + return _this; + } + + _createClass(Swatches, [{ + key: 'isEnabled', + value: function isEnabled() { + return this.getLength() > 0; + } + }, { + key: 'onCreate', + value: function onCreate(event) { + _get(Swatches.prototype.__proto__ || Object.getPrototypeOf(Swatches.prototype), 'onCreate', this).call(this, event); + + if (!this.isEnabled()) { + return; + } + + this.element = (0, _jquery2.default)(this.options.barTemplate); + this.load(); + this.colorpicker.picker.append(this.element); + } + }, { + key: 'load', + value: function load() { + var _this2 = this; + + var colorpicker = this.colorpicker, + swatchContainer = this.element.find('.colorpicker-swatches--inner'), + isAliased = this.options.namesAsValues === true && !Array.isArray(this.colors); + + swatchContainer.empty(); + + _jquery2.default.each(this.colors, function (name, value) { + var $swatch = (0, _jquery2.default)(_this2.options.swatchTemplate).attr('data-name', name).attr('data-value', value).attr('title', isAliased ? name + ': ' + value : value).on('mousedown.colorpicker touchstart.colorpicker', function (e) { + var $sw = (0, _jquery2.default)(this); + + // e.preventDefault(); + + colorpicker.setValue(isAliased ? $sw.attr('data-name') : $sw.attr('data-value')); + }); + + $swatch.find('.colorpicker-swatch--inner').css('background-color', value); + + swatchContainer.append($swatch); + }); + + swatchContainer.append((0, _jquery2.default)('')); + } + }]); + + return Swatches; +}(_Palette3.default); + +exports.default = Swatches; + +/***/ }), +/* 13 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +/** + * Class that handles all configured sliders on mouse or touch events. + * @ignore + */ +var SliderHandler = function () { + /** + * @param {Colorpicker} colorpicker + */ + function SliderHandler(colorpicker) { + _classCallCheck(this, SliderHandler); + + /** + * @type {Colorpicker} + */ + this.colorpicker = colorpicker; + /** + * @type {*|String} + * @private + */ + this.currentSlider = null; + /** + * @type {{left: number, top: number}} + * @private + */ + this.mousePointer = { + left: 0, + top: 0 + }; + + /** + * @type {Function} + */ + this.onMove = _jquery2.default.proxy(this.defaultOnMove, this); + } + + /** + * This function is called every time a slider guide is moved + * The scope of "this" is the SliderHandler object. + * + * @param {int} top + * @param {int} left + */ + + + _createClass(SliderHandler, [{ + key: 'defaultOnMove', + value: function defaultOnMove(top, left) { + if (!this.currentSlider) { + return; + } + + var slider = this.currentSlider, + cp = this.colorpicker, + ch = cp.colorHandler; + + // Create a color object + var color = !ch.hasColor() ? ch.getFallbackColor() : ch.color.getClone(); + + // Adjust the guide position + slider.guideStyle.left = left + 'px'; + slider.guideStyle.top = top + 'px'; + + // Adjust the color + if (slider.callLeft) { + color[slider.callLeft](left / slider.maxLeft); + } + if (slider.callTop) { + color[slider.callTop](top / slider.maxTop); + } + + // Set the new color + cp.setValue(color); + cp.popupHandler.focus(); + } + + /** + * Binds the colorpicker sliders to the mouse/touch events + */ + + }, { + key: 'bind', + value: function bind() { + var sliders = this.colorpicker.options.horizontal ? this.colorpicker.options.slidersHorz : this.colorpicker.options.sliders; + var sliderClasses = []; + + for (var sliderName in sliders) { + if (!sliders.hasOwnProperty(sliderName)) { + continue; + } + + sliderClasses.push(sliders[sliderName].selector); + } + + this.colorpicker.picker.find(sliderClasses.join(', ')).on('mousedown.colorpicker touchstart.colorpicker', _jquery2.default.proxy(this.pressed, this)); + } + + /** + * Unbinds any event bound by this handler + */ + + }, { + key: 'unbind', + value: function unbind() { + (0, _jquery2.default)(this.colorpicker.picker).off({ + 'mousemove.colorpicker': _jquery2.default.proxy(this.moved, this), + 'touchmove.colorpicker': _jquery2.default.proxy(this.moved, this), + 'mouseup.colorpicker': _jquery2.default.proxy(this.released, this), + 'touchend.colorpicker': _jquery2.default.proxy(this.released, this) + }); + } + + /** + * Function triggered when clicking in one of the color adjustment bars + * + * @private + * @fires Colorpicker#mousemove + * @param {Event} e + */ + + }, { + key: 'pressed', + value: function pressed(e) { + if (this.colorpicker.isDisabled()) { + return; + } + this.colorpicker.lastEvent.alias = 'pressed'; + this.colorpicker.lastEvent.e = e; + + if (!e.pageX && !e.pageY && e.originalEvent && e.originalEvent.touches) { + e.pageX = e.originalEvent.touches[0].pageX; + e.pageY = e.originalEvent.touches[0].pageY; + } + // e.stopPropagation(); + // e.preventDefault(); + + var target = (0, _jquery2.default)(e.target); + + // detect the slider and set the limits and callbacks + var zone = target.closest('div'); + var sliders = this.colorpicker.options.horizontal ? this.colorpicker.options.slidersHorz : this.colorpicker.options.sliders; + + if (zone.is('.colorpicker')) { + return; + } + + this.currentSlider = null; + + for (var sliderName in sliders) { + if (!sliders.hasOwnProperty(sliderName)) { + continue; + } + + var slider = sliders[sliderName]; + + if (zone.is(slider.selector)) { + this.currentSlider = _jquery2.default.extend({}, slider, { name: sliderName }); + break; + } else if (slider.childSelector !== undefined && zone.is(slider.childSelector)) { + this.currentSlider = _jquery2.default.extend({}, slider, { name: sliderName }); + zone = zone.parent(); // zone.parents(slider.selector).first() ? + break; + } + } + + var guide = zone.find('.colorpicker-guide').get(0); + + if (this.currentSlider === null || guide === null) { + return; + } + + var offset = zone.offset(); + + // reference to guide's style + this.currentSlider.guideStyle = guide.style; + this.currentSlider.left = e.pageX - offset.left; + this.currentSlider.top = e.pageY - offset.top; + this.mousePointer = { + left: e.pageX, + top: e.pageY + }; + + // TODO: fix moving outside the picker makes the guides to keep moving. The event needs to be bound to the window. + /** + * (window.document) Triggered on mousedown for the document object, + * so the color adjustment guide is moved to the clicked position. + * + * @event Colorpicker#mousemove + */ + (0, _jquery2.default)(this.colorpicker.picker).on({ + 'mousemove.colorpicker': _jquery2.default.proxy(this.moved, this), + 'touchmove.colorpicker': _jquery2.default.proxy(this.moved, this), + 'mouseup.colorpicker': _jquery2.default.proxy(this.released, this), + 'touchend.colorpicker': _jquery2.default.proxy(this.released, this) + }).trigger('mousemove'); + } + + /** + * Function triggered when dragging a guide inside one of the color adjustment bars. + * + * @private + * @param {Event} e + */ + + }, { + key: 'moved', + value: function moved(e) { + this.colorpicker.lastEvent.alias = 'moved'; + this.colorpicker.lastEvent.e = e; + + if (!e.pageX && !e.pageY && e.originalEvent && e.originalEvent.touches) { + e.pageX = e.originalEvent.touches[0].pageX; + e.pageY = e.originalEvent.touches[0].pageY; + } + + // e.stopPropagation(); + e.preventDefault(); // prevents scrolling on mobile + + var left = Math.max(0, Math.min(this.currentSlider.maxLeft, this.currentSlider.left + ((e.pageX || this.mousePointer.left) - this.mousePointer.left))); + + var top = Math.max(0, Math.min(this.currentSlider.maxTop, this.currentSlider.top + ((e.pageY || this.mousePointer.top) - this.mousePointer.top))); + + this.onMove(top, left); + } + + /** + * Function triggered when releasing the click in one of the color adjustment bars. + * + * @private + * @param {Event} e + */ + + }, { + key: 'released', + value: function released(e) { + this.colorpicker.lastEvent.alias = 'released'; + this.colorpicker.lastEvent.e = e; + + // e.stopPropagation(); + // e.preventDefault(); + + (0, _jquery2.default)(this.colorpicker.picker).off({ + 'mousemove.colorpicker': this.moved, + 'touchmove.colorpicker': this.moved, + 'mouseup.colorpicker': this.released, + 'touchend.colorpicker': this.released + }); + } + }]); + + return SliderHandler; +}(); + +exports.default = SliderHandler; + +/***/ }), +/* 14 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _options = __webpack_require__(3); + +var _options2 = _interopRequireDefault(_options); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +/** + * Handles everything related to the UI of the colorpicker popup: show, hide, position,... + * @ignore + */ +var PopupHandler = function () { + /** + * @param {Colorpicker} colorpicker + * @param {Window} root + */ + function PopupHandler(colorpicker, root) { + _classCallCheck(this, PopupHandler); + + /** + * @type {Window} + */ + this.root = root; + /** + * @type {Colorpicker} + */ + this.colorpicker = colorpicker; + /** + * @type {jQuery} + */ + this.popoverTarget = null; + /** + * @type {jQuery} + */ + this.popoverTip = null; + + /** + * If true, the latest click was inside the popover + * @type {boolean} + */ + this.clicking = false; + /** + * @type {boolean} + */ + this.hidding = false; + /** + * @type {boolean} + */ + this.showing = false; + } + + /** + * @private + * @returns {jQuery|false} + */ + + + _createClass(PopupHandler, [{ + key: 'bind', + + + /** + * Binds the different colorpicker elements to the focus/mouse/touch events so it reacts in order to show or + * hide the colorpicker popup accordingly. It also adds the proper classes. + */ + value: function bind() { + var cp = this.colorpicker; + + if (cp.options.inline) { + cp.picker.addClass('colorpicker-inline colorpicker-visible'); + return; // no need to bind show/hide events for inline elements + } + + cp.picker.addClass('colorpicker-popup colorpicker-hidden'); + + // there is no input or addon + if (!this.hasInput && !this.hasAddon) { + return; + } + + // create Bootstrap 4 popover + if (cp.options.popover) { + this.createPopover(); + } + + // bind addon show/hide events + if (this.hasAddon) { + // enable focus on addons + if (!this.addon.attr('tabindex')) { + this.addon.attr('tabindex', 0); + } + + this.addon.on({ + 'mousedown.colorpicker touchstart.colorpicker': _jquery2.default.proxy(this.toggle, this) + }); + + this.addon.on({ + 'focus.colorpicker': _jquery2.default.proxy(this.show, this) + }); + + this.addon.on({ + 'focusout.colorpicker': _jquery2.default.proxy(this.hide, this) + }); + } + + // bind input show/hide events + if (this.hasInput && !this.hasAddon) { + this.input.on({ + 'mousedown.colorpicker touchstart.colorpicker': _jquery2.default.proxy(this.show, this), + 'focus.colorpicker': _jquery2.default.proxy(this.show, this) + }); + + this.input.on({ + 'focusout.colorpicker': _jquery2.default.proxy(this.hide, this) + }); + } + + // reposition popup on window resize + (0, _jquery2.default)(this.root).on('resize.colorpicker', _jquery2.default.proxy(this.reposition, this)); + } + + /** + * Unbinds any event bound by this handler + */ + + }, { + key: 'unbind', + value: function unbind() { + if (this.hasInput) { + this.input.off({ + 'mousedown.colorpicker touchstart.colorpicker': _jquery2.default.proxy(this.show, this), + 'focus.colorpicker': _jquery2.default.proxy(this.show, this) + }); + this.input.off({ + 'focusout.colorpicker': _jquery2.default.proxy(this.hide, this) + }); + } + + if (this.hasAddon) { + this.addon.off({ + 'mousedown.colorpicker touchstart.colorpicker': _jquery2.default.proxy(this.toggle, this) + }); + this.addon.off({ + 'focus.colorpicker': _jquery2.default.proxy(this.show, this) + }); + this.addon.off({ + 'focusout.colorpicker': _jquery2.default.proxy(this.hide, this) + }); + } + + if (this.popoverTarget) { + this.popoverTarget.popover('dispose'); + } + + (0, _jquery2.default)(this.root).off('resize.colorpicker', _jquery2.default.proxy(this.reposition, this)); + (0, _jquery2.default)(this.root.document).off('mousedown.colorpicker touchstart.colorpicker', _jquery2.default.proxy(this.hide, this)); + (0, _jquery2.default)(this.root.document).off('mousedown.colorpicker touchstart.colorpicker', _jquery2.default.proxy(this.onClickingInside, this)); + } + }, { + key: 'isClickingInside', + value: function isClickingInside(e) { + if (!e) { + return false; + } + + return this.isOrIsInside(this.popoverTip, e.currentTarget) || this.isOrIsInside(this.popoverTip, e.target) || this.isOrIsInside(this.colorpicker.picker, e.currentTarget) || this.isOrIsInside(this.colorpicker.picker, e.target); + } + }, { + key: 'isOrIsInside', + value: function isOrIsInside(container, element) { + if (!container || !element) { + return false; + } + + element = (0, _jquery2.default)(element); + + return element.is(container) || container.find(element).length > 0; + } + }, { + key: 'onClickingInside', + value: function onClickingInside(e) { + this.clicking = this.isClickingInside(e); + } + }, { + key: 'createPopover', + value: function createPopover() { + var cp = this.colorpicker; + + this.popoverTarget = this.hasAddon ? this.addon : this.input; + + cp.picker.addClass('colorpicker-bs-popover-content'); + + this.popoverTarget.popover(_jquery2.default.extend(true, {}, _options2.default.popover, cp.options.popover, { trigger: 'manual', content: cp.picker, html: true })); + + this.popoverTip = (0, _jquery2.default)(this.popoverTarget.popover('getTipElement').data('bs.popover').tip); + this.popoverTip.addClass('colorpicker-bs-popover'); + + this.popoverTarget.on('shown.bs.popover', _jquery2.default.proxy(this.fireShow, this)); + this.popoverTarget.on('hidden.bs.popover', _jquery2.default.proxy(this.fireHide, this)); + } + + /** + * If the widget is not inside a container or inline, rearranges its position relative to its element offset. + * + * @param {Event} [e] + * @private + */ + + }, { + key: 'reposition', + value: function reposition(e) { + if (this.popoverTarget && this.isVisible()) { + this.popoverTarget.popover('update'); + } + } + + /** + * Toggles the colorpicker between visible or hidden + * + * @fires Colorpicker#colorpickerShow + * @fires Colorpicker#colorpickerHide + * @param {Event} [e] + */ + + }, { + key: 'toggle', + value: function toggle(e) { + if (this.isVisible()) { + this.hide(e); + } else { + this.show(e); + } + } + + /** + * Shows the colorpicker widget if hidden. + * + * @fires Colorpicker#colorpickerShow + * @param {Event} [e] + */ + + }, { + key: 'show', + value: function show(e) { + if (this.isVisible() || this.showing || this.hidding) { + return; + } + + this.showing = true; + this.hidding = false; + this.clicking = false; + + var cp = this.colorpicker; + + cp.lastEvent.alias = 'show'; + cp.lastEvent.e = e; + + // Prevent showing browser native HTML5 colorpicker + if (e && (!this.hasInput || this.input.attr('type') === 'color') && e && e.preventDefault) { + e.stopPropagation(); + e.preventDefault(); + } + + // If it's a popover, add event to the document to hide the picker when clicking outside of it + if (this.isPopover) { + (0, _jquery2.default)(this.root).on('resize.colorpicker', _jquery2.default.proxy(this.reposition, this)); + } + + // add visible class before popover is shown + cp.picker.addClass('colorpicker-visible').removeClass('colorpicker-hidden'); + + if (this.popoverTarget) { + this.popoverTarget.popover('show'); + } else { + this.fireShow(); + } + } + }, { + key: 'fireShow', + value: function fireShow() { + this.hidding = false; + this.showing = false; + + if (this.isPopover) { + // Add event to hide on outside click + (0, _jquery2.default)(this.root.document).on('mousedown.colorpicker touchstart.colorpicker', _jquery2.default.proxy(this.hide, this)); + (0, _jquery2.default)(this.root.document).on('mousedown.colorpicker touchstart.colorpicker', _jquery2.default.proxy(this.onClickingInside, this)); + } + + /** + * (Colorpicker) When show() is called and the widget can be shown. + * + * @event Colorpicker#colorpickerShow + */ + this.colorpicker.trigger('colorpickerShow'); + } + + /** + * Hides the colorpicker widget. + * Hide is prevented when it is triggered by an event whose target element has been clicked/touched. + * + * @fires Colorpicker#colorpickerHide + * @param {Event} [e] + */ + + }, { + key: 'hide', + value: function hide(e) { + if (this.isHidden() || this.showing || this.hidding) { + return; + } + + var cp = this.colorpicker, + clicking = this.clicking || this.isClickingInside(e); + + this.hidding = true; + this.showing = false; + this.clicking = false; + + cp.lastEvent.alias = 'hide'; + cp.lastEvent.e = e; + + // TODO: fix having to click twice outside when losing focus and last 2 clicks where inside the colorpicker + + // Prevent hide if triggered by an event and an element inside the colorpicker has been clicked/touched + if (clicking) { + this.hidding = false; + return; + } + + if (this.popoverTarget) { + this.popoverTarget.popover('hide'); + } else { + this.fireHide(); + } + } + }, { + key: 'fireHide', + value: function fireHide() { + this.hidding = false; + this.showing = false; + + var cp = this.colorpicker; + + // add hidden class after popover is hidden + cp.picker.addClass('colorpicker-hidden').removeClass('colorpicker-visible'); + + // Unbind window and document events, since there is no need to keep them while the popup is hidden + (0, _jquery2.default)(this.root).off('resize.colorpicker', _jquery2.default.proxy(this.reposition, this)); + (0, _jquery2.default)(this.root.document).off('mousedown.colorpicker touchstart.colorpicker', _jquery2.default.proxy(this.hide, this)); + (0, _jquery2.default)(this.root.document).off('mousedown.colorpicker touchstart.colorpicker', _jquery2.default.proxy(this.onClickingInside, this)); + + /** + * (Colorpicker) When hide() is called and the widget can be hidden. + * + * @event Colorpicker#colorpickerHide + */ + cp.trigger('colorpickerHide'); + } + }, { + key: 'focus', + value: function focus() { + if (this.hasAddon) { + return this.addon.focus(); + } + if (this.hasInput) { + return this.input.focus(); + } + return false; + } + + /** + * Returns true if the colorpicker element has the colorpicker-visible class and not the colorpicker-hidden one. + * False otherwise. + * + * @returns {boolean} + */ + + }, { + key: 'isVisible', + value: function isVisible() { + return this.colorpicker.picker.hasClass('colorpicker-visible') && !this.colorpicker.picker.hasClass('colorpicker-hidden'); + } + + /** + * Returns true if the colorpicker element has the colorpicker-hidden class and not the colorpicker-visible one. + * False otherwise. + * + * @returns {boolean} + */ + + }, { + key: 'isHidden', + value: function isHidden() { + return this.colorpicker.picker.hasClass('colorpicker-hidden') && !this.colorpicker.picker.hasClass('colorpicker-visible'); + } + }, { + key: 'input', + get: function get() { + return this.colorpicker.inputHandler.input; + } + + /** + * @private + * @returns {boolean} + */ + + }, { + key: 'hasInput', + get: function get() { + return this.colorpicker.inputHandler.hasInput(); + } + + /** + * @private + * @returns {jQuery|false} + */ + + }, { + key: 'addon', + get: function get() { + return this.colorpicker.addonHandler.addon; + } + + /** + * @private + * @returns {boolean} + */ + + }, { + key: 'hasAddon', + get: function get() { + return this.colorpicker.addonHandler.hasAddon(); + } + + /** + * @private + * @returns {boolean} + */ + + }, { + key: 'isPopover', + get: function get() { + return !this.colorpicker.options.inline && !!this.popoverTip; + } + }]); + + return PopupHandler; +}(); + +exports.default = PopupHandler; + +/***/ }), +/* 15 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _ColorItem = __webpack_require__(2); + +var _ColorItem2 = _interopRequireDefault(_ColorItem); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +/** + * Handles everything related to the colorpicker input + * @ignore + */ +var InputHandler = function () { + /** + * @param {Colorpicker} colorpicker + */ + function InputHandler(colorpicker) { + _classCallCheck(this, InputHandler); + + /** + * @type {Colorpicker} + */ + this.colorpicker = colorpicker; + /** + * @type {jQuery|false} + */ + this.input = this.colorpicker.element.is('input') ? this.colorpicker.element : this.colorpicker.options.input ? this.colorpicker.element.find(this.colorpicker.options.input) : false; + + if (this.input && this.input.length === 0) { + this.input = false; + } + + this._initValue(); + } + + _createClass(InputHandler, [{ + key: 'bind', + value: function bind() { + if (!this.hasInput()) { + return; + } + this.input.on({ + 'keyup.colorpicker': _jquery2.default.proxy(this.onkeyup, this) + }); + this.input.on({ + 'change.colorpicker': _jquery2.default.proxy(this.onchange, this) + }); + } + }, { + key: 'unbind', + value: function unbind() { + if (!this.hasInput()) { + return; + } + this.input.off('.colorpicker'); + } + }, { + key: '_initValue', + value: function _initValue() { + if (!this.hasInput()) { + return; + } + + var val = ''; + + [ + // candidates: + this.input.val(), this.input.data('color'), this.input.attr('data-color')].map(function (item) { + if (item && val === '') { + val = item; + } + }); + + if (val instanceof _ColorItem2.default) { + val = this.getFormattedColor(val.string(this.colorpicker.format)); + } else if (!(typeof val === 'string' || val instanceof String)) { + val = ''; + } + + this.input.prop('value', val); + } + + /** + * Returns the color string from the input value. + * If there is no input the return value is false. + * + * @returns {String|boolean} + */ + + }, { + key: 'getValue', + value: function getValue() { + if (!this.hasInput()) { + return false; + } + + return this.input.val(); + } + + /** + * If the input element is present, it updates the value with the current color object color string. + * If the value is changed, this method fires a "change" event on the input element. + * + * @param {String} val + * + * @fires Colorpicker#change + */ + + }, { + key: 'setValue', + value: function setValue(val) { + if (!this.hasInput()) { + return; + } + + var inputVal = this.input.prop('value'); + + val = val ? val : ''; + + if (val === (inputVal ? inputVal : '')) { + // No need to set value or trigger any event if nothing changed + return; + } + + this.input.prop('value', val); + + /** + * (Input) Triggered on the input element when a new color is selected. + * + * @event Colorpicker#change + */ + this.input.trigger({ + type: 'change', + colorpicker: this.colorpicker, + color: this.colorpicker.color, + value: val + }); + } + + /** + * Returns the formatted color string, with the formatting options applied + * (e.g. useHashPrefix) + * + * @param {String|null} val + * + * @returns {String} + */ + + }, { + key: 'getFormattedColor', + value: function getFormattedColor() { + var val = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + + val = val ? val : this.colorpicker.colorHandler.getColorString(); + + if (!val) { + return ''; + } + + val = this.colorpicker.colorHandler.resolveColorDelegate(val, false); + + if (this.colorpicker.options.useHashPrefix === false) { + val = val.replace(/^#/g, ''); + } + + return val; + } + + /** + * Returns true if the widget has an associated input element, false otherwise + * @returns {boolean} + */ + + }, { + key: 'hasInput', + value: function hasInput() { + return this.input !== false; + } + + /** + * Returns true if the input exists and is disabled + * @returns {boolean} + */ + + }, { + key: 'isEnabled', + value: function isEnabled() { + return this.hasInput() && !this.isDisabled(); + } + + /** + * Returns true if the input exists and is disabled + * @returns {boolean} + */ + + }, { + key: 'isDisabled', + value: function isDisabled() { + return this.hasInput() && this.input.prop('disabled') === true; + } + + /** + * Disables the input if any + * + * @fires Colorpicker#colorpickerDisable + * @returns {boolean} + */ + + }, { + key: 'disable', + value: function disable() { + if (this.hasInput()) { + this.input.prop('disabled', true); + } + } + + /** + * Enables the input if any + * + * @fires Colorpicker#colorpickerEnable + * @returns {boolean} + */ + + }, { + key: 'enable', + value: function enable() { + if (this.hasInput()) { + this.input.prop('disabled', false); + } + } + + /** + * Calls setValue with the current internal color value + * + * @fires Colorpicker#change + */ + + }, { + key: 'update', + value: function update() { + if (!this.hasInput()) { + return; + } + + if (this.colorpicker.options.autoInputFallback === false && this.colorpicker.colorHandler.isInvalidColor()) { + // prevent update if color is invalid, autoInputFallback is disabled and the last event is keyup. + return; + } + + this.setValue(this.getFormattedColor()); + } + + /** + * Function triggered when the input has changed, so the colorpicker gets updated. + * + * @private + * @param {Event} e + * @returns {boolean} + */ + + }, { + key: 'onchange', + value: function onchange(e) { + this.colorpicker.lastEvent.alias = 'input.change'; + this.colorpicker.lastEvent.e = e; + + var val = this.getValue(); + + if (val !== e.value) { + this.colorpicker.setValue(val); + } + } + + /** + * Function triggered after a keyboard key has been released. + * + * @private + * @param {Event} e + * @returns {boolean} + */ + + }, { + key: 'onkeyup', + value: function onkeyup(e) { + this.colorpicker.lastEvent.alias = 'input.keyup'; + this.colorpicker.lastEvent.e = e; + + var val = this.getValue(); + + if (val !== e.value) { + this.colorpicker.setValue(val); + } + } + }]); + + return InputHandler; +}(); + +exports.default = InputHandler; + +/***/ }), +/* 16 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var colorString = __webpack_require__(17); +var convert = __webpack_require__(20); + +var _slice = [].slice; + +var skippedModels = [ + // to be honest, I don't really feel like keyword belongs in color convert, but eh. + 'keyword', + + // gray conflicts with some method names, and has its own method defined. + 'gray', + + // shouldn't really be in color-convert either... + 'hex' +]; + +var hashedModelKeys = {}; +Object.keys(convert).forEach(function (model) { + hashedModelKeys[_slice.call(convert[model].labels).sort().join('')] = model; +}); + +var limiters = {}; + +function Color(obj, model) { + if (!(this instanceof Color)) { + return new Color(obj, model); + } + + if (model && model in skippedModels) { + model = null; + } + + if (model && !(model in convert)) { + throw new Error('Unknown model: ' + model); + } + + var i; + var channels; + + if (typeof obj === 'undefined') { + this.model = 'rgb'; + this.color = [0, 0, 0]; + this.valpha = 1; + } else if (obj instanceof Color) { + this.model = obj.model; + this.color = obj.color.slice(); + this.valpha = obj.valpha; + } else if (typeof obj === 'string') { + var result = colorString.get(obj); + if (result === null) { + throw new Error('Unable to parse color from string: ' + obj); + } + + this.model = result.model; + channels = convert[this.model].channels; + this.color = result.value.slice(0, channels); + this.valpha = typeof result.value[channels] === 'number' ? result.value[channels] : 1; + } else if (obj.length) { + this.model = model || 'rgb'; + channels = convert[this.model].channels; + var newArr = _slice.call(obj, 0, channels); + this.color = zeroArray(newArr, channels); + this.valpha = typeof obj[channels] === 'number' ? obj[channels] : 1; + } else if (typeof obj === 'number') { + // this is always RGB - can be converted later on. + obj &= 0xFFFFFF; + this.model = 'rgb'; + this.color = [ + (obj >> 16) & 0xFF, + (obj >> 8) & 0xFF, + obj & 0xFF + ]; + this.valpha = 1; + } else { + this.valpha = 1; + + var keys = Object.keys(obj); + if ('alpha' in obj) { + keys.splice(keys.indexOf('alpha'), 1); + this.valpha = typeof obj.alpha === 'number' ? obj.alpha : 0; + } + + var hashedKeys = keys.sort().join(''); + if (!(hashedKeys in hashedModelKeys)) { + throw new Error('Unable to parse color from object: ' + JSON.stringify(obj)); + } + + this.model = hashedModelKeys[hashedKeys]; + + var labels = convert[this.model].labels; + var color = []; + for (i = 0; i < labels.length; i++) { + color.push(obj[labels[i]]); + } + + this.color = zeroArray(color); + } + + // perform limitations (clamping, etc.) + if (limiters[this.model]) { + channels = convert[this.model].channels; + for (i = 0; i < channels; i++) { + var limit = limiters[this.model][i]; + if (limit) { + this.color[i] = limit(this.color[i]); + } + } + } + + this.valpha = Math.max(0, Math.min(1, this.valpha)); + + if (Object.freeze) { + Object.freeze(this); + } +} + +Color.prototype = { + toString: function () { + return this.string(); + }, + + toJSON: function () { + return this[this.model](); + }, + + string: function (places) { + var self = this.model in colorString.to ? this : this.rgb(); + self = self.round(typeof places === 'number' ? places : 1); + var args = self.valpha === 1 ? self.color : self.color.concat(this.valpha); + return colorString.to[self.model](args); + }, + + percentString: function (places) { + var self = this.rgb().round(typeof places === 'number' ? places : 1); + var args = self.valpha === 1 ? self.color : self.color.concat(this.valpha); + return colorString.to.rgb.percent(args); + }, + + array: function () { + return this.valpha === 1 ? this.color.slice() : this.color.concat(this.valpha); + }, + + object: function () { + var result = {}; + var channels = convert[this.model].channels; + var labels = convert[this.model].labels; + + for (var i = 0; i < channels; i++) { + result[labels[i]] = this.color[i]; + } + + if (this.valpha !== 1) { + result.alpha = this.valpha; + } + + return result; + }, + + unitArray: function () { + var rgb = this.rgb().color; + rgb[0] /= 255; + rgb[1] /= 255; + rgb[2] /= 255; + + if (this.valpha !== 1) { + rgb.push(this.valpha); + } + + return rgb; + }, + + unitObject: function () { + var rgb = this.rgb().object(); + rgb.r /= 255; + rgb.g /= 255; + rgb.b /= 255; + + if (this.valpha !== 1) { + rgb.alpha = this.valpha; + } + + return rgb; + }, + + round: function (places) { + places = Math.max(places || 0, 0); + return new Color(this.color.map(roundToPlace(places)).concat(this.valpha), this.model); + }, + + alpha: function (val) { + if (arguments.length) { + return new Color(this.color.concat(Math.max(0, Math.min(1, val))), this.model); + } + + return this.valpha; + }, + + // rgb + red: getset('rgb', 0, maxfn(255)), + green: getset('rgb', 1, maxfn(255)), + blue: getset('rgb', 2, maxfn(255)), + + hue: getset(['hsl', 'hsv', 'hsl', 'hwb', 'hcg'], 0, function (val) { return ((val % 360) + 360) % 360; }), // eslint-disable-line brace-style + + saturationl: getset('hsl', 1, maxfn(100)), + lightness: getset('hsl', 2, maxfn(100)), + + saturationv: getset('hsv', 1, maxfn(100)), + value: getset('hsv', 2, maxfn(100)), + + chroma: getset('hcg', 1, maxfn(100)), + gray: getset('hcg', 2, maxfn(100)), + + white: getset('hwb', 1, maxfn(100)), + wblack: getset('hwb', 2, maxfn(100)), + + cyan: getset('cmyk', 0, maxfn(100)), + magenta: getset('cmyk', 1, maxfn(100)), + yellow: getset('cmyk', 2, maxfn(100)), + black: getset('cmyk', 3, maxfn(100)), + + x: getset('xyz', 0, maxfn(100)), + y: getset('xyz', 1, maxfn(100)), + z: getset('xyz', 2, maxfn(100)), + + l: getset('lab', 0, maxfn(100)), + a: getset('lab', 1), + b: getset('lab', 2), + + keyword: function (val) { + if (arguments.length) { + return new Color(val); + } + + return convert[this.model].keyword(this.color); + }, + + hex: function (val) { + if (arguments.length) { + return new Color(val); + } + + return colorString.to.hex(this.rgb().round().color); + }, + + rgbNumber: function () { + var rgb = this.rgb().color; + return ((rgb[0] & 0xFF) << 16) | ((rgb[1] & 0xFF) << 8) | (rgb[2] & 0xFF); + }, + + luminosity: function () { + // http://www.w3.org/TR/WCAG20/#relativeluminancedef + var rgb = this.rgb().color; + + var lum = []; + for (var i = 0; i < rgb.length; i++) { + var chan = rgb[i] / 255; + lum[i] = (chan <= 0.03928) ? chan / 12.92 : Math.pow(((chan + 0.055) / 1.055), 2.4); + } + + return 0.2126 * lum[0] + 0.7152 * lum[1] + 0.0722 * lum[2]; + }, + + contrast: function (color2) { + // http://www.w3.org/TR/WCAG20/#contrast-ratiodef + var lum1 = this.luminosity(); + var lum2 = color2.luminosity(); + + if (lum1 > lum2) { + return (lum1 + 0.05) / (lum2 + 0.05); + } + + return (lum2 + 0.05) / (lum1 + 0.05); + }, + + level: function (color2) { + var contrastRatio = this.contrast(color2); + if (contrastRatio >= 7.1) { + return 'AAA'; + } + + return (contrastRatio >= 4.5) ? 'AA' : ''; + }, + + isDark: function () { + // YIQ equation from http://24ways.org/2010/calculating-color-contrast + var rgb = this.rgb().color; + var yiq = (rgb[0] * 299 + rgb[1] * 587 + rgb[2] * 114) / 1000; + return yiq < 128; + }, + + isLight: function () { + return !this.isDark(); + }, + + negate: function () { + var rgb = this.rgb(); + for (var i = 0; i < 3; i++) { + rgb.color[i] = 255 - rgb.color[i]; + } + return rgb; + }, + + lighten: function (ratio) { + var hsl = this.hsl(); + hsl.color[2] += hsl.color[2] * ratio; + return hsl; + }, + + darken: function (ratio) { + var hsl = this.hsl(); + hsl.color[2] -= hsl.color[2] * ratio; + return hsl; + }, + + saturate: function (ratio) { + var hsl = this.hsl(); + hsl.color[1] += hsl.color[1] * ratio; + return hsl; + }, + + desaturate: function (ratio) { + var hsl = this.hsl(); + hsl.color[1] -= hsl.color[1] * ratio; + return hsl; + }, + + whiten: function (ratio) { + var hwb = this.hwb(); + hwb.color[1] += hwb.color[1] * ratio; + return hwb; + }, + + blacken: function (ratio) { + var hwb = this.hwb(); + hwb.color[2] += hwb.color[2] * ratio; + return hwb; + }, + + grayscale: function () { + // http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale + var rgb = this.rgb().color; + var val = rgb[0] * 0.3 + rgb[1] * 0.59 + rgb[2] * 0.11; + return Color.rgb(val, val, val); + }, + + fade: function (ratio) { + return this.alpha(this.valpha - (this.valpha * ratio)); + }, + + opaquer: function (ratio) { + return this.alpha(this.valpha + (this.valpha * ratio)); + }, + + rotate: function (degrees) { + var hsl = this.hsl(); + var hue = hsl.color[0]; + hue = (hue + degrees) % 360; + hue = hue < 0 ? 360 + hue : hue; + hsl.color[0] = hue; + return hsl; + }, + + mix: function (mixinColor, weight) { + // ported from sass implementation in C + // https://github.com/sass/libsass/blob/0e6b4a2850092356aa3ece07c6b249f0221caced/functions.cpp#L209 + if (!mixinColor || !mixinColor.rgb) { + throw new Error('Argument to "mix" was not a Color instance, but rather an instance of ' + typeof mixinColor); + } + var color1 = mixinColor.rgb(); + var color2 = this.rgb(); + var p = weight === undefined ? 0.5 : weight; + + var w = 2 * p - 1; + var a = color1.alpha() - color2.alpha(); + + var w1 = (((w * a === -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0; + var w2 = 1 - w1; + + return Color.rgb( + w1 * color1.red() + w2 * color2.red(), + w1 * color1.green() + w2 * color2.green(), + w1 * color1.blue() + w2 * color2.blue(), + color1.alpha() * p + color2.alpha() * (1 - p)); + } +}; + +// model conversion methods and static constructors +Object.keys(convert).forEach(function (model) { + if (skippedModels.indexOf(model) !== -1) { + return; + } + + var channels = convert[model].channels; + + // conversion methods + Color.prototype[model] = function () { + if (this.model === model) { + return new Color(this); + } + + if (arguments.length) { + return new Color(arguments, model); + } + + var newAlpha = typeof arguments[channels] === 'number' ? channels : this.valpha; + return new Color(assertArray(convert[this.model][model].raw(this.color)).concat(newAlpha), model); + }; + + // 'static' construction methods + Color[model] = function (color) { + if (typeof color === 'number') { + color = zeroArray(_slice.call(arguments), channels); + } + return new Color(color, model); + }; +}); + +function roundTo(num, places) { + return Number(num.toFixed(places)); +} + +function roundToPlace(places) { + return function (num) { + return roundTo(num, places); + }; +} + +function getset(model, channel, modifier) { + model = Array.isArray(model) ? model : [model]; + + model.forEach(function (m) { + (limiters[m] || (limiters[m] = []))[channel] = modifier; + }); + + model = model[0]; + + return function (val) { + var result; + + if (arguments.length) { + if (modifier) { + val = modifier(val); + } + + result = this[model](); + result.color[channel] = val; + return result; + } + + result = this[model]().color[channel]; + if (modifier) { + result = modifier(result); + } + + return result; + }; +} + +function maxfn(max) { + return function (v) { + return Math.max(0, Math.min(max, v)); + }; +} + +function assertArray(val) { + return Array.isArray(val) ? val : [val]; +} + +function zeroArray(arr, length) { + for (var i = 0; i < length; i++) { + if (typeof arr[i] !== 'number') { + arr[i] = 0; + } + } + + return arr; +} + +module.exports = Color; + + +/***/ }), +/* 17 */ +/***/ (function(module, exports, __webpack_require__) { + +/* MIT license */ +var colorNames = __webpack_require__(5); +var swizzle = __webpack_require__(18); + +var reverseNames = {}; + +// create a list of reverse color names +for (var name in colorNames) { + if (colorNames.hasOwnProperty(name)) { + reverseNames[colorNames[name]] = name; + } +} + +var cs = module.exports = { + to: {}, + get: {} +}; + +cs.get = function (string) { + var prefix = string.substring(0, 3).toLowerCase(); + var val; + var model; + switch (prefix) { + case 'hsl': + val = cs.get.hsl(string); + model = 'hsl'; + break; + case 'hwb': + val = cs.get.hwb(string); + model = 'hwb'; + break; + default: + val = cs.get.rgb(string); + model = 'rgb'; + break; + } + + if (!val) { + return null; + } + + return {model: model, value: val}; +}; + +cs.get.rgb = function (string) { + if (!string) { + return null; + } + + var abbr = /^#([a-f0-9]{3,4})$/i; + var hex = /^#([a-f0-9]{6})([a-f0-9]{2})?$/i; + var rgba = /^rgba?\(\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/; + var per = /^rgba?\(\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/; + var keyword = /(\D+)/; + + var rgb = [0, 0, 0, 1]; + var match; + var i; + var hexAlpha; + + if (match = string.match(hex)) { + hexAlpha = match[2]; + match = match[1]; + + for (i = 0; i < 3; i++) { + // https://jsperf.com/slice-vs-substr-vs-substring-methods-long-string/19 + var i2 = i * 2; + rgb[i] = parseInt(match.slice(i2, i2 + 2), 16); + } + + if (hexAlpha) { + rgb[3] = Math.round((parseInt(hexAlpha, 16) / 255) * 100) / 100; + } + } else if (match = string.match(abbr)) { + match = match[1]; + hexAlpha = match[3]; + + for (i = 0; i < 3; i++) { + rgb[i] = parseInt(match[i] + match[i], 16); + } + + if (hexAlpha) { + rgb[3] = Math.round((parseInt(hexAlpha + hexAlpha, 16) / 255) * 100) / 100; + } + } else if (match = string.match(rgba)) { + for (i = 0; i < 3; i++) { + rgb[i] = parseInt(match[i + 1], 0); + } + + if (match[4]) { + rgb[3] = parseFloat(match[4]); + } + } else if (match = string.match(per)) { + for (i = 0; i < 3; i++) { + rgb[i] = Math.round(parseFloat(match[i + 1]) * 2.55); + } + + if (match[4]) { + rgb[3] = parseFloat(match[4]); + } + } else if (match = string.match(keyword)) { + if (match[1] === 'transparent') { + return [0, 0, 0, 0]; + } + + rgb = colorNames[match[1]]; + + if (!rgb) { + return null; + } + + rgb[3] = 1; + + return rgb; + } else { + return null; + } + + for (i = 0; i < 3; i++) { + rgb[i] = clamp(rgb[i], 0, 255); + } + rgb[3] = clamp(rgb[3], 0, 1); + + return rgb; +}; + +cs.get.hsl = function (string) { + if (!string) { + return null; + } + + var hsl = /^hsla?\(\s*([+-]?(?:\d*\.)?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/; + var match = string.match(hsl); + + if (match) { + var alpha = parseFloat(match[4]); + var h = (parseFloat(match[1]) + 360) % 360; + var s = clamp(parseFloat(match[2]), 0, 100); + var l = clamp(parseFloat(match[3]), 0, 100); + var a = clamp(isNaN(alpha) ? 1 : alpha, 0, 1); + + return [h, s, l, a]; + } + + return null; +}; + +cs.get.hwb = function (string) { + if (!string) { + return null; + } + + var hwb = /^hwb\(\s*([+-]?\d*[\.]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/; + var match = string.match(hwb); + + if (match) { + var alpha = parseFloat(match[4]); + var h = ((parseFloat(match[1]) % 360) + 360) % 360; + var w = clamp(parseFloat(match[2]), 0, 100); + var b = clamp(parseFloat(match[3]), 0, 100); + var a = clamp(isNaN(alpha) ? 1 : alpha, 0, 1); + return [h, w, b, a]; + } + + return null; +}; + +cs.to.hex = function () { + var rgba = swizzle(arguments); + + return ( + '#' + + hexDouble(rgba[0]) + + hexDouble(rgba[1]) + + hexDouble(rgba[2]) + + (rgba[3] < 1 + ? (hexDouble(Math.round(rgba[3] * 255))) + : '') + ); +}; + +cs.to.rgb = function () { + var rgba = swizzle(arguments); + + return rgba.length < 4 || rgba[3] === 1 + ? 'rgb(' + Math.round(rgba[0]) + ', ' + Math.round(rgba[1]) + ', ' + Math.round(rgba[2]) + ')' + : 'rgba(' + Math.round(rgba[0]) + ', ' + Math.round(rgba[1]) + ', ' + Math.round(rgba[2]) + ', ' + rgba[3] + ')'; +}; + +cs.to.rgb.percent = function () { + var rgba = swizzle(arguments); + + var r = Math.round(rgba[0] / 255 * 100); + var g = Math.round(rgba[1] / 255 * 100); + var b = Math.round(rgba[2] / 255 * 100); + + return rgba.length < 4 || rgba[3] === 1 + ? 'rgb(' + r + '%, ' + g + '%, ' + b + '%)' + : 'rgba(' + r + '%, ' + g + '%, ' + b + '%, ' + rgba[3] + ')'; +}; + +cs.to.hsl = function () { + var hsla = swizzle(arguments); + return hsla.length < 4 || hsla[3] === 1 + ? 'hsl(' + hsla[0] + ', ' + hsla[1] + '%, ' + hsla[2] + '%)' + : 'hsla(' + hsla[0] + ', ' + hsla[1] + '%, ' + hsla[2] + '%, ' + hsla[3] + ')'; +}; + +// hwb is a bit different than rgb(a) & hsl(a) since there is no alpha specific syntax +// (hwb have alpha optional & 1 is default value) +cs.to.hwb = function () { + var hwba = swizzle(arguments); + + var a = ''; + if (hwba.length >= 4 && hwba[3] !== 1) { + a = ', ' + hwba[3]; + } + + return 'hwb(' + hwba[0] + ', ' + hwba[1] + '%, ' + hwba[2] + '%' + a + ')'; +}; + +cs.to.keyword = function (rgb) { + return reverseNames[rgb.slice(0, 3)]; +}; + +// helpers +function clamp(num, min, max) { + return Math.min(Math.max(min, num), max); +} + +function hexDouble(num) { + var str = num.toString(16).toUpperCase(); + return (str.length < 2) ? '0' + str : str; +} + + +/***/ }), +/* 18 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var isArrayish = __webpack_require__(19); + +var concat = Array.prototype.concat; +var slice = Array.prototype.slice; + +var swizzle = module.exports = function swizzle(args) { + var results = []; + + for (var i = 0, len = args.length; i < len; i++) { + var arg = args[i]; + + if (isArrayish(arg)) { + // http://jsperf.com/javascript-array-concat-vs-push/98 + results = concat.call(results, slice.call(arg)); + } else { + results.push(arg); + } + } + + return results; +}; + +swizzle.wrap = function (fn) { + return function () { + return fn(swizzle(arguments)); + }; +}; + + +/***/ }), +/* 19 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +module.exports = function isArrayish(obj) { + if (!obj) { + return false; + } + + return obj instanceof Array || Array.isArray(obj) || + (obj.length >= 0 && obj.splice instanceof Function); +}; + + +/***/ }), +/* 20 */ +/***/ (function(module, exports, __webpack_require__) { + +var conversions = __webpack_require__(6); +var route = __webpack_require__(21); + +var convert = {}; + +var models = Object.keys(conversions); + +function wrapRaw(fn) { + var wrappedFn = function (args) { + if (args === undefined || args === null) { + return args; + } + + if (arguments.length > 1) { + args = Array.prototype.slice.call(arguments); + } + + return fn(args); + }; + + // preserve .conversion property if there is one + if ('conversion' in fn) { + wrappedFn.conversion = fn.conversion; + } + + return wrappedFn; +} + +function wrapRounded(fn) { + var wrappedFn = function (args) { + if (args === undefined || args === null) { + return args; + } + + if (arguments.length > 1) { + args = Array.prototype.slice.call(arguments); + } + + var result = fn(args); + + // we're assuming the result is an array here. + // see notice in conversions.js; don't use box types + // in conversion functions. + if (typeof result === 'object') { + for (var len = result.length, i = 0; i < len; i++) { + result[i] = Math.round(result[i]); + } + } + + return result; + }; + + // preserve .conversion property if there is one + if ('conversion' in fn) { + wrappedFn.conversion = fn.conversion; + } + + return wrappedFn; +} + +models.forEach(function (fromModel) { + convert[fromModel] = {}; + + Object.defineProperty(convert[fromModel], 'channels', {value: conversions[fromModel].channels}); + Object.defineProperty(convert[fromModel], 'labels', {value: conversions[fromModel].labels}); + + var routes = route(fromModel); + var routeModels = Object.keys(routes); + + routeModels.forEach(function (toModel) { + var fn = routes[toModel]; + + convert[fromModel][toModel] = wrapRounded(fn); + convert[fromModel][toModel].raw = wrapRaw(fn); + }); +}); + +module.exports = convert; + + +/***/ }), +/* 21 */ +/***/ (function(module, exports, __webpack_require__) { + +var conversions = __webpack_require__(6); + +/* + this function routes a model to all other models. + + all functions that are routed have a property `.conversion` attached + to the returned synthetic function. This property is an array + of strings, each with the steps in between the 'from' and 'to' + color models (inclusive). + + conversions that are not possible simply are not included. +*/ + +function buildGraph() { + var graph = {}; + // https://jsperf.com/object-keys-vs-for-in-with-closure/3 + var models = Object.keys(conversions); + + for (var len = models.length, i = 0; i < len; i++) { + graph[models[i]] = { + // http://jsperf.com/1-vs-infinity + // micro-opt, but this is simple. + distance: -1, + parent: null + }; + } + + return graph; +} + +// https://en.wikipedia.org/wiki/Breadth-first_search +function deriveBFS(fromModel) { + var graph = buildGraph(); + var queue = [fromModel]; // unshift -> queue -> pop + + graph[fromModel].distance = 0; + + while (queue.length) { + var current = queue.pop(); + var adjacents = Object.keys(conversions[current]); + + for (var len = adjacents.length, i = 0; i < len; i++) { + var adjacent = adjacents[i]; + var node = graph[adjacent]; + + if (node.distance === -1) { + node.distance = graph[current].distance + 1; + node.parent = current; + queue.unshift(adjacent); + } + } + } + + return graph; +} + +function link(from, to) { + return function (args) { + return to(from(args)); + }; +} + +function wrapConversion(toModel, graph) { + var path = [graph[toModel].parent, toModel]; + var fn = conversions[graph[toModel].parent][toModel]; + + var cur = graph[toModel].parent; + while (graph[cur].parent) { + path.unshift(graph[cur].parent); + fn = link(conversions[graph[cur].parent][cur], fn); + cur = graph[cur].parent; + } + + fn.conversion = path; + return fn; +} + +module.exports = function (fromModel) { + var graph = deriveBFS(fromModel); + var conversion = {}; + + var models = Object.keys(graph); + for (var len = models.length, i = 0; i < len; i++) { + var toModel = models[i]; + var node = graph[toModel]; + + if (node.parent === null) { + // no possible conversion, or this node is the source model. + continue; + } + + conversion[toModel] = wrapConversion(toModel, graph); + } + + return conversion; +}; + + + +/***/ }), +/* 22 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +var _ColorItem = __webpack_require__(2); + +var _ColorItem2 = _interopRequireDefault(_ColorItem); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +/** + * Handles everything related to the colorpicker color + * @ignore + */ +var ColorHandler = function () { + /** + * @param {Colorpicker} colorpicker + */ + function ColorHandler(colorpicker) { + _classCallCheck(this, ColorHandler); + + /** + * @type {Colorpicker} + */ + this.colorpicker = colorpicker; + } + + /** + * @returns {*|String|ColorItem} + */ + + + _createClass(ColorHandler, [{ + key: 'bind', + value: function bind() { + // if the color option is set + if (this.colorpicker.options.color) { + this.color = this.createColor(this.colorpicker.options.color); + return; + } + + // if element[color] is empty and the input has a value + if (!this.color && !!this.colorpicker.inputHandler.getValue()) { + this.color = this.createColor(this.colorpicker.inputHandler.getValue(), this.colorpicker.options.autoInputFallback); + } + } + }, { + key: 'unbind', + value: function unbind() { + this.colorpicker.element.removeData('color'); + } + + /** + * Returns the color string from the input value or the 'data-color' attribute of the input or element. + * If empty, it returns the defaultValue parameter. + * + * @returns {String|*} + */ + + }, { + key: 'getColorString', + value: function getColorString() { + if (!this.hasColor()) { + return ''; + } + + return this.color.string(this.format); + } + + /** + * Sets the color value + * + * @param {String|ColorItem} val + */ + + }, { + key: 'setColorString', + value: function setColorString(val) { + var color = val ? this.createColor(val) : null; + + this.color = color ? color : null; + } + + /** + * Creates a new color using the widget instance options (fallbackColor, format). + * + * @fires Colorpicker#colorpickerInvalid + * @param {*} val + * @param {boolean} fallbackOnInvalid + * @returns {ColorItem} + */ + + }, { + key: 'createColor', + value: function createColor(val) { + var fallbackOnInvalid = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + + var color = new _ColorItem2.default(this.resolveColorDelegate(val), this.format); + + if (!color.isValid()) { + if (fallbackOnInvalid) { + color = this.getFallbackColor(); + } + + /** + * (Colorpicker) Fired when the color is invalid and the fallback color is going to be used. + * + * @event Colorpicker#colorpickerInvalid + */ + this.colorpicker.trigger('colorpickerInvalid', color, val); + } + + if (!this.isAlphaEnabled()) { + // Alpha is disabled + color.alpha = 1; + } + + return color; + } + }, { + key: 'getFallbackColor', + value: function getFallbackColor() { + if (this.fallback && this.fallback === this.color) { + return this.color; + } + + var fallback = this.resolveColorDelegate(this.fallback); + var color = new _ColorItem2.default(fallback, this.format); + + if (!color.isValid()) { + console.warn('The fallback color is invalid. Falling back to the previous color or black if any.'); + return this.color ? this.color : new _ColorItem2.default('#000000', this.format); + } + + return color; + } + + /** + * @returns {ColorItem} + */ + + }, { + key: 'assureColor', + value: function assureColor() { + if (!this.hasColor()) { + this.color = this.getFallbackColor(); + } + + return this.color; + } + + /** + * Delegates the color resolution to the colorpicker extensions. + * + * @param {String|*} color + * @param {boolean} realColor if true, the color should resolve into a real (not named) color code + * @returns {ColorItem|String|*|null} + */ + + }, { + key: 'resolveColorDelegate', + value: function resolveColorDelegate(color) { + var realColor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + + var extResolvedColor = false; + + _jquery2.default.each(this.colorpicker.extensions, function (name, ext) { + if (extResolvedColor !== false) { + // skip if resolved + return; + } + extResolvedColor = ext.resolveColor(color, realColor); + }); + + return extResolvedColor ? extResolvedColor : color; + } + + /** + * Checks if there is a color object, that it is valid and it is not a fallback + * @returns {boolean} + */ + + }, { + key: 'isInvalidColor', + value: function isInvalidColor() { + return !this.hasColor() || !this.color.isValid(); + } + + /** + * Returns true if the useAlpha option is exactly true, false otherwise + * @returns {boolean} + */ + + }, { + key: 'isAlphaEnabled', + value: function isAlphaEnabled() { + return this.colorpicker.options.useAlpha !== false; + } + + /** + * Returns true if the current color object is an instance of Color, false otherwise. + * @returns {boolean} + */ + + }, { + key: 'hasColor', + value: function hasColor() { + return this.color instanceof _ColorItem2.default; + } + }, { + key: 'fallback', + get: function get() { + return this.colorpicker.options.fallbackColor ? this.colorpicker.options.fallbackColor : this.hasColor() ? this.color : null; + } + + /** + * @returns {String|null} + */ + + }, { + key: 'format', + get: function get() { + if (this.colorpicker.options.format) { + return this.colorpicker.options.format; + } + + if (this.hasColor() && this.color.hasTransparency() && this.color.format.match(/^hex/)) { + return this.isAlphaEnabled() ? 'rgba' : 'hex'; + } + + if (this.hasColor()) { + return this.color.format; + } + + return 'rgb'; + } + + /** + * Internal color getter + * + * @type {ColorItem|null} + */ + + }, { + key: 'color', + get: function get() { + return this.colorpicker.element.data('color'); + } + + /** + * Internal color setter + * + * @ignore + * @param {ColorItem|null} value + */ + , + set: function set(value) { + this.colorpicker.element.data('color', value); + + if (value instanceof _ColorItem2.default && this.colorpicker.options.format === 'auto') { + // If format is 'auto', use the first parsed one from now on + this.colorpicker.options.format = this.color.format; + } + } + }]); + + return ColorHandler; +}(); + +exports.default = ColorHandler; + +/***/ }), +/* 23 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _jquery = __webpack_require__(0); + +var _jquery2 = _interopRequireDefault(_jquery); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +/** + * Handles everything related to the colorpicker UI + * @ignore + */ +var PickerHandler = function () { + /** + * @param {Colorpicker} colorpicker + */ + function PickerHandler(colorpicker) { + _classCallCheck(this, PickerHandler); + + /** + * @type {Colorpicker} + */ + this.colorpicker = colorpicker; + /** + * @type {jQuery} + */ + this.picker = null; + } + + _createClass(PickerHandler, [{ + key: 'bind', + value: function bind() { + /** + * @type {jQuery|HTMLElement} + */ + var picker = this.picker = (0, _jquery2.default)(this.options.template); + + if (this.options.customClass) { + picker.addClass(this.options.customClass); + } + + if (this.options.horizontal) { + picker.addClass('colorpicker-horizontal'); + } + + if (this._supportsAlphaBar()) { + this.options.useAlpha = true; + picker.addClass('colorpicker-with-alpha'); + } else { + this.options.useAlpha = false; + } + } + }, { + key: 'attach', + value: function attach() { + // Inject the colorpicker element into the DOM + var pickerParent = this.colorpicker.container ? this.colorpicker.container : null; + + if (pickerParent) { + this.picker.appendTo(pickerParent); + } + } + }, { + key: 'unbind', + value: function unbind() { + this.picker.remove(); + } + }, { + key: '_supportsAlphaBar', + value: function _supportsAlphaBar() { + return (this.options.useAlpha || this.colorpicker.colorHandler.hasColor() && this.color.hasTransparency()) && this.options.useAlpha !== false && (!this.options.format || this.options.format && !this.options.format.match(/^hex([36])?$/i)); + } + + /** + * Changes the color adjustment bars using the current color object information. + */ + + }, { + key: 'update', + value: function update() { + if (!this.colorpicker.colorHandler.hasColor()) { + return; + } + + var vertical = this.options.horizontal !== true, + slider = vertical ? this.options.sliders : this.options.slidersHorz; + + var saturationGuide = this.picker.find('.colorpicker-saturation .colorpicker-guide'), + hueGuide = this.picker.find('.colorpicker-hue .colorpicker-guide'), + alphaGuide = this.picker.find('.colorpicker-alpha .colorpicker-guide'); + + var hsva = this.color.toHsvaRatio(); + + // Set guides position + if (hueGuide.length) { + hueGuide.css(vertical ? 'top' : 'left', (vertical ? slider.hue.maxTop : slider.hue.maxLeft) * (1 - hsva.h)); + } + if (alphaGuide.length) { + alphaGuide.css(vertical ? 'top' : 'left', (vertical ? slider.alpha.maxTop : slider.alpha.maxLeft) * (1 - hsva.a)); + } + if (saturationGuide.length) { + saturationGuide.css({ + 'top': slider.saturation.maxTop - hsva.v * slider.saturation.maxTop, + 'left': hsva.s * slider.saturation.maxLeft + }); + } + + // Set saturation hue background + this.picker.find('.colorpicker-saturation').css('backgroundColor', this.color.getCloneHueOnly().toHexString()); // we only need hue + + // Set alpha color gradient + var hexColor = this.color.toHexString(); + var alphaBg = ''; + + if (this.options.horizontal) { + alphaBg = 'linear-gradient(to right, ' + hexColor + ' 0%, transparent 100%)'; + } else { + alphaBg = 'linear-gradient(to bottom, ' + hexColor + ' 0%, transparent 100%)'; + } + + this.picker.find('.colorpicker-alpha-color').css('background', alphaBg); + } + }, { + key: 'options', + get: function get() { + return this.colorpicker.options; + } + }, { + key: 'color', + get: function get() { + return this.colorpicker.colorHandler.color; + } + }]); + + return PickerHandler; +}(); + +exports.default = PickerHandler; + +/***/ }), +/* 24 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +/** + * Handles everything related to the colorpicker addon + * @ignore + */ + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var AddonHandler = function () { + /** + * @param {Colorpicker} colorpicker + */ + function AddonHandler(colorpicker) { + _classCallCheck(this, AddonHandler); + + /** + * @type {Colorpicker} + */ + this.colorpicker = colorpicker; + /** + * @type {jQuery} + */ + this.addon = null; + } + + _createClass(AddonHandler, [{ + key: 'hasAddon', + value: function hasAddon() { + return !!this.addon; + } + }, { + key: 'bind', + value: function bind() { + /** + * @type {*|jQuery} + */ + this.addon = this.colorpicker.options.addon ? this.colorpicker.element.find(this.colorpicker.options.addon) : null; + + if (this.addon && this.addon.length === 0) { + // not found + this.addon = null; + } + } + }, { + key: 'unbind', + value: function unbind() { + if (this.hasAddon()) { + this.addon.off('.colorpicker'); + } + } + + /** + * If the addon element is present, its background color is updated + */ + + }, { + key: 'update', + value: function update() { + if (!this.colorpicker.colorHandler.hasColor() || !this.hasAddon()) { + return; + } + + var colorStr = this.colorpicker.colorHandler.getColorString(); + var styles = { 'background': colorStr }; + + var icn = this.addon.find('i').eq(0); + + if (icn.length > 0) { + icn.css(styles); + } else { + this.addon.css(styles); + } + } + }]); + + return AddonHandler; +}(); + +exports.default = AddonHandler; + +/***/ }) +/******/ ]); +}); +//# sourceMappingURL=bootstrap-colorpicker.js.map ADDED public/bootstrap-colorpicker/dist/js/bootstrap-colorpicker.js.map Index: public/bootstrap-colorpicker/dist/js/bootstrap-colorpicker.js.map ================================================================== --- public/bootstrap-colorpicker/dist/js/bootstrap-colorpicker.js.map +++ public/bootstrap-colorpicker/dist/js/bootstrap-colorpicker.js.map cannot compute difference between binary files ADDED public/bootstrap-colorpicker/dist/js/bootstrap-colorpicker.min.js Index: public/bootstrap-colorpicker/dist/js/bootstrap-colorpicker.min.js ================================================================== --- public/bootstrap-colorpicker/dist/js/bootstrap-colorpicker.min.js +++ public/bootstrap-colorpicker/dist/js/bootstrap-colorpicker.min.js cannot compute difference between binary files ADDED public/bootstrap-colorpicker/dist/js/bootstrap-colorpicker.min.js.map Index: public/bootstrap-colorpicker/dist/js/bootstrap-colorpicker.min.js.map ================================================================== --- public/bootstrap-colorpicker/dist/js/bootstrap-colorpicker.min.js.map +++ public/bootstrap-colorpicker/dist/js/bootstrap-colorpicker.min.js.map cannot compute difference between binary files ADDED public/bootstrap-colorpicker/logo.png Index: public/bootstrap-colorpicker/logo.png ================================================================== --- public/bootstrap-colorpicker/logo.png +++ public/bootstrap-colorpicker/logo.png cannot compute difference between binary files ADDED public/bootstrap-colorpicker/package.json Index: public/bootstrap-colorpicker/package.json ================================================================== --- public/bootstrap-colorpicker/package.json +++ public/bootstrap-colorpicker/package.json @@ -0,0 +1,110 @@ +{ + "_from": "bootstrap-colorpicker@^3.1.0", + "_id": "bootstrap-colorpicker@3.1.2", + "_inBundle": false, + "_integrity": "sha512-yUWegXox8GYoXVtYdrEIN3QMOeEFbcSFGDadZu2pWmmMgTaw4ECX9T8GvYQzJkRusvK9uzi39FjE0W2k8lQECA==", + "_location": "/bootstrap-colorpicker", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "bootstrap-colorpicker@^3.1.0", + "name": "bootstrap-colorpicker", + "escapedName": "bootstrap-colorpicker", + "rawSpec": "^3.1.0", + "saveSpec": null, + "fetchSpec": "^3.1.0" + }, + "_requiredBy": [ + "/" + ], + "_resolved": "https://registry.npmjs.org/bootstrap-colorpicker/-/bootstrap-colorpicker-3.1.2.tgz", + "_shasum": "42737d7fb3f52b42ad9e33ac97f021252307dfae", + "_spec": "bootstrap-colorpicker@^3.1.0", + "_where": "/Users/itsjavi/Developer/github.com/farbelous/bootstrap-colorpicker-test", + "author": { + "name": "Javi Aguilar" + }, + "ava": { + "files": [ + "tests/**/*test.js" + ], + "source": [ + "src/js/**/*.{js,jsx}" + ], + "concurrency": 5, + "failFast": true, + "failWithoutAssertions": false, + "tap": false, + "powerAssert": false, + "require": [ + "babel-register" + ], + "babel": "inherit" + }, + "bugs": { + "url": "https://github.com/farbelous/bootstrap-colorpicker/issues" + }, + "bundleDependencies": false, + "dependencies": { + "bootstrap": ">=4.0", + "jquery": ">=2.1.0" + }, + "deprecated": false, + "description": "Bootstrap Colorpicker is a modular color picker plugin for Bootstrap 4.", + "devDependencies": { + "ava": "^0.23.0", + "babel-cli": "^6.26.0", + "babel-eslint": "^8.0.2", + "babel-loader": "^7.1.2", + "babel-plugin-add-module-exports": "^0.2.1", + "babel-preset-env": "^1.6.1", + "color": "^3.0.0", + "del": "^3.0.0", + "eslint": "^4.11.0", + "eslint-loader": "^1.9.0", + "gh-pages": "^1.0.0", + "gulp": "^3.9.1", + "gulp-autoprefixer": "^4.0.0", + "gulp-clean-css": "^3.9.0", + "gulp-compile-handlebars": "^0.6.1", + "gulp-header": "^1.8.9", + "gulp-rename": "^1.2.2", + "gulp-sass": "^2.3.2", + "gulp-shell": "^0.6.3", + "gulp-sourcemaps": "^2.6.1", + "gulp-string-replace": "^1.1.1", + "handlebars-layouts": "^3.1.4", + "http-server": "^0.10.0", + "jsdoc": "^3.5.5", + "jsdom": "^11.3.0", + "run-sequence": "^2.2.1", + "uglifyjs-webpack-plugin": "^1.0.1", + "webpack": "^3.8.1", + "webpack-stream": "^4.0.0" + }, + "homepage": "https://farbelous.github.io/bootstrap-colorpicker/", + "keywords": [ + "bootstrap", + "colorpicker" + ], + "license": "MIT", + "main": "./dist/js/bootstrap-colorpicker.js", + "name": "bootstrap-colorpicker", + "repository": { + "type": "git", + "url": "git+https://github.com/farbelous/bootstrap-colorpicker.git" + }, + "scripts": { + "build": "gulp clean && gulp dist && gulp docs && gulp docs:add-v2-docs", + "build-dist": "gulp dist", + "build-docs": "gulp dist && gulp docs && gulp docs:add-v2-docs", + "build-npm": "npm run build && gulp npm-prepublish", + "lint": "eslint ./src/js ./*.js ./test", + "lint-fix": "eslint --fix ./src/js ./*.js ./test", + "publish-docs": "npm run build && npm run test && gulp publish-gh-pages", + "start": "http-server ./build/docs", + "test": "npm run lint && ava --color --verbose" + }, + "version": "3.1.2" +} ADDED public/bootstrap-colorpicker/src/js/AddonHandler.js Index: public/bootstrap-colorpicker/src/js/AddonHandler.js ================================================================== --- public/bootstrap-colorpicker/src/js/AddonHandler.js +++ public/bootstrap-colorpicker/src/js/AddonHandler.js @@ -0,0 +1,66 @@ +'use strict'; + +/** + * Handles everything related to the colorpicker addon + * @ignore + */ +class AddonHandler { + /** + * @param {Colorpicker} colorpicker + */ + constructor(colorpicker) { + /** + * @type {Colorpicker} + */ + this.colorpicker = colorpicker; + /** + * @type {jQuery} + */ + this.addon = null; + } + + hasAddon() { + return !!this.addon; + } + + bind() { + /** + * @type {*|jQuery} + */ + this.addon = this.colorpicker.options.addon ? + this.colorpicker.element.find(this.colorpicker.options.addon) : null; + + if (this.addon && (this.addon.length === 0)) { + // not found + this.addon = null; + } + } + + unbind() { + if (this.hasAddon()) { + this.addon.off('.colorpicker'); + } + } + + /** + * If the addon element is present, its background color is updated + */ + update() { + if (!this.colorpicker.colorHandler.hasColor() || !this.hasAddon()) { + return; + } + + let colorStr = this.colorpicker.colorHandler.getColorString(); + let styles = {'background': colorStr}; + + let icn = this.addon.find('i').eq(0); + + if (icn.length > 0) { + icn.css(styles); + } else { + this.addon.css(styles); + } + } +} + +export default AddonHandler; ADDED public/bootstrap-colorpicker/src/js/ColorHandler.js Index: public/bootstrap-colorpicker/src/js/ColorHandler.js ================================================================== --- public/bootstrap-colorpicker/src/js/ColorHandler.js +++ public/bootstrap-colorpicker/src/js/ColorHandler.js @@ -0,0 +1,221 @@ +'use strict'; + +import $ from 'jquery'; +import ColorItem from './ColorItem'; + +/** + * Handles everything related to the colorpicker color + * @ignore + */ +class ColorHandler { + /** + * @param {Colorpicker} colorpicker + */ + constructor(colorpicker) { + /** + * @type {Colorpicker} + */ + this.colorpicker = colorpicker; + } + + /** + * @returns {*|String|ColorItem} + */ + get fallback() { + return this.colorpicker.options.fallbackColor ? + this.colorpicker.options.fallbackColor : (this.hasColor() ? this.color : null); + } + + /** + * @returns {String|null} + */ + get format() { + if (this.colorpicker.options.format) { + return this.colorpicker.options.format; + } + + if (this.hasColor() && this.color.hasTransparency() && this.color.format.match(/^hex/)) { + return this.isAlphaEnabled() ? 'rgba' : 'hex'; + } + + if (this.hasColor()) { + return this.color.format; + } + + return 'rgb'; + } + + /** + * Internal color getter + * + * @type {ColorItem|null} + */ + get color() { + return this.colorpicker.element.data('color'); + } + + /** + * Internal color setter + * + * @ignore + * @param {ColorItem|null} value + */ + set color(value) { + this.colorpicker.element.data('color', value); + + if ((value instanceof ColorItem) && (this.colorpicker.options.format === 'auto')) { + // If format is 'auto', use the first parsed one from now on + this.colorpicker.options.format = this.color.format; + } + } + + bind() { + // if the color option is set + if (this.colorpicker.options.color) { + this.color = this.createColor(this.colorpicker.options.color); + return; + } + + // if element[color] is empty and the input has a value + if (!this.color && !!this.colorpicker.inputHandler.getValue()) { + this.color = this.createColor( + this.colorpicker.inputHandler.getValue(), this.colorpicker.options.autoInputFallback + ); + } + } + + unbind() { + this.colorpicker.element.removeData('color'); + } + + /** + * Returns the color string from the input value or the 'data-color' attribute of the input or element. + * If empty, it returns the defaultValue parameter. + * + * @returns {String|*} + */ + getColorString() { + if (!this.hasColor()) { + return ''; + } + + return this.color.string(this.format); + } + + /** + * Sets the color value + * + * @param {String|ColorItem} val + */ + setColorString(val) { + let color = val ? this.createColor(val) : null; + + this.color = color ? color : null; + } + + /** + * Creates a new color using the widget instance options (fallbackColor, format). + * + * @fires Colorpicker#colorpickerInvalid + * @param {*} val + * @param {boolean} fallbackOnInvalid + * @returns {ColorItem} + */ + createColor(val, fallbackOnInvalid = true) { + let color = new ColorItem(this.resolveColorDelegate(val), this.format); + + if (!color.isValid()) { + if (fallbackOnInvalid) { + color = this.getFallbackColor(); + } + + /** + * (Colorpicker) Fired when the color is invalid and the fallback color is going to be used. + * + * @event Colorpicker#colorpickerInvalid + */ + this.colorpicker.trigger('colorpickerInvalid', color, val); + } + + if (!this.isAlphaEnabled()) { + // Alpha is disabled + color.alpha = 1; + } + + return color; + } + + getFallbackColor() { + if (this.fallback && (this.fallback === this.color)) { + return this.color; + } + + let fallback = this.resolveColorDelegate(this.fallback); + let color = new ColorItem(fallback, this.format); + + if (!color.isValid()) { + console.warn('The fallback color is invalid. Falling back to the previous color or black if any.'); + return this.color ? this.color : new ColorItem('#000000', this.format); + } + + return color; + } + + /** + * @returns {ColorItem} + */ + assureColor() { + if (!this.hasColor()) { + this.color = this.getFallbackColor(); + } + + return this.color; + } + + /** + * Delegates the color resolution to the colorpicker extensions. + * + * @param {String|*} color + * @param {boolean} realColor if true, the color should resolve into a real (not named) color code + * @returns {ColorItem|String|*|null} + */ + resolveColorDelegate(color, realColor = true) { + let extResolvedColor = false; + + $.each(this.colorpicker.extensions, function (name, ext) { + if (extResolvedColor !== false) { + // skip if resolved + return; + } + extResolvedColor = ext.resolveColor(color, realColor); + }); + + return extResolvedColor ? extResolvedColor : color; + } + + /** + * Checks if there is a color object, that it is valid and it is not a fallback + * @returns {boolean} + */ + isInvalidColor() { + return !this.hasColor() || !this.color.isValid(); + } + + /** + * Returns true if the useAlpha option is exactly true, false otherwise + * @returns {boolean} + */ + isAlphaEnabled() { + return (this.colorpicker.options.useAlpha !== false); + } + + /** + * Returns true if the current color object is an instance of Color, false otherwise. + * @returns {boolean} + */ + hasColor() { + return this.color instanceof ColorItem; + } +} + +export default ColorHandler; ADDED public/bootstrap-colorpicker/src/js/ColorItem.js Index: public/bootstrap-colorpicker/src/js/ColorItem.js ================================================================== --- public/bootstrap-colorpicker/src/js/ColorItem.js +++ public/bootstrap-colorpicker/src/js/ColorItem.js @@ -0,0 +1,652 @@ +/** + * Color manipulation class, specific for Bootstrap Colorpicker + */ +import QixColor from 'color'; + +/** + * HSVA color data class, containing the hue, saturation, value and alpha + * information. + */ +class HSVAColor { + /** + * @param {number|int} h + * @param {number|int} s + * @param {number|int} v + * @param {number|int} a + */ + constructor(h, s, v, a) { + this.h = isNaN(h) ? 0 : h; + this.s = isNaN(s) ? 0 : s; + this.v = isNaN(v) ? 0 : v; + this.a = isNaN(h) ? 1 : a; + } + + toString() { + return `${this.h}, ${this.s}%, ${this.v}%, ${this.a}`; + } +} + +/** + * HSVA color manipulation + */ +class ColorItem { + + /** + * Returns the HSVAColor class + * + * @static + * @example let colorData = new ColorItem.HSVAColor(360, 100, 100, 1); + * @returns {HSVAColor} + */ + static get HSVAColor() { + return HSVAColor; + } + + /** + * Applies a method of the QixColor API and returns a new Color object or + * the return value of the method call. + * + * If no argument is provided, the internal QixColor object is returned. + * + * @param {String} fn QixColor function name + * @param args QixColor function arguments + * @example let darkerColor = color.api('darken', 0.25); + * @example let luminosity = color.api('luminosity'); + * @example color = color.api('negate'); + * @example let qColor = color.api().negate(); + * @returns {ColorItem|QixColor|*} + */ + api(fn, ...args) { + if (arguments.length === 0) { + return this._color; + } + + let result = this._color[fn].apply(this._color, args); + + if (!(result instanceof QixColor)) { + // return result of the method call + return result; + } + + return new ColorItem(result, this.format); + } + + /** + * Returns the original ColorItem constructor data, + * plus a 'valid' flag to know if it's valid or not. + * + * @returns {{color: *, format: String, valid: boolean}} + */ + get original() { + return this._original; + } + + /** + * @param {ColorItem|HSVAColor|QixColor|String|*|null} color Color data + * @param {String|null} format Color model to convert to by default. Supported: 'rgb', 'hsl', 'hex'. + */ + constructor(color = null, format = null) { + this.replace(color, format); + } + + /** + * Replaces the internal QixColor object with a new one. + * This also replaces the internal original color data. + * + * @param {ColorItem|HSVAColor|QixColor|String|*|null} color Color data to be parsed (if needed) + * @param {String|null} format Color model to convert to by default. Supported: 'rgb', 'hsl', 'hex'. + * @example color.replace('rgb(255,0,0)', 'hsl'); + * @example color.replace(hsvaColorData); + */ + replace(color, format = null) { + format = ColorItem.sanitizeFormat(format); + + /** + * @type {{color: *, format: String}} + * @private + */ + this._original = { + color: color, + format: format, + valid: true + }; + /** + * @type {QixColor} + * @private + */ + this._color = ColorItem.parse(color); + + if (this._color === null) { + this._color = QixColor(); + this._original.valid = false; + return; + } + + /** + * @type {*|string} + * @private + */ + this._format = format ? format : + (ColorItem.isHex(color) ? 'hex' : this._color.model); + } + + /** + * Parses the color returning a Qix Color object or null if cannot be + * parsed. + * + * @param {ColorItem|HSVAColor|QixColor|String|*|null} color Color data + * @example let qColor = ColorItem.parse('rgb(255,0,0)'); + * @static + * @returns {QixColor|null} + */ + static parse(color) { + if (color instanceof QixColor) { + return color; + } + + if (color instanceof ColorItem) { + return color._color; + } + + let format = null; + + if (color instanceof HSVAColor) { + color = [color.h, color.s, color.v, isNaN(color.a) ? 1 : color.a]; + } else { + color = ColorItem.sanitizeString(color); + } + + if (color === null) { + return null; + } + + if (Array.isArray(color)) { + format = 'hsv'; + } + + try { + return QixColor(color, format); + } catch (e) { + return null; + } + } + + /** + * Sanitizes a color string, adding missing hash to hexadecimal colors + * and converting 'transparent' to a color code. + * + * @param {String|*} str Color string + * @example let colorStr = ColorItem.sanitizeString('ffaa00'); + * @static + * @returns {String|*} + */ + static sanitizeString(str) { + if (!(typeof str === 'string' || str instanceof String)) { + return str; + } + + if (str.match(/^[0-9a-f]{2,}$/i)) { + return `#${str}`; + } + + if (str.toLowerCase() === 'transparent') { + return '#FFFFFF00'; + } + + return str; + } + + /** + * Detects if a value is a string and a color in hexadecimal format (in any variant). + * + * @param {String} str + * @example ColorItem.isHex('rgba(0,0,0)'); // false + * @example ColorItem.isHex('ffaa00'); // true + * @example ColorItem.isHex('#ffaa00'); // true + * @static + * @returns {boolean} + */ + static isHex(str) { + if (!(typeof str === 'string' || str instanceof String)) { + return false; + } + + return !!str.match(/^#?[0-9a-f]{2,}$/i); + } + + /** + * Sanitizes a color format to one supported by web browsers. + * Returns an empty string of the format can't be recognised. + * + * @param {String|*} format + * @example ColorItem.sanitizeFormat('rgba'); // 'rgb' + * @example ColorItem.isHex('hex8'); // 'hex' + * @example ColorItem.isHex('invalid'); // '' + * @static + * @returns {String} 'rgb', 'hsl', 'hex' or ''. + */ + static sanitizeFormat(format) { + switch (format) { + case 'hex': + case 'hex3': + case 'hex4': + case 'hex6': + case 'hex8': + return 'hex'; + case 'rgb': + case 'rgba': + case 'keyword': + case 'name': + return 'rgb'; + case 'hsl': + case 'hsla': + case 'hsv': + case 'hsva': + case 'hwb': // HWB this is supported by Qix Color, but not by browsers + case 'hwba': + return 'hsl'; + default : + return ''; + } + } + + /** + * Returns true if the color is valid, false if not. + * + * @returns {boolean} + */ + isValid() { + return this._original.valid === true; + } + + /** + * Hue value from 0 to 360 + * + * @returns {int} + */ + get hue() { + return this._color.hue(); + } + + /** + * Saturation value from 0 to 100 + * + * @returns {int} + */ + get saturation() { + return this._color.saturationv(); + } + + /** + * Value channel value from 0 to 100 + * + * @returns {int} + */ + get value() { + return this._color.value(); + } + + /** + * Alpha value from 0.0 to 1.0 + * + * @returns {number} + */ + get alpha() { + let a = this._color.alpha(); + + return isNaN(a) ? 1 : a; + } + + /** + * Default color format to convert to when calling toString() or string() + * + * @returns {String} 'rgb', 'hsl', 'hex' or '' + */ + get format() { + return this._format ? this._format : this._color.model; + } + + /** + * Sets the hue value + * + * @param {int} value Integer from 0 to 360 + */ + set hue(value) { + this._color = this._color.hue(value); + } + + /** + * Sets the hue ratio, where 1.0 is 0, 0.5 is 180 and 0.0 is 360. + * + * @ignore + * @param {number} h Ratio from 1.0 to 0.0 + */ + setHueRatio(h) { + this.hue = ((1 - h) * 360); + } + + /** + * Sets the saturation value + * + * @param {int} value Integer from 0 to 100 + */ + set saturation(value) { + this._color = this._color.saturationv(value); + } + + /** + * Sets the saturation ratio, where 1.0 is 100 and 0.0 is 0. + * + * @ignore + * @param {number} s Ratio from 0.0 to 1.0 + */ + setSaturationRatio(s) { + this.saturation = (s * 100); + } + + /** + * Sets the 'value' channel value + * + * @param {int} value Integer from 0 to 100 + */ + set value(value) { + this._color = this._color.value(value); + } + + /** + * Sets the value ratio, where 1.0 is 0 and 0.0 is 100. + * + * @ignore + * @param {number} v Ratio from 1.0 to 0.0 + */ + setValueRatio(v) { + this.value = ((1 - v) * 100); + } + + /** + * Sets the alpha value. It will be rounded to 2 decimals. + * + * @param {int} value Float from 0.0 to 1.0 + */ + set alpha(value) { + // 2 decimals max + this._color = this._color.alpha(Math.round(value * 100) / 100); + } + + /** + * Sets the alpha ratio, where 1.0 is 0.0 and 0.0 is 1.0. + * + * @ignore + * @param {number} a Ratio from 1.0 to 0.0 + */ + setAlphaRatio(a) { + this.alpha = 1 - a; + } + + /** + * Sets the default color format + * + * @param {String} value Supported: 'rgb', 'hsl', 'hex' + */ + set format(value) { + this._format = ColorItem.sanitizeFormat(value); + } + + /** + * Returns true if the saturation value is zero, false otherwise + * + * @returns {boolean} + */ + isDesaturated() { + return this.saturation === 0; + } + + /** + * Returns true if the alpha value is zero, false otherwise + * + * @returns {boolean} + */ + isTransparent() { + return this.alpha === 0; + } + + /** + * Returns true if the alpha value is numeric and less than 1, false otherwise + * + * @returns {boolean} + */ + hasTransparency() { + return this.hasAlpha() && (this.alpha < 1); + } + + /** + * Returns true if the alpha value is numeric, false otherwise + * + * @returns {boolean} + */ + hasAlpha() { + return !isNaN(this.alpha); + } + + /** + * Returns a new HSVAColor object, based on the current color + * + * @returns {HSVAColor} + */ + toObject() { + return new HSVAColor(this.hue, this.saturation, this.value, this.alpha); + } + + /** + * Alias of toObject() + * + * @returns {HSVAColor} + */ + toHsva() { + return this.toObject(); + } + + /** + * Returns a new HSVAColor object with the ratio values (from 0.0 to 1.0), + * based on the current color. + * + * @ignore + * @returns {HSVAColor} + */ + toHsvaRatio() { + return new HSVAColor( + this.hue / 360, + this.saturation / 100, + this.value / 100, + this.alpha + ); + } + + /** + * Converts the current color to its string representation, + * using the internal format of this instance. + * + * @returns {String} + */ + toString() { + return this.string(); + } + + /** + * Converts the current color to its string representation, + * using the given format. + * + * @param {String|null} format Format to convert to. If empty or null, the internal format will be used. + * @returns {String} + */ + string(format = null) { + format = ColorItem.sanitizeFormat(format ? format : this.format); + + if (!format) { + return this._color.round().string(); + } + + if (this._color[format] === undefined) { + throw new Error(`Unsupported color format: '${format}'`); + } + + let str = this._color[format](); + + return str.round ? str.round().string() : str; + } + + /** + * Returns true if the given color values equals this one, false otherwise. + * The format is not compared. + * If any of the colors is invalid, the result will be false. + * + * @param {ColorItem|HSVAColor|QixColor|String|*|null} color Color data + * + * @returns {boolean} + */ + equals(color) { + color = (color instanceof ColorItem) ? color : new ColorItem(color); + + if (!color.isValid() || !this.isValid()) { + return false; + } + + return ( + this.hue === color.hue && + this.saturation === color.saturation && + this.value === color.value && + this.alpha === color.alpha + ); + } + + /** + * Creates a copy of this instance + * + * @returns {ColorItem} + */ + getClone() { + return new ColorItem(this._color, this.format); + } + + /** + * Creates a copy of this instance, only copying the hue value, + * and setting the others to its max value. + * + * @returns {ColorItem} + */ + getCloneHueOnly() { + return new ColorItem([this.hue, 100, 100, 1], this.format); + } + + /** + * Creates a copy of this instance setting the alpha to the max. + * + * @returns {ColorItem} + */ + getCloneOpaque() { + return new ColorItem(this._color.alpha(1), this.format); + } + + /** + * Converts the color to a RGB string + * + * @returns {String} + */ + toRgbString() { + return this.string('rgb'); + } + + /** + * Converts the color to a Hexadecimal string + * + * @returns {String} + */ + toHexString() { + return this.string('hex'); + } + + /** + * Converts the color to a HSL string + * + * @returns {String} + */ + toHslString() { + return this.string('hsl'); + } + + /** + * Returns true if the color is dark, false otherwhise. + * This is useful to decide a text color. + * + * @returns {boolean} + */ + isDark() { + return this._color.isDark(); + } + + /** + * Returns true if the color is light, false otherwhise. + * This is useful to decide a text color. + * + * @returns {boolean} + */ + isLight() { + return this._color.isLight(); + } + + /** + * Generates a list of colors using the given hue-based formula or the given array of hue values. + * Hue formulas can be extended using ColorItem.colorFormulas static property. + * + * @param {String|Number[]} formula Examples: 'complementary', 'triad', 'tetrad', 'splitcomplement', [180, 270] + * @example let colors = color.generate('triad'); + * @example let colors = color.generate([45, 80, 112, 200]); + * @returns {ColorItem[]} + */ + generate(formula) { + let hues = []; + + if (Array.isArray(formula)) { + hues = formula; + } else if (!ColorItem.colorFormulas.hasOwnProperty(formula)) { + throw new Error(`No color formula found with the name '${formula}'.`); + } else { + hues = ColorItem.colorFormulas[formula]; + } + + let colors = [], mainColor = this._color, format = this.format; + + hues.forEach(function (hue) { + let levels = [ + hue ? ((mainColor.hue() + hue) % 360) : mainColor.hue(), + mainColor.saturationv(), + mainColor.value(), + mainColor.alpha() + ]; + + colors.push(new ColorItem(levels, format)); + }); + + return colors; + } +} + +/** + * List of hue-based color formulas used by ColorItem.prototype.generate() + * + * @static + * @type {{complementary: number[], triad: number[], tetrad: number[], splitcomplement: number[]}} + */ +ColorItem.colorFormulas = { + complementary: [180], + triad: [0, 120, 240], + tetrad: [0, 90, 180, 270], + splitcomplement: [0, 72, 216] +}; + +export default ColorItem; + +export { + HSVAColor, + ColorItem +}; ADDED public/bootstrap-colorpicker/src/js/Colorpicker.js Index: public/bootstrap-colorpicker/src/js/Colorpicker.js ================================================================== --- public/bootstrap-colorpicker/src/js/Colorpicker.js +++ public/bootstrap-colorpicker/src/js/Colorpicker.js @@ -0,0 +1,452 @@ +'use strict'; + +import Extension from './Extension'; +import defaults from './options'; +import coreExtensions from 'extensions'; +import $ from 'jquery'; +import SliderHandler from './SliderHandler'; +import PopupHandler from './PopupHandler'; +import InputHandler from './InputHandler'; +import ColorHandler from './ColorHandler'; +import PickerHandler from './PickerHandler'; +import AddonHandler from './AddonHandler'; +import ColorItem from './ColorItem'; + +let colorPickerIdCounter = 0; +let root = (typeof self !== 'undefined' ? self : this); // window + +/** + * Colorpicker widget class + */ +class Colorpicker { + /** + * Color class + * + * @static + * @type {Color} + */ + static get Color() { + return ColorItem; + } + + /** + * Extension class + * + * @static + * @type {Extension} + */ + static get Extension() { + return Extension; + } + + /** + * Internal color object + * + * @type {Color|null} + */ + get color() { + return this.colorHandler.color; + } + + /** + * Internal color format + * + * @type {String|null} + */ + get format() { + return this.colorHandler.format; + } + + /** + * Getter of the picker element + * + * @returns {jQuery|HTMLElement} + */ + get picker() { + return this.pickerHandler.picker; + } + + /** + * @fires Colorpicker#colorpickerCreate + * @param {Object|String} element + * @param {Object} options + * @constructor + */ + constructor(element, options) { + colorPickerIdCounter += 1; + /** + * The colorpicker instance number + * @type {number} + */ + this.id = colorPickerIdCounter; + + /** + * Latest colorpicker event + * + * @type {{name: String, e: *}} + */ + this.lastEvent = { + alias: null, + e: null + }; + + /** + * The element that the colorpicker is bound to + * + * @type {*|jQuery} + */ + this.element = $(element) + .addClass('colorpicker-element') + .attr('data-colorpicker-id', this.id); + + /** + * @type {defaults} + */ + this.options = $.extend(true, {}, defaults, options, this.element.data()); + + /** + * @type {boolean} + * @private + */ + this.disabled = false; + + /** + * Extensions added to this instance + * + * @type {Extension[]} + */ + this.extensions = []; + + /** + * The element where the + * @type {*|jQuery} + */ + this.container = ( + this.options.container === true || + (this.options.container !== true && this.options.inline === true) + ) ? this.element : this.options.container; + + this.container = (this.container !== false) ? $(this.container) : false; + + /** + * @type {InputHandler} + */ + this.inputHandler = new InputHandler(this); + /** + * @type {ColorHandler} + */ + this.colorHandler = new ColorHandler(this); + /** + * @type {SliderHandler} + */ + this.sliderHandler = new SliderHandler(this); + /** + * @type {PopupHandler} + */ + this.popupHandler = new PopupHandler(this, root); + /** + * @type {PickerHandler} + */ + this.pickerHandler = new PickerHandler(this); + /** + * @type {AddonHandler} + */ + this.addonHandler = new AddonHandler(this); + + this.init(); + + // Emit a create event + $($.proxy(function () { + /** + * (Colorpicker) When the Colorpicker instance has been created and the DOM is ready. + * + * @event Colorpicker#colorpickerCreate + */ + this.trigger('colorpickerCreate'); + }, this)); + } + + /** + * Initializes the plugin + * @private + */ + init() { + // Init addon + this.addonHandler.bind(); + + // Init input + this.inputHandler.bind(); + + // Init extensions (before initializing the color) + this.initExtensions(); + + // Init color + this.colorHandler.bind(); + + // Init picker + this.pickerHandler.bind(); + + // Init sliders and popup + this.sliderHandler.bind(); + this.popupHandler.bind(); + + // Inject into the DOM (this may make it visible) + this.pickerHandler.attach(); + + // Update all components + this.update(); + + if (this.inputHandler.isDisabled()) { + this.disable(); + } + } + + /** + * Initializes the plugin extensions + * @private + */ + initExtensions() { + if (!Array.isArray(this.options.extensions)) { + this.options.extensions = []; + } + + if (this.options.debug) { + this.options.extensions.push({name: 'debugger'}); + } + + // Register and instantiate extensions + this.options.extensions.forEach((ext) => { + this.registerExtension(Colorpicker.extensions[ext.name.toLowerCase()], ext.options || {}); + }); + } + + /** + * Creates and registers the given extension + * + * @param {Extension} ExtensionClass The extension class to instantiate + * @param {Object} [config] Extension configuration + * @returns {Extension} + */ + registerExtension(ExtensionClass, config = {}) { + let ext = new ExtensionClass(this, config); + + this.extensions.push(ext); + return ext; + } + + /** + * Destroys the current instance + * + * @fires Colorpicker#colorpickerDestroy + */ + destroy() { + let color = this.color; + + this.sliderHandler.unbind(); + this.inputHandler.unbind(); + this.popupHandler.unbind(); + this.colorHandler.unbind(); + this.addonHandler.unbind(); + this.pickerHandler.unbind(); + + this.element + .removeClass('colorpicker-element') + .removeData('colorpicker', 'color') + .off('.colorpicker'); + + /** + * (Colorpicker) When the instance is destroyed with all events unbound. + * + * @event Colorpicker#colorpickerDestroy + */ + this.trigger('colorpickerDestroy', color); + } + + /** + * Shows the colorpicker widget if hidden. + * If the colorpicker is disabled this call will be ignored. + * + * @fires Colorpicker#colorpickerShow + * @param {Event} [e] + */ + show(e) { + this.popupHandler.show(e); + } + + /** + * Hides the colorpicker widget. + * + * @fires Colorpicker#colorpickerHide + * @param {Event} [e] + */ + hide(e) { + this.popupHandler.hide(e); + } + + /** + * Toggles the colorpicker between visible and hidden. + * + * @fires Colorpicker#colorpickerShow + * @fires Colorpicker#colorpickerHide + * @param {Event} [e] + */ + toggle(e) { + this.popupHandler.toggle(e); + } + + /** + * Returns the current color value as string + * + * @param {String|*} [defaultValue] + * @returns {String|*} + */ + getValue(defaultValue = null) { + let val = this.colorHandler.color; + + val = (val instanceof ColorItem) ? val : defaultValue; + + if (val instanceof ColorItem) { + return val.string(this.format); + } + + return val; + } + + /** + * Sets the color manually + * + * @fires Colorpicker#colorpickerChange + * @param {String|Color} val + */ + setValue(val) { + if (this.isDisabled()) { + return; + } + let ch = this.colorHandler; + + if ( + (ch.hasColor() && !!val && ch.color.equals(val)) || + (!ch.hasColor() && !val) + ) { + // same color or still empty + return; + } + + ch.color = val ? ch.createColor(val, this.options.autoInputFallback) : null; + + /** + * (Colorpicker) When the color is set programmatically with setValue(). + * + * @event Colorpicker#colorpickerChange + */ + this.trigger('colorpickerChange', ch.color, val); + + // force update if color has changed to empty + this.update(); + } + + /** + * Updates the UI and the input color according to the internal color. + * + * @fires Colorpicker#colorpickerUpdate + */ + update() { + if (this.colorHandler.hasColor()) { + this.inputHandler.update(); + } else { + this.colorHandler.assureColor(); + } + + this.addonHandler.update(); + this.pickerHandler.update(); + + /** + * (Colorpicker) Fired when the widget is updated. + * + * @event Colorpicker#colorpickerUpdate + */ + this.trigger('colorpickerUpdate'); + } + + /** + * Enables the widget and the input if any + * + * @fires Colorpicker#colorpickerEnable + * @returns {boolean} + */ + enable() { + this.inputHandler.enable(); + this.disabled = false; + this.picker.removeClass('colorpicker-disabled'); + + /** + * (Colorpicker) When the widget has been enabled. + * + * @event Colorpicker#colorpickerEnable + */ + this.trigger('colorpickerEnable'); + return true; + } + + /** + * Disables the widget and the input if any + * + * @fires Colorpicker#colorpickerDisable + * @returns {boolean} + */ + disable() { + this.inputHandler.disable(); + this.disabled = true; + this.picker.addClass('colorpicker-disabled'); + + /** + * (Colorpicker) When the widget has been disabled. + * + * @event Colorpicker#colorpickerDisable + */ + this.trigger('colorpickerDisable'); + return true; + } + + /** + * Returns true if this instance is enabled + * @returns {boolean} + */ + isEnabled() { + return !this.isDisabled(); + } + + /** + * Returns true if this instance is disabled + * @returns {boolean} + */ + isDisabled() { + return this.disabled === true; + } + + /** + * Triggers a Colorpicker event. + * + * @param eventName + * @param color + * @param value + */ + trigger(eventName, color = null, value = null) { + this.element.trigger({ + type: eventName, + colorpicker: this, + color: color ? color : this.color, + value: value ? value : this.getValue() + }); + } +} + +/** + * Colorpicker extension classes, indexed by extension name + * + * @static + * @type {Object} a map between the extension name and its class + */ +Colorpicker.extensions = coreExtensions; + +export default Colorpicker; ADDED public/bootstrap-colorpicker/src/js/Extension.js Index: public/bootstrap-colorpicker/src/js/Extension.js ================================================================== --- public/bootstrap-colorpicker/src/js/Extension.js +++ public/bootstrap-colorpicker/src/js/Extension.js @@ -0,0 +1,145 @@ +'use strict'; + +import $ from 'jquery'; + +/** + * Colorpicker extension class. + */ +class Extension { + /** + * @param {Colorpicker} colorpicker + * @param {Object} options + */ + constructor(colorpicker, options = {}) { + /** + * The colorpicker instance + * @type {Colorpicker} + */ + this.colorpicker = colorpicker; + /** + * Extension options + * + * @type {Object} + */ + this.options = options; + + if (!(this.colorpicker.element && this.colorpicker.element.length)) { + throw new Error('Extension: this.colorpicker.element is not valid'); + } + + this.colorpicker.element.on('colorpickerCreate.colorpicker-ext', $.proxy(this.onCreate, this)); + this.colorpicker.element.on('colorpickerDestroy.colorpicker-ext', $.proxy(this.onDestroy, this)); + this.colorpicker.element.on('colorpickerUpdate.colorpicker-ext', $.proxy(this.onUpdate, this)); + this.colorpicker.element.on('colorpickerChange.colorpicker-ext', $.proxy(this.onChange, this)); + this.colorpicker.element.on('colorpickerInvalid.colorpicker-ext', $.proxy(this.onInvalid, this)); + this.colorpicker.element.on('colorpickerShow.colorpicker-ext', $.proxy(this.onShow, this)); + this.colorpicker.element.on('colorpickerHide.colorpicker-ext', $.proxy(this.onHide, this)); + this.colorpicker.element.on('colorpickerEnable.colorpicker-ext', $.proxy(this.onEnable, this)); + this.colorpicker.element.on('colorpickerDisable.colorpicker-ext', $.proxy(this.onDisable, this)); + } + + /** + * Function called every time a new color needs to be created. + * Return false to skip this resolver and continue with other extensions' ones + * or return anything else to consider the color resolved. + * + * @param {ColorItem|String|*} color + * @param {boolean} realColor if true, the color should resolve into a real (not named) color code + * @return {ColorItem|String|*} + */ + resolveColor(color, realColor = true) { + return false; + } + + /** + * Method called after the colorpicker is created + * + * @listens Colorpicker#colorpickerCreate + * @param {Event} event + */ + onCreate(event) { + // to be extended + } + + /** + * Method called after the colorpicker is destroyed + * + * @listens Colorpicker#colorpickerDestroy + * @param {Event} event + */ + onDestroy(event) { + this.colorpicker.element.off('.colorpicker-ext'); + } + + /** + * Method called after the colorpicker is updated + * + * @listens Colorpicker#colorpickerUpdate + * @param {Event} event + */ + onUpdate(event) { + // to be extended + } + + /** + * Method called after the colorpicker color is changed + * + * @listens Colorpicker#colorpickerChange + * @param {Event} event + */ + onChange(event) { + // to be extended + } + + /** + * Method called when the colorpicker color is invalid + * + * @listens Colorpicker#colorpickerInvalid + * @param {Event} event + */ + onInvalid(event) { + // to be extended + } + + /** + * Method called after the colorpicker is hidden + * + * @listens Colorpicker#colorpickerHide + * @param {Event} event + */ + onHide(event) { + // to be extended + } + + /** + * Method called after the colorpicker is shown + * + * @listens Colorpicker#colorpickerShow + * @param {Event} event + */ + onShow(event) { + // to be extended + } + + /** + * Method called after the colorpicker is disabled + * + * @listens Colorpicker#colorpickerDisable + * @param {Event} event + */ + onDisable(event) { + // to be extended + } + + /** + * Method called after the colorpicker is enabled + * + * @listens Colorpicker#colorpickerEnable + * @param {Event} event + */ + onEnable(event) { + // to be extended + } +} + +export default Extension; ADDED public/bootstrap-colorpicker/src/js/InputHandler.js Index: public/bootstrap-colorpicker/src/js/InputHandler.js ================================================================== --- public/bootstrap-colorpicker/src/js/InputHandler.js +++ public/bootstrap-colorpicker/src/js/InputHandler.js @@ -0,0 +1,259 @@ +'use strict'; + +import $ from 'jquery'; +import ColorItem from './ColorItem'; + +/** + * Handles everything related to the colorpicker input + * @ignore + */ +class InputHandler { + /** + * @param {Colorpicker} colorpicker + */ + constructor(colorpicker) { + /** + * @type {Colorpicker} + */ + this.colorpicker = colorpicker; + /** + * @type {jQuery|false} + */ + this.input = this.colorpicker.element.is('input') ? this.colorpicker.element : (this.colorpicker.options.input ? + this.colorpicker.element.find(this.colorpicker.options.input) : false); + + if (this.input && (this.input.length === 0)) { + this.input = false; + } + + this._initValue(); + } + + bind() { + if (!this.hasInput()) { + return; + } + this.input.on({ + 'keyup.colorpicker': $.proxy(this.onkeyup, this) + }); + this.input.on({ + 'change.colorpicker': $.proxy(this.onchange, this) + }); + } + + unbind() { + if (!this.hasInput()) { + return; + } + this.input.off('.colorpicker'); + } + + _initValue() { + if (!this.hasInput()) { + return; + } + + let val = ''; + + [ + // candidates: + this.input.val(), + this.input.data('color'), + this.input.attr('data-color') + ].map((item) => { + if (item && (val === '')) { + val = item; + } + }); + + if (val instanceof ColorItem) { + val = this.getFormattedColor(val.string(this.colorpicker.format)); + } else if (!(typeof val === 'string' || val instanceof String)) { + val = ''; + } + + this.input.prop('value', val); + } + + /** + * Returns the color string from the input value. + * If there is no input the return value is false. + * + * @returns {String|boolean} + */ + getValue() { + if (!this.hasInput()) { + return false; + } + + return this.input.val(); + } + + /** + * If the input element is present, it updates the value with the current color object color string. + * If the value is changed, this method fires a "change" event on the input element. + * + * @param {String} val + * + * @fires Colorpicker#change + */ + setValue(val) { + if (!this.hasInput()) { + return; + } + + let inputVal = this.input.prop('value'); + + val = val ? val : ''; + + if (val === (inputVal ? inputVal : '')) { + // No need to set value or trigger any event if nothing changed + return; + } + + this.input.prop('value', val); + + /** + * (Input) Triggered on the input element when a new color is selected. + * + * @event Colorpicker#change + */ + this.input.trigger({ + type: 'change', + colorpicker: this.colorpicker, + color: this.colorpicker.color, + value: val + }); + } + + /** + * Returns the formatted color string, with the formatting options applied + * (e.g. useHashPrefix) + * + * @param {String|null} val + * + * @returns {String} + */ + getFormattedColor(val = null) { + val = val ? val : this.colorpicker.colorHandler.getColorString(); + + if (!val) { + return ''; + } + + val = this.colorpicker.colorHandler.resolveColorDelegate(val, false); + + if (this.colorpicker.options.useHashPrefix === false) { + val = val.replace(/^#/g, ''); + } + + return val; + } + + /** + * Returns true if the widget has an associated input element, false otherwise + * @returns {boolean} + */ + hasInput() { + return (this.input !== false); + } + + /** + * Returns true if the input exists and is disabled + * @returns {boolean} + */ + isEnabled() { + return this.hasInput() && !this.isDisabled(); + } + + /** + * Returns true if the input exists and is disabled + * @returns {boolean} + */ + isDisabled() { + return this.hasInput() && (this.input.prop('disabled') === true); + } + + /** + * Disables the input if any + * + * @fires Colorpicker#colorpickerDisable + * @returns {boolean} + */ + disable() { + if (this.hasInput()) { + this.input.prop('disabled', true); + } + } + + /** + * Enables the input if any + * + * @fires Colorpicker#colorpickerEnable + * @returns {boolean} + */ + enable() { + if (this.hasInput()) { + this.input.prop('disabled', false); + } + } + + /** + * Calls setValue with the current internal color value + * + * @fires Colorpicker#change + */ + update() { + if (!this.hasInput()) { + return; + } + + if ( + (this.colorpicker.options.autoInputFallback === false) && + this.colorpicker.colorHandler.isInvalidColor() + ) { + // prevent update if color is invalid, autoInputFallback is disabled and the last event is keyup. + return; + } + + this.setValue(this.getFormattedColor()); + } + + /** + * Function triggered when the input has changed, so the colorpicker gets updated. + * + * @private + * @param {Event} e + * @returns {boolean} + */ + onchange(e) { + this.colorpicker.lastEvent.alias = 'input.change'; + this.colorpicker.lastEvent.e = e; + + let val = this.getValue(); + + if (val !== e.value) { + this.colorpicker.setValue(val); + } + } + + /** + * Function triggered after a keyboard key has been released. + * + * @private + * @param {Event} e + * @returns {boolean} + */ + onkeyup(e) { + this.colorpicker.lastEvent.alias = 'input.keyup'; + this.colorpicker.lastEvent.e = e; + + let val = this.getValue(); + + if (val !== e.value) { + this.colorpicker.setValue(val); + } + } +} + +export default InputHandler; ADDED public/bootstrap-colorpicker/src/js/PickerHandler.js Index: public/bootstrap-colorpicker/src/js/PickerHandler.js ================================================================== --- public/bootstrap-colorpicker/src/js/PickerHandler.js +++ public/bootstrap-colorpicker/src/js/PickerHandler.js @@ -0,0 +1,124 @@ +'use strict'; + +import $ from 'jquery'; + +/** + * Handles everything related to the colorpicker UI + * @ignore + */ +class PickerHandler { + /** + * @param {Colorpicker} colorpicker + */ + constructor(colorpicker) { + /** + * @type {Colorpicker} + */ + this.colorpicker = colorpicker; + /** + * @type {jQuery} + */ + this.picker = null; + } + + get options() { + return this.colorpicker.options; + } + + get color() { + return this.colorpicker.colorHandler.color; + } + + bind() { + /** + * @type {jQuery|HTMLElement} + */ + let picker = this.picker = $(this.options.template); + + if (this.options.customClass) { + picker.addClass(this.options.customClass); + } + + if (this.options.horizontal) { + picker.addClass('colorpicker-horizontal'); + } + + if (this._supportsAlphaBar()) { + this.options.useAlpha = true; + picker.addClass('colorpicker-with-alpha'); + } else { + this.options.useAlpha = false; + } + } + + attach() { + // Inject the colorpicker element into the DOM + let pickerParent = this.colorpicker.container ? this.colorpicker.container : null; + + if (pickerParent) { + this.picker.appendTo(pickerParent); + } + } + + unbind() { + this.picker.remove(); + } + + _supportsAlphaBar() { + return ( + (this.options.useAlpha || (this.colorpicker.colorHandler.hasColor() && this.color.hasTransparency())) && + (this.options.useAlpha !== false) && + (!this.options.format || (this.options.format && !this.options.format.match(/^hex([36])?$/i))) + ); + } + + /** + * Changes the color adjustment bars using the current color object information. + */ + update() { + if (!this.colorpicker.colorHandler.hasColor()) { + return; + } + + let vertical = (this.options.horizontal !== true), + slider = vertical ? this.options.sliders : this.options.slidersHorz; + + let saturationGuide = this.picker.find('.colorpicker-saturation .colorpicker-guide'), + hueGuide = this.picker.find('.colorpicker-hue .colorpicker-guide'), + alphaGuide = this.picker.find('.colorpicker-alpha .colorpicker-guide'); + + let hsva = this.color.toHsvaRatio(); + + // Set guides position + if (hueGuide.length) { + hueGuide.css(vertical ? 'top' : 'left', (vertical ? slider.hue.maxTop : slider.hue.maxLeft) * (1 - hsva.h)); + } + if (alphaGuide.length) { + alphaGuide.css(vertical ? 'top' : 'left', (vertical ? slider.alpha.maxTop : slider.alpha.maxLeft) * (1 - hsva.a)); + } + if (saturationGuide.length) { + saturationGuide.css({ + 'top': slider.saturation.maxTop - hsva.v * slider.saturation.maxTop, + 'left': hsva.s * slider.saturation.maxLeft + }); + } + + // Set saturation hue background + this.picker.find('.colorpicker-saturation') + .css('backgroundColor', this.color.getCloneHueOnly().toHexString()); // we only need hue + + // Set alpha color gradient + let hexColor = this.color.toHexString(); + let alphaBg = ''; + + if (this.options.horizontal) { + alphaBg = `linear-gradient(to right, ${hexColor} 0%, transparent 100%)`; + } else { + alphaBg = `linear-gradient(to bottom, ${hexColor} 0%, transparent 100%)`; + } + + this.picker.find('.colorpicker-alpha-color').css('background', alphaBg); + } +} + +export default PickerHandler; ADDED public/bootstrap-colorpicker/src/js/PopupHandler.js Index: public/bootstrap-colorpicker/src/js/PopupHandler.js ================================================================== --- public/bootstrap-colorpicker/src/js/PopupHandler.js +++ public/bootstrap-colorpicker/src/js/PopupHandler.js @@ -0,0 +1,417 @@ +'use strict'; + +import $ from 'jquery'; +import _defaults from './options'; + +/** + * Handles everything related to the UI of the colorpicker popup: show, hide, position,... + * @ignore + */ +class PopupHandler { + /** + * @param {Colorpicker} colorpicker + * @param {Window} root + */ + constructor(colorpicker, root) { + /** + * @type {Window} + */ + this.root = root; + /** + * @type {Colorpicker} + */ + this.colorpicker = colorpicker; + /** + * @type {jQuery} + */ + this.popoverTarget = null; + /** + * @type {jQuery} + */ + this.popoverTip = null; + + /** + * If true, the latest click was inside the popover + * @type {boolean} + */ + this.clicking = false; + /** + * @type {boolean} + */ + this.hidding = false; + /** + * @type {boolean} + */ + this.showing = false; + } + + /** + * @private + * @returns {jQuery|false} + */ + get input() { + return this.colorpicker.inputHandler.input; + } + + /** + * @private + * @returns {boolean} + */ + get hasInput() { + return this.colorpicker.inputHandler.hasInput(); + } + + /** + * @private + * @returns {jQuery|false} + */ + get addon() { + return this.colorpicker.addonHandler.addon; + } + + /** + * @private + * @returns {boolean} + */ + get hasAddon() { + return this.colorpicker.addonHandler.hasAddon(); + } + + /** + * @private + * @returns {boolean} + */ + get isPopover() { + return !this.colorpicker.options.inline && !!this.popoverTip; + } + + /** + * Binds the different colorpicker elements to the focus/mouse/touch events so it reacts in order to show or + * hide the colorpicker popup accordingly. It also adds the proper classes. + */ + bind() { + let cp = this.colorpicker; + + if (cp.options.inline) { + cp.picker.addClass('colorpicker-inline colorpicker-visible'); + return; // no need to bind show/hide events for inline elements + } + + cp.picker.addClass('colorpicker-popup colorpicker-hidden'); + + // there is no input or addon + if (!this.hasInput && !this.hasAddon) { + return; + } + + // create Bootstrap 4 popover + if (cp.options.popover) { + this.createPopover(); + } + + // bind addon show/hide events + if (this.hasAddon) { + // enable focus on addons + if (!this.addon.attr('tabindex')) { + this.addon.attr('tabindex', 0); + } + + this.addon.on({ + 'mousedown.colorpicker touchstart.colorpicker': $.proxy(this.toggle, this) + }); + + this.addon.on({ + 'focus.colorpicker': $.proxy(this.show, this) + }); + + this.addon.on({ + 'focusout.colorpicker': $.proxy(this.hide, this) + }); + } + + // bind input show/hide events + if (this.hasInput && !this.hasAddon) { + this.input.on({ + 'mousedown.colorpicker touchstart.colorpicker': $.proxy(this.show, this), + 'focus.colorpicker': $.proxy(this.show, this) + }); + + this.input.on({ + 'focusout.colorpicker': $.proxy(this.hide, this) + }); + } + + // reposition popup on window resize + $(this.root).on('resize.colorpicker', $.proxy(this.reposition, this)); + } + + /** + * Unbinds any event bound by this handler + */ + unbind() { + if (this.hasInput) { + this.input.off({ + 'mousedown.colorpicker touchstart.colorpicker': $.proxy(this.show, this), + 'focus.colorpicker': $.proxy(this.show, this) + }); + this.input.off({ + 'focusout.colorpicker': $.proxy(this.hide, this) + }); + } + + if (this.hasAddon) { + this.addon.off({ + 'mousedown.colorpicker touchstart.colorpicker': $.proxy(this.toggle, this) + }); + this.addon.off({ + 'focus.colorpicker': $.proxy(this.show, this) + }); + this.addon.off({ + 'focusout.colorpicker': $.proxy(this.hide, this) + }); + } + + if (this.popoverTarget) { + this.popoverTarget.popover('dispose'); + } + + $(this.root).off('resize.colorpicker', $.proxy(this.reposition, this)); + $(this.root.document).off('mousedown.colorpicker touchstart.colorpicker', $.proxy(this.hide, this)); + $(this.root.document).off('mousedown.colorpicker touchstart.colorpicker', $.proxy(this.onClickingInside, this)); + } + + isClickingInside(e) { + if (!e) { + return false; + } + + return ( + this.isOrIsInside(this.popoverTip, e.currentTarget) || + this.isOrIsInside(this.popoverTip, e.target) || + this.isOrIsInside(this.colorpicker.picker, e.currentTarget) || + this.isOrIsInside(this.colorpicker.picker, e.target) + ); + } + + isOrIsInside(container, element) { + if (!container || !element) { + return false; + } + + element = $(element); + + return ( + element.is(container) || + container.find(element).length > 0 + ); + } + + onClickingInside(e) { + this.clicking = this.isClickingInside(e); + } + + createPopover() { + let cp = this.colorpicker; + + this.popoverTarget = this.hasAddon ? this.addon : this.input; + + cp.picker.addClass('colorpicker-bs-popover-content'); + + this.popoverTarget.popover( + $.extend( + true, + {}, + _defaults.popover, + cp.options.popover, + {trigger: 'manual', content: cp.picker, html: true} + ) + ); + + this.popoverTip = $(this.popoverTarget.popover('getTipElement').data('bs.popover').tip); + this.popoverTip.addClass('colorpicker-bs-popover'); + + this.popoverTarget.on('shown.bs.popover', $.proxy(this.fireShow, this)); + this.popoverTarget.on('hidden.bs.popover', $.proxy(this.fireHide, this)); + } + + /** + * If the widget is not inside a container or inline, rearranges its position relative to its element offset. + * + * @param {Event} [e] + * @private + */ + reposition(e) { + if (this.popoverTarget && this.isVisible()) { + this.popoverTarget.popover('update'); + } + } + + /** + * Toggles the colorpicker between visible or hidden + * + * @fires Colorpicker#colorpickerShow + * @fires Colorpicker#colorpickerHide + * @param {Event} [e] + */ + toggle(e) { + if (this.isVisible()) { + this.hide(e); + } else { + this.show(e); + } + } + + /** + * Shows the colorpicker widget if hidden. + * + * @fires Colorpicker#colorpickerShow + * @param {Event} [e] + */ + show(e) { + if (this.isVisible() || this.showing || this.hidding) { + return; + } + + this.showing = true; + this.hidding = false; + this.clicking = false; + + let cp = this.colorpicker; + + cp.lastEvent.alias = 'show'; + cp.lastEvent.e = e; + + // Prevent showing browser native HTML5 colorpicker + if ( + (e && (!this.hasInput || this.input.attr('type') === 'color')) && + (e && e.preventDefault) + ) { + e.stopPropagation(); + e.preventDefault(); + } + + // If it's a popover, add event to the document to hide the picker when clicking outside of it + if (this.isPopover) { + $(this.root).on('resize.colorpicker', $.proxy(this.reposition, this)); + } + + // add visible class before popover is shown + cp.picker.addClass('colorpicker-visible').removeClass('colorpicker-hidden'); + + if (this.popoverTarget) { + this.popoverTarget.popover('show'); + } else { + this.fireShow(); + } + } + + fireShow() { + this.hidding = false; + this.showing = false; + + if (this.isPopover) { + // Add event to hide on outside click + $(this.root.document).on('mousedown.colorpicker touchstart.colorpicker', $.proxy(this.hide, this)); + $(this.root.document).on('mousedown.colorpicker touchstart.colorpicker', $.proxy(this.onClickingInside, this)); + } + + /** + * (Colorpicker) When show() is called and the widget can be shown. + * + * @event Colorpicker#colorpickerShow + */ + this.colorpicker.trigger('colorpickerShow'); + } + + /** + * Hides the colorpicker widget. + * Hide is prevented when it is triggered by an event whose target element has been clicked/touched. + * + * @fires Colorpicker#colorpickerHide + * @param {Event} [e] + */ + hide(e) { + if (this.isHidden() || this.showing || this.hidding) { + return; + } + + let cp = this.colorpicker, clicking = (this.clicking || this.isClickingInside(e)); + + this.hidding = true; + this.showing = false; + this.clicking = false; + + cp.lastEvent.alias = 'hide'; + cp.lastEvent.e = e; + + // TODO: fix having to click twice outside when losing focus and last 2 clicks where inside the colorpicker + + // Prevent hide if triggered by an event and an element inside the colorpicker has been clicked/touched + if (clicking) { + this.hidding = false; + return; + } + + if (this.popoverTarget) { + this.popoverTarget.popover('hide'); + } else { + this.fireHide(); + } + } + + fireHide() { + this.hidding = false; + this.showing = false; + + let cp = this.colorpicker; + + // add hidden class after popover is hidden + cp.picker.addClass('colorpicker-hidden').removeClass('colorpicker-visible'); + + // Unbind window and document events, since there is no need to keep them while the popup is hidden + $(this.root).off('resize.colorpicker', $.proxy(this.reposition, this)); + $(this.root.document).off('mousedown.colorpicker touchstart.colorpicker', $.proxy(this.hide, this)); + $(this.root.document).off('mousedown.colorpicker touchstart.colorpicker', $.proxy(this.onClickingInside, this)); + + /** + * (Colorpicker) When hide() is called and the widget can be hidden. + * + * @event Colorpicker#colorpickerHide + */ + cp.trigger('colorpickerHide'); + } + + focus() { + if (this.hasAddon) { + return this.addon.focus(); + } + if (this.hasInput) { + return this.input.focus(); + } + return false; + } + + /** + * Returns true if the colorpicker element has the colorpicker-visible class and not the colorpicker-hidden one. + * False otherwise. + * + * @returns {boolean} + */ + isVisible() { + return this.colorpicker.picker.hasClass('colorpicker-visible') && + !this.colorpicker.picker.hasClass('colorpicker-hidden'); + } + + /** + * Returns true if the colorpicker element has the colorpicker-hidden class and not the colorpicker-visible one. + * False otherwise. + * + * @returns {boolean} + */ + isHidden() { + return this.colorpicker.picker.hasClass('colorpicker-hidden') && + !this.colorpicker.picker.hasClass('colorpicker-visible'); + } +} + +export default PopupHandler; ADDED public/bootstrap-colorpicker/src/js/SliderHandler.js Index: public/bootstrap-colorpicker/src/js/SliderHandler.js ================================================================== --- public/bootstrap-colorpicker/src/js/SliderHandler.js +++ public/bootstrap-colorpicker/src/js/SliderHandler.js @@ -0,0 +1,246 @@ +'use strict'; + +import $ from 'jquery'; + +/** + * Class that handles all configured sliders on mouse or touch events. + * @ignore + */ +class SliderHandler { + /** + * @param {Colorpicker} colorpicker + */ + constructor(colorpicker) { + /** + * @type {Colorpicker} + */ + this.colorpicker = colorpicker; + /** + * @type {*|String} + * @private + */ + this.currentSlider = null; + /** + * @type {{left: number, top: number}} + * @private + */ + this.mousePointer = { + left: 0, + top: 0 + }; + + /** + * @type {Function} + */ + this.onMove = $.proxy(this.defaultOnMove, this); + } + + /** + * This function is called every time a slider guide is moved + * The scope of "this" is the SliderHandler object. + * + * @param {int} top + * @param {int} left + */ + defaultOnMove(top, left) { + if (!this.currentSlider) { + return; + } + + let slider = this.currentSlider, cp = this.colorpicker, ch = cp.colorHandler; + + // Create a color object + let color = !ch.hasColor() ? ch.getFallbackColor() : ch.color.getClone(); + + // Adjust the guide position + slider.guideStyle.left = left + 'px'; + slider.guideStyle.top = top + 'px'; + + // Adjust the color + if (slider.callLeft) { + color[slider.callLeft](left / slider.maxLeft); + } + if (slider.callTop) { + color[slider.callTop](top / slider.maxTop); + } + + // Set the new color + cp.setValue(color); + cp.popupHandler.focus(); + } + + /** + * Binds the colorpicker sliders to the mouse/touch events + */ + bind() { + let sliders = this.colorpicker.options.horizontal ? this.colorpicker + .options.slidersHorz : this.colorpicker.options.sliders; + let sliderClasses = []; + + for (let sliderName in sliders) { + if (!sliders.hasOwnProperty(sliderName)) { + continue; + } + + sliderClasses.push(sliders[sliderName].selector); + } + + this.colorpicker.picker.find(sliderClasses.join(', ')) + .on('mousedown.colorpicker touchstart.colorpicker', $.proxy(this.pressed, this)); + } + + /** + * Unbinds any event bound by this handler + */ + unbind() { + $(this.colorpicker.picker).off({ + 'mousemove.colorpicker': $.proxy(this.moved, this), + 'touchmove.colorpicker': $.proxy(this.moved, this), + 'mouseup.colorpicker': $.proxy(this.released, this), + 'touchend.colorpicker': $.proxy(this.released, this) + }); + } + + /** + * Function triggered when clicking in one of the color adjustment bars + * + * @private + * @fires Colorpicker#mousemove + * @param {Event} e + */ + pressed(e) { + if (this.colorpicker.isDisabled()) { + return; + } + this.colorpicker.lastEvent.alias = 'pressed'; + this.colorpicker.lastEvent.e = e; + + if (!e.pageX && !e.pageY && e.originalEvent && e.originalEvent.touches) { + e.pageX = e.originalEvent.touches[0].pageX; + e.pageY = e.originalEvent.touches[0].pageY; + } + // e.stopPropagation(); + // e.preventDefault(); + + let target = $(e.target); + + // detect the slider and set the limits and callbacks + let zone = target.closest('div'); + let sliders = this.colorpicker.options.horizontal ? this.colorpicker + .options.slidersHorz : this.colorpicker.options.sliders; + + if (zone.is('.colorpicker')) { + return; + } + + this.currentSlider = null; + + for (let sliderName in sliders) { + if (!sliders.hasOwnProperty(sliderName)) { + continue; + } + + let slider = sliders[sliderName]; + + if (zone.is(slider.selector)) { + this.currentSlider = $.extend({}, slider, {name: sliderName}); + break; + } else if (slider.childSelector !== undefined && zone.is(slider.childSelector)) { + this.currentSlider = $.extend({}, slider, {name: sliderName}); + zone = zone.parent(); // zone.parents(slider.selector).first() ? + break; + } + } + + let guide = zone.find('.colorpicker-guide').get(0); + + if (this.currentSlider === null || guide === null) { + return; + } + + let offset = zone.offset(); + + // reference to guide's style + this.currentSlider.guideStyle = guide.style; + this.currentSlider.left = e.pageX - offset.left; + this.currentSlider.top = e.pageY - offset.top; + this.mousePointer = { + left: e.pageX, + top: e.pageY + }; + + // TODO: fix moving outside the picker makes the guides to keep moving. The event needs to be bound to the window. + /** + * (window.document) Triggered on mousedown for the document object, + * so the color adjustment guide is moved to the clicked position. + * + * @event Colorpicker#mousemove + */ + $(this.colorpicker.picker).on({ + 'mousemove.colorpicker': $.proxy(this.moved, this), + 'touchmove.colorpicker': $.proxy(this.moved, this), + 'mouseup.colorpicker': $.proxy(this.released, this), + 'touchend.colorpicker': $.proxy(this.released, this) + }).trigger('mousemove'); + } + + /** + * Function triggered when dragging a guide inside one of the color adjustment bars. + * + * @private + * @param {Event} e + */ + moved(e) { + this.colorpicker.lastEvent.alias = 'moved'; + this.colorpicker.lastEvent.e = e; + + if (!e.pageX && !e.pageY && e.originalEvent && e.originalEvent.touches) { + e.pageX = e.originalEvent.touches[0].pageX; + e.pageY = e.originalEvent.touches[0].pageY; + } + + // e.stopPropagation(); + e.preventDefault(); // prevents scrolling on mobile + + let left = Math.max( + 0, + Math.min( + this.currentSlider.maxLeft, + this.currentSlider.left + ((e.pageX || this.mousePointer.left) - this.mousePointer.left) + ) + ); + + let top = Math.max( + 0, + Math.min( + this.currentSlider.maxTop, + this.currentSlider.top + ((e.pageY || this.mousePointer.top) - this.mousePointer.top) + ) + ); + + this.onMove(top, left); + } + + /** + * Function triggered when releasing the click in one of the color adjustment bars. + * + * @private + * @param {Event} e + */ + released(e) { + this.colorpicker.lastEvent.alias = 'released'; + this.colorpicker.lastEvent.e = e; + + // e.stopPropagation(); + // e.preventDefault(); + + $(this.colorpicker.picker).off({ + 'mousemove.colorpicker': this.moved, + 'touchmove.colorpicker': this.moved, + 'mouseup.colorpicker': this.released, + 'touchend.colorpicker': this.released + }); + } +} + +export default SliderHandler; ADDED public/bootstrap-colorpicker/src/js/extensions/Debugger.js Index: public/bootstrap-colorpicker/src/js/extensions/Debugger.js ================================================================== --- public/bootstrap-colorpicker/src/js/extensions/Debugger.js +++ public/bootstrap-colorpicker/src/js/extensions/Debugger.js @@ -0,0 +1,119 @@ +'use strict'; + +import Extension from 'Extension'; +import $ from 'jquery'; + +/** + * Debugger extension class + * @alias DebuggerExtension + * @ignore + */ +class Debugger extends Extension { + constructor(colorpicker, options = {}) { + super(colorpicker, options); + + /** + * @type {number} + */ + this.eventCounter = 0; + if (this.colorpicker.inputHandler.hasInput()) { + this.colorpicker.inputHandler.input.on('change.colorpicker-ext', $.proxy(this.onChangeInput, this)); + } + } + + /** + * @fires DebuggerExtension#colorpickerDebug + * @param {string} eventName + * @param {*} args + */ + log(eventName, ...args) { + this.eventCounter += 1; + + let logMessage = `#${this.eventCounter}: Colorpicker#${this.colorpicker.id} [${eventName}]`; + + console.debug(logMessage, ...args); + + /** + * Whenever the debugger logs an event, this other event is emitted. + * + * @event DebuggerExtension#colorpickerDebug + * @type {object} The event object + * @property {Colorpicker} colorpicker The Colorpicker instance + * @property {ColorItem} color The color instance + * @property {{debugger: DebuggerExtension, eventName: String, logArgs: Array, logMessage: String}} debug + * The debug info + */ + this.colorpicker.element.trigger({ + type: 'colorpickerDebug', + colorpicker: this.colorpicker, + color: this.color, + value: null, + debug: { + debugger: this, + eventName: eventName, + logArgs: args, + logMessage: logMessage + } + }); + } + + resolveColor(color, realColor = true) { + this.log('resolveColor()', color, realColor); + return false; + } + + onCreate(event) { + this.log('colorpickerCreate'); + return super.onCreate(event); + } + + onDestroy(event) { + this.log('colorpickerDestroy'); + this.eventCounter = 0; + + if (this.colorpicker.inputHandler.hasInput()) { + this.colorpicker.inputHandler.input.off('.colorpicker-ext'); + } + + return super.onDestroy(event); + } + + onUpdate(event) { + this.log('colorpickerUpdate'); + } + + /** + * @listens Colorpicker#change + * @param {Event} event + */ + onChangeInput(event) { + this.log('input:change.colorpicker', event.value, event.color); + } + + onChange(event) { + this.log('colorpickerChange', event.value, event.color); + } + + onInvalid(event) { + this.log('colorpickerInvalid', event.value, event.color); + } + + onHide(event) { + this.log('colorpickerHide'); + this.eventCounter = 0; + } + + onShow(event) { + this.log('colorpickerShow'); + } + + onDisable(event) { + this.log('colorpickerDisable'); + } + + onEnable(event) { + this.log('colorpickerEnable'); + } +} + +export default Debugger; ADDED public/bootstrap-colorpicker/src/js/extensions/Palette.js Index: public/bootstrap-colorpicker/src/js/extensions/Palette.js ================================================================== --- public/bootstrap-colorpicker/src/js/extensions/Palette.js +++ public/bootstrap-colorpicker/src/js/extensions/Palette.js @@ -0,0 +1,150 @@ +'use strict'; + +import Extension from 'Extension'; +import $ from 'jquery'; + +let defaults = { + /** + * Key-value pairs defining a color alias and its CSS color representation. + * + * They can also be just an array of values. In that case, no special names are used, only the real colors. + * + * @type {Object|Array} + * @default null + * @example + * { + * 'black': '#000000', + * 'white': '#ffffff', + * 'red': '#FF0000', + * 'default': '#777777', + * 'primary': '#337ab7', + * 'success': '#5cb85c', + * 'info': '#5bc0de', + * 'warning': '#f0ad4e', + * 'danger': '#d9534f' + * } + * + * @example ['#f0ad4e', '#337ab7', '#5cb85c'] + */ + colors: null, + /** + * If true, when a color swatch is selected the name (alias) will be used as input value, + * otherwise the swatch real color value will be used. + * + * @type {boolean} + * @default true + */ + namesAsValues: true +}; + +/** + * Palette extension + * @ignore + */ +class Palette extends Extension { + + /** + * @returns {Object|Array} + */ + get colors() { + return this.options.colors; + } + + constructor(colorpicker, options = {}) { + super(colorpicker, $.extend(true, {}, defaults, options)); + + if ((!Array.isArray(this.options.colors)) && (typeof this.options.colors !== 'object')) { + this.options.colors = null; + } + } + + /** + * @returns {int} + */ + getLength() { + if (!this.options.colors) { + return 0; + } + + if (Array.isArray(this.options.colors)) { + return this.options.colors.length; + } + + if (typeof this.options.colors === 'object') { + return Object.keys(this.options.colors).length; + } + + return 0; + } + + resolveColor(color, realColor = true) { + if (this.getLength() <= 0) { + return false; + } + + // Array of colors + if (Array.isArray(this.options.colors)) { + if (this.options.colors.indexOf(color) >= 0) { + return color; + } + if (this.options.colors.indexOf(color.toUpperCase()) >= 0) { + return color.toUpperCase(); + } + if (this.options.colors.indexOf(color.toLowerCase()) >= 0) { + return color.toLowerCase(); + } + return false; + } + + if (typeof this.options.colors !== 'object') { + return false; + } + + // Map of objects + if (!this.options.namesAsValues || realColor) { + return this.getValue(color, false); + } + return this.getName(color, this.getName('#' + color)); + } + + /** + * Given a color value, returns the corresponding color name or defaultValue. + * + * @param {String} value + * @param {*} defaultValue + * @returns {*} + */ + getName(value, defaultValue = false) { + if (!(typeof value === 'string') || !this.options.colors) { + return defaultValue; + } + for (let name in this.options.colors) { + if (!this.options.colors.hasOwnProperty(name)) { + continue; + } + if (this.options.colors[name].toLowerCase() === value.toLowerCase()) { + return name; + } + } + return defaultValue; + } + + /** + * Given a color name, returns the corresponding color value or defaultValue. + * + * @param {String} name + * @param {*} defaultValue + * @returns {*} + */ + getValue(name, defaultValue = false) { + if (!(typeof name === 'string') || !this.options.colors) { + return defaultValue; + } + if (this.options.colors.hasOwnProperty(name)) { + return this.options.colors[name]; + } + return defaultValue; + } +} + +export default Palette; ADDED public/bootstrap-colorpicker/src/js/extensions/Preview.js Index: public/bootstrap-colorpicker/src/js/extensions/Preview.js ================================================================== --- public/bootstrap-colorpicker/src/js/extensions/Preview.js +++ public/bootstrap-colorpicker/src/js/extensions/Preview.js @@ -0,0 +1,57 @@ +'use strict'; + +import Extension from 'Extension'; +import $ from 'jquery'; + +/** + * Color preview extension + * @ignore + */ +class Preview extends Extension { + constructor(colorpicker, options = {}) { + super(colorpicker, $.extend(true, {}, + { + template: '
', + showText: true, + format: colorpicker.format + }, + options + )); + + this.element = $(this.options.template); + this.elementInner = this.element.find('div'); + } + + onCreate(event) { + super.onCreate(event); + this.colorpicker.picker.append(this.element); + } + + onUpdate(event) { + super.onUpdate(event); + + if (!event.color) { + this.elementInner + .css('backgroundColor', null) + .css('color', null) + .html(''); + return; + } + + this.elementInner + .css('backgroundColor', event.color.toRgbString()); + + if (this.options.showText) { + this.elementInner + .html(event.color.string(this.options.format || this.colorpicker.format)); + + if (event.color.isDark() && (event.color.alpha > 0.5)) { + this.elementInner.css('color', 'white'); + } else { + this.elementInner.css('color', 'black'); + } + } + } +} + +export default Preview; ADDED public/bootstrap-colorpicker/src/js/extensions/Swatches.js Index: public/bootstrap-colorpicker/src/js/extensions/Swatches.js ================================================================== --- public/bootstrap-colorpicker/src/js/extensions/Swatches.js +++ public/bootstrap-colorpicker/src/js/extensions/Swatches.js @@ -0,0 +1,71 @@ +'use strict'; + +import Palette from './Palette'; +import $ from 'jquery'; + +let defaults = { + barTemplate: `
+
+
`, + swatchTemplate: '' +}; + +/** + * Color swatches extension + * @ignore + */ +class Swatches extends Palette { + constructor(colorpicker, options = {}) { + super(colorpicker, $.extend(true, {}, defaults, options)); + this.element = null; + } + + isEnabled() { + return this.getLength() > 0; + } + + onCreate(event) { + super.onCreate(event); + + if (!this.isEnabled()) { + return; + } + + this.element = $(this.options.barTemplate); + this.load(); + this.colorpicker.picker.append(this.element); + } + + load() { + let colorpicker = this.colorpicker, + swatchContainer = this.element.find('.colorpicker-swatches--inner'), + isAliased = (this.options.namesAsValues === true) && !Array.isArray(this.colors); + + swatchContainer.empty(); + + $.each(this.colors, (name, value) => { + let $swatch = $(this.options.swatchTemplate) + .attr('data-name', name) + .attr('data-value', value) + .attr('title', isAliased ? `${name}: ${value}` : value) + .on('mousedown.colorpicker touchstart.colorpicker', + function (e) { + let $sw = $(this); + + // e.preventDefault(); + + colorpicker.setValue(isAliased ? $sw.attr('data-name') : $sw.attr('data-value')); + } + ); + + $swatch.find('.colorpicker-swatch--inner') + .css('background-color', value); + + swatchContainer.append($swatch); + }); + + swatchContainer.append($('')); + } +} + +export default Swatches; ADDED public/bootstrap-colorpicker/src/js/extensions/index.js Index: public/bootstrap-colorpicker/src/js/extensions/index.js ================================================================== --- public/bootstrap-colorpicker/src/js/extensions/index.js +++ public/bootstrap-colorpicker/src/js/extensions/index.js @@ -0,0 +1,15 @@ +import Debugger from './Debugger'; +import Preview from './Preview'; +import Swatches from './Swatches'; +import Palette from './Palette'; + +export { + Debugger, Preview, Swatches, Palette +}; + +export default { + 'debugger': Debugger, + 'preview': Preview, + 'swatches': Swatches, + 'palette': Palette +}; ADDED public/bootstrap-colorpicker/src/js/options.js Index: public/bootstrap-colorpicker/src/js/options.js ================================================================== --- public/bootstrap-colorpicker/src/js/options.js +++ public/bootstrap-colorpicker/src/js/options.js @@ -0,0 +1,256 @@ +'use strict'; +/** + * @module + */ + +// adjust these values accordingly to the sass vars +let sassVars = { + 'bar_size_short': 16, + 'base_margin': 6, + 'columns': 6 +}; + +let sliderSize = (sassVars.bar_size_short * sassVars.columns) + (sassVars.base_margin * (sassVars.columns - 1)); + +/** + * Colorpicker default options + */ +export default { + /** + * Custom class to be added to the `.colorpicker-element` element + * + * @type {String|null} + * @default null + */ + customClass: null, + /** + * Sets a initial color, ignoring the one from the element/input value or the data-color attribute. + * + * @type {(String|ColorItem|boolean)} + * @default false + */ + color: false, + /** + * Fallback color to use when the given color is invalid. + * If false, the latest valid color will be used as a fallback. + * + * @type {String|ColorItem|boolean} + * @default false + */ + fallbackColor: false, + /** + * Forces an specific color format. If 'auto', it will be automatically detected the first time only, + * but if null it will be always recalculated. + * + * Note that the ending 'a' of the format meaning "alpha" has currently no effect, meaning that rgb is the same as + * rgba excepting if the alpha channel is disabled (see useAlpha). + * + * @type {('rgb'|'hex'|'hsl'|'auto'|null)} + * @default 'auto' + */ + format: 'auto', + /** + * Horizontal mode layout. + * + * If true, the hue and alpha channel bars will be rendered horizontally, above the saturation selector. + * + * @type {boolean} + * @default false + */ + horizontal: false, + /** + * Forces to show the colorpicker as an inline element. + * + * Note that if there is no container specified, the inline element + * will be added to the body, so you may want to set the container option. + * + * @type {boolean} + * @default false + */ + inline: false, + /** + * Container where the colorpicker is appended to in the DOM. + * + * If is a string (CSS selector), the colorpicker will be placed inside this container. + * If true, the `.colorpicker-element` element itself will be used as the container. + * If false, the document body is used as the container, unless it is a popover (in this case it is appended to the + * popover body instead). + * + * @type {String|boolean} + * @default false + */ + container: false, + /** + * Bootstrap Popover options. + * The trigger, content and html options are always ignored. + * + * @type {boolean} + * @default Object + */ + popover: { + animation: true, + placement: 'bottom', + fallbackPlacement: 'flip' + }, + /** + * If true, loads the 'debugger' extension automatically, which logs the events in the console + * @type {boolean} + * @default false + */ + debug: false, + /** + * Child CSS selector for the colorpicker input. + * + * @type {String} + * @default 'input' + */ + input: 'input', + /** + * Child CSS selector for the colorpicker addon. + * If it exists, the child element background will be changed on color change. + * + * @type {String} + * @default '.colorpicker-trigger, .colorpicker-input-addon' + */ + addon: '.colorpicker-input-addon', + /** + * If true, the input content will be replaced always with a valid color, + * if false, the invalid color will be left in the input, + * while the internal color object will still resolve into a valid one. + * + * @type {boolean} + * @default true + */ + autoInputFallback: true, + /** + * If true a hash will be prepended to hexadecimal colors. + * If false, the hash will be removed. + * This only affects the input values in hexadecimal format. + * + * @type {boolean} + * @default true + */ + useHashPrefix: true, + /** + * If true, the alpha channel bar will be displayed no matter what. + * + * If false, it will be always hidden and alpha channel will be disabled also programmatically, meaning that + * the selected or typed color will be always opaque. + * + * If null, the alpha channel will be automatically disabled/enabled depending if the initial color format supports + * alpha or not. + * + * @type {boolean} + * @default true + */ + useAlpha: true, + /** + * Colorpicker widget template + * @type {String} + * @example + * + *
+ *
+ *
+ *
+ *
+ * + *
+ *
+ */ + template: `
+
+
+
+
+ +
+
`, + /** + * + * Associative object with the extension class name and its config. + * Colorpicker comes with many bundled extensions: debugger, palette, preview and swatches (a superset of palette). + * + * @type {Object[]} + * @example + * extensions: [ + * { + * name: 'swatches' + * options: { + * colors: { + * 'primary': '#337ab7', + * 'success': '#5cb85c', + * 'info': '#5bc0de', + * 'warning': '#f0ad4e', + * 'danger': '#d9534f' + * }, + * namesAsValues: true + * } + * } + * ] + */ + extensions: [ + { + name: 'preview', + options: { + showText: true + } + } + ], + /** + * Vertical sliders configuration + * @type {Object} + */ + sliders: { + saturation: { + selector: '.colorpicker-saturation', + maxLeft: sliderSize, + maxTop: sliderSize, + callLeft: 'setSaturationRatio', + callTop: 'setValueRatio' + }, + hue: { + selector: '.colorpicker-hue', + maxLeft: 0, + maxTop: sliderSize, + callLeft: false, + callTop: 'setHueRatio' + }, + alpha: { + selector: '.colorpicker-alpha', + childSelector: '.colorpicker-alpha-color', + maxLeft: 0, + maxTop: sliderSize, + callLeft: false, + callTop: 'setAlphaRatio' + } + }, + /** + * Horizontal sliders configuration + * @type {Object} + */ + slidersHorz: { + saturation: { + selector: '.colorpicker-saturation', + maxLeft: sliderSize, + maxTop: sliderSize, + callLeft: 'setSaturationRatio', + callTop: 'setValueRatio' + }, + hue: { + selector: '.colorpicker-hue', + maxLeft: sliderSize, + maxTop: 0, + callLeft: 'setHueRatio', + callTop: false + }, + alpha: { + selector: '.colorpicker-alpha', + childSelector: '.colorpicker-alpha-color', + maxLeft: sliderSize, + maxTop: 0, + callLeft: 'setAlphaRatio', + callTop: false + } + } +}; ADDED public/bootstrap-colorpicker/src/js/plugin.js Index: public/bootstrap-colorpicker/src/js/plugin.js ================================================================== --- public/bootstrap-colorpicker/src/js/plugin.js +++ public/bootstrap-colorpicker/src/js/plugin.js @@ -0,0 +1,50 @@ +'use strict'; + +import Colorpicker from './Colorpicker'; +import $ from 'jquery'; + +let plugin = 'colorpicker'; + +$[plugin] = Colorpicker; + +// Colorpicker jQuery Plugin API +$.fn[plugin] = function (option) { + let fnArgs = Array.prototype.slice.call(arguments, 1), + isSingleElement = (this.length === 1), + returnValue = null; + + let $elements = this.each(function () { + let $this = $(this), + inst = $this.data(plugin), + options = ((typeof option === 'object') ? option : {}); + + // Create instance if does not exist + if (!inst) { + inst = new Colorpicker(this, options); + $this.data(plugin, inst); + } + + if (!isSingleElement) { + return; + } + + returnValue = $this; + + if (typeof option === 'string') { + if (option === 'colorpicker') { + // Return colorpicker instance: e.g. .colorpicker('colorpicker') + returnValue = inst; + } else if ($.isFunction(inst[option])) { + // Return method call return value: e.g. .colorpicker('isEnabled') + returnValue = inst[option].apply(inst, fnArgs); + } else { + // Return property value: e.g. .colorpicker('element') + returnValue = inst[option]; + } + } + }); + + return isSingleElement ? returnValue : $elements; +}; + +$.fn[plugin].constructor = Colorpicker; ADDED public/bootstrap-colorpicker/src/sass/colorpicker.scss Index: public/bootstrap-colorpicker/src/sass/colorpicker.scss ================================================================== --- public/bootstrap-colorpicker/src/sass/colorpicker.scss +++ public/bootstrap-colorpicker/src/sass/colorpicker.scss @@ -0,0 +1,468 @@ +$outline-color: rgba(0, 0, 0, 0.2); +$box-shadow-outline: 0 0 0 1px $outline-color; +$bar-size-short: 16px !default; +$base-margin: 6px !default; +$columns: 6 !default; // this affects the number of swatches per row and the width of the color picker, saturation, etc. +$bar-size-large: ($bar-size-short * $columns) + ($base-margin * ($columns - 1)); + +@mixin bgCheckerBox($size: 10px) { + background: linear-gradient(45deg, rgba(0, 0, 0, 0.1) 25%, rgba(0, 0, 0, 0) 25%, rgba(0, 0, 0, 0) 75%, rgba(0, 0, 0, 0.1) 75%, rgba(0, 0, 0, 0.1) 0), + linear-gradient(45deg, rgba(0, 0, 0, 0.1) 25%, rgba(0, 0, 0, 0) 25%, rgba(0, 0, 0, 0) 75%, rgba(0, 0, 0, 0.1) 75%, rgba(0, 0, 0, 0.1) 0), + rgb(255, 255, 255); + background-size: $size $size; + background-position: 0 0, $size/2 $size/2; +} + +@mixin bgSaturation() { + background: -moz-linear-gradient(top, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 1) 100%), + -moz-linear-gradient(left, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 100%); /* FF3.6+ */ + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(0, 0, 0, 0)), color-stop(100%, rgba(0, 0, 0, 1))), + -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255, 255, 255, 1)), color-stop(100%, rgba(255, 255, 255, 0))); /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(top, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 1) 100%), + -webkit-linear-gradient(left, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 100%); /* Chrome10+,Safari5.1+ */ + background: -o-linear-gradient(top, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 1) 100%), + -o-linear-gradient(left, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 100%); /* Opera 11.10+ */ + background: -ms-linear-gradient(top, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 1) 100%), + -ms-linear-gradient(left, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 100%); /* IE10+ */ + background: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 1) 100%), + linear-gradient(to right, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 100%); /* W3C */ +} + +@mixin bgHueHorizontal() { + background: -moz-linear-gradient(right, rgb(255, 0, 0) 0%, rgb(255, 128, 0) 8%, rgb(255, 255, 0) 17%, rgb(128, 255, 0) 25%, rgb(0, 255, 0) 33%, rgb(0, 255, 128) 42%, rgb(0, 255, 255) 50%, rgb(0, 128, 255) 58%, rgb(0, 0, 255) 67%, rgb(128, 0, 255) 75%, rgb(255, 0, 255) 83%, rgb(255, 0, 128) 92%, rgb(255, 0, 0) 100%); /* FF3.6+ */ + background: -webkit-gradient(linear, right top, left top, color-stop(0%, rgb(255, 0, 0)), color-stop(8%, rgb(255, 128, 0)), color-stop(17%, rgb(255, 255, 0)), color-stop(25%, rgb(128, 255, 0)), color-stop(33%, rgb(0, 255, 0)), color-stop(42%, rgb(0, 255, 128)), color-stop(50%, rgb(0, 255, 255)), color-stop(58%, rgb(0, 128, 255)), color-stop(67%, rgb(0, 0, 255)), color-stop(75%, rgb(128, 0, 255)), color-stop(83%, rgb(255, 0, 255)), color-stop(92%, rgb(255, 0, 128)), color-stop(100%, rgb(255, 0, 0))); /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(right, rgb(255, 0, 0) 0%, rgb(255, 128, 0) 8%, rgb(255, 255, 0) 17%, rgb(128, 255, 0) 25%, rgb(0, 255, 0) 33%, rgb(0, 255, 128) 42%, rgb(0, 255, 255) 50%, rgb(0, 128, 255) 58%, rgb(0, 0, 255) 67%, rgb(128, 0, 255) 75%, rgb(255, 0, 255) 83%, rgb(255, 0, 128) 92%, rgb(255, 0, 0) 100%); /* Chrome10+,Safari5.1+ */ + background: -o-linear-gradient(right, rgb(255, 0, 0) 0%, rgb(255, 128, 0) 8%, rgb(255, 255, 0) 17%, rgb(128, 255, 0) 25%, rgb(0, 255, 0) 33%, rgb(0, 255, 128) 42%, rgb(0, 255, 255) 50%, rgb(0, 128, 255) 58%, rgb(0, 0, 255) 67%, rgb(128, 0, 255) 75%, rgb(255, 0, 255) 83%, rgb(255, 0, 128) 92%, rgb(255, 0, 0) 100%); /* Opera 11.10+ */ + background: -ms-linear-gradient(right, rgb(255, 0, 0) 0%, rgb(255, 128, 0) 8%, rgb(255, 255, 0) 17%, rgb(128, 255, 0) 25%, rgb(0, 255, 0) 33%, rgb(0, 255, 128) 42%, rgb(0, 255, 255) 50%, rgb(0, 128, 255) 58%, rgb(0, 0, 255) 67%, rgb(128, 0, 255) 75%, rgb(255, 0, 255) 83%, rgb(255, 0, 128) 92%, rgb(255, 0, 0) 100%); /* IE10+ */ + background: linear-gradient(to left, rgb(255, 0, 0) 0%, rgb(255, 128, 0) 8%, rgb(255, 255, 0) 17%, rgb(128, 255, 0) 25%, rgb(0, 255, 0) 33%, rgb(0, 255, 128) 42%, rgb(0, 255, 255) 50%, rgb(0, 128, 255) 58%, rgb(0, 0, 255) 67%, rgb(128, 0, 255) 75%, rgb(255, 0, 255) 83%, rgb(255, 0, 128) 92%, rgb(255, 0, 0) 100%); /* W3C */ + +} + +@mixin bgHueVertical() { + background: -moz-linear-gradient(bottom, rgba(255, 0, 0, 1) 0%, rgba(255, 128, 0, 1) 8%, rgba(255, 255, 0, 1) 17%, rgba(128, 255, 0, 1) 25%, rgba(0, 255, 0, 1) 33%, rgba(0, 255, 128, 1) 42%, rgba(0, 255, 255, 1) 50%, rgba(0, 128, 255, 1) 58%, rgba(0, 0, 255, 1) 67%, rgba(128, 0, 255, 1) 75%, rgba(255, 0, 255, 1) 83%, rgba(255, 0, 128, 1) 92%, rgba(255, 0, 0, 1) 100%); /* FF3.6+ */ + background: -webkit-gradient(linear, left bottom, left top, color-stop(0%, rgba(255, 0, 0, 1)), color-stop(8%, rgba(255, 128, 0, 1)), color-stop(17%, rgba(255, 255, 0, 1)), color-stop(25%, rgba(128, 255, 0, 1)), color-stop(33%, rgba(0, 255, 0, 1)), color-stop(42%, rgba(0, 255, 128, 1)), color-stop(50%, rgba(0, 255, 255, 1)), color-stop(58%, rgba(0, 128, 255, 1)), color-stop(67%, rgba(0, 0, 255, 1)), color-stop(75%, rgba(128, 0, 255, 1)), color-stop(83%, rgba(255, 0, 255, 1)), color-stop(92%, rgba(255, 0, 128, 1)), color-stop(100%, rgba(255, 0, 0, 1))); /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(bottom, rgba(255, 0, 0, 1) 0%, rgba(255, 128, 0, 1) 8%, rgba(255, 255, 0, 1) 17%, rgba(128, 255, 0, 1) 25%, rgba(0, 255, 0, 1) 33%, rgba(0, 255, 128, 1) 42%, rgba(0, 255, 255, 1) 50%, rgba(0, 128, 255, 1) 58%, rgba(0, 0, 255, 1) 67%, rgba(128, 0, 255, 1) 75%, rgba(255, 0, 255, 1) 83%, rgba(255, 0, 128, 1) 92%, rgba(255, 0, 0, 1) 100%); /* Chrome10+,Safari5.1+ */ + background: -o-linear-gradient(bottom, rgba(255, 0, 0, 1) 0%, rgba(255, 128, 0, 1) 8%, rgba(255, 255, 0, 1) 17%, rgba(128, 255, 0, 1) 25%, rgba(0, 255, 0, 1) 33%, rgba(0, 255, 128, 1) 42%, rgba(0, 255, 255, 1) 50%, rgba(0, 128, 255, 1) 58%, rgba(0, 0, 255, 1) 67%, rgba(128, 0, 255, 1) 75%, rgba(255, 0, 255, 1) 83%, rgba(255, 0, 128, 1) 92%, rgba(255, 0, 0, 1) 100%); /* Opera 11.10+ */ + background: -ms-linear-gradient(bottom, rgba(255, 0, 0, 1) 0%, rgba(255, 128, 0, 1) 8%, rgba(255, 255, 0, 1) 17%, rgba(128, 255, 0, 1) 25%, rgba(0, 255, 0, 1) 33%, rgba(0, 255, 128, 1) 42%, rgba(0, 255, 255, 1) 50%, rgba(0, 128, 255, 1) 58%, rgba(0, 0, 255, 1) 67%, rgba(128, 0, 255, 1) 75%, rgba(255, 0, 255, 1) 83%, rgba(255, 0, 128, 1) 92%, rgba(255, 0, 0, 1) 100%); /* IE10+ */ + background: linear-gradient(to top, rgba(255, 0, 0, 1) 0%, rgba(255, 128, 0, 1) 8%, rgba(255, 255, 0, 1) 17%, rgba(128, 255, 0, 1) 25%, rgba(0, 255, 0, 1) 33%, rgba(0, 255, 128, 1) 42%, rgba(0, 255, 255, 1) 50%, rgba(0, 128, 255, 1) 58%, rgba(0, 0, 255, 1) 67%, rgba(128, 0, 255, 1) 75%, rgba(255, 0, 255, 1) 83%, rgba(255, 0, 128, 1) 92%, rgba(255, 0, 0, 1) 100%); /* W3C */ +} + +.colorpicker { + position: relative; + display: none; + font-size: inherit; + color: inherit; + text-align: left; + list-style: none; + background-color: #ffffff; + background-clip: padding-box; + border: 1px solid $outline-color; + //box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + padding: .75rem .75rem; + width: ($bar-size-large + $base-margin + $bar-size-short); + border-radius: 4px; + box-sizing: content-box; +} + +.colorpicker.colorpicker-disabled, +.colorpicker.colorpicker-disabled * { + cursor: default !important; +} + +.colorpicker div { + position: relative; +} + +.colorpicker-popup { + position: absolute; + top: 100%; + left: 0; + float: left; + margin-top: 1px; + z-index: 1060; +} + +.colorpicker-popup.colorpicker-bs-popover-content { + position: relative; + top: auto; + left: auto; + float: none; + margin: 0; + z-index: initial; + border: none; + padding: 0.25rem 0; // popover padding correction + border-radius: 0; + background: none; + box-shadow: none; +} + +.colorpicker:before, +.colorpicker:after { + content: ""; + display: table; + clear: both; + line-height: 0; +} + +.colorpicker-clear { + clear: both; + display: block; +} + +.colorpicker:before { + content: ''; + display: inline-block; + border-left: 7px solid transparent; + border-right: 7px solid transparent; + border-bottom: 7px solid #ccc; + border-bottom-color: $outline-color; + position: absolute; + top: -7px; + left: auto; + right: 6px; +} + +.colorpicker:after { + content: ''; + display: inline-block; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-bottom: 6px solid #ffffff; + position: absolute; + top: -6px; + left: auto; + right: 7px; +} + +.colorpicker.colorpicker-with-alpha { + width: ($bar-size-large + (($base-margin + $bar-size-short) * 2)); +} + +.colorpicker.colorpicker-with-alpha .colorpicker-alpha { + display: block; +} + +.colorpicker-saturation { + position: relative; + width: $bar-size-large; + height: $bar-size-large; + @include bgSaturation(); + cursor: crosshair; + float: left; + box-shadow: $box-shadow-outline; + margin-bottom: $base-margin; + + .colorpicker-guide { + display: block; + height: 6px; + width: 6px; + border-radius: 6px; + border: 1px solid #000; + box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.8); + position: absolute; + top: 0; + left: 0; + margin: -3px 0 0 -3px; + } +} + +.colorpicker-hue, +.colorpicker-alpha { + position: relative; + width: $bar-size-short; + height: $bar-size-large; + float: left; + cursor: row-resize; + margin-left: $base-margin; + margin-bottom: $base-margin; +} + +.colorpicker-alpha-color { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +} + +.colorpicker-hue, +.colorpicker-alpha-color { + box-shadow: $box-shadow-outline; +} + +.colorpicker-hue .colorpicker-guide, +.colorpicker-alpha .colorpicker-guide { + display: block; + height: 4px; + background: rgba(255, 255, 255, 0.8); + border: 1px solid rgba(0, 0, 0, 0.4); + position: absolute; + top: 0; + left: 0; + margin-left: -2px; + margin-top: -2px; + right: -2px; + z-index: 1; +} + +.colorpicker-hue { + @include bgHueVertical(); +} + +.colorpicker-alpha { + @include bgCheckerBox(); + display: none; +} + +.colorpicker-bar { + min-height: $bar-size-short; + margin: $base-margin 0 0 0; + clear: both; + text-align: center; + font-size: 10px; + line-height: normal; + max-width: 100%; + box-shadow: $box-shadow-outline; + + &:before { + content: ""; + display: table; + clear: both; + } +} + +.colorpicker-bar.colorpicker-bar-horizontal { + height: $bar-size-large; + width: $bar-size-short; + margin: 0 0 $base-margin 0; + float: left; +} + +.colorpicker-input-addon { + position: relative; +} + +.colorpicker-input-addon i { + display: inline-block; + cursor: pointer; + vertical-align: text-top; + height: 16px; + width: 16px; + position: relative; +} + +.colorpicker-input-addon:before { + content: ""; + position: absolute; + width: 16px; + height: 16px; + display: inline-block; + vertical-align: text-top; + @include bgCheckerBox(); +} + +.colorpicker.colorpicker-inline { + position: relative; + display: inline-block; + float: none; + z-index: auto; + vertical-align: text-bottom; +} + +.colorpicker.colorpicker-horizontal { + width: $bar-size-large; + height: auto; +} + +.colorpicker.colorpicker-horizontal .colorpicker-bar { + width: $bar-size-large; +} + +.colorpicker.colorpicker-horizontal .colorpicker-saturation { + float: none; + margin-bottom: 0; +} + +.colorpicker.colorpicker-horizontal .colorpicker-hue, +.colorpicker.colorpicker-horizontal .colorpicker-alpha { + float: none; + width: $bar-size-large; + height: $bar-size-short; + cursor: col-resize; + margin-left: 0; + margin-top: $base-margin; + margin-bottom: 0; +} + +.colorpicker.colorpicker-horizontal .colorpicker-hue .colorpicker-guide, +.colorpicker.colorpicker-horizontal .colorpicker-alpha .colorpicker-guide { + position: absolute; + display: block; + bottom: -2px; + left: 0; + right: auto; + height: auto; + width: 4px; +} + +.colorpicker.colorpicker-horizontal .colorpicker-hue { + @include bgHueHorizontal(); +} + +.colorpicker.colorpicker-horizontal .colorpicker-alpha { + @include bgCheckerBox(); +} + +.colorpicker-inline:before, +.colorpicker-no-arrow:before, +.colorpicker-popup.colorpicker-bs-popover-content:before { + content: none; + display: none; +} + +.colorpicker-inline:after, +.colorpicker-no-arrow:after, +.colorpicker-popup.colorpicker-bs-popover-content:after { + content: none; + display: none; +} + + +.colorpicker-alpha, +.colorpicker-saturation, +.colorpicker-hue { + user-select: none; +} + +.colorpicker, +.colorpicker-alpha, +.colorpicker-saturation, +.colorpicker-hue, +.colorpicker-bar { + &.colorpicker-visible { + display: block; + } +} + +.colorpicker, +.colorpicker-alpha, +.colorpicker-saturation, +.colorpicker-hue, +.colorpicker-bar { + &.colorpicker-hidden { + display: none; + } +} + +.colorpicker-inline.colorpicker-visible { + display: inline-block; +} + +.colorpicker.colorpicker-disabled:after { + border: none; + content: ''; + display: block; + width: 100%; + height: 100%; + background: rgba(233, 236, 239, 0.33); + top: 0; + left: 0; + right: auto; + z-index: 2; + position: absolute; +} + +.colorpicker.colorpicker-disabled .colorpicker-guide { + display: none; +} + +/** EXTENSIONS **/ + +.colorpicker-preview { + @include bgCheckerBox(); +} + +.colorpicker-preview > div { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; +} + +.colorpicker-bar.colorpicker-swatches { + box-shadow: none; + height: auto; +} + +.colorpicker-swatches--inner { + clear: both; + margin-top: -$base-margin; +} + +.colorpicker-swatch { + position: relative; + cursor: pointer; + float: left; + height: $bar-size-short; + width: $bar-size-short; + margin-right: $base-margin; + margin-top: $base-margin; + margin-left: 0; + display: block; + box-shadow: $box-shadow-outline; + @include bgCheckerBox(); +} + +.colorpicker-swatch--inner { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +} + +// saturation + hue vertical (clear margin-right on nth column + 1) +.colorpicker-swatch:nth-of-type(#{$columns + 1}n+0) { + margin-right: 0; +} + +// saturation + hue + alpha vertical (clear margin-right on nth column + 2) +.colorpicker-with-alpha { + .colorpicker-swatch:nth-of-type(#{$columns + 1}n+0) { + margin-right: $base-margin; + } + + .colorpicker-swatch:nth-of-type(#{$columns + 2}n+0) { + margin-right: 0; + } +} + +// horizontal mode (clear margin-right on nth column) +.colorpicker-horizontal { + .colorpicker-swatch:nth-of-type(#{$columns}n+0) { + margin-right: 0; + } + + .colorpicker-swatch:nth-of-type(#{$columns + 1}n+0) { + margin-right: $base-margin; + } + + .colorpicker-swatch:nth-of-type(#{$columns + 2}n+0) { + margin-right: $base-margin; + } +} + +.colorpicker-swatch:last-of-type:after { + content: ""; + display: table; + clear: both; +} + +// RTL writing mode support +*[dir='rtl'] .colorpicker-element input, +.colorpicker-element[dir='rtl'] input, +.colorpicker-element input[dir='rtl'] { + direction: ltr; + text-align: right; +} ADDED public/bootstrap-colorpicker/yarn.lock Index: public/bootstrap-colorpicker/yarn.lock ================================================================== --- public/bootstrap-colorpicker/yarn.lock +++ public/bootstrap-colorpicker/yarn.lock @@ -0,0 +1,8012 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@ava/babel-plugin-throws-helper@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@ava/babel-plugin-throws-helper/-/babel-plugin-throws-helper-2.0.0.tgz#2fc1fe3c211a71071a4eca7b8f7af5842cd1ae7c" + integrity sha1-L8H+PCEacQcaTsp7j3r1hCzRrnw= + +"@ava/babel-preset-stage-4@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@ava/babel-preset-stage-4/-/babel-preset-stage-4-1.1.0.tgz#ae60be881a0babf7d35f52aba770d1f6194f76bd" + integrity sha512-oWqTnIGXW3k72UFidXzW0ONlO7hnO9x02S/QReJ7NBGeiBH9cUHY9+EfV6C8PXC6YJH++WrliEq03wMSJGNZFg== + dependencies: + babel-plugin-check-es2015-constants "^6.8.0" + babel-plugin-syntax-trailing-function-commas "^6.20.0" + babel-plugin-transform-async-to-generator "^6.16.0" + babel-plugin-transform-es2015-destructuring "^6.19.0" + babel-plugin-transform-es2015-function-name "^6.9.0" + babel-plugin-transform-es2015-modules-commonjs "^6.18.0" + babel-plugin-transform-es2015-parameters "^6.21.0" + babel-plugin-transform-es2015-spread "^6.8.0" + babel-plugin-transform-es2015-sticky-regex "^6.8.0" + babel-plugin-transform-es2015-unicode-regex "^6.11.0" + babel-plugin-transform-exponentiation-operator "^6.8.0" + package-hash "^1.2.0" + +"@ava/babel-preset-transform-test-files@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@ava/babel-preset-transform-test-files/-/babel-preset-transform-test-files-3.0.0.tgz#cded1196a8d8d9381a509240ab92e91a5ec069f7" + integrity sha1-ze0RlqjY2TgaUJJAq5LpGl7Aafc= + dependencies: + "@ava/babel-plugin-throws-helper" "^2.0.0" + babel-plugin-espower "^2.3.2" + +"@ava/write-file-atomic@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@ava/write-file-atomic/-/write-file-atomic-2.2.0.tgz#d625046f3495f1f5e372135f473909684b429247" + integrity sha512-BTNB3nGbEfJT+69wuqXFr/bQH7Vr7ihx2xGOMNqPgDGhwspoZhiWumDDZNjBy7AScmqS5CELIOGtPVXESyrnDA== + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + slide "^1.1.5" + +"@babel/code-frame@7.0.0-beta.44": + version "7.0.0-beta.44" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.44.tgz#2a02643368de80916162be70865c97774f3adbd9" + integrity sha512-cuAuTTIQ9RqcFRJ/Y8PvTh+paepNcaGxwQwjIDRWPXmzzyAeCO4KqS9ikMvq0MCbRk6GlYKwfzStrcP3/jSL8g== + dependencies: + "@babel/highlight" "7.0.0-beta.44" + +"@babel/generator@7.0.0-beta.44": + version "7.0.0-beta.44" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.0.0-beta.44.tgz#c7e67b9b5284afcf69b309b50d7d37f3e5033d42" + integrity sha512-5xVb7hlhjGcdkKpMXgicAVgx8syK5VJz193k0i/0sLP6DzE6lRrU1K3B/rFefgdo9LPGMAOOOAWW4jycj07ShQ== + dependencies: + "@babel/types" "7.0.0-beta.44" + jsesc "^2.5.1" + lodash "^4.2.0" + source-map "^0.5.0" + trim-right "^1.0.1" + +"@babel/helper-function-name@7.0.0-beta.44": + version "7.0.0-beta.44" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.44.tgz#e18552aaae2231100a6e485e03854bc3532d44dd" + integrity sha512-MHRG2qZMKMFaBavX0LWpfZ2e+hLloT++N7rfM3DYOMUOGCD8cVjqZpwiL8a0bOX3IYcQev1ruciT0gdFFRTxzg== + dependencies: + "@babel/helper-get-function-arity" "7.0.0-beta.44" + "@babel/template" "7.0.0-beta.44" + "@babel/types" "7.0.0-beta.44" + +"@babel/helper-get-function-arity@7.0.0-beta.44": + version "7.0.0-beta.44" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.44.tgz#d03ca6dd2b9f7b0b1e6b32c56c72836140db3a15" + integrity sha512-w0YjWVwrM2HwP6/H3sEgrSQdkCaxppqFeJtAnB23pRiJB5E/O9Yp7JAAeWBl+gGEgmBFinnTyOv2RN7rcSmMiw== + dependencies: + "@babel/types" "7.0.0-beta.44" + +"@babel/helper-split-export-declaration@7.0.0-beta.44": + version "7.0.0-beta.44" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0-beta.44.tgz#c0b351735e0fbcb3822c8ad8db4e583b05ebd9dc" + integrity sha512-aQ7QowtkgKKzPGf0j6u77kBMdUFVBKNHw2p/3HX/POt5/oz8ec5cs0GwlgM8Hz7ui5EwJnzyfRmkNF1Nx1N7aA== + dependencies: + "@babel/types" "7.0.0-beta.44" + +"@babel/highlight@7.0.0-beta.44": + version "7.0.0-beta.44" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0-beta.44.tgz#18c94ce543916a80553edcdcf681890b200747d5" + integrity sha512-Il19yJvy7vMFm8AVAh6OZzaFoAd0hbkeMZiX3P5HGD+z7dyI7RzndHB0dg6Urh/VAFfHtpOIzDUSxmY6coyZWQ== + dependencies: + chalk "^2.0.0" + esutils "^2.0.2" + js-tokens "^3.0.0" + +"@babel/parser@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.4.4.tgz#5977129431b8fe33471730d255ce8654ae1250b6" + integrity sha512-5pCS4mOsL+ANsFZGdvNLybx4wtqAZJ0MJjMHxvzI3bvIsz6sQvzW8XX92EYIkiPtIvcfG3Aj+Ir5VNyjnZhP7w== + +"@babel/template@7.0.0-beta.44": + version "7.0.0-beta.44" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.44.tgz#f8832f4fdcee5d59bf515e595fc5106c529b394f" + integrity sha512-w750Sloq0UNifLx1rUqwfbnC6uSUk0mfwwgGRfdLiaUzfAOiH0tHJE6ILQIUi3KYkjiCDTskoIsnfqZvWLBDng== + dependencies: + "@babel/code-frame" "7.0.0-beta.44" + "@babel/types" "7.0.0-beta.44" + babylon "7.0.0-beta.44" + lodash "^4.2.0" + +"@babel/traverse@7.0.0-beta.44": + version "7.0.0-beta.44" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0-beta.44.tgz#a970a2c45477ad18017e2e465a0606feee0d2966" + integrity sha512-UHuDz8ukQkJCDASKHf+oDt3FVUzFd+QYfuBIsiNu/4+/ix6pP/C+uQZJ6K1oEfbCMv/IKWbgDEh7fcsnIE5AtA== + dependencies: + "@babel/code-frame" "7.0.0-beta.44" + "@babel/generator" "7.0.0-beta.44" + "@babel/helper-function-name" "7.0.0-beta.44" + "@babel/helper-split-export-declaration" "7.0.0-beta.44" + "@babel/types" "7.0.0-beta.44" + babylon "7.0.0-beta.44" + debug "^3.1.0" + globals "^11.1.0" + invariant "^2.2.0" + lodash "^4.2.0" + +"@babel/types@7.0.0-beta.44": + version "7.0.0-beta.44" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.0.0-beta.44.tgz#6b1b164591f77dec0a0342aca995f2d046b3a757" + integrity sha512-5eTV4WRmqbaFM3v9gHAIljEQJU4Ssc6fxL61JN+Oe2ga/BwyjzjamwkCVVAQjHGuAX8i0BWo42dshL8eO5KfLQ== + dependencies: + esutils "^2.0.2" + lodash "^4.2.0" + to-fast-properties "^2.0.0" + +"@concordance/react@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@concordance/react/-/react-1.0.0.tgz#fcf3cad020e5121bfd1c61d05bc3516aac25f734" + integrity sha512-htrsRaQX8Iixlsek8zQU7tE8wcsTQJ5UhZkSPEA8slCDAisKpC/2VgU/ucPn32M5/LjGGXRaUEKvEw1Wiuu4zQ== + dependencies: + arrify "^1.0.1" + +"@gulp-sourcemaps/identity-map@1.X": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@gulp-sourcemaps/identity-map/-/identity-map-1.0.2.tgz#1e6fe5d8027b1f285dc0d31762f566bccd73d5a9" + integrity sha512-ciiioYMLdo16ShmfHBXJBOFm3xPC4AuwO4xeRpFeHz7WK9PYsWCmigagG2XyzZpubK4a3qNKoUBDhbzHfa50LQ== + dependencies: + acorn "^5.0.3" + css "^2.2.1" + normalize-path "^2.1.1" + source-map "^0.6.0" + through2 "^2.0.3" + +"@gulp-sourcemaps/map-sources@1.X": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@gulp-sourcemaps/map-sources/-/map-sources-1.0.0.tgz#890ae7c5d8c877f6d384860215ace9d7ec945bda" + integrity sha1-iQrnxdjId/bThIYCFazp1+yUW9o= + dependencies: + normalize-path "^2.0.1" + through2 "^2.0.3" + +abab@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.0.tgz#aba0ab4c5eee2d4c79d3487d85450fb2376ebb0f" + integrity sha512-sY5AXXVZv4Y1VACTtR11UJCPHHudgY5i26Qj5TypE6DKlIApbwb5uqhXcJ5UUGbvZNRh7EeIoW+LrJumBsKp7w== + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + +acorn-dynamic-import@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz#c752bd210bef679501b6c6cb7fc84f8f47158cc4" + integrity sha1-x1K9IQvvZ5UBtsbLf8hPj0cVjMQ= + dependencies: + acorn "^4.0.3" + +acorn-globals@^4.1.0: + version "4.3.2" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.2.tgz#4e2c2313a597fd589720395f6354b41cd5ec8006" + integrity sha512-BbzvZhVtZP+Bs1J1HcwrQe8ycfO0wStkSGxuul3He3GkHOIZ6eTqOkPuw9IP1X3+IkOo4wiJmwkobzXYz4wewQ== + dependencies: + acorn "^6.0.1" + acorn-walk "^6.0.1" + +acorn-jsx@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" + integrity sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s= + dependencies: + acorn "^3.0.4" + +acorn-walk@^6.0.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.1.1.tgz#d363b66f5fac5f018ff9c3a1e7b6f8e310cc3913" + integrity sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw== + +acorn@5.X, acorn@^5.0.0, acorn@^5.0.3, acorn@^5.5.0, acorn@^5.5.3: + version "5.7.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" + integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw== + +acorn@^3.0.4: + version "3.3.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" + integrity sha1-ReN/s56No/JbruP/U2niu18iAXo= + +acorn@^4.0.3: + version "4.0.13" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787" + integrity sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c= + +acorn@^6.0.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.1.1.tgz#7d25ae05bb8ad1f9b699108e1094ecd7884adc1f" + integrity sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA== + +ajv-keywords@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762" + integrity sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I= + +ajv-keywords@^3.1.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.0.tgz#4b831e7b531415a7cc518cd404e73f6193c6349d" + integrity sha512-aUjdRFISbuFOl0EIZc+9e4FfZp0bDZgAdOOf30bJmw8VM9v84SHyVyxDfbWxpGYbdZD/9XoKxfHVNmxPkhwyGw== + +ajv@^5.2.3, ajv@^5.3.0: + version "5.5.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" + integrity sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU= + dependencies: + co "^4.6.0" + fast-deep-equal "^1.0.0" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.3.0" + +ajv@^6.1.0, ajv@^6.5.5: + version "6.10.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.0.tgz#90d0d54439da587cd7e843bfb7045f50bd22bdf1" + integrity sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg== + dependencies: + fast-deep-equal "^2.0.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +align-text@^0.1.1, align-text@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" + integrity sha1-DNkKVhCT810KmSVsIrcGlDP60Rc= + dependencies: + kind-of "^3.0.2" + longest "^1.0.1" + repeat-string "^1.5.2" + +amdefine@>=0.0.4: + version "1.0.1" + resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU= + +ansi-align@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f" + integrity sha1-w2rsy6VjuJzrVW82kPCx2eNUf38= + dependencies: + string-width "^2.0.0" + +ansi-colors@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-1.1.0.tgz#6374b4dd5d4718ff3ce27a671a3b1cad077132a9" + integrity sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA== + dependencies: + ansi-wrap "^0.1.0" + +ansi-cyan@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-cyan/-/ansi-cyan-0.1.1.tgz#538ae528af8982f28ae30d86f2f17456d2609873" + integrity sha1-U4rlKK+JgvKK4w2G8vF0VtJgmHM= + dependencies: + ansi-wrap "0.1.0" + +ansi-escapes@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-2.0.0.tgz#5bae52be424878dd9783e8910e3fc2922e83c81b" + integrity sha1-W65SvkJIeN2Xg+iRDj/Cki6DyBs= + +ansi-escapes@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" + integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== + +ansi-gray@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-gray/-/ansi-gray-0.1.1.tgz#2962cf54ec9792c48510a3deb524436861ef7251" + integrity sha1-KWLPVOyXksSFEKPetSRDaGHvclE= + dependencies: + ansi-wrap "0.1.0" + +ansi-red@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-red/-/ansi-red-0.1.1.tgz#8c638f9d1080800a353c9c28c8a81ca4705d946c" + integrity sha1-jGOPnRCAgAo1PJwoyKgcpHBdlGw= + dependencies: + ansi-wrap "0.1.0" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= + +ansi-styles@^3.1.0, ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.0.0.tgz#cb102df1c56f5123eab8b67cd7b98027a0279178" + integrity sha1-yxAt8cVvUSPquLZ817mAJ6AnkXg= + +ansi-wrap@0.1.0, ansi-wrap@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" + integrity sha1-qCJQ3bABXponyoLoLqYDu/pF768= + +anymatch@^1.3.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a" + integrity sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA== + dependencies: + micromatch "^2.1.5" + normalize-path "^2.0.0" + +anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + +aproba@^1.0.3, aproba@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + +archy@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" + integrity sha1-+cjBN1fMHde8N5rHeyxipcKGjEA= + +are-we-there-yet@~1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" + integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +arr-diff@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-1.1.0.tgz#687c32758163588fef7de7b36fabe495eb1a399a" + integrity sha1-aHwydYFjWI/vfeezb6vklesaOZo= + dependencies: + arr-flatten "^1.0.1" + array-slice "^0.2.3" + +arr-diff@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" + integrity sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8= + dependencies: + arr-flatten "^1.0.1" + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= + +arr-exclude@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/arr-exclude/-/arr-exclude-1.0.0.tgz#dfc7c2e552a270723ccda04cf3128c8cbfe5c631" + integrity sha1-38fC5VKicHI8zaBM8xKMjL/lxjE= + +arr-flatten@^1.0.1, arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + +arr-union@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-2.1.0.tgz#20f9eab5ec70f5c7d215b1077b1c39161d292c7d" + integrity sha1-IPnqtexw9cfSFbEHexw5Fh0pLH0= + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= + +array-differ@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031" + integrity sha1-7/UuN1gknTO+QCuLuOVkuytdQDE= + +array-each@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/array-each/-/array-each-1.0.1.tgz#a794af0c05ab1752846ee753a1f211a05ba0c44f" + integrity sha1-p5SvDAWrF1KEbudTofIRoFugxE8= + +array-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" + integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM= + +array-find-index@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" + integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E= + +array-slice@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-0.2.3.tgz#dd3cfb80ed7973a75117cdac69b0b99ec86186f5" + integrity sha1-3Tz7gO15c6dRF82sabC5nshhhvU= + +array-slice@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-1.1.0.tgz#e368ea15f89bc7069f7ffb89aec3a6c7d4ac22d4" + integrity sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w== + +array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= + dependencies: + array-uniq "^1.0.1" + +array-uniq@^1.0.1, array-uniq@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= + +array-unique@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" + integrity sha1-odl8yvy8JiXMcPrc6zalDFiwGlM= + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= + +arrify@^1.0.0, arrify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= + +asn1.js@^4.0.0: + version "4.10.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" + integrity sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw== + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +asn1@~0.2.3: + version "0.2.4" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" + integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= + +assert@^1.1.1: + version "1.5.0" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" + integrity sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA== + dependencies: + object-assign "^4.1.1" + util "0.10.3" + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= + +async-each@^1.0.0, async-each@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" + integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== + +async-foreach@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/async-foreach/-/async-foreach-0.1.3.tgz#36121f845c0578172de419a97dbeb1d16ec34542" + integrity sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI= + +async-limiter@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" + integrity sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg== + +async@2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610" + integrity sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ== + dependencies: + lodash "^4.17.10" + +async@^1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo= + +async@^2.1.2, async@^2.1.5: + version "2.6.2" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.2.tgz#18330ea7e6e313887f5d2f2a904bac6fe4dd5381" + integrity sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg== + dependencies: + lodash "^4.17.11" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +atob@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + +auto-bind@^1.1.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/auto-bind/-/auto-bind-1.2.1.tgz#807f7910b0210db9eefe133f3492c28e89698b96" + integrity sha512-/W9yj1yKmBLwpexwAujeD9YHwYmRuWFGV8HWE7smQab797VeHa4/cnE2NFeDhA+E+5e/OGBI8763EhLjfZ/MXA== + +autoprefixer@^7.0.0: + version "7.2.6" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-7.2.6.tgz#256672f86f7c735da849c4f07d008abb056067dc" + integrity sha512-Iq8TRIB+/9eQ8rbGhcP7ct5cYb/3qjNYAR2SnzLCEcwF6rvVOax8+9+fccgXk4bEhQGjOZd5TLhsksmAdsbGqQ== + dependencies: + browserslist "^2.11.3" + caniuse-lite "^1.0.30000805" + normalize-range "^0.1.2" + num2fraction "^1.2.2" + postcss "^6.0.17" + postcss-value-parser "^3.2.3" + +ava-init@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/ava-init/-/ava-init-0.2.1.tgz#75ac4c8553326290d2866e63b62fa7035684bd58" + integrity sha512-lXwK5LM+2g1euDRqW1mcSX/tqzY1QU7EjKpqayFPPtNRmbSYZ8RzPO5tqluTToijmtjp2M+pNpVdbcHssC4glg== + dependencies: + arr-exclude "^1.0.0" + execa "^0.7.0" + has-yarn "^1.0.0" + read-pkg-up "^2.0.0" + write-pkg "^3.1.0" + +ava@^0.23.0: + version "0.23.0" + resolved "https://registry.yarnpkg.com/ava/-/ava-0.23.0.tgz#beed11730adef74a857761b62b8882bf16d5a038" + integrity sha512-ZsVwO8UENDoZHlYQOEBv6oSGuUiZ8AFqaa+OhTv/McwC+4Y2V9skip5uYwN3egT9I9c+mKzLWA9lXUv7D6g8ZA== + dependencies: + "@ava/babel-preset-stage-4" "^1.1.0" + "@ava/babel-preset-transform-test-files" "^3.0.0" + "@ava/write-file-atomic" "^2.2.0" + "@concordance/react" "^1.0.0" + ansi-escapes "^2.0.0" + ansi-styles "^3.1.0" + arr-flatten "^1.0.1" + array-union "^1.0.1" + array-uniq "^1.0.2" + arrify "^1.0.0" + auto-bind "^1.1.0" + ava-init "^0.2.0" + babel-core "^6.17.0" + bluebird "^3.0.0" + caching-transform "^1.0.0" + chalk "^2.0.1" + chokidar "^1.4.2" + clean-stack "^1.1.1" + clean-yaml-object "^0.1.0" + cli-cursor "^2.1.0" + cli-spinners "^1.0.0" + cli-truncate "^1.0.0" + co-with-promise "^4.6.0" + code-excerpt "^2.1.0" + common-path-prefix "^1.0.0" + concordance "^3.0.0" + convert-source-map "^1.2.0" + core-assert "^0.2.0" + currently-unhandled "^0.4.1" + debug "^3.0.1" + dot-prop "^4.1.0" + empower-core "^0.6.1" + equal-length "^1.0.0" + figures "^2.0.0" + find-cache-dir "^1.0.0" + fn-name "^2.0.0" + get-port "^3.0.0" + globby "^6.0.0" + has-flag "^2.0.0" + hullabaloo-config-manager "^1.1.0" + ignore-by-default "^1.0.0" + import-local "^0.1.1" + indent-string "^3.0.0" + is-ci "^1.0.7" + is-generator-fn "^1.0.0" + is-obj "^1.0.0" + is-observable "^0.2.0" + is-promise "^2.1.0" + js-yaml "^3.8.2" + last-line-stream "^1.0.0" + lodash.clonedeepwith "^4.5.0" + lodash.debounce "^4.0.3" + lodash.difference "^4.3.0" + lodash.flatten "^4.2.0" + loud-rejection "^1.2.0" + make-dir "^1.0.0" + matcher "^1.0.0" + md5-hex "^2.0.0" + meow "^3.7.0" + ms "^2.0.0" + multimatch "^2.1.0" + observable-to-promise "^0.5.0" + option-chain "^1.0.0" + package-hash "^2.0.0" + pkg-conf "^2.0.0" + plur "^2.0.0" + pretty-ms "^3.0.0" + require-precompiled "^0.1.0" + resolve-cwd "^2.0.0" + safe-buffer "^5.1.1" + slash "^1.0.0" + source-map-support "^0.4.0" + stack-utils "^1.0.1" + strip-ansi "^4.0.0" + strip-bom-buf "^1.0.0" + supports-color "^4.0.0" + time-require "^0.1.2" + trim-off-newlines "^1.0.1" + unique-temp-dir "^1.0.0" + update-notifier "^2.3.0" + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= + +aws4@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" + integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ== + +babel-cli@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-cli/-/babel-cli-6.26.0.tgz#502ab54874d7db88ad00b887a06383ce03d002f1" + integrity sha1-UCq1SHTX24itALiHoGODzgPQAvE= + dependencies: + babel-core "^6.26.0" + babel-polyfill "^6.26.0" + babel-register "^6.26.0" + babel-runtime "^6.26.0" + commander "^2.11.0" + convert-source-map "^1.5.0" + fs-readdir-recursive "^1.0.0" + glob "^7.1.2" + lodash "^4.17.4" + output-file-sync "^1.1.2" + path-is-absolute "^1.0.1" + slash "^1.0.0" + source-map "^0.5.6" + v8flags "^2.1.1" + optionalDependencies: + chokidar "^1.6.1" + +babel-code-frame@^6.22.0, babel-code-frame@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" + integrity sha1-Y/1D99weO7fONZR9uP42mj9Yx0s= + dependencies: + chalk "^1.1.3" + esutils "^2.0.2" + js-tokens "^3.0.2" + +babel-core@^6.17.0, babel-core@^6.26.0: + version "6.26.3" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207" + integrity sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA== + dependencies: + babel-code-frame "^6.26.0" + babel-generator "^6.26.0" + babel-helpers "^6.24.1" + babel-messages "^6.23.0" + babel-register "^6.26.0" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + convert-source-map "^1.5.1" + debug "^2.6.9" + json5 "^0.5.1" + lodash "^4.17.4" + minimatch "^3.0.4" + path-is-absolute "^1.0.1" + private "^0.1.8" + slash "^1.0.0" + source-map "^0.5.7" + +babel-eslint@^8.0.2: + version "8.2.6" + resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-8.2.6.tgz#6270d0c73205628067c0f7ae1693a9e797acefd9" + integrity sha512-aCdHjhzcILdP8c9lej7hvXKvQieyRt20SF102SIGyY4cUIiw6UaAtK4j2o3dXX74jEmy0TJ0CEhv4fTIM3SzcA== + dependencies: + "@babel/code-frame" "7.0.0-beta.44" + "@babel/traverse" "7.0.0-beta.44" + "@babel/types" "7.0.0-beta.44" + babylon "7.0.0-beta.44" + eslint-scope "3.7.1" + eslint-visitor-keys "^1.0.0" + +babel-generator@^6.1.0, babel-generator@^6.26.0: + version "6.26.1" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" + integrity sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA== + dependencies: + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + detect-indent "^4.0.0" + jsesc "^1.3.0" + lodash "^4.17.4" + source-map "^0.5.7" + trim-right "^1.0.1" + +babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" + integrity sha1-zORReto1b0IgvK6KAsKzRvmlZmQ= + dependencies: + babel-helper-explode-assignable-expression "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-call-delegate@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" + integrity sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340= + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-define-map@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" + integrity sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8= + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-helper-explode-assignable-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" + integrity sha1-8luCz33BBDPFX3BZLVdGQArCLKo= + dependencies: + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-function-name@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" + integrity sha1-00dbjAPtmCQqJbSDUasYOZ01gKk= + dependencies: + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-get-function-arity@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" + integrity sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0= + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-hoist-variables@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" + integrity sha1-HssnaJydJVE+rbyZFKc/VAi+enY= + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-optimise-call-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" + integrity sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc= + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-regex@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" + integrity sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI= + dependencies: + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-helper-remap-async-to-generator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" + integrity sha1-XsWBgnrXI/7N04HxySg5BnbkVRs= + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-replace-supers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" + integrity sha1-v22/5Dk40XNpohPKiov3S2qQqxo= + dependencies: + babel-helper-optimise-call-expression "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helpers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" + integrity sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI= + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-loader@^7.1.2: + version "7.1.5" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-7.1.5.tgz#e3ee0cd7394aa557e013b02d3e492bfd07aa6d68" + integrity sha512-iCHfbieL5d1LfOQeeVJEUyD9rTwBcP/fcEbRCfempxTDuqrKpu0AZjLAQHEQa3Yqyj9ORKe2iHfoj4rHLf7xpw== + dependencies: + find-cache-dir "^1.0.0" + loader-utils "^1.0.2" + mkdirp "^0.5.1" + +babel-messages@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + integrity sha1-8830cDhYA1sqKVHG7F7fbGLyYw4= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-add-module-exports@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/babel-plugin-add-module-exports/-/babel-plugin-add-module-exports-0.2.1.tgz#9ae9a1f4a8dc67f0cdec4f4aeda1e43a5ff65e25" + integrity sha1-mumh9KjcZ/DN7E9K7aHkOl/2XiU= + +babel-plugin-check-es2015-constants@^6.22.0, babel-plugin-check-es2015-constants@^6.8.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" + integrity sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-espower@^2.3.2: + version "2.4.0" + resolved "https://registry.yarnpkg.com/babel-plugin-espower/-/babel-plugin-espower-2.4.0.tgz#9f92c080e9adfe73f69baed7ab3e24f649009373" + integrity sha512-/+SRpy7pKgTI28oEHfn1wkuM5QFAdRq8WNsOOih1dVrdV6A/WbNbRZyl0eX5eyDgtb0lOE27PeDFuCX2j8OxVg== + dependencies: + babel-generator "^6.1.0" + babylon "^6.1.0" + call-matcher "^1.0.0" + core-js "^2.0.0" + espower-location-detector "^1.0.0" + espurify "^1.6.0" + estraverse "^4.1.1" + +babel-plugin-syntax-async-functions@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" + integrity sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU= + +babel-plugin-syntax-exponentiation-operator@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" + integrity sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4= + +babel-plugin-syntax-trailing-function-commas@^6.20.0, babel-plugin-syntax-trailing-function-commas@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" + integrity sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM= + +babel-plugin-transform-async-to-generator@^6.16.0, babel-plugin-transform-async-to-generator@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" + integrity sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E= + dependencies: + babel-helper-remap-async-to-generator "^6.24.1" + babel-plugin-syntax-async-functions "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-arrow-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" + integrity sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" + integrity sha1-u8UbSflk1wy42OC5ToICRs46YUE= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoping@^6.23.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" + integrity sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8= + dependencies: + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-plugin-transform-es2015-classes@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" + integrity sha1-WkxYpQyclGHlZLSyo7+ryXolhNs= + dependencies: + babel-helper-define-map "^6.24.1" + babel-helper-function-name "^6.24.1" + babel-helper-optimise-call-expression "^6.24.1" + babel-helper-replace-supers "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-computed-properties@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" + integrity sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM= + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-destructuring@^6.19.0, babel-plugin-transform-es2015-destructuring@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" + integrity sha1-mXux8auWf2gtKwh2/jWNYOdlxW0= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-duplicate-keys@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" + integrity sha1-c+s9MQypaePvnskcU3QabxV2Qj4= + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-for-of@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" + integrity sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-function-name@^6.22.0, babel-plugin-transform-es2015-function-name@^6.9.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" + integrity sha1-g0yJhTvDaxrw86TF26qU/Y6sqos= + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" + integrity sha1-T1SgLWzWbPkVKAAZox0xklN3yi4= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015-modules-amd@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" + integrity sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ= + dependencies: + babel-plugin-transform-es2015-modules-commonjs "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-modules-commonjs@^6.18.0, babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1: + version "6.26.2" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz#58a793863a9e7ca870bdc5a881117ffac27db6f3" + integrity sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q== + dependencies: + babel-plugin-transform-strict-mode "^6.24.1" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-types "^6.26.0" + +babel-plugin-transform-es2015-modules-systemjs@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" + integrity sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM= + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-modules-umd@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" + integrity sha1-rJl+YoXNGO1hdq22B9YCNErThGg= + dependencies: + babel-plugin-transform-es2015-modules-amd "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-object-super@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" + integrity sha1-JM72muIcuDp/hgPa0CH1cusnj40= + dependencies: + babel-helper-replace-supers "^6.24.1" + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-parameters@^6.21.0, babel-plugin-transform-es2015-parameters@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" + integrity sha1-V6w1GrScrxSpfNE7CfZv3wpiXys= + dependencies: + babel-helper-call-delegate "^6.24.1" + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-shorthand-properties@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" + integrity sha1-JPh11nIch2YbvZmkYi5R8U3jiqA= + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-spread@^6.22.0, babel-plugin-transform-es2015-spread@^6.8.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" + integrity sha1-1taKmfia7cRTbIGlQujdnxdG+NE= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-sticky-regex@^6.22.0, babel-plugin-transform-es2015-sticky-regex@^6.8.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" + integrity sha1-AMHNsaynERLN8M9hJsLta0V8zbw= + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-template-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" + integrity sha1-qEs0UPfp+PH2g51taH2oS7EjbY0= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-typeof-symbol@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" + integrity sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-unicode-regex@^6.11.0, babel-plugin-transform-es2015-unicode-regex@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" + integrity sha1-04sS9C6nMj9yk4fxinxa4frrNek= + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + regexpu-core "^2.0.0" + +babel-plugin-transform-exponentiation-operator@^6.22.0, babel-plugin-transform-exponentiation-operator@^6.8.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" + integrity sha1-KrDJx/MJj6SJB3cruBP+QejeOg4= + dependencies: + babel-helper-builder-binary-assignment-operator-visitor "^6.24.1" + babel-plugin-syntax-exponentiation-operator "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-regenerator@^6.22.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" + integrity sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8= + dependencies: + regenerator-transform "^0.10.0" + +babel-plugin-transform-strict-mode@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" + integrity sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g= + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-polyfill@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.26.0.tgz#379937abc67d7895970adc621f284cd966cf2153" + integrity sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM= + dependencies: + babel-runtime "^6.26.0" + core-js "^2.5.0" + regenerator-runtime "^0.10.5" + +babel-preset-env@^1.6.1: + version "1.7.0" + resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.7.0.tgz#dea79fa4ebeb883cd35dab07e260c1c9c04df77a" + integrity sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg== + dependencies: + babel-plugin-check-es2015-constants "^6.22.0" + babel-plugin-syntax-trailing-function-commas "^6.22.0" + babel-plugin-transform-async-to-generator "^6.22.0" + babel-plugin-transform-es2015-arrow-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoped-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoping "^6.23.0" + babel-plugin-transform-es2015-classes "^6.23.0" + babel-plugin-transform-es2015-computed-properties "^6.22.0" + babel-plugin-transform-es2015-destructuring "^6.23.0" + babel-plugin-transform-es2015-duplicate-keys "^6.22.0" + babel-plugin-transform-es2015-for-of "^6.23.0" + babel-plugin-transform-es2015-function-name "^6.22.0" + babel-plugin-transform-es2015-literals "^6.22.0" + babel-plugin-transform-es2015-modules-amd "^6.22.0" + babel-plugin-transform-es2015-modules-commonjs "^6.23.0" + babel-plugin-transform-es2015-modules-systemjs "^6.23.0" + babel-plugin-transform-es2015-modules-umd "^6.23.0" + babel-plugin-transform-es2015-object-super "^6.22.0" + babel-plugin-transform-es2015-parameters "^6.23.0" + babel-plugin-transform-es2015-shorthand-properties "^6.22.0" + babel-plugin-transform-es2015-spread "^6.22.0" + babel-plugin-transform-es2015-sticky-regex "^6.22.0" + babel-plugin-transform-es2015-template-literals "^6.22.0" + babel-plugin-transform-es2015-typeof-symbol "^6.23.0" + babel-plugin-transform-es2015-unicode-regex "^6.22.0" + babel-plugin-transform-exponentiation-operator "^6.22.0" + babel-plugin-transform-regenerator "^6.22.0" + browserslist "^3.2.6" + invariant "^2.2.2" + semver "^5.3.0" + +babel-register@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" + integrity sha1-btAhFz4vy0htestFxgCahW9kcHE= + dependencies: + babel-core "^6.26.0" + babel-runtime "^6.26.0" + core-js "^2.5.0" + home-or-tmp "^2.0.0" + lodash "^4.17.4" + mkdirp "^0.5.1" + source-map-support "^0.4.15" + +babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.11.0" + +babel-template@^6.24.1, babel-template@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" + integrity sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI= + dependencies: + babel-runtime "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + lodash "^4.17.4" + +babel-traverse@^6.24.1, babel-traverse@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" + integrity sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4= + dependencies: + babel-code-frame "^6.26.0" + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + debug "^2.6.8" + globals "^9.18.0" + invariant "^2.2.2" + lodash "^4.17.4" + +babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" + integrity sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc= + dependencies: + babel-runtime "^6.26.0" + esutils "^2.0.2" + lodash "^4.17.4" + to-fast-properties "^1.0.3" + +babylon@7.0.0-beta.44: + version "7.0.0-beta.44" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.44.tgz#89159e15e6e30c5096e22d738d8c0af8a0e8ca1d" + integrity sha512-5Hlm13BJVAioCHpImtFqNOF2H3ieTOHd0fmFGMxOJ9jgeFqeAwsv3u5P5cR7CSeFrkgHsT19DgFJkHV0/Mcd8g== + +babylon@^6.1.0, babylon@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" + integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ== + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +base64-js@^1.0.2: + version "1.3.0" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.0.tgz#cab1e6118f051095e58b5281aea8c1cd22bfc0e3" + integrity sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw== + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= + dependencies: + tweetnacl "^0.14.3" + +beeper@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/beeper/-/beeper-1.1.1.tgz#e6d5ea8c5dad001304a70b22638447f69cb2f809" + integrity sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak= + +big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== + +binary-extensions@^1.0.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" + integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== + +block-stream@*: + version "0.0.9" + resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" + integrity sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo= + dependencies: + inherits "~2.0.0" + +bluebird@^3.0.0, bluebird@^3.5.1, bluebird@^3.5.4: + version "3.5.4" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.4.tgz#d6cc661595de30d5b3af5fcedd3c0b3ef6ec5714" + integrity sha512-FG+nFEZChJrbQ9tIccIfZJBz3J7mLrAhxakAbnrJWn8d7aKOC+LWifa0G+p4ZqKp4y13T7juYvdhq9NzKdsrjw== + +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: + version "4.11.8" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" + integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== + +bootstrap@>=4.0: + version "4.3.1" + resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.3.1.tgz#280ca8f610504d99d7b6b4bfc4b68cec601704ac" + integrity sha512-rXqOmH1VilAt2DyPzluTi2blhk17bO7ef+zLLPlWvG494pDxcM234pJ8wTc/6R40UWizAIIMgxjvxZg5kmsbag== + +boxen@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b" + integrity sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw== + dependencies: + ansi-align "^2.0.0" + camelcase "^4.0.0" + chalk "^2.0.1" + cli-boxes "^1.0.0" + string-width "^2.0.0" + term-size "^1.2.0" + widest-line "^2.0.0" + +brace-expansion@^1.0.0, brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^1.8.2: + version "1.8.5" + resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" + integrity sha1-uneWLhLf+WnWt2cR6RS3N4V79qc= + dependencies: + expand-range "^1.8.1" + preserve "^0.2.0" + repeat-element "^1.1.2" + +braces@^2.3.1, braces@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +brorand@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= + +browser-process-hrtime@^0.1.2: + version "0.1.3" + resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz#616f00faef1df7ec1b5bf9cfe2bdc3170f26c7b4" + integrity sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw== + +browserify-aes@^1.0.0, browserify-aes@^1.0.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== + dependencies: + buffer-xor "^1.0.3" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.3" + inherits "^2.0.1" + safe-buffer "^5.0.1" + +browserify-cipher@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" + integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== + dependencies: + browserify-aes "^1.0.4" + browserify-des "^1.0.0" + evp_bytestokey "^1.0.0" + +browserify-des@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== + dependencies: + cipher-base "^1.0.1" + des.js "^1.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +browserify-rsa@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" + integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ= + dependencies: + bn.js "^4.1.0" + randombytes "^2.0.1" + +browserify-sign@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" + integrity sha1-qk62jl17ZYuqa/alfmMMvXqT0pg= + dependencies: + bn.js "^4.1.1" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.2" + elliptic "^6.0.0" + inherits "^2.0.1" + parse-asn1 "^5.0.0" + +browserify-zlib@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" + integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== + dependencies: + pako "~1.0.5" + +browserslist@^2.11.3: + version "2.11.3" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.11.3.tgz#fe36167aed1bbcde4827ebfe71347a2cc70b99b2" + integrity sha512-yWu5cXT7Av6mVwzWc8lMsJMHWn4xyjSuGYi4IozbVTLUOEYPSagUB8kiMDUHA1fS3zjr8nkxkn9jdvug4BBRmA== + dependencies: + caniuse-lite "^1.0.30000792" + electron-to-chromium "^1.3.30" + +browserslist@^3.2.6: + version "3.2.8" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-3.2.8.tgz#b0005361d6471f0f5952797a76fc985f1f978fc6" + integrity sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ== + dependencies: + caniuse-lite "^1.0.30000844" + electron-to-chromium "^1.3.47" + +buf-compare@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/buf-compare/-/buf-compare-1.0.1.tgz#fef28da8b8113a0a0db4430b0b6467b69730b34a" + integrity sha1-/vKNqLgROgoNtEMLC2Rntpcws0o= + +buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + +buffer-xor@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= + +buffer@^4.3.0: + version "4.9.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" + integrity sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg= + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + +builtin-status-codes@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" + integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= + +cacache@^10.0.4: + version "10.0.4" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-10.0.4.tgz#6452367999eff9d4188aefd9a14e9d7c6a263460" + integrity sha512-Dph0MzuH+rTQzGPNT9fAnrPmMmjKfST6trxJeK7NQuHRaVw24VzPRWTmg9MpcwOVQZO0E1FBICUlFeNaKPIfHA== + dependencies: + bluebird "^3.5.1" + chownr "^1.0.1" + glob "^7.1.2" + graceful-fs "^4.1.11" + lru-cache "^4.1.1" + mississippi "^2.0.0" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + promise-inflight "^1.0.1" + rimraf "^2.6.2" + ssri "^5.2.4" + unique-filename "^1.1.0" + y18n "^4.0.0" + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + +caching-transform@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/caching-transform/-/caching-transform-1.0.1.tgz#6dbdb2f20f8d8fbce79f3e94e9d1742dcdf5c0a1" + integrity sha1-bb2y8g+Nj7znnz6U6dF0Lc31wKE= + dependencies: + md5-hex "^1.2.0" + mkdirp "^0.5.1" + write-file-atomic "^1.1.4" + +call-matcher@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/call-matcher/-/call-matcher-1.1.0.tgz#23b2c1bc7a8394c8be28609d77ddbd5786680432" + integrity sha512-IoQLeNwwf9KTNbtSA7aEBb1yfDbdnzwjCetjkC8io5oGeOmK2CBNdg0xr+tadRYKO0p7uQyZzvon0kXlZbvGrw== + dependencies: + core-js "^2.0.0" + deep-equal "^1.0.0" + espurify "^1.6.0" + estraverse "^4.0.0" + +call-signature@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/call-signature/-/call-signature-0.0.2.tgz#a84abc825a55ef4cb2b028bd74e205a65b9a4996" + integrity sha1-qEq8glpV70yysCi9dOIFpluaSZY= + +caller-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" + integrity sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8= + dependencies: + callsites "^0.2.0" + +callsites@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" + integrity sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo= + +camelcase-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" + integrity sha1-MIvur/3ygRkFHvodkyITyRuPkuc= + dependencies: + camelcase "^2.0.0" + map-obj "^1.0.0" + +camelcase@^1.0.2: + version "1.2.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" + integrity sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk= + +camelcase@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" + integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8= + +camelcase@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" + integrity sha1-MvxLn82vhF/N9+c7uXysImHwqwo= + +camelcase@^4.0.0, camelcase@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" + integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= + +caniuse-lite@^1.0.30000792, caniuse-lite@^1.0.30000805, caniuse-lite@^1.0.30000844: + version "1.0.30000967" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000967.tgz#a5039577806fccee80a04aaafb2c0890b1ee2f73" + integrity sha512-rUBIbap+VJfxTzrM4akJ00lkvVb5/n5v3EGXfWzSH5zT8aJmGzjA8HWhJ4U6kCpzxozUSnB+yvAYDRPY6mRpgQ== + +capture-stack-trace@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz#a6c0bbe1f38f3aa0b92238ecb6ff42c344d4135d" + integrity sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw== + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= + +catharsis@^0.8.10: + version "0.8.10" + resolved "https://registry.yarnpkg.com/catharsis/-/catharsis-0.8.10.tgz#364198c1fbf084ae17028ee33ec7db53ca942ee6" + integrity sha512-l2OUaz/3PU3MZylspVFJvwHCVfWyvcduPq4lv3AzZ2pJzZCo7kNKFNyatwujD7XgvGkNAE/Jhhbh2uARNwNkfw== + dependencies: + lodash "^4.17.11" + +center-align@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" + integrity sha1-qg0yYptu6XIgBBHL1EYckHvCt60= + dependencies: + align-text "^0.1.3" + lazy-cache "^1.0.3" + +chalk@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.4.0.tgz#5199a3ddcd0c1efe23bc08c1b027b06176e0c64f" + integrity sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8= + dependencies: + ansi-styles "~1.0.0" + has-color "~0.1.0" + strip-ansi "~0.1.0" + +chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.4.1: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chardet@^0.4.0: + version "0.4.2" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" + integrity sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I= + +chokidar@^1.4.2, chokidar@^1.6.1: + version "1.7.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" + integrity sha1-eY5ol3gVHIB2tLNg5e3SjNortGg= + dependencies: + anymatch "^1.3.0" + async-each "^1.0.0" + glob-parent "^2.0.0" + inherits "^2.0.1" + is-binary-path "^1.0.0" + is-glob "^2.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.0.0" + optionalDependencies: + fsevents "^1.0.0" + +chokidar@^2.0.2: + version "2.1.5" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.5.tgz#0ae8434d962281a5f56c72869e79cb6d9d86ad4d" + integrity sha512-i0TprVWp+Kj4WRPtInjexJ8Q+BqTE909VpH8xVhXrJkoc5QC8VO9TryGOqTr+2hljzc1sC62t22h5tZePodM/A== + dependencies: + anymatch "^2.0.0" + async-each "^1.0.1" + braces "^2.3.2" + glob-parent "^3.1.0" + inherits "^2.0.3" + is-binary-path "^1.0.0" + is-glob "^4.0.0" + normalize-path "^3.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.2.1" + upath "^1.1.1" + optionalDependencies: + fsevents "^1.2.7" + +chownr@^1.0.1, chownr@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.1.tgz#54726b8b8fff4df053c42187e801fb4412df1494" + integrity sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g== + +ci-info@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" + integrity sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A== + +cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +circular-json@^0.3.1: + version "0.3.3" + resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" + integrity sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A== + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +clean-css@4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.1.tgz#2d411ef76b8569b6d0c84068dabe85b0aa5e5c17" + integrity sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g== + dependencies: + source-map "~0.6.0" + +clean-stack@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-1.3.0.tgz#9e821501ae979986c46b1d66d2d432db2fd4ae31" + integrity sha1-noIVAa6XmYbEax1m0tQy2y/UrjE= + +clean-yaml-object@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/clean-yaml-object/-/clean-yaml-object-0.1.0.tgz#63fb110dc2ce1a84dc21f6d9334876d010ae8b68" + integrity sha1-Y/sRDcLOGoTcIfbZM0h20BCui2g= + +cli-boxes@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" + integrity sha1-T6kXw+WclKAEzWH47lCdplFocUM= + +cli-cursor@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= + dependencies: + restore-cursor "^2.0.0" + +cli-spinners@^1.0.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-1.3.1.tgz#002c1990912d0d59580c93bd36c056de99e4259a" + integrity sha512-1QL4544moEsDVH9T/l6Cemov/37iv1RtoKf7NJ04A60+4MREXNfx/QvavbH6QoGdsD4N4Mwy49cmaINR/o2mdg== + +cli-truncate@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-1.1.0.tgz#2b2dfd83c53cfd3572b87fc4d430a808afb04086" + integrity sha512-bAtZo0u82gCfaAGfSNxUdTI9mNyza7D8w4CVCcaOsy7sgwDzvx6ekr6cuWJqY3UGzgnQ1+4wgENup5eIhgxEYA== + dependencies: + slice-ansi "^1.0.0" + string-width "^2.0.0" + +cli-width@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" + integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= + +cliui@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" + integrity sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE= + dependencies: + center-align "^0.1.1" + right-align "^0.1.1" + wordwrap "0.0.2" + +cliui@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" + integrity sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0= + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrap-ansi "^2.0.0" + +clone-buffer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58" + integrity sha1-4+JbIHrE5wGvch4staFnksrD3Fg= + +clone-stats@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-0.0.1.tgz#b88f94a82cf38b8791d58046ea4029ad88ca99d1" + integrity sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE= + +clone-stats@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680" + integrity sha1-s3gt/4u1R04Yuba/D9/ngvh3doA= + +clone@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/clone/-/clone-0.2.0.tgz#c6126a90ad4f72dbf5acdb243cc37724fe93fc1f" + integrity sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8= + +clone@^1.0.0, clone@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" + integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= + +clone@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" + integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= + +cloneable-readable@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/cloneable-readable/-/cloneable-readable-1.1.2.tgz#d591dee4a8f8bc15da43ce97dceeba13d43e2a65" + integrity sha512-Bq6+4t+lbM8vhTs/Bef5c5AdEMtapp/iFb6+s4/Hh9MVTt8OLKH7ZOOZSCT+Ys7hsHvqv0GuMPJ1lnQJVHvxpg== + dependencies: + inherits "^2.0.1" + process-nextick-args "^2.0.0" + readable-stream "^2.3.5" + +co-with-promise@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co-with-promise/-/co-with-promise-4.6.0.tgz#413e7db6f5893a60b942cf492c4bec93db415ab7" + integrity sha1-QT59tvWJOmC5Qs9JLEvsk9tBWrc= + dependencies: + pinkie-promise "^1.0.0" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= + +code-excerpt@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/code-excerpt/-/code-excerpt-2.1.1.tgz#5fe3057bfbb71a5f300f659ef2cc0a47651ba77c" + integrity sha512-tJLhH3EpFm/1x7heIW0hemXJTUU5EWl2V0EIX558jp05Mt1U6DVryCgkp3l37cxqs+DNbNgxG43SkwJXpQ14Jw== + dependencies: + convert-to-spaces "^1.0.1" + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-convert@^1.9.0, color-convert@^1.9.1: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +color-name@^1.0.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +color-string@^1.5.2: + version "1.5.3" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.3.tgz#c9bbc5f01b58b5492f3d6857459cb6590ce204cc" + integrity sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw== + dependencies: + color-name "^1.0.0" + simple-swizzle "^0.2.2" + +color-support@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" + integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== + +color@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/color/-/color-3.1.1.tgz#7abf5c0d38e89378284e873c207ae2172dcc8a61" + integrity sha512-PvUltIXRjehRKPSy89VnDWFKY58xyhTLyxIg21vwQBI6qLwZNPmC8k3C1uytIgFKEpOIzN4y32iPm8231zFHIg== + dependencies: + color-convert "^1.9.1" + color-string "^1.5.2" + +colors@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" + integrity sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs= + +combined-stream@^1.0.6, combined-stream@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.7.tgz#2d1d24317afb8abe95d6d2c0b07b57813539d828" + integrity sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w== + dependencies: + delayed-stream "~1.0.0" + +commander@2.15.1: + version "2.15.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" + integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag== + +commander@^2.11.0, commander@~2.20.0: + version "2.20.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" + integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== + +commander@~2.13.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c" + integrity sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA== + +common-path-prefix@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/common-path-prefix/-/common-path-prefix-1.0.0.tgz#cd52f6f0712e0baab97d6f9732874f22f47752c0" + integrity sha1-zVL28HEuC6q5fW+XModPIvR3UsA= + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= + +component-emitter@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +concat-stream@^1.5.0, concat-stream@^1.6.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +concat-with-sourcemaps@*: + version "1.1.0" + resolved "https://registry.yarnpkg.com/concat-with-sourcemaps/-/concat-with-sourcemaps-1.1.0.tgz#d4ea93f05ae25790951b99e7b3b09e3908a4082e" + integrity sha512-4gEjHJFT9e+2W/77h/DS5SGUgwDaOwprX8L/gl5+3ixnzkVJJsZWDSelmN3Oilw3LNDZjZV0yqH1hLG3k6nghg== + dependencies: + source-map "^0.6.1" + +concordance@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/concordance/-/concordance-3.0.0.tgz#b2286af54405fc995fc7345b0b106d8dd073cb29" + integrity sha512-CZBzJ3/l5QJjlZM20WY7+5GP5pMTw+1UEbThcpMw8/rojsi5sBCiD8ZbBLtD+jYpRGAkwuKuqk108c154V9eyQ== + dependencies: + date-time "^2.1.0" + esutils "^2.0.2" + fast-diff "^1.1.1" + function-name-support "^0.2.0" + js-string-escape "^1.0.1" + lodash.clonedeep "^4.5.0" + lodash.flattendeep "^4.4.0" + lodash.merge "^4.6.0" + md5-hex "^2.0.0" + semver "^5.3.0" + well-known-symbols "^1.0.0" + +configstore@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.2.tgz#c6f25defaeef26df12dd33414b001fe81a543f8f" + integrity sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw== + dependencies: + dot-prop "^4.1.0" + graceful-fs "^4.1.2" + make-dir "^1.0.0" + unique-string "^1.0.0" + write-file-atomic "^2.0.0" + xdg-basedir "^3.0.0" + +console-browserify@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10" + integrity sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA= + dependencies: + date-now "^0.1.4" + +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= + +constants-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" + integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= + +convert-source-map@1.X, convert-source-map@^1.2.0, convert-source-map@^1.5.0, convert-source-map@^1.5.1: + version "1.6.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" + integrity sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A== + dependencies: + safe-buffer "~5.1.1" + +convert-to-spaces@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/convert-to-spaces/-/convert-to-spaces-1.0.2.tgz#7e3e48bbe6d997b1417ddca2868204b4d3d85715" + integrity sha1-fj5Iu+bZl7FBfdyihoIEtNPYVxU= + +copy-concurrently@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" + integrity sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A== + dependencies: + aproba "^1.1.1" + fs-write-stream-atomic "^1.0.8" + iferr "^0.1.5" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.0" + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= + +core-assert@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/core-assert/-/core-assert-0.2.1.tgz#f85e2cf9bfed28f773cc8b3fa5c5b69bdc02fe3f" + integrity sha1-+F4s+b/tKPdzzIs/pcW2m9wC/j8= + dependencies: + buf-compare "^1.0.0" + is-error "^2.2.0" + +core-js@^2.0.0, core-js@^2.4.0, core-js@^2.5.0: + version "2.6.5" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.5.tgz#44bc8d249e7fb2ff5d00e0341a7ffb94fbf67895" + integrity sha512-klh/kDpwX8hryYL14M9w/xei6vrv6sE8gTHDG7/T/+SEovB/G4ejwcfE/CBzO6Edsu+OETZMZ3wcX/EjUkrl5A== + +core-util-is@1.0.2, core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +corser@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/corser/-/corser-2.0.1.tgz#8eda252ecaab5840dcd975ceb90d9370c819ff87" + integrity sha1-jtolLsqrWEDc2XXOuQ2TcMgZ/4c= + +create-ecdh@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" + integrity sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw== + dependencies: + bn.js "^4.1.0" + elliptic "^6.0.0" + +create-error-class@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" + integrity sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y= + dependencies: + capture-stack-trace "^1.0.0" + +create-hash@^1.1.0, create-hash@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + +create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +cross-spawn@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-3.0.1.tgz#1256037ecb9f0c5f79e3d6ef135e30770184b982" + integrity sha1-ElYDfsufDF9549bvE14wdwGEuYI= + dependencies: + lru-cache "^4.0.1" + which "^1.2.9" + +cross-spawn@^5.0.1, cross-spawn@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk= + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + +crypto-browserify@^3.11.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" + integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== + dependencies: + browserify-cipher "^1.0.0" + browserify-sign "^4.0.0" + create-ecdh "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.0" + diffie-hellman "^5.0.0" + inherits "^2.0.1" + pbkdf2 "^3.0.3" + public-encrypt "^4.0.0" + randombytes "^2.0.0" + randomfill "^1.0.3" + +crypto-random-string@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" + integrity sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4= + +css@2.X, css@^2.2.1: + version "2.2.4" + resolved "https://registry.yarnpkg.com/css/-/css-2.2.4.tgz#c646755c73971f2bba6a601e2cf2fd71b1298929" + integrity sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw== + dependencies: + inherits "^2.0.3" + source-map "^0.6.1" + source-map-resolve "^0.5.2" + urix "^0.1.0" + +cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": + version "0.3.6" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.6.tgz#f85206cee04efa841f3c5982a74ba96ab20d65ad" + integrity sha512-DtUeseGk9/GBW0hl0vVPpU22iHL6YB5BUX7ml1hB+GMpo0NX5G4voX3kdWiMSEguFtcW3Vh3djqNF4aIe6ne0A== + +cssstyle@^1.0.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-1.2.2.tgz#427ea4d585b18624f6fdbf9de7a2a1a3ba713077" + integrity sha512-43wY3kl1CVQSvL7wUY1qXkxVGkStjpkDmVjiIKX8R97uhajy8Bybay78uOtqvh7Q5GK75dNPfW0geWjE6qQQow== + dependencies: + cssom "0.3.x" + +currently-unhandled@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" + integrity sha1-mI3zP+qxke95mmE2nddsF635V+o= + dependencies: + array-find-index "^1.0.1" + +cyclist@~0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640" + integrity sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA= + +d@1: + version "1.0.0" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" + integrity sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8= + dependencies: + es5-ext "^0.10.9" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= + dependencies: + assert-plus "^1.0.0" + +data-urls@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-1.1.0.tgz#15ee0582baa5e22bb59c77140da8f9c76963bbfe" + integrity sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ== + dependencies: + abab "^2.0.0" + whatwg-mimetype "^2.2.0" + whatwg-url "^7.0.0" + +date-now@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" + integrity sha1-6vQ5/U1ISK105cx9vvIAZyueNFs= + +date-time@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/date-time/-/date-time-0.1.1.tgz#ed2f6d93d9790ce2fd66d5b5ff3edd5bbcbf3b07" + integrity sha1-7S9tk9l5DOL9ZtW1/z7dW7y/Owc= + +date-time@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/date-time/-/date-time-2.1.0.tgz#0286d1b4c769633b3ca13e1e62558d2dbdc2eba2" + integrity sha512-/9+C44X7lot0IeiyfgJmETtRMhBidBYM2QFFIkGa0U1k+hSyY87Nw7PY3eDqpvCBm7I3WCSfPeZskW/YYq6m4g== + dependencies: + time-zone "^1.0.0" + +dateformat@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-2.2.0.tgz#4065e2013cf9fb916ddfd82efb506ad4c6769062" + integrity sha1-QGXiATz5+5Ft39gu+1Bq1MZ2kGI= + +debug-fabulous@1.X: + version "1.1.0" + resolved "https://registry.yarnpkg.com/debug-fabulous/-/debug-fabulous-1.1.0.tgz#af8a08632465224ef4174a9f06308c3c2a1ebc8e" + integrity sha512-GZqvGIgKNlUnHUPQhepnUZFIMoi3dgZKQBzKDeL2g7oJF9SNAji/AAu36dusFUas0O+pae74lNeoIPHqXWDkLg== + dependencies: + debug "3.X" + memoizee "0.4.X" + object-assign "4.X" + +debug@3.X, debug@^3.0.1, debug@^3.1.0, debug@^3.2.6: + version "3.2.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== + dependencies: + ms "^2.1.1" + +debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" + integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== + dependencies: + ms "^2.1.1" + +decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= + +deep-equal@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" + integrity sha1-9dJgKStmDghO/0zbyfCK0yR0SLU= + +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= + +defaults@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" + integrity sha1-xlYFHpgX2f8I7YgUd/P+QBnz730= + dependencies: + clone "^1.0.2" + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +del@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/del/-/del-3.0.0.tgz#53ecf699ffcbcb39637691ab13baf160819766e5" + integrity sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU= + dependencies: + globby "^6.1.0" + is-path-cwd "^1.0.0" + is-path-in-cwd "^1.0.0" + p-map "^1.1.1" + pify "^3.0.0" + rimraf "^2.2.8" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= + +deprecated@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/deprecated/-/deprecated-0.0.1.tgz#f9c9af5464afa1e7a971458a8bdef2aa94d5bb19" + integrity sha1-+cmvVGSvoeepcUWKi97yqpTVuxk= + +des.js@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc" + integrity sha1-wHTS4qpqipoH29YfmhXCzYPsjsw= + dependencies: + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +detect-file@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7" + integrity sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc= + +detect-indent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" + integrity sha1-920GQ1LN9Docts5hnE7jqUdd4gg= + dependencies: + repeating "^2.0.0" + +detect-indent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" + integrity sha1-OHHMCmoALow+Wzz38zYmRnXwa50= + +detect-libc@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= + +detect-newline@2.X: + version "2.1.0" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" + integrity sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I= + +diffie-hellman@^5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== + dependencies: + bn.js "^4.1.0" + miller-rabin "^4.0.0" + randombytes "^2.0.0" + +doctrine@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" + integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== + dependencies: + esutils "^2.0.2" + +domain-browser@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" + integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== + +domexception@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" + integrity sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug== + dependencies: + webidl-conversions "^4.0.2" + +dot-prop@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" + integrity sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ== + dependencies: + is-obj "^1.0.0" + +duplexer2@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.0.2.tgz#c614dcf67e2fb14995a91711e5a617e8a60a31db" + integrity sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds= + dependencies: + readable-stream "~1.1.9" + +duplexer3@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" + integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= + +duplexify@^3.4.2, duplexify@^3.6.0: + version "3.7.1" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" + integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + +ecstatic@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ecstatic/-/ecstatic-2.2.1.tgz#b5087fad439dd9dd49d31e18131454817fe87769" + integrity sha512-ztE4WqheoWLh3wv+HQwy7dACnvNY620coWpa+XqY6R2cVWgaAT2lUISU1Uf7JpdLLJCURktJOaA9av2AOzsyYQ== + dependencies: + he "^1.1.1" + mime "^1.2.11" + minimist "^1.1.0" + url-join "^2.0.2" + +electron-to-chromium@^1.3.30, electron-to-chromium@^1.3.47: + version "1.3.133" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.133.tgz#c47639c19b91feee3e22fad69f5556142007008c" + integrity sha512-lyoC8aoqbbDqsprb6aPdt9n3DpOZZzdz/T4IZKsR0/dkZIxnJVUjjcpOSwA66jPRIOyDAamCTAUqweU05kKNSg== + +elliptic@^6.0.0: + version "6.4.1" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.1.tgz#c2d0b7776911b86722c632c3c06c60f2f819939a" + integrity sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ== + dependencies: + bn.js "^4.4.0" + brorand "^1.0.1" + hash.js "^1.0.0" + hmac-drbg "^1.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.0" + +emojis-list@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" + integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= + +empower-core@^0.6.1: + version "0.6.2" + resolved "https://registry.yarnpkg.com/empower-core/-/empower-core-0.6.2.tgz#5adef566088e31fba80ba0a36df47d7094169144" + integrity sha1-Wt71ZgiOMfuoC6CjbfR9cJQWkUQ= + dependencies: + call-signature "0.0.2" + core-js "^2.0.0" + +end-of-stream@^1.0.0, end-of-stream@^1.1.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" + integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q== + dependencies: + once "^1.4.0" + +end-of-stream@~0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-0.1.5.tgz#8e177206c3c80837d85632e8b9359dfe8b2f6eaf" + integrity sha1-jhdyBsPICDfYVjLouTWd/osvbq8= + dependencies: + once "~1.3.0" + +enhanced-resolve@^3.4.0: + version "3.4.1" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz#0421e339fd71419b3da13d129b3979040230476e" + integrity sha1-BCHjOf1xQZs9oT0Smzl5BAIwR24= + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.4.0" + object-assign "^4.0.1" + tapable "^0.2.7" + +entities@~1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" + integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== + +equal-length@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/equal-length/-/equal-length-1.0.1.tgz#21ca112d48ab24b4e1e7ffc0e5339d31fdfc274c" + integrity sha1-IcoRLUirJLTh5//A5TOdMf38J0w= + +errno@^0.1.3, errno@~0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" + integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg== + dependencies: + prr "~1.0.1" + +error-ex@^1.2.0, error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +es5-ext@^0.10.14, es5-ext@^0.10.35, es5-ext@^0.10.45, es5-ext@^0.10.9, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46: + version "0.10.50" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.50.tgz#6d0e23a0abdb27018e5ac4fd09b412bc5517a778" + integrity sha512-KMzZTPBkeQV/JcSQhI5/z6d9VWJ3EnQ194USTUwIYZ2ZbpN8+SGXQKt1h68EX44+qt+Fzr8DO17vnxrw7c3agw== + dependencies: + es6-iterator "~2.0.3" + es6-symbol "~3.1.1" + next-tick "^1.0.0" + +es6-error@^4.0.1, es6-error@^4.0.2: + version "4.1.1" + resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d" + integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg== + +es6-iterator@^2.0.1, es6-iterator@~2.0.1, es6-iterator@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + +es6-map@^0.1.3: + version "0.1.5" + resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.5.tgz#9136e0503dcc06a301690f0bb14ff4e364e949f0" + integrity sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA= + dependencies: + d "1" + es5-ext "~0.10.14" + es6-iterator "~2.0.1" + es6-set "~0.1.5" + es6-symbol "~3.1.1" + event-emitter "~0.3.5" + +es6-set@~0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1" + integrity sha1-0rPsXU2ADO2BjbU40ol02wpzzLE= + dependencies: + d "1" + es5-ext "~0.10.14" + es6-iterator "~2.0.1" + es6-symbol "3.1.1" + event-emitter "~0.3.5" + +es6-symbol@3.1.1, es6-symbol@^3.1.1, es6-symbol@~3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" + integrity sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc= + dependencies: + d "1" + es5-ext "~0.10.14" + +es6-weak-map@^2.0.1, es6-weak-map@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.2.tgz#5e3ab32251ffd1538a1f8e5ffa1357772f92d96f" + integrity sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8= + dependencies: + d "1" + es5-ext "^0.10.14" + es6-iterator "^2.0.1" + es6-symbol "^3.1.1" + +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.3, escape-string-regexp@^1.0.4, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + +escodegen@^1.9.1: + version "1.11.1" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.11.1.tgz#c485ff8d6b4cdb89e27f4a856e91f118401ca510" + integrity sha512-JwiqFD9KdGVVpeuRa68yU3zZnBEOcPs0nKW7wZzXky8Z7tffdYUHbe11bPCV5jYlK6DVdKLWLm0f5I/QlL0Kmw== + dependencies: + esprima "^3.1.3" + estraverse "^4.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + +escope@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3" + integrity sha1-4Bl16BJ4GhY6ba392AOY3GTIicM= + dependencies: + es6-map "^0.1.3" + es6-weak-map "^2.0.1" + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-loader@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/eslint-loader/-/eslint-loader-1.9.0.tgz#7e1be9feddca328d3dcfaef1ad49d5beffe83a13" + integrity sha512-40aN976qSNPyb9ejTqjEthZITpls1SVKtwguahmH1dzGCwQU/vySE+xX33VZmD8csU0ahVNCtFlsPgKqRBiqgg== + dependencies: + loader-fs-cache "^1.0.0" + loader-utils "^1.0.2" + object-assign "^4.0.1" + object-hash "^1.1.4" + rimraf "^2.6.1" + +eslint-scope@3.7.1: + version "3.7.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8" + integrity sha1-PWPD7f2gLgbgGkUq2IyqzHzctug= + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-scope@^3.7.1: + version "3.7.3" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.3.tgz#bb507200d3d17f60247636160b4826284b108535" + integrity sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-visitor-keys@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" + integrity sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ== + +eslint@^4.11.0: + version "4.19.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.19.1.tgz#32d1d653e1d90408854bfb296f076ec7e186a300" + integrity sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ== + dependencies: + ajv "^5.3.0" + babel-code-frame "^6.22.0" + chalk "^2.1.0" + concat-stream "^1.6.0" + cross-spawn "^5.1.0" + debug "^3.1.0" + doctrine "^2.1.0" + eslint-scope "^3.7.1" + eslint-visitor-keys "^1.0.0" + espree "^3.5.4" + esquery "^1.0.0" + esutils "^2.0.2" + file-entry-cache "^2.0.0" + functional-red-black-tree "^1.0.1" + glob "^7.1.2" + globals "^11.0.1" + ignore "^3.3.3" + imurmurhash "^0.1.4" + inquirer "^3.0.6" + is-resolvable "^1.0.0" + js-yaml "^3.9.1" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.3.0" + lodash "^4.17.4" + minimatch "^3.0.2" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + optionator "^0.8.2" + path-is-inside "^1.0.2" + pluralize "^7.0.0" + progress "^2.0.0" + regexpp "^1.0.1" + require-uncached "^1.0.3" + semver "^5.3.0" + strip-ansi "^4.0.0" + strip-json-comments "~2.0.1" + table "4.0.2" + text-table "~0.2.0" + +espower-location-detector@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/espower-location-detector/-/espower-location-detector-1.0.0.tgz#a17b7ecc59d30e179e2bef73fb4137704cb331b5" + integrity sha1-oXt+zFnTDheeK+9z+0E3cEyzMbU= + dependencies: + is-url "^1.2.1" + path-is-absolute "^1.0.0" + source-map "^0.5.0" + xtend "^4.0.0" + +espree@^3.5.4: + version "3.5.4" + resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.4.tgz#b0f447187c8a8bed944b815a660bddf5deb5d1a7" + integrity sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A== + dependencies: + acorn "^5.5.0" + acorn-jsx "^3.0.0" + +esprima@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" + integrity sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM= + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +espurify@^1.6.0: + version "1.8.1" + resolved "https://registry.yarnpkg.com/espurify/-/espurify-1.8.1.tgz#5746c6c1ab42d302de10bd1d5bf7f0e8c0515056" + integrity sha512-ZDko6eY/o+D/gHCWyHTU85mKDgYcS4FJj7S+YD6WIInm7GQ6AnOjmcL4+buFV/JOztVLELi/7MmuGU5NHta0Mg== + dependencies: + core-js "^2.0.0" + +esquery@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708" + integrity sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA== + dependencies: + estraverse "^4.0.0" + +esrecurse@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" + integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== + dependencies: + estraverse "^4.1.0" + +estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" + integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= + +esutils@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" + integrity sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs= + +event-emitter@^0.3.5, event-emitter@~0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" + integrity sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk= + dependencies: + d "1" + es5-ext "~0.10.14" + +eventemitter3@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.2.tgz#2d3d48f9c346698fce83a85d7d664e98535df6e7" + integrity sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q== + +events@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.0.0.tgz#9a0a0dfaf62893d92b875b8f2698ca4114973e88" + integrity sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA== + +evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== + dependencies: + md5.js "^1.3.4" + safe-buffer "^5.1.1" + +execa@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" + integrity sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c= + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +expand-brackets@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" + integrity sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s= + dependencies: + is-posix-bracket "^0.1.0" + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +expand-range@^1.8.1: + version "1.8.2" + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" + integrity sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc= + dependencies: + fill-range "^2.1.0" + +expand-tilde@^2.0.0, expand-tilde@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" + integrity sha1-l+gBqgUt8CRU3kawK/YhZCzchQI= + dependencies: + homedir-polyfill "^1.0.1" + +extend-shallow@^1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-1.1.4.tgz#19d6bf94dfc09d76ba711f39b872d21ff4dd9071" + integrity sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE= + dependencies: + kind-of "^1.1.0" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extend@^3.0.0, extend@^3.0.1, extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +external-editor@^2.0.4: + version "2.2.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5" + integrity sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A== + dependencies: + chardet "^0.4.0" + iconv-lite "^0.4.17" + tmp "^0.0.33" + +extglob@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" + integrity sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE= + dependencies: + is-extglob "^1.0.0" + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= + +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= + +fancy-log@^1.1.0, fancy-log@^1.3.2: + version "1.3.3" + resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-1.3.3.tgz#dbc19154f558690150a23953a0adbd035be45fc7" + integrity sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw== + dependencies: + ansi-gray "^0.1.1" + color-support "^1.1.3" + parse-node-version "^1.0.0" + time-stamp "^1.0.0" + +fast-deep-equal@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614" + integrity sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ= + +fast-deep-equal@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" + integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= + +fast-diff@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" + integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== + +fast-json-stable-stringify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" + integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= + +fast-levenshtein@~2.0.4: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + +figures@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" + integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= + dependencies: + escape-string-regexp "^1.0.5" + +file-entry-cache@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" + integrity sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E= + dependencies: + flat-cache "^1.2.1" + object-assign "^4.0.1" + +filename-regex@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" + integrity sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY= + +filename-reserved-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/filename-reserved-regex/-/filename-reserved-regex-1.0.0.tgz#e61cf805f0de1c984567d0386dc5df50ee5af7e4" + integrity sha1-5hz4BfDeHJhFZ9A4bcXfUO5a9+Q= + +filenamify-url@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/filenamify-url/-/filenamify-url-1.0.0.tgz#b32bd81319ef5863b73078bed50f46a4f7975f50" + integrity sha1-syvYExnvWGO3MHi+1Q9GpPeXX1A= + dependencies: + filenamify "^1.0.0" + humanize-url "^1.0.0" + +filenamify@^1.0.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/filenamify/-/filenamify-1.2.1.tgz#a9f2ffd11c503bed300015029272378f1f1365a5" + integrity sha1-qfL/0RxQO+0wABUCknI3jx8TZaU= + dependencies: + filename-reserved-regex "^1.0.0" + strip-outer "^1.0.0" + trim-repeated "^1.0.0" + +fill-range@^2.1.0: + version "2.2.4" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.4.tgz#eb1e773abb056dcd8df2bfdf6af59b8b3a936565" + integrity sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q== + dependencies: + is-number "^2.1.0" + isobject "^2.0.0" + randomatic "^3.0.0" + repeat-element "^1.1.2" + repeat-string "^1.5.2" + +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +find-cache-dir@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-0.1.1.tgz#c8defae57c8a52a8a784f9e31c57c742e993a0b9" + integrity sha1-yN765XyKUqinhPnjHFfHQumToLk= + dependencies: + commondir "^1.0.1" + mkdirp "^0.5.1" + pkg-dir "^1.0.0" + +find-cache-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-1.0.0.tgz#9288e3e9e3cc3748717d39eade17cf71fc30ee6f" + integrity sha1-kojj6ePMN0hxfTnq3hfPcfww7m8= + dependencies: + commondir "^1.0.1" + make-dir "^1.0.0" + pkg-dir "^2.0.0" + +find-index@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/find-index/-/find-index-0.1.1.tgz#675d358b2ca3892d795a1ab47232f8b6e2e0dde4" + integrity sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ= + +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + +find-up@^2.0.0, find-up@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= + dependencies: + locate-path "^2.0.0" + +findup-sync@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-2.0.0.tgz#9326b1488c22d1a6088650a86901b2d9a90a2cbc" + integrity sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw= + dependencies: + detect-file "^1.0.0" + is-glob "^3.1.0" + micromatch "^3.0.4" + resolve-dir "^1.0.1" + +fined@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/fined/-/fined-1.2.0.tgz#d00beccf1aa2b475d16d423b0238b713a2c4a37b" + integrity sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng== + dependencies: + expand-tilde "^2.0.2" + is-plain-object "^2.0.3" + object.defaults "^1.1.0" + object.pick "^1.2.0" + parse-filepath "^1.0.1" + +first-chunk-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz#59bfb50cd905f60d7c394cd3d9acaab4e6ad934e" + integrity sha1-Wb+1DNkF9g18OUzT2ayqtOatk04= + +flagged-respawn@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/flagged-respawn/-/flagged-respawn-1.0.1.tgz#e7de6f1279ddd9ca9aac8a5971d618606b3aab41" + integrity sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q== + +flat-cache@^1.2.1: + version "1.3.4" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.4.tgz#2c2ef77525cc2929007dfffa1dd314aa9c9dee6f" + integrity sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg== + dependencies: + circular-json "^0.3.1" + graceful-fs "^4.1.2" + rimraf "~2.6.2" + write "^0.2.1" + +flush-write-stream@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" + integrity sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w== + dependencies: + inherits "^2.0.3" + readable-stream "^2.3.6" + +fn-name@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fn-name/-/fn-name-2.0.1.tgz#5214d7537a4d06a4a301c0cc262feb84188002e7" + integrity sha1-UhTXU3pNBqSjAcDMJi/rhBiAAuc= + +follow-redirects@^1.0.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.7.0.tgz#489ebc198dc0e7f64167bd23b03c4c19b5784c76" + integrity sha512-m/pZQy4Gj287eNy94nivy5wchN3Kp+Q5WgUPNy5lJSZ3sgkVKSYV/ZChMAQVIgx1SqfZ2zBZtPA2YlXIWxxJOQ== + dependencies: + debug "^3.2.6" + +for-in@^1.0.1, for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= + +for-own@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" + integrity sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4= + dependencies: + for-in "^1.0.1" + +for-own@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-1.0.0.tgz#c63332f415cedc4b04dbfe70cf836494c53cb44b" + integrity sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs= + dependencies: + for-in "^1.0.1" + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= + +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= + dependencies: + map-cache "^0.2.2" + +from2@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" + integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8= + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.0" + +fs-extra@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-5.0.0.tgz#414d0110cdd06705734d055652c5411260c31abd" + integrity sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-minipass@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" + integrity sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ== + dependencies: + minipass "^2.2.1" + +fs-readdir-recursive@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27" + integrity sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA== + +fs-write-stream-atomic@^1.0.8: + version "1.0.10" + resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" + integrity sha1-tH31NJPvkR33VzHnCp3tAYnbQMk= + dependencies: + graceful-fs "^4.1.2" + iferr "^0.1.5" + imurmurhash "^0.1.4" + readable-stream "1 || 2" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fsevents@^1.0.0, fsevents@^1.2.7: + version "1.2.9" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.9.tgz#3f5ed66583ccd6f400b5a00db6f7e861363e388f" + integrity sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw== + dependencies: + nan "^2.12.1" + node-pre-gyp "^0.12.0" + +fstream@^1.0.0, fstream@^1.0.2: + version "1.0.11" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171" + integrity sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE= + dependencies: + graceful-fs "^4.1.2" + inherits "~2.0.0" + mkdirp ">=0.5 0" + rimraf "2" + +function-name-support@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/function-name-support/-/function-name-support-0.2.0.tgz#55d3bfaa6eafd505a50f9bc81fdf57564a0bb071" + integrity sha1-VdO/qm6v1QWlD5vIH99XVkoLsHE= + +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= + +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + +gaze@^0.5.1: + version "0.5.2" + resolved "https://registry.yarnpkg.com/gaze/-/gaze-0.5.2.tgz#40b709537d24d1d45767db5a908689dfe69ac44f" + integrity sha1-QLcJU30k0dRXZ9takIaJ3+aaxE8= + dependencies: + globule "~0.1.0" + +gaze@^1.0.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/gaze/-/gaze-1.1.3.tgz#c441733e13b927ac8c0ff0b4c3b033f28812924a" + integrity sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g== + dependencies: + globule "^1.0.0" + +get-caller-file@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" + integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== + +get-port@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/get-port/-/get-port-3.2.0.tgz#dd7ce7de187c06c8bf353796ac71e099f0980ebc" + integrity sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw= + +get-stdin@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" + integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4= + +get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= + dependencies: + assert-plus "^1.0.0" + +gh-pages@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/gh-pages/-/gh-pages-1.2.0.tgz#1acb92801078f7c038a167f447221d1496ccfbee" + integrity sha512-cGLYAvxtlQ1iTwAS4g7FreZPXoE/g62Fsxln2mmR19mgs4zZI+XJ+wVVUhBFCF/0+Nmvbq+abyTWue1m1BSnmg== + dependencies: + async "2.6.1" + commander "2.15.1" + filenamify-url "^1.0.0" + fs-extra "^5.0.0" + globby "^6.1.0" + graceful-fs "4.1.11" + rimraf "^2.6.2" + +glob-base@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" + integrity sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q= + dependencies: + glob-parent "^2.0.0" + is-glob "^2.0.0" + +glob-parent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" + integrity sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg= + dependencies: + is-glob "^2.0.0" + +glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob-stream@^3.1.5: + version "3.1.18" + resolved "https://registry.yarnpkg.com/glob-stream/-/glob-stream-3.1.18.tgz#9170a5f12b790306fdfe598f313f8f7954fd143b" + integrity sha1-kXCl8St5Awb9/lmPMT+PeVT9FDs= + dependencies: + glob "^4.3.1" + glob2base "^0.0.12" + minimatch "^2.0.1" + ordered-read-streams "^0.1.0" + through2 "^0.6.1" + unique-stream "^1.0.0" + +glob-watcher@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/glob-watcher/-/glob-watcher-0.0.6.tgz#b95b4a8df74b39c83298b0c05c978b4d9a3b710b" + integrity sha1-uVtKjfdLOcgymLDAXJeLTZo7cQs= + dependencies: + gaze "^0.5.1" + +glob2base@^0.0.12: + version "0.0.12" + resolved "https://registry.yarnpkg.com/glob2base/-/glob2base-0.0.12.tgz#9d419b3e28f12e83a362164a277055922c9c0d56" + integrity sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY= + dependencies: + find-index "^0.1.1" + +glob@^4.3.1: + version "4.5.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-4.5.3.tgz#c6cb73d3226c1efef04de3c56d012f03377ee15f" + integrity sha1-xstz0yJsHv7wTePFbQEvAzd+4V8= + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "^2.0.1" + once "^1.3.0" + +glob@^7.0.0, glob@^7.0.3, glob@^7.1.2, glob@^7.1.3, glob@~7.1.1: + version "7.1.4" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255" + integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@~3.1.21: + version "3.1.21" + resolved "https://registry.yarnpkg.com/glob/-/glob-3.1.21.tgz#d29e0a055dea5138f4d07ed40e8982e83c2066cd" + integrity sha1-0p4KBV3qUTj00H7UDomC6DwgZs0= + dependencies: + graceful-fs "~1.2.0" + inherits "1" + minimatch "~0.2.11" + +global-dirs@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445" + integrity sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU= + dependencies: + ini "^1.3.4" + +global-modules@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" + integrity sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg== + dependencies: + global-prefix "^1.0.1" + is-windows "^1.0.1" + resolve-dir "^1.0.0" + +global-prefix@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe" + integrity sha1-2/dDxsFJklk8ZVVoy2btMsASLr4= + dependencies: + expand-tilde "^2.0.2" + homedir-polyfill "^1.0.1" + ini "^1.3.4" + is-windows "^1.0.1" + which "^1.2.14" + +globals@^11.0.1, globals@^11.1.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +globals@^9.18.0: + version "9.18.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" + integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ== + +globby@^6.0.0, globby@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" + integrity sha1-9abXDoOV4hyFj7BInWTfAkJNUGw= + dependencies: + array-union "^1.0.1" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +globule@^1.0.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/globule/-/globule-1.2.1.tgz#5dffb1b191f22d20797a9369b49eab4e9839696d" + integrity sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ== + dependencies: + glob "~7.1.1" + lodash "~4.17.10" + minimatch "~3.0.2" + +globule@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/globule/-/globule-0.1.0.tgz#d9c8edde1da79d125a151b79533b978676346ae5" + integrity sha1-2cjt3h2nnRJaFRt5UzuXhnY0auU= + dependencies: + glob "~3.1.21" + lodash "~1.0.1" + minimatch "~0.2.11" + +glogg@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/glogg/-/glogg-1.0.2.tgz#2d7dd702beda22eb3bffadf880696da6d846313f" + integrity sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA== + dependencies: + sparkles "^1.0.0" + +got@^6.7.1: + version "6.7.1" + resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" + integrity sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA= + dependencies: + create-error-class "^3.0.0" + duplexer3 "^0.1.4" + get-stream "^3.0.0" + is-redirect "^1.0.0" + is-retry-allowed "^1.0.0" + is-stream "^1.0.0" + lowercase-keys "^1.0.0" + safe-buffer "^5.0.1" + timed-out "^4.0.0" + unzip-response "^2.0.1" + url-parse-lax "^1.0.0" + +graceful-fs@4.1.11: + version "4.1.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" + integrity sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg= + +graceful-fs@4.X, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.4, graceful-fs@^4.1.6, graceful-fs@^4.1.9: + version "4.1.15" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" + integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== + +graceful-fs@^3.0.0: + version "3.0.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-3.0.11.tgz#7613c778a1afea62f25c630a086d7f3acbbdd818" + integrity sha1-dhPHeKGv6mLyXGMKCG1/Osu92Bg= + dependencies: + natives "^1.1.0" + +graceful-fs@~1.2.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-1.2.3.tgz#15a4806a57547cb2d2dbf27f42e89a8c3451b364" + integrity sha1-FaSAaldUfLLS2/J/QuiajDRRs2Q= + +gulp-autoprefixer@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/gulp-autoprefixer/-/gulp-autoprefixer-4.1.0.tgz#064af73cc02cadac8ff34d0bf93ffdfb94ea12aa" + integrity sha1-Bkr3PMAsrayP800L+T/9+5TqEqo= + dependencies: + autoprefixer "^7.0.0" + fancy-log "^1.3.2" + plugin-error "^0.1.2" + postcss "^6.0.1" + through2 "^2.0.0" + vinyl-sourcemaps-apply "^0.2.0" + +gulp-clean-css@^3.9.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/gulp-clean-css/-/gulp-clean-css-3.10.0.tgz#bccd4605eff104bfa4980014cc4b3c24c571736d" + integrity sha512-7Isf9Y690o/Q5MVjEylH1H7L8WeZ89woW7DnhD5unTintOdZb67KdOayRgp9trUFo+f9UyJtuatV42e/+kghPg== + dependencies: + clean-css "4.2.1" + plugin-error "1.0.1" + through2 "2.0.3" + vinyl-sourcemaps-apply "0.2.1" + +gulp-compile-handlebars@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/gulp-compile-handlebars/-/gulp-compile-handlebars-0.6.1.tgz#9cc1d9cb951105dfae530928d2a904a14d74c5d3" + integrity sha1-nMHZy5URBd+uUwko0qkEoU10xdM= + dependencies: + gulp-util "^3.0.3" + handlebars ">=3.0.0" + through2 "^0.6.3" + +gulp-header@^1.8.9: + version "1.8.12" + resolved "https://registry.yarnpkg.com/gulp-header/-/gulp-header-1.8.12.tgz#ad306be0066599127281c4f8786660e705080a84" + integrity sha512-lh9HLdb53sC7XIZOYzTXM4lFuXElv3EVkSDhsd7DoJBj7hm+Ni7D3qYbb+Rr8DuM8nRanBvkVO9d7askreXGnQ== + dependencies: + concat-with-sourcemaps "*" + lodash.template "^4.4.0" + through2 "^2.0.0" + +gulp-rename@^1.2.2: + version "1.4.0" + resolved "https://registry.yarnpkg.com/gulp-rename/-/gulp-rename-1.4.0.tgz#de1c718e7c4095ae861f7296ef4f3248648240bd" + integrity sha512-swzbIGb/arEoFK89tPY58vg3Ok1bw+d35PfUNwWqdo7KM4jkmuGA78JiDNqR+JeZFaeeHnRg9N7aihX3YPmsyg== + +gulp-sass@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/gulp-sass/-/gulp-sass-2.3.2.tgz#82b7ab90fe902cdc34c04f180d92f2c34902dd52" + integrity sha1-grerkP6QLNw0wE8YDZLyw0kC3VI= + dependencies: + gulp-util "^3.0" + lodash.clonedeep "^4.3.2" + node-sass "^3.4.2" + through2 "^2.0.0" + vinyl-sourcemaps-apply "^0.2.0" + +gulp-shell@^0.6.3: + version "0.6.5" + resolved "https://registry.yarnpkg.com/gulp-shell/-/gulp-shell-0.6.5.tgz#f07b204ad8ad1c2659f7a1b6d76efa16d416a759" + integrity sha512-f3m1WcS0o2B72/PGj1Jbv9zYR9rynBh/EQJv64n01xQUo7j7anols0eww9GG/WtDTzGVQLrupVDYkifRFnj5Zg== + dependencies: + async "^2.1.5" + chalk "^2.3.0" + fancy-log "^1.3.2" + lodash "^4.17.4" + lodash.template "^4.4.0" + plugin-error "^0.1.2" + through2 "^2.0.3" + +gulp-sourcemaps@^2.6.1: + version "2.6.5" + resolved "https://registry.yarnpkg.com/gulp-sourcemaps/-/gulp-sourcemaps-2.6.5.tgz#a3f002d87346d2c0f3aec36af7eb873f23de8ae6" + integrity sha512-SYLBRzPTew8T5Suh2U8jCSDKY+4NARua4aqjj8HOysBh2tSgT9u4jc1FYirAdPx1akUxxDeK++fqw6Jg0LkQRg== + dependencies: + "@gulp-sourcemaps/identity-map" "1.X" + "@gulp-sourcemaps/map-sources" "1.X" + acorn "5.X" + convert-source-map "1.X" + css "2.X" + debug-fabulous "1.X" + detect-newline "2.X" + graceful-fs "4.X" + source-map "~0.6.0" + strip-bom-string "1.X" + through2 "2.X" + +gulp-string-replace@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/gulp-string-replace/-/gulp-string-replace-1.1.2.tgz#26e646ae1201954d07cce9172ed25efbcd01d171" + integrity sha512-8T0eE2SIKPxhG4YNgVM6SEoKRXKh4mRgNT3N/0zXLBGTN4y/E9Y+TR+1gDCrqi431RNkS6ZeLlJ24rKNrdVzYQ== + dependencies: + chalk "^2.4.1" + extend "^3.0.1" + fancy-log "^1.3.2" + plugin-error "^1.0.1" + replacestream "^4.0.3" + through2 "^2.0.3" + +gulp-util@^3.0, gulp-util@^3.0.0, gulp-util@^3.0.3: + version "3.0.8" + resolved "https://registry.yarnpkg.com/gulp-util/-/gulp-util-3.0.8.tgz#0054e1e744502e27c04c187c3ecc505dd54bbb4f" + integrity sha1-AFTh50RQLifATBh8PsxQXdVLu08= + dependencies: + array-differ "^1.0.0" + array-uniq "^1.0.2" + beeper "^1.0.0" + chalk "^1.0.0" + dateformat "^2.0.0" + fancy-log "^1.1.0" + gulplog "^1.0.0" + has-gulplog "^0.1.0" + lodash._reescape "^3.0.0" + lodash._reevaluate "^3.0.0" + lodash._reinterpolate "^3.0.0" + lodash.template "^3.0.0" + minimist "^1.1.0" + multipipe "^0.1.2" + object-assign "^3.0.0" + replace-ext "0.0.1" + through2 "^2.0.0" + vinyl "^0.5.0" + +gulp@^3.9.1: + version "3.9.1" + resolved "https://registry.yarnpkg.com/gulp/-/gulp-3.9.1.tgz#571ce45928dd40af6514fc4011866016c13845b4" + integrity sha1-VxzkWSjdQK9lFPxAEYZgFsE4RbQ= + dependencies: + archy "^1.0.0" + chalk "^1.0.0" + deprecated "^0.0.1" + gulp-util "^3.0.0" + interpret "^1.0.0" + liftoff "^2.1.0" + minimist "^1.1.0" + orchestrator "^0.3.0" + pretty-hrtime "^1.0.0" + semver "^4.1.0" + tildify "^1.0.0" + v8flags "^2.0.2" + vinyl-fs "^0.3.0" + +gulplog@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gulplog/-/gulplog-1.0.0.tgz#e28c4d45d05ecbbed818363ce8f9c5926229ffe5" + integrity sha1-4oxNRdBey77YGDY86PnFkmIp/+U= + dependencies: + glogg "^1.0.0" + +handlebars-layouts@^3.1.4: + version "3.1.4" + resolved "https://registry.yarnpkg.com/handlebars-layouts/-/handlebars-layouts-3.1.4.tgz#26b3beb931b4b877dfbf7e6feaf4058ee6228b02" + integrity sha1-JrO+uTG0uHffv35v6vQFjuYiiwI= + +handlebars@>=3.0.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.1.2.tgz#b6b37c1ced0306b221e094fc7aca3ec23b131b67" + integrity sha512-nvfrjqvt9xQ8Z/w0ijewdD/vvWDTOweBUm96NTr66Wfvo1mJenBLwcYmPs3TIBP5ruzYGD7Hx/DaM9RmhroGPw== + dependencies: + neo-async "^2.6.0" + optimist "^0.6.1" + source-map "^0.6.1" + optionalDependencies: + uglify-js "^3.1.4" + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= + +har-validator@~5.1.0: + version "5.1.3" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" + integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== + dependencies: + ajv "^6.5.5" + har-schema "^2.0.0" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= + dependencies: + ansi-regex "^2.0.0" + +has-color@~0.1.0: + version "0.1.7" + resolved "https://registry.yarnpkg.com/has-color/-/has-color-0.1.7.tgz#67144a5260c34fc3cca677d041daf52fe7b78b2f" + integrity sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8= + +has-flag@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" + integrity sha1-6CB68cx7MNRGzHC3NLXovhj4jVE= + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-gulplog@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/has-gulplog/-/has-gulplog-0.1.0.tgz#6414c82913697da51590397dafb12f22967811ce" + integrity sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4= + dependencies: + sparkles "^1.0.0" + +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +has-yarn@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-1.0.0.tgz#89e25db604b725c8f5976fff0addc921b828a5a7" + integrity sha1-ieJdtgS3Jcj1l2//Ct3JIbgopac= + +hash-base@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" + integrity sha1-X8hoaEfs1zSZQDMZprCj8/auSRg= + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + +he@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +hmac-drbg@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +home-or-tmp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" + integrity sha1-42w/LSyufXRqhX440Y1fMqeILbg= + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.1" + +homedir-polyfill@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8" + integrity sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA== + dependencies: + parse-passwd "^1.0.0" + +hosted-git-info@^2.1.4: + version "2.7.1" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" + integrity sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w== + +html-encoding-sniffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8" + integrity sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw== + dependencies: + whatwg-encoding "^1.0.1" + +http-proxy@^1.8.1: + version "1.17.0" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.17.0.tgz#7ad38494658f84605e2f6db4436df410f4e5be9a" + integrity sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g== + dependencies: + eventemitter3 "^3.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + +http-server@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/http-server/-/http-server-0.10.0.tgz#b2a446b16a9db87ed3c622ba9beb1b085b1234a7" + integrity sha1-sqRGsWqduH7TxiK6m+sbCFsSNKc= + dependencies: + colors "1.0.3" + corser "~2.0.0" + ecstatic "^2.0.0" + http-proxy "^1.8.1" + opener "~1.4.0" + optimist "0.6.x" + portfinder "^1.0.13" + union "~0.4.3" + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +https-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" + integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= + +hullabaloo-config-manager@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/hullabaloo-config-manager/-/hullabaloo-config-manager-1.1.1.tgz#1d9117813129ad035fd9e8477eaf066911269fe3" + integrity sha512-ztKnkZV0TmxnumCDHHgLGNiDnotu4EHCp9YMkznWuo4uTtCyJ+cu+RNcxUeXYKTllpvLFWnbfWry09yzszgg+A== + dependencies: + dot-prop "^4.1.0" + es6-error "^4.0.2" + graceful-fs "^4.1.11" + indent-string "^3.1.0" + json5 "^0.5.1" + lodash.clonedeep "^4.5.0" + lodash.clonedeepwith "^4.5.0" + lodash.isequal "^4.5.0" + lodash.merge "^4.6.0" + md5-hex "^2.0.0" + package-hash "^2.0.0" + pkg-dir "^2.0.0" + resolve-from "^3.0.0" + safe-buffer "^5.0.1" + +humanize-url@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/humanize-url/-/humanize-url-1.0.1.tgz#f4ab99e0d288174ca4e1e50407c55fbae464efff" + integrity sha1-9KuZ4NKIF0yk4eUEB8VfuuRk7/8= + dependencies: + normalize-url "^1.0.0" + strip-url-auth "^1.0.0" + +iconv-lite@0.4.24, iconv-lite@^0.4.17, iconv-lite@^0.4.4: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +ieee754@^1.1.4: + version "1.1.13" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" + integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== + +iferr@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" + integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= + +ignore-by-default@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" + integrity sha1-SMptcvbGo68Aqa1K5odr44ieKwk= + +ignore-walk@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" + integrity sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ== + dependencies: + minimatch "^3.0.4" + +ignore@^3.3.3: + version "3.3.10" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" + integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug== + +import-lazy@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" + integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM= + +import-local@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-0.1.1.tgz#b1179572aacdc11c6a91009fb430dbcab5f668a8" + integrity sha1-sReVcqrNwRxqkQCftDDbyrX2aKg= + dependencies: + pkg-dir "^2.0.0" + resolve-cwd "^2.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + +in-publish@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/in-publish/-/in-publish-2.0.0.tgz#e20ff5e3a2afc2690320b6dc552682a9c7fadf51" + integrity sha1-4g/146KvwmkDILbcVSaCqcf631E= + +indent-string@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" + integrity sha1-ji1INIdCEhtKghi3oTfppSBJ3IA= + dependencies: + repeating "^2.0.0" + +indent-string@^3.0.0, indent-string@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" + integrity sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok= + +indexof@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" + integrity sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10= + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-1.0.2.tgz#ca4309dadee6b54cc0b8d247e8d7c7a0975bdc9b" + integrity sha1-ykMJ2t7mtUzAuNJH6NfHoJdb3Js= + +inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +inherits@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= + +ini@^1.3.4, ini@~1.3.0: + version "1.3.5" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== + +inquirer@^3.0.6: + version "3.3.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9" + integrity sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ== + dependencies: + ansi-escapes "^3.0.0" + chalk "^2.0.0" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^2.0.4" + figures "^2.0.0" + lodash "^4.3.0" + mute-stream "0.0.7" + run-async "^2.2.0" + rx-lite "^4.0.8" + rx-lite-aggregates "^4.0.8" + string-width "^2.1.0" + strip-ansi "^4.0.0" + through "^2.3.6" + +interpret@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296" + integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw== + +invariant@^2.2.0, invariant@^2.2.2: + version "2.2.4" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== + dependencies: + loose-envify "^1.0.0" + +invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY= + +irregular-plurals@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/irregular-plurals/-/irregular-plurals-1.4.0.tgz#2ca9b033651111855412f16be5d77c62a458a766" + integrity sha1-LKmwM2UREYVUEvFr5dd8YqRYp2Y= + +is-absolute@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-1.0.0.tgz#395e1ae84b11f26ad1795e73c17378e48a301576" + integrity sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA== + dependencies: + is-relative "^1.0.0" + is-windows "^1.0.1" + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== + dependencies: + kind-of "^6.0.0" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + +is-arrayish@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" + integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= + dependencies: + binary-extensions "^1.0.0" + +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + +is-ci@^1.0.10, is-ci@^1.0.7: + version "1.2.1" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c" + integrity sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg== + dependencies: + ci-info "^1.5.0" + +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== + dependencies: + kind-of "^6.0.0" + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-dotfile@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" + integrity sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE= + +is-equal-shallow@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" + integrity sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ= + dependencies: + is-primitive "^2.0.0" + +is-error@^2.2.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/is-error/-/is-error-2.2.2.tgz#c10ade187b3c93510c5470a5567833ee25649843" + integrity sha512-IOQqts/aHWbiisY5DuPJQ0gcbvaLFCa7fBa9xoLfxBZvQ+ZI/Zh9xoI7Gk+G64N0FdK4AbibytHht2tWgpJWLg== + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" + integrity sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA= + +is-extglob@^2.1.0, is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-finite@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" + integrity sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko= + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + +is-generator-fn@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-1.0.0.tgz#969d49e1bb3329f6bb7f09089be26578b2ddd46a" + integrity sha1-lp1J4bszKfa7fwkIm+JleLLd1Go= + +is-glob@^2.0.0, is-glob@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" + integrity sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM= + dependencies: + is-extglob "^1.0.0" + +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= + dependencies: + is-extglob "^2.1.0" + +is-glob@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + +is-installed-globally@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.1.0.tgz#0dfd98f5a9111716dd535dda6492f67bf3d25a80" + integrity sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA= + dependencies: + global-dirs "^0.1.0" + is-path-inside "^1.0.0" + +is-npm@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" + integrity sha1-8vtjpl5JBbQGyGBydloaTceTufQ= + +is-number@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" + integrity sha1-Afy7s5NGOlSPL0ZszhbezknbkI8= + dependencies: + kind-of "^3.0.2" + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= + dependencies: + kind-of "^3.0.2" + +is-number@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" + integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ== + +is-obj@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= + +is-observable@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/is-observable/-/is-observable-0.2.0.tgz#b361311d83c6e5d726cabf5e250b0237106f5ae2" + integrity sha1-s2ExHYPG5dcmyr9eJQsCNxBvWuI= + dependencies: + symbol-observable "^0.2.2" + +is-path-cwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" + integrity sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0= + +is-path-in-cwd@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz#5ac48b345ef675339bd6c7a48a912110b241cf52" + integrity sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ== + dependencies: + is-path-inside "^1.0.0" + +is-path-inside@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" + integrity sha1-jvW33lBDej/cprToZe96pVy0gDY= + dependencies: + path-is-inside "^1.0.1" + +is-plain-obj@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= + +is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-posix-bracket@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" + integrity sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q= + +is-primitive@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" + integrity sha1-IHurkWOEmcB7Kt8kCkGochADRXU= + +is-promise@^2.1, is-promise@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= + +is-redirect@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" + integrity sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ= + +is-relative@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-1.0.0.tgz#a1bb6935ce8c5dba1e8b9754b9b2dcc020e2260d" + integrity sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA== + dependencies: + is-unc-path "^1.0.0" + +is-resolvable@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" + integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg== + +is-retry-allowed@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" + integrity sha1-EaBgVotnM5REAz0BJaYaINVk+zQ= + +is-stream@^1.0.0, is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + +is-unc-path@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-unc-path/-/is-unc-path-1.0.0.tgz#d731e8898ed090a12c352ad2eaed5095ad322c9d" + integrity sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ== + dependencies: + unc-path-regex "^0.1.2" + +is-url@^1.2.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.4.tgz#04a4df46d28c4cff3d73d01ff06abeb318a1aa52" + integrity sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww== + +is-utf8@^0.2.0, is-utf8@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= + +is-windows@^1.0.1, is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= + +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= + +jquery@>=2.1.0: + version "3.4.1" + resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.4.1.tgz#714f1f8d9dde4bdfa55764ba37ef214630d80ef2" + integrity sha512-36+AdBzCL+y6qjw5Tx7HgzeGCzC81MDDgaUP8ld2zhx58HdqXGoBd+tHdrBMiyjGQs0Hxs/MLZTu/eHNJJuWPw== + +js-base64@^2.1.8: + version "2.5.1" + resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.5.1.tgz#1efa39ef2c5f7980bb1784ade4a8af2de3291121" + integrity sha512-M7kLczedRMYX4L8Mdh4MzyAMM9O5osx+4FcOQuTvr3A9F2D9S5JXheN0ewNbrvK2UatkTRhL5ejGmGSjNMiZuw== + +js-string-escape@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/js-string-escape/-/js-string-escape-1.0.1.tgz#e2625badbc0d67c7533e9edc1068c587ae4137ef" + integrity sha1-4mJbrbwNZ8dTPp7cEGjFh65BN+8= + +js-tokens@^3.0.0, js-tokens@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= + +"js-tokens@^3.0.0 || ^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.8.2, js-yaml@^3.9.1: + version "3.13.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" + integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +js2xmlparser@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js2xmlparser/-/js2xmlparser-4.0.0.tgz#ae14cc711b2892083eed6e219fbc993d858bc3a5" + integrity sha512-WuNgdZOXVmBk5kUPMcTcVUpbGRzLfNkv7+7APq7WiDihpXVKrgxo6wwRpRl9OQeEBgKCVk9mR7RbzrnNWC8oBw== + dependencies: + xmlcreate "^2.0.0" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= + +jsdoc@^3.5.5: + version "3.6.1" + resolved "https://registry.yarnpkg.com/jsdoc/-/jsdoc-3.6.1.tgz#f60276a1033feaf20191965605383f75d9166279" + integrity sha512-mMMsst31b8c7/Z6ewnO6ORIdVMwsobg1enX9b/2XAzW8mM3KuMANRWcMD1KMBq91IAUMOIhC5NsXu7xvNQrRyQ== + dependencies: + "@babel/parser" "^7.4.4" + bluebird "^3.5.4" + catharsis "^0.8.10" + escape-string-regexp "^2.0.0" + js2xmlparser "^4.0.0" + klaw "^3.0.0" + markdown-it "^8.4.2" + markdown-it-anchor "^5.0.2" + marked "^0.6.2" + mkdirp "^0.5.1" + requizzle "^0.2.2" + strip-json-comments "^3.0.1" + taffydb "2.6.2" + underscore "~1.9.1" + +jsdom@^11.3.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.12.0.tgz#1a80d40ddd378a1de59656e9e6dc5a3ba8657bc8" + integrity sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw== + dependencies: + abab "^2.0.0" + acorn "^5.5.3" + acorn-globals "^4.1.0" + array-equal "^1.0.0" + cssom ">= 0.3.2 < 0.4.0" + cssstyle "^1.0.0" + data-urls "^1.0.0" + domexception "^1.0.1" + escodegen "^1.9.1" + html-encoding-sniffer "^1.0.2" + left-pad "^1.3.0" + nwsapi "^2.0.7" + parse5 "4.0.0" + pn "^1.1.0" + request "^2.87.0" + request-promise-native "^1.0.5" + sax "^1.2.4" + symbol-tree "^3.2.2" + tough-cookie "^2.3.4" + w3c-hr-time "^1.0.1" + webidl-conversions "^4.0.2" + whatwg-encoding "^1.0.3" + whatwg-mimetype "^2.1.0" + whatwg-url "^6.4.1" + ws "^5.2.0" + xml-name-validator "^3.0.0" + +jsesc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" + integrity sha1-RsP+yMGJKxKwgz25vHYiF226s0s= + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= + +json-loader@^0.5.4: + version "0.5.7" + resolved "https://registry.yarnpkg.com/json-loader/-/json-loader-0.5.7.tgz#dca14a70235ff82f0ac9a3abeb60d337a365185d" + integrity sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w== + +json-parse-better-errors@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== + +json-schema-traverse@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" + integrity sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A= + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + +json5@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= + +json5@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" + integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== + dependencies: + minimist "^1.2.0" + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= + optionalDependencies: + graceful-fs "^4.1.6" + +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + +kind-of@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-1.1.0.tgz#140a3d2d41a36d2efcfa9377b62c24f8495a5c44" + integrity sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ= + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" + integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== + +klaw@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/klaw/-/klaw-3.0.0.tgz#b11bec9cf2492f06756d6e809ab73a2910259146" + integrity sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g== + dependencies: + graceful-fs "^4.1.9" + +last-line-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/last-line-stream/-/last-line-stream-1.0.0.tgz#d1b64d69f86ff24af2d04883a2ceee14520a5600" + integrity sha1-0bZNafhv8kry0EiDos7uFFIKVgA= + dependencies: + through2 "^2.0.0" + +latest-version@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15" + integrity sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU= + dependencies: + package-json "^4.0.0" + +lazy-cache@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" + integrity sha1-odePw6UEdMuAhF07O24dpJpEbo4= + +lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + integrity sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU= + dependencies: + invert-kv "^1.0.0" + +left-pad@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e" + integrity sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA== + +levn@^0.3.0, levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +liftoff@^2.1.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/liftoff/-/liftoff-2.5.0.tgz#2009291bb31cea861bbf10a7c15a28caf75c31ec" + integrity sha1-IAkpG7Mc6oYbvxCnwVooyvdcMew= + dependencies: + extend "^3.0.0" + findup-sync "^2.0.0" + fined "^1.0.1" + flagged-respawn "^1.0.0" + is-plain-object "^2.0.4" + object.map "^1.0.0" + rechoir "^0.6.2" + resolve "^1.1.7" + +linkify-it@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-2.1.0.tgz#c4caf38a6cd7ac2212ef3c7d2bde30a91561f9db" + integrity sha512-4REs8/062kV2DSHxNfq5183zrqXMl7WP0WzABH9IeJI+NLm429FgE1PDecltYfnOoFDFlZGh2T8PfZn0r+GTRg== + dependencies: + uc.micro "^1.0.1" + +load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + +load-json-file@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" + integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg= + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + strip-bom "^3.0.0" + +load-json-file@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" + integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= + dependencies: + graceful-fs "^4.1.2" + parse-json "^4.0.0" + pify "^3.0.0" + strip-bom "^3.0.0" + +loader-fs-cache@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/loader-fs-cache/-/loader-fs-cache-1.0.2.tgz#54cedf6b727e1779fd8f01205f05f6e88706f086" + integrity sha512-70IzT/0/L+M20jUlEqZhZyArTU6VKLRTYRDAYN26g4jfzpJqjipLL3/hgYpySqI9PwsVRHHFja0LfEmsx9X2Cw== + dependencies: + find-cache-dir "^0.1.1" + mkdirp "0.5.1" + +loader-runner@^2.3.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" + integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw== + +loader-utils@^1.0.2, loader-utils@^1.1.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7" + integrity sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA== + dependencies: + big.js "^5.2.2" + emojis-list "^2.0.0" + json5 "^1.0.1" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +lodash._basecopy@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" + integrity sha1-jaDmqHbPNEwK2KVIghEd08XHyjY= + +lodash._basetostring@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz#d1861d877f824a52f669832dcaf3ee15566a07d5" + integrity sha1-0YYdh3+CSlL2aYMtyvPuFVZqB9U= + +lodash._basevalues@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz#5b775762802bde3d3297503e26300820fdf661b7" + integrity sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc= + +lodash._getnative@^3.0.0: + version "3.9.1" + resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" + integrity sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U= + +lodash._isiterateecall@^3.0.0: + version "3.0.9" + resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" + integrity sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw= + +lodash._reescape@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reescape/-/lodash._reescape-3.0.0.tgz#2b1d6f5dfe07c8a355753e5f27fac7f1cde1616a" + integrity sha1-Kx1vXf4HyKNVdT5fJ/rH8c3hYWo= + +lodash._reevaluate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz#58bc74c40664953ae0b124d806996daca431e2ed" + integrity sha1-WLx0xAZklTrgsSTYBpltrKQx4u0= + +lodash._reinterpolate@^3.0.0, lodash._reinterpolate@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" + integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= + +lodash._root@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692" + integrity sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI= + +lodash.assign@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" + integrity sha1-DZnzzNem0mHRm9rrkkUAXShYCOc= + +lodash.clone@^4.3.2: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clone/-/lodash.clone-4.5.0.tgz#195870450f5a13192478df4bc3d23d2dea1907b6" + integrity sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y= + +lodash.clonedeep@^4.3.2, lodash.clonedeep@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= + +lodash.clonedeepwith@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeepwith/-/lodash.clonedeepwith-4.5.0.tgz#6ee30573a03a1a60d670a62ef33c10cf1afdbdd4" + integrity sha1-buMFc6A6GmDWcKYu8zwQzxr9vdQ= + +lodash.debounce@^4.0.3: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= + +lodash.difference@^4.3.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.difference/-/lodash.difference-4.5.0.tgz#9ccb4e505d486b91651345772885a2df27fd017c" + integrity sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw= + +lodash.escape@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-3.2.0.tgz#995ee0dc18c1b48cc92effae71a10aab5b487698" + integrity sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg= + dependencies: + lodash._root "^3.0.0" + +lodash.flatten@^4.2.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" + integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8= + +lodash.flattendeep@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2" + integrity sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI= + +lodash.isarguments@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" + integrity sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo= + +lodash.isarray@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" + integrity sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U= + +lodash.isequal@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" + integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA= + +lodash.keys@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" + integrity sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo= + dependencies: + lodash._getnative "^3.0.0" + lodash.isarguments "^3.0.0" + lodash.isarray "^3.0.0" + +lodash.merge@^4.6.0: + version "4.6.1" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.1.tgz#adc25d9cb99b9391c59624f379fbba60d7111d54" + integrity sha512-AOYza4+Hf5z1/0Hztxpm2/xiPZgi/cjMqdnKTUWTBSKchJlxXXuUSxCCl8rJlf4g6yww/j6mA8nC8Hw/EZWxKQ== + +lodash.restparam@^3.0.0: + version "3.6.1" + resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" + integrity sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU= + +lodash.some@^4.2.2: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d" + integrity sha1-G7nzFO9ri63tE7VJFpsqlF62jk0= + +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= + +lodash.template@^3.0.0: + version "3.6.2" + resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-3.6.2.tgz#f8cdecc6169a255be9098ae8b0c53d378931d14f" + integrity sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8= + dependencies: + lodash._basecopy "^3.0.0" + lodash._basetostring "^3.0.0" + lodash._basevalues "^3.0.0" + lodash._isiterateecall "^3.0.0" + lodash._reinterpolate "^3.0.0" + lodash.escape "^3.0.0" + lodash.keys "^3.0.0" + lodash.restparam "^3.0.0" + lodash.templatesettings "^3.0.0" + +lodash.template@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.4.0.tgz#e73a0385c8355591746e020b99679c690e68fba0" + integrity sha1-5zoDhcg1VZF0bgILmWecaQ5o+6A= + dependencies: + lodash._reinterpolate "~3.0.0" + lodash.templatesettings "^4.0.0" + +lodash.templatesettings@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz#fb307844753b66b9f1afa54e262c745307dba8e5" + integrity sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU= + dependencies: + lodash._reinterpolate "^3.0.0" + lodash.escape "^3.0.0" + +lodash.templatesettings@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz#2b4d4e95ba440d915ff08bc899e4553666713316" + integrity sha1-K01OlbpEDZFf8IvImeRVNmZxMxY= + dependencies: + lodash._reinterpolate "~3.0.0" + +lodash@^4.0.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.3.0, lodash@~4.17.10: + version "4.17.11" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" + integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== + +lodash@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-1.0.2.tgz#8f57560c83b59fc270bd3d561b690043430e2551" + integrity sha1-j1dWDIO1n8JwvT1WG2kAQ0MOJVE= + +longest@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" + integrity sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc= + +loose-envify@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +loud-rejection@^1.0.0, loud-rejection@^1.2.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" + integrity sha1-W0b4AUft7leIcPCG0Eghz5mOVR8= + dependencies: + currently-unhandled "^0.4.1" + signal-exit "^3.0.0" + +lowercase-keys@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== + +lru-cache@2: + version "2.7.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.7.3.tgz#6d4524e8b955f95d4f5b58851ce21dd72fb4e952" + integrity sha1-bUUk6LlV+V1PW1iFHOId1y+06VI= + +lru-cache@^4.0.1, lru-cache@^4.1.1: + version "4.1.5" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" + integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + +lru-queue@0.1: + version "0.1.0" + resolved "https://registry.yarnpkg.com/lru-queue/-/lru-queue-0.1.0.tgz#2738bd9f0d3cf4f84490c5736c48699ac632cda3" + integrity sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM= + dependencies: + es5-ext "~0.10.2" + +make-dir@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" + integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== + dependencies: + pify "^3.0.0" + +make-iterator@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/make-iterator/-/make-iterator-1.0.1.tgz#29b33f312aa8f547c4a5e490f56afcec99133ad6" + integrity sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw== + dependencies: + kind-of "^6.0.2" + +map-cache@^0.2.0, map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= + +map-obj@^1.0.0, map-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= + dependencies: + object-visit "^1.0.0" + +markdown-it-anchor@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/markdown-it-anchor/-/markdown-it-anchor-5.0.2.tgz#cdd917a05b7bf92fb736a6dae3385c6d0d0fa552" + integrity sha512-AFM/woBI8QDJMS/9+MmsBMT5/AR+ImfOsunQZTZhzcTmna3rIzAzbOh5E0l6mlFM/i9666BpUtkqQ9bS7WApCg== + +markdown-it@^8.4.2: + version "8.4.2" + resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-8.4.2.tgz#386f98998dc15a37722aa7722084f4020bdd9b54" + integrity sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ== + dependencies: + argparse "^1.0.7" + entities "~1.1.1" + linkify-it "^2.0.0" + mdurl "^1.0.1" + uc.micro "^1.0.5" + +marked@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/marked/-/marked-0.6.2.tgz#c574be8b545a8b48641456ca1dbe0e37b6dccc1a" + integrity sha512-LqxwVH3P/rqKX4EKGz7+c2G9r98WeM/SW34ybhgNGhUQNKtf1GmmSkJ6cDGJ/t6tiyae49qRkpyTw2B9HOrgUA== + +matcher@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/matcher/-/matcher-1.1.1.tgz#51d8301e138f840982b338b116bb0c09af62c1c2" + integrity sha512-+BmqxWIubKTRKNWx/ahnCkk3mG8m7OturVlqq6HiojGJTd5hVYbgZm6WzcYPCoB+KBT4Vd6R7WSRG2OADNaCjg== + dependencies: + escape-string-regexp "^1.0.4" + +math-random@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.4.tgz#5dd6943c938548267016d4e34f057583080c514c" + integrity sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A== + +md5-hex@^1.2.0, md5-hex@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/md5-hex/-/md5-hex-1.3.0.tgz#d2c4afe983c4370662179b8cad145219135046c4" + integrity sha1-0sSv6YPENwZiF5uMrRRSGRNQRsQ= + dependencies: + md5-o-matic "^0.1.1" + +md5-hex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/md5-hex/-/md5-hex-2.0.0.tgz#d0588e9f1c74954492ecd24ac0ac6ce997d92e33" + integrity sha1-0FiOnxx0lUSS7NJKwKxs6ZfZLjM= + dependencies: + md5-o-matic "^0.1.1" + +md5-o-matic@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/md5-o-matic/-/md5-o-matic-0.1.1.tgz#822bccd65e117c514fab176b25945d54100a03c3" + integrity sha1-givM1l4RfFFPqxdrJZRdVBAKA8M= + +md5.js@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +mdurl@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" + integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4= + +mem@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" + integrity sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y= + dependencies: + mimic-fn "^1.0.0" + +memoizee@0.4.X: + version "0.4.14" + resolved "https://registry.yarnpkg.com/memoizee/-/memoizee-0.4.14.tgz#07a00f204699f9a95c2d9e77218271c7cd610d57" + integrity sha512-/SWFvWegAIYAO4NQMpcX+gcra0yEZu4OntmUdrBaWrJncxOqAziGFlHxc7yjKVK2uu3lpPW27P27wkR82wA8mg== + dependencies: + d "1" + es5-ext "^0.10.45" + es6-weak-map "^2.0.2" + event-emitter "^0.3.5" + is-promise "^2.1" + lru-queue "0.1" + next-tick "1" + timers-ext "^0.1.5" + +memory-fs@^0.4.0, memory-fs@^0.4.1, memory-fs@~0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" + integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI= + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +meow@^3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" + integrity sha1-cstmi0JSKCkKu/qFaJJYcwioAfs= + dependencies: + camelcase-keys "^2.0.0" + decamelize "^1.1.2" + loud-rejection "^1.0.0" + map-obj "^1.0.1" + minimist "^1.1.3" + normalize-package-data "^2.3.4" + object-assign "^4.0.1" + read-pkg-up "^1.0.1" + redent "^1.0.0" + trim-newlines "^1.0.0" + +micromatch@^2.1.5: + version "2.3.11" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" + integrity sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU= + dependencies: + arr-diff "^2.0.0" + array-unique "^0.2.1" + braces "^1.8.2" + expand-brackets "^0.1.4" + extglob "^0.3.1" + filename-regex "^2.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.1" + kind-of "^3.0.2" + normalize-path "^2.0.1" + object.omit "^2.0.0" + parse-glob "^3.0.4" + regex-cache "^0.4.2" + +micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +miller-rabin@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== + dependencies: + bn.js "^4.0.0" + brorand "^1.0.1" + +mime-db@1.40.0: + version "1.40.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.40.0.tgz#a65057e998db090f732a68f6c276d387d4126c32" + integrity sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA== + +mime-types@^2.1.12, mime-types@~2.1.19: + version "2.1.24" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.24.tgz#b6f8d0b3e951efb77dedeca194cff6d16f676f81" + integrity sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ== + dependencies: + mime-db "1.40.0" + +mime@^1.2.11: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mimic-fn@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" + integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= + +minimatch@^2.0.1: + version "2.0.10" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-2.0.10.tgz#8d087c39c6b38c001b97fca7ce6d0e1e80afbac7" + integrity sha1-jQh8OcazjAAbl/ynzm0OHoCvusc= + dependencies: + brace-expansion "^1.0.0" + +minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.4, minimatch@~3.0.2: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimatch@~0.2.11: + version "0.2.14" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.2.14.tgz#c74e780574f63c6f9a090e90efbe6ef53a6a756a" + integrity sha1-x054BXT2PG+aCQ6Q775u9TpqdWo= + dependencies: + lru-cache "2" + sigmund "~1.0.0" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= + +minimist@^1.1.0, minimist@^1.1.3, minimist@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= + +minimist@~0.0.1: + version "0.0.10" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" + integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= + +minipass@^2.2.1, minipass@^2.3.4: + version "2.3.5" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848" + integrity sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA== + dependencies: + safe-buffer "^5.1.2" + yallist "^3.0.0" + +minizlib@^1.1.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.2.1.tgz#dd27ea6136243c7c880684e8672bb3a45fd9b614" + integrity sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA== + dependencies: + minipass "^2.2.1" + +mississippi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-2.0.0.tgz#3442a508fafc28500486feea99409676e4ee5a6f" + integrity sha512-zHo8v+otD1J10j/tC+VNoGK9keCuByhKovAvdn74dmxJl9+mWHnx6EMsDN4lgRoMI/eYo2nchAxniIbUPb5onw== + dependencies: + concat-stream "^1.5.0" + duplexify "^3.4.2" + end-of-stream "^1.1.0" + flush-write-stream "^1.0.0" + from2 "^2.1.0" + parallel-transform "^1.1.0" + pump "^2.0.1" + pumpify "^1.3.3" + stream-each "^1.1.0" + through2 "^2.0.0" + +mixin-deep@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" + integrity sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ== + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +mkdirp@0.5.1, mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= + dependencies: + minimist "0.0.8" + +move-concurrently@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" + integrity sha1-viwAX9oy4LKa8fBdfEszIUxwH5I= + dependencies: + aproba "^1.1.1" + copy-concurrently "^1.0.0" + fs-write-stream-atomic "^1.0.8" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.3" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@^2.0.0, ms@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== + +multimatch@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b" + integrity sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis= + dependencies: + array-differ "^1.0.0" + array-union "^1.0.1" + arrify "^1.0.0" + minimatch "^3.0.0" + +multipipe@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/multipipe/-/multipipe-0.1.2.tgz#2a8f2ddf70eed564dff2d57f1e1a137d9f05078b" + integrity sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s= + dependencies: + duplexer2 "0.0.2" + +mute-stream@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" + integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= + +nan@^2.12.1, nan@^2.3.2: + version "2.13.2" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.13.2.tgz#f51dc7ae66ba7d5d55e1e6d4d8092e802c9aefe7" + integrity sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw== + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +natives@^1.1.0: + version "1.1.6" + resolved "https://registry.yarnpkg.com/natives/-/natives-1.1.6.tgz#a603b4a498ab77173612b9ea1acdec4d980f00bb" + integrity sha512-6+TDFewD4yxY14ptjKaS63GVdtKiES1pTPyxn9Jb0rBqPMZ7VcCiooEhPNsr+mqHtMGxa/5c/HhcC4uPEUw/nA== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + +needle@^2.2.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.3.1.tgz#d272f2f4034afb9c4c9ab1379aabc17fc85c9388" + integrity sha512-CaLXV3W8Vnbps8ZANqDGz7j4x7Yj1LW4TWF/TQuDfj7Cfx4nAPTvw98qgTevtto1oHDrh3pQkaODbqupXlsWTg== + dependencies: + debug "^4.1.0" + iconv-lite "^0.4.4" + sax "^1.2.4" + +neo-async@^2.5.0, neo-async@^2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.0.tgz#b9d15e4d71c6762908654b5183ed38b753340835" + integrity sha512-MFh0d/Wa7vkKO3Y3LlacqAEeHK0mckVqzDieUKTT+KGxi+zIpeVsFxymkIiRpbpDziHc290Xr9A1O4Om7otoRA== + +next-tick@1, next-tick@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" + integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= + +node-gyp@^3.3.1: + version "3.8.0" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.8.0.tgz#540304261c330e80d0d5edce253a68cb3964218c" + integrity sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA== + dependencies: + fstream "^1.0.0" + glob "^7.0.3" + graceful-fs "^4.1.2" + mkdirp "^0.5.0" + nopt "2 || 3" + npmlog "0 || 1 || 2 || 3 || 4" + osenv "0" + request "^2.87.0" + rimraf "2" + semver "~5.3.0" + tar "^2.0.0" + which "1" + +node-libs-browser@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.0.tgz#c72f60d9d46de08a940dedbb25f3ffa2f9bbaa77" + integrity sha512-5MQunG/oyOaBdttrL40dA7bUfPORLRWMUJLQtMg7nluxUvk5XwnLdL9twQHFAjRx/y7mIMkLKT9++qPbbk6BZA== + dependencies: + assert "^1.1.1" + browserify-zlib "^0.2.0" + buffer "^4.3.0" + console-browserify "^1.1.0" + constants-browserify "^1.0.0" + crypto-browserify "^3.11.0" + domain-browser "^1.1.1" + events "^3.0.0" + https-browserify "^1.0.0" + os-browserify "^0.3.0" + path-browserify "0.0.0" + process "^0.11.10" + punycode "^1.2.4" + querystring-es3 "^0.2.0" + readable-stream "^2.3.3" + stream-browserify "^2.0.1" + stream-http "^2.7.2" + string_decoder "^1.0.0" + timers-browserify "^2.0.4" + tty-browserify "0.0.0" + url "^0.11.0" + util "^0.11.0" + vm-browserify "0.0.4" + +node-pre-gyp@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz#39ba4bb1439da030295f899e3b520b7785766149" + integrity sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A== + dependencies: + detect-libc "^1.0.2" + mkdirp "^0.5.1" + needle "^2.2.1" + nopt "^4.0.1" + npm-packlist "^1.1.6" + npmlog "^4.0.2" + rc "^1.2.7" + rimraf "^2.6.1" + semver "^5.3.0" + tar "^4" + +node-sass@^3.4.2: + version "3.13.1" + resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-3.13.1.tgz#7240fbbff2396304b4223527ed3020589c004fc2" + integrity sha1-ckD7v/I5YwS0IjUn7TAgWJwAT8I= + dependencies: + async-foreach "^0.1.3" + chalk "^1.1.1" + cross-spawn "^3.0.0" + gaze "^1.0.0" + get-stdin "^4.0.1" + glob "^7.0.3" + in-publish "^2.0.0" + lodash.assign "^4.2.0" + lodash.clonedeep "^4.3.2" + meow "^3.7.0" + mkdirp "^0.5.1" + nan "^2.3.2" + node-gyp "^3.3.1" + npmlog "^4.0.0" + request "^2.61.0" + sass-graph "^2.1.1" + +"nopt@2 || 3": + version "3.0.6" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" + integrity sha1-xkZdvwirzU2zWTF/eaxopkayj/k= + dependencies: + abbrev "1" + +nopt@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" + integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00= + dependencies: + abbrev "1" + osenv "^0.1.4" + +normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^2.0.0, normalize-path@^2.0.1, normalize-path@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= + dependencies: + remove-trailing-separator "^1.0.1" + +normalize-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +normalize-range@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" + integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI= + +normalize-url@^1.0.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-1.9.1.tgz#2cc0d66b31ea23036458436e3620d85954c66c3c" + integrity sha1-LMDWazHqIwNkWENuNiDYWVTGbDw= + dependencies: + object-assign "^4.0.1" + prepend-http "^1.0.0" + query-string "^4.1.0" + sort-keys "^1.0.0" + +npm-bundled@^1.0.1: + version "1.0.6" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.6.tgz#e7ba9aadcef962bb61248f91721cd932b3fe6bdd" + integrity sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g== + +npm-packlist@^1.1.6: + version "1.4.1" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.1.tgz#19064cdf988da80ea3cee45533879d90192bbfbc" + integrity sha512-+TcdO7HJJ8peiiYhvPxsEDhF3PJFGUGRcFsGve3vxvxdcpO2Z4Z7rkosRM0kWj6LfbK/P0gu3dzk5RU1ffvFcw== + dependencies: + ignore-walk "^3.0.1" + npm-bundled "^1.0.1" + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= + dependencies: + path-key "^2.0.0" + +"npmlog@0 || 1 || 2 || 3 || 4", npmlog@^4.0.0, npmlog@^4.0.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + +num2fraction@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" + integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4= + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= + +nwsapi@^2.0.7: + version "2.1.4" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.1.4.tgz#e006a878db23636f8e8a67d33ca0e4edf61a842f" + integrity sha512-iGfd9Y6SFdTNldEy2L0GUhcarIutFmk+MPWIn9dmj8NMIup03G08uUF2KGbbmv/Ux4RT0VZJoP/sVbWA6d/VIw== + +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + +object-assign@4.X, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +object-assign@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-3.0.0.tgz#9bedd5ca0897949bca47e7ff408062d549f587f2" + integrity sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I= + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-hash@^1.1.4: + version "1.3.1" + resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.3.1.tgz#fde452098a951cb145f039bb7d455449ddc126df" + integrity sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA== + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= + dependencies: + isobject "^3.0.0" + +object.defaults@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/object.defaults/-/object.defaults-1.1.0.tgz#3a7f868334b407dea06da16d88d5cd29e435fecf" + integrity sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8= + dependencies: + array-each "^1.0.1" + array-slice "^1.0.0" + for-own "^1.0.0" + isobject "^3.0.0" + +object.map@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object.map/-/object.map-1.0.1.tgz#cf83e59dc8fcc0ad5f4250e1f78b3b81bd801d37" + integrity sha1-z4Plncj8wK1fQlDh94s7gb2AHTc= + dependencies: + for-own "^1.0.0" + make-iterator "^1.0.0" + +object.omit@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" + integrity sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo= + dependencies: + for-own "^0.1.4" + is-extendable "^0.1.1" + +object.pick@^1.2.0, object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= + dependencies: + isobject "^3.0.1" + +observable-to-promise@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/observable-to-promise/-/observable-to-promise-0.5.0.tgz#c828f0f0dc47e9f86af8a4977c5d55076ce7a91f" + integrity sha1-yCjw8NxH6fhq+KSXfF1VB2znqR8= + dependencies: + is-observable "^0.2.0" + symbol-observable "^1.0.4" + +once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +once@~1.3.0: + version "1.3.3" + resolved "https://registry.yarnpkg.com/once/-/once-1.3.3.tgz#b2e261557ce4c314ec8304f3fa82663e4297ca20" + integrity sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA= + dependencies: + wrappy "1" + +onetime@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= + dependencies: + mimic-fn "^1.0.0" + +opener@~1.4.0: + version "1.4.3" + resolved "https://registry.yarnpkg.com/opener/-/opener-1.4.3.tgz#5c6da2c5d7e5831e8ffa3964950f8d6674ac90b8" + integrity sha1-XG2ixdflgx6P+jlklQ+NZnSskLg= + +optimist@0.6.x, optimist@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" + integrity sha1-2j6nRob6IaGaERwybpDrFaAZZoY= + dependencies: + minimist "~0.0.1" + wordwrap "~0.0.2" + +option-chain@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/option-chain/-/option-chain-1.0.0.tgz#938d73bd4e1783f948d34023644ada23669e30f2" + integrity sha1-k41zvU4Xg/lI00AjZEraI2aeMPI= + +optionator@^0.8.1, optionator@^0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" + integrity sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q= + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.4" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + wordwrap "~1.0.0" + +orchestrator@^0.3.0: + version "0.3.8" + resolved "https://registry.yarnpkg.com/orchestrator/-/orchestrator-0.3.8.tgz#14e7e9e2764f7315fbac184e506c7aa6df94ad7e" + integrity sha1-FOfp4nZPcxX7rBhOUGx6pt+UrX4= + dependencies: + end-of-stream "~0.1.5" + sequencify "~0.0.7" + stream-consume "~0.1.0" + +ordered-read-streams@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/ordered-read-streams/-/ordered-read-streams-0.1.0.tgz#fd565a9af8eb4473ba69b6ed8a34352cb552f126" + integrity sha1-/VZamvjrRHO6abbtijQ1LLVS8SY= + +os-browserify@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" + integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= + +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= + +os-locale@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" + integrity sha1-IPnxeuKe00XoveWDsT0gCYA8FNk= + dependencies: + lcid "^1.0.0" + +os-locale@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" + integrity sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA== + dependencies: + execa "^0.7.0" + lcid "^1.0.0" + mem "^1.1.0" + +os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= + +osenv@0, osenv@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" + integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + +output-file-sync@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/output-file-sync/-/output-file-sync-1.1.2.tgz#d0a33eefe61a205facb90092e826598d5245ce76" + integrity sha1-0KM+7+YaIF+suQCS6CZZjVJFznY= + dependencies: + graceful-fs "^4.1.4" + mkdirp "^0.5.1" + object-assign "^4.1.0" + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= + +p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== + dependencies: + p-try "^1.0.0" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= + dependencies: + p-limit "^1.1.0" + +p-map@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b" + integrity sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA== + +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= + +package-hash@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/package-hash/-/package-hash-1.2.0.tgz#003e56cd57b736a6ed6114cc2b81542672770e44" + integrity sha1-AD5WzVe3NqbtYRTMK4FUJnJ3DkQ= + dependencies: + md5-hex "^1.3.0" + +package-hash@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/package-hash/-/package-hash-2.0.0.tgz#78ae326c89e05a4d813b68601977af05c00d2a0d" + integrity sha1-eK4ybIngWk2BO2hgGXevBcANKg0= + dependencies: + graceful-fs "^4.1.11" + lodash.flattendeep "^4.4.0" + md5-hex "^2.0.0" + release-zalgo "^1.0.0" + +package-json@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" + integrity sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0= + dependencies: + got "^6.7.1" + registry-auth-token "^3.0.1" + registry-url "^3.0.3" + semver "^5.1.0" + +pako@~1.0.5: + version "1.0.10" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.10.tgz#4328badb5086a426aa90f541977d4955da5c9732" + integrity sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw== + +parallel-transform@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.1.0.tgz#d410f065b05da23081fcd10f28854c29bda33b06" + integrity sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY= + dependencies: + cyclist "~0.2.2" + inherits "^2.0.3" + readable-stream "^2.1.5" + +parse-asn1@^5.0.0: + version "5.1.4" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.4.tgz#37f6628f823fbdeb2273b4d540434a22f3ef1fcc" + integrity sha512-Qs5duJcuvNExRfFZ99HDD3z4mAi3r9Wl/FOjEOijlxwCZs7E7mW2vjTpgQ4J8LpTF8x5v+1Vn5UQFejmWT11aw== + dependencies: + asn1.js "^4.0.0" + browserify-aes "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.0" + pbkdf2 "^3.0.3" + safe-buffer "^5.1.1" + +parse-filepath@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/parse-filepath/-/parse-filepath-1.0.2.tgz#a632127f53aaf3d15876f5872f3ffac763d6c891" + integrity sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE= + dependencies: + is-absolute "^1.0.0" + map-cache "^0.2.0" + path-root "^0.1.1" + +parse-glob@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" + integrity sha1-ssN2z7EfNVE7rdFz7wu246OIORw= + dependencies: + glob-base "^0.3.0" + is-dotfile "^1.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.0" + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= + dependencies: + error-ex "^1.2.0" + +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= + dependencies: + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + +parse-ms@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/parse-ms/-/parse-ms-0.1.2.tgz#dd3fa25ed6c2efc7bdde12ad9b46c163aa29224e" + integrity sha1-3T+iXtbC78e93hKtm0bBY6opIk4= + +parse-ms@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parse-ms/-/parse-ms-1.0.1.tgz#56346d4749d78f23430ca0c713850aef91aa361d" + integrity sha1-VjRtR0nXjyNDDKDHE4UK75GqNh0= + +parse-node-version@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parse-node-version/-/parse-node-version-1.0.1.tgz#e2b5dbede00e7fa9bc363607f53327e8b073189b" + integrity sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA== + +parse-passwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" + integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY= + +parse5@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608" + integrity sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA== + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= + +path-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.0.tgz#a0b870729aae214005b7d5032ec2cbbb0fb4451a" + integrity sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo= + +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= + dependencies: + pinkie-promise "^2.0.0" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + +path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-is-inside@^1.0.1, path-is-inside@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= + +path-key@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= + +path-parse@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" + integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== + +path-root-regex@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/path-root-regex/-/path-root-regex-0.1.2.tgz#bfccdc8df5b12dc52c8b43ec38d18d72c04ba96d" + integrity sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0= + +path-root@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/path-root/-/path-root-0.1.1.tgz#9a4a6814cac1c0cd73360a95f32083c8ea4745b7" + integrity sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc= + dependencies: + path-root-regex "^0.1.0" + +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +path-type@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" + integrity sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM= + dependencies: + pify "^2.0.0" + +pbkdf2@^3.0.3: + version "3.0.17" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" + integrity sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA== + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + +pify@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= + +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= + +pinkie-promise@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-1.0.0.tgz#d1da67f5482563bb7cf57f286ae2822ecfbf3670" + integrity sha1-0dpn9UglY7t89X8oauKCLs+/NnA= + dependencies: + pinkie "^1.0.0" + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= + dependencies: + pinkie "^2.0.0" + +pinkie@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-1.0.0.tgz#5a47f28ba1015d0201bda7bf0f358e47bec8c7e4" + integrity sha1-Wkfyi6EBXQIBvae/DzWOR77Ix+Q= + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= + +pkg-conf@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/pkg-conf/-/pkg-conf-2.1.0.tgz#2126514ca6f2abfebd168596df18ba57867f0058" + integrity sha1-ISZRTKbyq/69FoWW3xi6V4Z/AFg= + dependencies: + find-up "^2.0.0" + load-json-file "^4.0.0" + +pkg-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" + integrity sha1-ektQio1bstYp1EcFb/TpyTFM89Q= + dependencies: + find-up "^1.0.0" + +pkg-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" + integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s= + dependencies: + find-up "^2.1.0" + +plugin-error@1.0.1, plugin-error@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/plugin-error/-/plugin-error-1.0.1.tgz#77016bd8919d0ac377fdcdd0322328953ca5781c" + integrity sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA== + dependencies: + ansi-colors "^1.0.1" + arr-diff "^4.0.0" + arr-union "^3.1.0" + extend-shallow "^3.0.2" + +plugin-error@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/plugin-error/-/plugin-error-0.1.2.tgz#3b9bb3335ccf00f425e07437e19276967da47ace" + integrity sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4= + dependencies: + ansi-cyan "^0.1.1" + ansi-red "^0.1.1" + arr-diff "^1.0.1" + arr-union "^2.0.1" + extend-shallow "^1.1.2" + +plur@^2.0.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/plur/-/plur-2.1.2.tgz#7482452c1a0f508e3e344eaec312c91c29dc655a" + integrity sha1-dIJFLBoPUI4+NE6uwxLJHCncZVo= + dependencies: + irregular-plurals "^1.0.0" + +pluralize@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" + integrity sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow== + +pn@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" + integrity sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA== + +portfinder@^1.0.13: + version "1.0.20" + resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.20.tgz#bea68632e54b2e13ab7b0c4775e9b41bf270e44a" + integrity sha512-Yxe4mTyDzTd59PZJY4ojZR8F+E5e97iq2ZOHPz3HDgSvYC5siNad2tLooQ5y5QHyQhc3xVqvyk/eNA3wuoa7Sw== + dependencies: + async "^1.5.2" + debug "^2.2.0" + mkdirp "0.5.x" + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= + +postcss-value-parser@^3.2.3: + version "3.3.1" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" + integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== + +postcss@^6.0.1, postcss@^6.0.17: + version "6.0.23" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.23.tgz#61c82cc328ac60e677645f979054eb98bc0e3324" + integrity sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag== + dependencies: + chalk "^2.4.1" + source-map "^0.6.1" + supports-color "^5.4.0" + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= + +prepend-http@^1.0.0, prepend-http@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= + +preserve@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" + integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks= + +pretty-hrtime@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" + integrity sha1-t+PqQkNaTJsnWdmeDyAesZWALuE= + +pretty-ms@^0.2.1: + version "0.2.2" + resolved "https://registry.yarnpkg.com/pretty-ms/-/pretty-ms-0.2.2.tgz#da879a682ff33a37011046f13d627f67c73b84f6" + integrity sha1-2oeaaC/zOjcBEEbxPWJ/Z8c7hPY= + dependencies: + parse-ms "^0.1.0" + +pretty-ms@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/pretty-ms/-/pretty-ms-3.2.0.tgz#87a8feaf27fc18414d75441467d411d6e6098a25" + integrity sha512-ZypexbfVUGTFxb0v+m1bUyy92DHe5SyYlnyY0msyms5zd3RwyvNgyxZZsXXgoyzlxjx5MiqtXUdhUfvQbe0A2Q== + dependencies: + parse-ms "^1.0.0" + +private@^0.1.6, private@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" + integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== + +process-nextick-args@^2.0.0, process-nextick-args@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" + integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw== + +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= + +progress@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= + +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= + +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= + +psl@^1.1.24, psl@^1.1.28: + version "1.1.31" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.31.tgz#e9aa86d0101b5b105cbe93ac6b784cd547276184" + integrity sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw== + +public-encrypt@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" + integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== + dependencies: + bn.js "^4.1.0" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + parse-asn1 "^5.0.0" + randombytes "^2.0.1" + safe-buffer "^5.1.2" + +pump@^2.0.0, pump@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" + integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pumpify@^1.3.3: + version "1.5.1" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" + integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== + dependencies: + duplexify "^3.6.0" + inherits "^2.0.3" + pump "^2.0.0" + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= + +punycode@^1.2.4, punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= + +punycode@^2.1.0, punycode@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +qs@~2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-2.3.3.tgz#e9e85adbe75da0bbe4c8e0476a086290f863b404" + integrity sha1-6eha2+ddoLvkyOBHaghikPhjtAQ= + +qs@~6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== + +query-string@^4.1.0: + version "4.3.4" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-4.3.4.tgz#bbb693b9ca915c232515b228b1a02b609043dbeb" + integrity sha1-u7aTucqRXCMlFbIosaArYJBD2+s= + dependencies: + object-assign "^4.1.0" + strict-uri-encode "^1.0.0" + +querystring-es3@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" + integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM= + +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= + +randomatic@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.1.1.tgz#b776efc59375984e36c537b2f51a1f0aff0da1ed" + integrity sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw== + dependencies: + is-number "^4.0.0" + kind-of "^6.0.0" + math-random "^1.0.1" + +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +randomfill@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== + dependencies: + randombytes "^2.0.5" + safe-buffer "^5.1.0" + +rc@^1.0.1, rc@^1.1.6, rc@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + +read-pkg-up@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" + integrity sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4= + dependencies: + find-up "^2.0.0" + read-pkg "^2.0.0" + +read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + +read-pkg@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" + integrity sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg= + dependencies: + load-json-file "^2.0.0" + normalize-package-data "^2.3.2" + path-type "^2.0.0" + +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6: + version "2.3.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" + integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +"readable-stream@>=1.0.33-1 <1.1.0-0": + version "1.0.34" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" + integrity sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw= + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@~1.1.9: + version "1.1.14" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk= + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readdirp@^2.0.0, readdirp@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== + dependencies: + graceful-fs "^4.1.11" + micromatch "^3.1.10" + readable-stream "^2.0.2" + +rechoir@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" + integrity sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q= + dependencies: + resolve "^1.1.6" + +redent@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" + integrity sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94= + dependencies: + indent-string "^2.1.0" + strip-indent "^1.0.1" + +regenerate@^1.2.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" + integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg== + +regenerator-runtime@^0.10.5: + version "0.10.5" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" + integrity sha1-M2w+/BIgrc7dosn6tntaeVWjNlg= + +regenerator-runtime@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== + +regenerator-transform@^0.10.0: + version "0.10.1" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" + integrity sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q== + dependencies: + babel-runtime "^6.18.0" + babel-types "^6.19.0" + private "^0.1.6" + +regex-cache@^0.4.2: + version "0.4.4" + resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" + integrity sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ== + dependencies: + is-equal-shallow "^0.1.3" + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +regexpp@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-1.1.0.tgz#0e3516dd0b7904f413d2d4193dce4618c3a689ab" + integrity sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw== + +regexpu-core@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" + integrity sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA= + dependencies: + regenerate "^1.2.1" + regjsgen "^0.2.0" + regjsparser "^0.1.4" + +registry-auth-token@^3.0.1: + version "3.4.0" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.4.0.tgz#d7446815433f5d5ed6431cd5dca21048f66b397e" + integrity sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A== + dependencies: + rc "^1.1.6" + safe-buffer "^5.0.1" + +registry-url@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" + integrity sha1-PU74cPc93h138M+aOBQyRE4XSUI= + dependencies: + rc "^1.0.1" + +regjsgen@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" + integrity sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc= + +regjsparser@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" + integrity sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw= + dependencies: + jsesc "~0.5.0" + +release-zalgo@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/release-zalgo/-/release-zalgo-1.0.0.tgz#09700b7e5074329739330e535c5a90fb67851730" + integrity sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA= + dependencies: + es6-error "^4.0.1" + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= + +repeat-element@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" + integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== + +repeat-string@^1.5.2, repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= + +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo= + dependencies: + is-finite "^1.0.0" + +replace-ext@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-0.0.1.tgz#29bbd92078a739f0bcce2b4ee41e837953522924" + integrity sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ= + +replace-ext@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb" + integrity sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs= + +replacestream@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/replacestream/-/replacestream-4.0.3.tgz#3ee5798092be364b1cdb1484308492cb3dff2f36" + integrity sha512-AC0FiLS352pBBiZhd4VXB1Ab/lh0lEgpP+GGvZqbQh8a5cmXVoTe5EX/YeTFArnp4SRGTHh1qCHu9lGs1qG8sA== + dependencies: + escape-string-regexp "^1.0.3" + object-assign "^4.0.1" + readable-stream "^2.0.2" + +request-promise-core@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.2.tgz#339f6aababcafdb31c799ff158700336301d3346" + integrity sha512-UHYyq1MO8GsefGEt7EprS8UrXsm1TxEvFUX1IMTuSLU2Rh7fTIdFtl8xD7JiEYiWU2dl+NYAjCTksTehQUxPag== + dependencies: + lodash "^4.17.11" + +request-promise-native@^1.0.5: + version "1.0.7" + resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.7.tgz#a49868a624bdea5069f1251d0a836e0d89aa2c59" + integrity sha512-rIMnbBdgNViL37nZ1b3L/VfPOpSi0TqVDQPAvO6U14lMzOLrt5nilxCQqtDKhZeDiW0/hkCXGoQjhgJd/tCh6w== + dependencies: + request-promise-core "1.1.2" + stealthy-require "^1.1.1" + tough-cookie "^2.3.3" + +request@^2.61.0, request@^2.87.0: + version "2.88.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" + integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.0" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.4.3" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= + +require-precompiled@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/require-precompiled/-/require-precompiled-0.1.0.tgz#5a1b52eb70ebed43eb982e974c85ab59571e56fa" + integrity sha1-WhtS63Dr7UPrmC6XTIWrWVceVvo= + +require-uncached@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" + integrity sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM= + dependencies: + caller-path "^0.1.0" + resolve-from "^1.0.0" + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= + +requizzle@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/requizzle/-/requizzle-0.2.2.tgz#df991c0cffbbbdde721504c1455f68f53f7c7bd1" + integrity sha512-oJ6y7JcUJkblRGhMByGNcszeLgU0qDxNKFCiUZR1XyzHyVsev+Mxb1tyygxLd1ORsKee1SA5BInFdUwY64GE/A== + dependencies: + lodash "^4.17.11" + +resolve-cwd@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" + integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo= + dependencies: + resolve-from "^3.0.0" + +resolve-dir@^1.0.0, resolve-dir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" + integrity sha1-eaQGRMNivoLybv/nOcm7U4IEb0M= + dependencies: + expand-tilde "^2.0.0" + global-modules "^1.0.0" + +resolve-from@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" + integrity sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY= + +resolve-from@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" + integrity sha1-six699nWiBvItuZTM17rywoYh0g= + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= + +resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0: + version "1.10.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.10.1.tgz#664842ac960795bbe758221cdccda61fb64b5f18" + integrity sha512-KuIe4mf++td/eFb6wkaPbMDnP6kObCaEtIDuHOUED6MNUo4K670KZUHuuvYPZDxNF0WVLw49n06M2m2dXphEzA== + dependencies: + path-parse "^1.0.6" + +restore-cursor@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= + dependencies: + onetime "^2.0.0" + signal-exit "^3.0.2" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + +right-align@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" + integrity sha1-YTObci/mo1FWiSENJOFMlhSGE+8= + dependencies: + align-text "^0.1.1" + +rimraf@2, rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@~2.6.2: + version "2.6.3" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" + integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== + dependencies: + glob "^7.1.3" + +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + +run-async@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" + integrity sha1-A3GrSuC91yDUFm19/aZP96RFpsA= + dependencies: + is-promise "^2.1.0" + +run-queue@^1.0.0, run-queue@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" + integrity sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec= + dependencies: + aproba "^1.1.1" + +run-sequence@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/run-sequence/-/run-sequence-2.2.1.tgz#1ce643da36fd8c7ea7e1a9329da33fc2b8898495" + integrity sha512-qkzZnQWMZjcKbh3CNly2srtrkaO/2H/SI5f2eliMCapdRD3UhMrwjfOAZJAnZ2H8Ju4aBzFZkBGXUqFs9V0yxw== + dependencies: + chalk "^1.1.3" + fancy-log "^1.3.2" + plugin-error "^0.1.2" + +rx-lite-aggregates@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be" + integrity sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74= + dependencies: + rx-lite "*" + +rx-lite@*, rx-lite@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444" + integrity sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ= + +safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= + dependencies: + ret "~0.1.10" + +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +sass-graph@^2.1.1: + version "2.2.4" + resolved "https://registry.yarnpkg.com/sass-graph/-/sass-graph-2.2.4.tgz#13fbd63cd1caf0908b9fd93476ad43a51d1e0b49" + integrity sha1-E/vWPNHK8JCLn9k0dq1DpR0eC0k= + dependencies: + glob "^7.0.0" + lodash "^4.0.0" + scss-tokenizer "^0.2.3" + yargs "^7.0.0" + +sax@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + +schema-utils@^0.4.5: + version "0.4.7" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.7.tgz#ba74f597d2be2ea880131746ee17d0a093c68187" + integrity sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ== + dependencies: + ajv "^6.1.0" + ajv-keywords "^3.1.0" + +scss-tokenizer@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz#8eb06db9a9723333824d3f5530641149847ce5d1" + integrity sha1-jrBtualyMzOCTT9VMGQRSYR85dE= + dependencies: + js-base64 "^2.1.8" + source-map "^0.4.2" + +semver-diff@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" + integrity sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY= + dependencies: + semver "^5.0.3" + +"semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.3.0: + version "5.7.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b" + integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA== + +semver@^4.1.0: + version "4.3.6" + resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.6.tgz#300bc6e0e86374f7ba61068b5b1ecd57fc6532da" + integrity sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto= + +semver@~5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" + integrity sha1-myzl094C0XxgEq0yaqa00M9U+U8= + +sequencify@~0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/sequencify/-/sequencify-0.0.7.tgz#90cff19d02e07027fd767f5ead3e7b95d1e7380c" + integrity sha1-kM/xnQLgcCf9dn9erT57ldHnOAw= + +serialize-javascript@^1.4.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.7.0.tgz#d6e0dfb2a3832a8c94468e6eb1db97e55a192a65" + integrity sha512-ke8UG8ulpFOxO8f8gRYabHQe/ZntKlcig2Mp+8+URDP1D8vJZ0KUt7LYo07q25Z/+JVSgpr/cui9PIp5H6/+nA== + +set-blocking@^2.0.0, set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + +set-value@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" + integrity sha1-fbCPnT0i3H945Trzw79GZuzfzPE= + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.1" + to-object-path "^0.3.0" + +set-value@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274" + integrity sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg== + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +setimmediate@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= + +sha.js@^2.4.0, sha.js@^2.4.8: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= + +sigmund@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" + integrity sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA= + +signal-exit@^3.0.0, signal-exit@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= + +simple-swizzle@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" + integrity sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo= + dependencies: + is-arrayish "^0.3.1" + +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= + +slice-ansi@1.0.0, slice-ansi@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d" + integrity sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg== + dependencies: + is-fullwidth-code-point "^2.0.0" + +slide@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" + integrity sha1-VusCfWW00tzmyy4tMsTUr8nh1wc= + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +sort-keys@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" + integrity sha1-RBttTTRnmPG05J6JIK37oOVD+a0= + dependencies: + is-plain-obj "^1.0.0" + +sort-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" + integrity sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg= + dependencies: + is-plain-obj "^1.0.0" + +source-list-map@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" + integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== + +source-map-resolve@^0.5.0, source-map-resolve@^0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" + integrity sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA== + dependencies: + atob "^2.1.1" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-support@^0.4.0, source-map-support@^0.4.15: + version "0.4.18" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" + integrity sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA== + dependencies: + source-map "^0.5.6" + +source-map-url@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" + integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= + +source-map@^0.4.2: + version "0.4.4" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" + integrity sha1-66T12pwNyZneaAMti092FzZSA2s= + dependencies: + amdefine ">=0.0.4" + +source-map@^0.5.0, source-map@^0.5.1, source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7, source-map@~0.5.1: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +sparkles@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sparkles/-/sparkles-1.0.1.tgz#008db65edce6c50eec0c5e228e1945061dd0437c" + integrity sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw== + +spdx-correct@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" + integrity sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977" + integrity sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA== + +spdx-expression-parse@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" + integrity sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.4.tgz#75ecd1a88de8c184ef015eafb51b5b48bfd11bb1" + integrity sha512-7j8LYJLeY/Yb6ACbQ7F76qy5jHkp0U6jgBfJsk97bwWlVUnUWsAgpyaCvo17h0/RQGnQ036tVDomiwoI4pDkQA== + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== + dependencies: + extend-shallow "^3.0.0" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +sshpk@^1.7.0: + version "1.16.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" + integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + +ssri@^5.2.4: + version "5.3.0" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-5.3.0.tgz#ba3872c9c6d33a0704a7d71ff045e5ec48999d06" + integrity sha512-XRSIPqLij52MtgoQavH/x/dU1qVKtWUAAZeOHsR9c2Ddi4XerFy3mc1alf+dLJKl9EUIm/Ht+EowFkTUOA6GAQ== + dependencies: + safe-buffer "^5.1.1" + +stack-utils@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.2.tgz#33eba3897788558bebfc2db059dc158ec36cebb8" + integrity sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA== + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +stealthy-require@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" + integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= + +stream-browserify@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" + integrity sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg== + dependencies: + inherits "~2.0.1" + readable-stream "^2.0.2" + +stream-consume@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/stream-consume/-/stream-consume-0.1.1.tgz#d3bdb598c2bd0ae82b8cac7ac50b1107a7996c48" + integrity sha512-tNa3hzgkjEP7XbCkbRXe1jpg+ievoa0O4SCFlMOYEscGSS4JJsckGL8swUyAa/ApGU3Ae4t6Honor4HhL+tRyg== + +stream-each@^1.1.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" + integrity sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw== + dependencies: + end-of-stream "^1.1.0" + stream-shift "^1.0.0" + +stream-http@^2.7.2: + version "2.8.3" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" + integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw== + dependencies: + builtin-status-codes "^3.0.0" + inherits "^2.0.1" + readable-stream "^2.3.6" + to-arraybuffer "^1.0.0" + xtend "^4.0.0" + +stream-shift@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" + integrity sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI= + +strict-uri-encode@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" + integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= + +string-width@^1.0.1, string-width@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string_decoder@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.2.0.tgz#fe86e738b19544afe70469243b2a1ee9240eae8d" + integrity sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w== + dependencies: + safe-buffer "~5.1.0" + +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + dependencies: + ansi-regex "^3.0.0" + +strip-ansi@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.1.1.tgz#39e8a98d044d150660abe4a6808acf70bb7bc991" + integrity sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE= + +strip-bom-buf@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-bom-buf/-/strip-bom-buf-1.0.0.tgz#1cb45aaf57530f4caf86c7f75179d2c9a51dd572" + integrity sha1-HLRar1dTD0yvhsf3UXnSyaUd1XI= + dependencies: + is-utf8 "^0.2.1" + +strip-bom-string@1.X: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-bom-string/-/strip-bom-string-1.0.0.tgz#e5211e9224369fbb81d633a2f00044dc8cedad92" + integrity sha1-5SEekiQ2n7uB1jOi8ABE3IztrZI= + +strip-bom@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-1.0.0.tgz#85b8862f3844b5a6d5ec8467a93598173a36f794" + integrity sha1-hbiGLzhEtabV7IRnqTWYFzo295Q= + dependencies: + first-chunk-stream "^1.0.0" + is-utf8 "^0.2.0" + +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= + dependencies: + is-utf8 "^0.2.0" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= + +strip-indent@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" + integrity sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI= + dependencies: + get-stdin "^4.0.1" + +strip-json-comments@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.0.1.tgz#85713975a91fb87bf1b305cca77395e40d2a64a7" + integrity sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw== + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= + +strip-outer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/strip-outer/-/strip-outer-1.0.1.tgz#b2fd2abf6604b9d1e6013057195df836b8a9d631" + integrity sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg== + dependencies: + escape-string-regexp "^1.0.2" + +strip-url-auth@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/strip-url-auth/-/strip-url-auth-1.0.1.tgz#22b0fa3a41385b33be3f331551bbb837fa0cd7ae" + integrity sha1-IrD6OkE4WzO+PzMVUbu4N/oM164= + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= + +supports-color@^4.0.0, supports-color@^4.2.1: + version "4.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b" + integrity sha1-vnoN5ITexcXN34s9WRJQRJEvY1s= + dependencies: + has-flag "^2.0.0" + +supports-color@^5.3.0, supports-color@^5.4.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +symbol-observable@^0.2.2: + version "0.2.4" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-0.2.4.tgz#95a83db26186d6af7e7a18dbd9760a2f86d08f40" + integrity sha1-lag9smGG1q9+ehjb2XYKL4bQj0A= + +symbol-observable@^1.0.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" + integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== + +symbol-tree@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6" + integrity sha1-rifbOPZgp64uHDt9G8KQgZuFGeY= + +table@4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/table/-/table-4.0.2.tgz#a33447375391e766ad34d3486e6e2aedc84d2e36" + integrity sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA== + dependencies: + ajv "^5.2.3" + ajv-keywords "^2.1.0" + chalk "^2.1.0" + lodash "^4.17.4" + slice-ansi "1.0.0" + string-width "^2.1.1" + +taffydb@2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/taffydb/-/taffydb-2.6.2.tgz#7cbcb64b5a141b6a2efc2c5d2c67b4e150b2a268" + integrity sha1-fLy2S1oUG2ou/CxdLGe04VCyomg= + +tapable@^0.2.7: + version "0.2.9" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.2.9.tgz#af2d8bbc9b04f74ee17af2b4d9048f807acd18a8" + integrity sha512-2wsvQ+4GwBvLPLWsNfLCDYGsW6xb7aeC6utq2Qh0PFwgEy7K7dsma9Jsmb2zSQj7GvYAyUGSntLtsv++GmgL1A== + +tar@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" + integrity sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE= + dependencies: + block-stream "*" + fstream "^1.0.2" + inherits "2" + +tar@^4: + version "4.4.8" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.8.tgz#b19eec3fde2a96e64666df9fdb40c5ca1bc3747d" + integrity sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ== + dependencies: + chownr "^1.1.1" + fs-minipass "^1.2.5" + minipass "^2.3.4" + minizlib "^1.1.1" + mkdirp "^0.5.0" + safe-buffer "^5.1.2" + yallist "^3.0.2" + +term-size@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69" + integrity sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk= + dependencies: + execa "^0.7.0" + +text-table@^0.2.0, text-table@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= + +through2@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" + integrity sha1-AARWmzfHx0ujnEPzzteNGtlBQL4= + dependencies: + readable-stream "^2.1.5" + xtend "~4.0.1" + +through2@2.X, through2@^2.0.0, through2@^2.0.3: + version "2.0.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" + integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== + dependencies: + readable-stream "~2.3.6" + xtend "~4.0.1" + +through2@^0.6.1, through2@^0.6.3: + version "0.6.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-0.6.5.tgz#41ab9c67b29d57209071410e1d7a7a968cd3ad48" + integrity sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg= + dependencies: + readable-stream ">=1.0.33-1 <1.1.0-0" + xtend ">=4.0.0 <4.1.0-0" + +through@^2.3.6, through@^2.3.8: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + +tildify@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/tildify/-/tildify-1.2.0.tgz#dcec03f55dca9b7aa3e5b04f21817eb56e63588a" + integrity sha1-3OwD9V3Km3qj5bBPIYF+tW5jWIo= + dependencies: + os-homedir "^1.0.0" + +time-require@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/time-require/-/time-require-0.1.2.tgz#f9e12cb370fc2605e11404582ba54ef5ca2b2d98" + integrity sha1-+eEss3D8JgXhFARYK6VO9corLZg= + dependencies: + chalk "^0.4.0" + date-time "^0.1.1" + pretty-ms "^0.2.1" + text-table "^0.2.0" + +time-stamp@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" + integrity sha1-dkpaEa9QVhkhsTPztE5hhofg9cM= + +time-zone@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/time-zone/-/time-zone-1.0.0.tgz#99c5bf55958966af6d06d83bdf3800dc82faec5d" + integrity sha1-mcW/VZWJZq9tBtg73zgA3IL67F0= + +timed-out@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" + integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8= + +timers-browserify@^2.0.4: + version "2.0.10" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.10.tgz#1d28e3d2aadf1d5a5996c4e9f95601cd053480ae" + integrity sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg== + dependencies: + setimmediate "^1.0.4" + +timers-ext@^0.1.5: + version "0.1.7" + resolved "https://registry.yarnpkg.com/timers-ext/-/timers-ext-0.1.7.tgz#6f57ad8578e07a3fb9f91d9387d65647555e25c6" + integrity sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ== + dependencies: + es5-ext "~0.10.46" + next-tick "1" + +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== + dependencies: + os-tmpdir "~1.0.2" + +to-arraybuffer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" + integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= + +to-fast-properties@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" + integrity sha1-uDVx+k2MJbguIxsG46MFXeTKGkc= + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= + +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= + dependencies: + kind-of "^3.0.2" + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + +tough-cookie@^2.3.3, tough-cookie@^2.3.4: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + +tough-cookie@~2.4.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" + integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ== + dependencies: + psl "^1.1.24" + punycode "^1.4.1" + +tr46@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" + integrity sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk= + dependencies: + punycode "^2.1.0" + +trim-newlines@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" + integrity sha1-WIeWa7WCpFA6QetST301ARgVphM= + +trim-off-newlines@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz#9f9ba9d9efa8764c387698bcbfeb2c848f11adb3" + integrity sha1-n5up2e+odkw4dpi8v+sshI8RrbM= + +trim-repeated@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/trim-repeated/-/trim-repeated-1.0.0.tgz#e3646a2ea4e891312bf7eace6cfb05380bc01c21" + integrity sha1-42RqLqTokTEr9+rObPsFOAvAHCE= + dependencies: + escape-string-regexp "^1.0.2" + +trim-right@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" + integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= + +tty-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" + integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= + dependencies: + prelude-ls "~1.1.2" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= + +uc.micro@^1.0.1, uc.micro@^1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac" + integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA== + +uglify-es@^3.3.4: + version "3.3.9" + resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.3.9.tgz#0c1c4f0700bed8dbc124cdb304d2592ca203e677" + integrity sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ== + dependencies: + commander "~2.13.0" + source-map "~0.6.1" + +uglify-js@^2.8.29: + version "2.8.29" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" + integrity sha1-KcVzMUgFe7Th913zW3qcty5qWd0= + dependencies: + source-map "~0.5.1" + yargs "~3.10.0" + optionalDependencies: + uglify-to-browserify "~1.0.0" + +uglify-js@^3.1.4: + version "3.5.11" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.5.11.tgz#833442c0aa29b3a7d34344c7c63adaa3f3504f6a" + integrity sha512-izPJg8RsSyqxbdnqX36ExpbH3K7tDBsAU/VfNv89VkMFy3z39zFjunQGsSHOlGlyIfGLGprGeosgQno3bo2/Kg== + dependencies: + commander "~2.20.0" + source-map "~0.6.1" + +uglify-to-browserify@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" + integrity sha1-bgkk1r2mta/jSeOabWMoUKD4grc= + +uglifyjs-webpack-plugin@^0.4.6: + version "0.4.6" + resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-0.4.6.tgz#b951f4abb6bd617e66f63eb891498e391763e309" + integrity sha1-uVH0q7a9YX5m9j64kUmOORdj4wk= + dependencies: + source-map "^0.5.6" + uglify-js "^2.8.29" + webpack-sources "^1.0.1" + +uglifyjs-webpack-plugin@^1.0.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.3.0.tgz#75f548160858163a08643e086d5fefe18a5d67de" + integrity sha512-ovHIch0AMlxjD/97j9AYovZxG5wnHOPkL7T1GKochBADp/Zwc44pEWNqpKl1Loupp1WhFg7SlYmHZRUfdAacgw== + dependencies: + cacache "^10.0.4" + find-cache-dir "^1.0.0" + schema-utils "^0.4.5" + serialize-javascript "^1.4.0" + source-map "^0.6.1" + uglify-es "^3.3.4" + webpack-sources "^1.1.0" + worker-farm "^1.5.2" + +uid2@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/uid2/-/uid2-0.0.3.tgz#483126e11774df2f71b8b639dcd799c376162b82" + integrity sha1-SDEm4Rd03y9xuLY53NeZw3YWK4I= + +unc-path-regex@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa" + integrity sha1-5z3T17DXxe2G+6xrCufYxqadUPo= + +underscore@~1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.9.1.tgz#06dce34a0e68a7babc29b365b8e74b8925203961" + integrity sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg== + +union-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" + integrity sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ= + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^0.4.3" + +union@~0.4.3: + version "0.4.6" + resolved "https://registry.yarnpkg.com/union/-/union-0.4.6.tgz#198fbdaeba254e788b0efcb630bc11f24a2959e0" + integrity sha1-GY+9rrolTniLDvy2MLwR8kopWeA= + dependencies: + qs "~2.3.3" + +unique-filename@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" + integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== + dependencies: + unique-slug "^2.0.0" + +unique-slug@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.1.tgz#5e9edc6d1ce8fb264db18a507ef9bd8544451ca6" + integrity sha512-n9cU6+gITaVu7VGj1Z8feKMmfAjEAQGhwD9fE3zvpRRa0wEIx8ODYkVGfSc94M2OX00tUFV8wH3zYbm1I8mxFg== + dependencies: + imurmurhash "^0.1.4" + +unique-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unique-stream/-/unique-stream-1.0.0.tgz#d59a4a75427447d9aa6c91e70263f8d26a4b104b" + integrity sha1-1ZpKdUJ0R9mqbJHnAmP40mpLEEs= + +unique-string@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a" + integrity sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo= + dependencies: + crypto-random-string "^1.0.0" + +unique-temp-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unique-temp-dir/-/unique-temp-dir-1.0.0.tgz#6dce95b2681ca003eebfb304a415f9cbabcc5385" + integrity sha1-bc6VsmgcoAPuv7MEpBX5y6vMU4U= + dependencies: + mkdirp "^0.5.1" + os-tmpdir "^1.0.1" + uid2 "0.0.3" + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +unzip-response@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" + integrity sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c= + +upath@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.2.tgz#3db658600edaeeccbe6db5e684d67ee8c2acd068" + integrity sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q== + +update-notifier@^2.3.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-2.5.0.tgz#d0744593e13f161e406acb1d9408b72cad08aff6" + integrity sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw== + dependencies: + boxen "^1.2.1" + chalk "^2.0.1" + configstore "^3.0.0" + import-lazy "^2.1.0" + is-ci "^1.0.10" + is-installed-globally "^0.1.0" + is-npm "^1.0.0" + latest-version "^3.0.0" + semver-diff "^2.0.0" + xdg-basedir "^3.0.0" + +uri-js@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== + dependencies: + punycode "^2.1.0" + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= + +url-join@^2.0.2: + version "2.0.5" + resolved "https://registry.yarnpkg.com/url-join/-/url-join-2.0.5.tgz#5af22f18c052a000a48d7b82c5e9c2e2feeda728" + integrity sha1-WvIvGMBSoACkjXuCxenC4v7tpyg= + +url-parse-lax@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" + integrity sha1-evjzA2Rem9eaJy56FKxovAYJ2nM= + dependencies: + prepend-http "^1.0.1" + +url@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== + +user-home@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190" + integrity sha1-K1viOjK2Onyd640PKNSFcko98ZA= + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +util@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= + dependencies: + inherits "2.0.1" + +util@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61" + integrity sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ== + dependencies: + inherits "2.0.3" + +uuid@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" + integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== + +v8flags@^2.0.2, v8flags@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-2.1.1.tgz#aab1a1fa30d45f88dd321148875ac02c0b55e5b4" + integrity sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ= + dependencies: + user-home "^1.1.1" + +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +vinyl-fs@^0.3.0: + version "0.3.14" + resolved "https://registry.yarnpkg.com/vinyl-fs/-/vinyl-fs-0.3.14.tgz#9a6851ce1cac1c1cea5fe86c0931d620c2cfa9e6" + integrity sha1-mmhRzhysHBzqX+hsCTHWIMLPqeY= + dependencies: + defaults "^1.0.0" + glob-stream "^3.1.5" + glob-watcher "^0.0.6" + graceful-fs "^3.0.0" + mkdirp "^0.5.0" + strip-bom "^1.0.0" + through2 "^0.6.1" + vinyl "^0.4.0" + +vinyl-sourcemaps-apply@0.2.1, vinyl-sourcemaps-apply@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz#ab6549d61d172c2b1b87be5c508d239c8ef87705" + integrity sha1-q2VJ1h0XLCsbh75cUI0jnI74dwU= + dependencies: + source-map "^0.5.1" + +vinyl@^0.4.0: + version "0.4.6" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-0.4.6.tgz#2f356c87a550a255461f36bbeb2a5ba8bf784847" + integrity sha1-LzVsh6VQolVGHza76ypbqL94SEc= + dependencies: + clone "^0.2.0" + clone-stats "^0.0.1" + +vinyl@^0.5.0: + version "0.5.3" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-0.5.3.tgz#b0455b38fc5e0cf30d4325132e461970c2091cde" + integrity sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4= + dependencies: + clone "^1.0.0" + clone-stats "^0.0.1" + replace-ext "0.0.1" + +vinyl@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.2.0.tgz#d85b07da96e458d25b2ffe19fece9f2caa13ed86" + integrity sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg== + dependencies: + clone "^2.1.1" + clone-buffer "^1.0.0" + clone-stats "^1.0.0" + cloneable-readable "^1.0.0" + remove-trailing-separator "^1.0.1" + replace-ext "^1.0.0" + +vm-browserify@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73" + integrity sha1-XX6kW7755Kb/ZflUOOCofDV9WnM= + dependencies: + indexof "0.0.1" + +w3c-hr-time@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz#82ac2bff63d950ea9e3189a58a65625fedf19045" + integrity sha1-gqwr/2PZUOqeMYmlimViX+3xkEU= + dependencies: + browser-process-hrtime "^0.1.2" + +watchpack@^1.4.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00" + integrity sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA== + dependencies: + chokidar "^2.0.2" + graceful-fs "^4.1.2" + neo-async "^2.5.0" + +webidl-conversions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" + integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== + +webpack-sources@^1.0.1, webpack-sources@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.3.0.tgz#2a28dcb9f1f45fe960d8f1493252b5ee6530fa85" + integrity sha512-OiVgSrbGu7NEnEvQJJgdSFPl2qWKkWq5lHMhgiToIiN9w34EBnjYzSYs+VbL5KoYiLNtFFa7BZIKxRED3I32pA== + dependencies: + source-list-map "^2.0.0" + source-map "~0.6.1" + +webpack-stream@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/webpack-stream/-/webpack-stream-4.0.3.tgz#96399fd7911b94c264bfc59e356738a89b5ca136" + integrity sha512-Tx7ks7Of/JiPz7/tUM4WqSg4OcXF4m4OzNSaEzNA1TNXQaiTHIjiKqUoL79wGXbFt2q1IP8VG5DcEdaxifY5Ew== + dependencies: + fancy-log "^1.3.2" + lodash.clone "^4.3.2" + lodash.some "^4.2.2" + memory-fs "^0.4.1" + plugin-error "^1.0.1" + supports-color "^5.3.0" + through "^2.3.8" + vinyl "^2.1.0" + webpack "^3.4.1" + +webpack@^3.4.1, webpack@^3.8.1: + version "3.12.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-3.12.0.tgz#3f9e34360370602fcf639e97939db486f4ec0d74" + integrity sha512-Sw7MdIIOv/nkzPzee4o0EdvCuPmxT98+vVpIvwtcwcF1Q4SDSNp92vwcKc4REe7NItH9f1S4ra9FuQ7yuYZ8bQ== + dependencies: + acorn "^5.0.0" + acorn-dynamic-import "^2.0.0" + ajv "^6.1.0" + ajv-keywords "^3.1.0" + async "^2.1.2" + enhanced-resolve "^3.4.0" + escope "^3.6.0" + interpret "^1.0.0" + json-loader "^0.5.4" + json5 "^0.5.1" + loader-runner "^2.3.0" + loader-utils "^1.1.0" + memory-fs "~0.4.1" + mkdirp "~0.5.0" + node-libs-browser "^2.0.0" + source-map "^0.5.3" + supports-color "^4.2.1" + tapable "^0.2.7" + uglifyjs-webpack-plugin "^0.4.6" + watchpack "^1.4.0" + webpack-sources "^1.0.1" + yargs "^8.0.2" + +well-known-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/well-known-symbols/-/well-known-symbols-1.0.0.tgz#73c78ae81a7726a8fa598e2880801c8b16225518" + integrity sha1-c8eK6Bp3Jqj6WY4ogIAcixYiVRg= + +whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3: + version "1.0.5" + resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" + integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== + dependencies: + iconv-lite "0.4.24" + +whatwg-mimetype@^2.1.0, whatwg-mimetype@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" + integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== + +whatwg-url@^6.4.1: + version "6.5.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-6.5.0.tgz#f2df02bff176fd65070df74ad5ccbb5a199965a8" + integrity sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ== + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + +whatwg-url@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.0.0.tgz#fde926fa54a599f3adf82dff25a9f7be02dc6edd" + integrity sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ== + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + +which-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" + integrity sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8= + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + +which@1, which@^1.2.14, which@^1.2.9: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +wide-align@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== + dependencies: + string-width "^1.0.2 || 2" + +widest-line@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-2.0.1.tgz#7438764730ec7ef4381ce4df82fb98a53142a3fc" + integrity sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA== + dependencies: + string-width "^2.1.1" + +window-size@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" + integrity sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0= + +wordwrap@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" + integrity sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8= + +wordwrap@~0.0.2: + version "0.0.3" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" + integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc= + +wordwrap@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= + +worker-farm@^1.5.2: + version "1.7.0" + resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" + integrity sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw== + dependencies: + errno "~0.1.7" + +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +write-file-atomic@^1.1.4: + version "1.3.4" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-1.3.4.tgz#f807a4f0b1d9e913ae7a48112e6cc3af1991b45f" + integrity sha1-+Aek8LHZ6ROuekgRLmzDrxmRtF8= + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + slide "^1.1.5" + +write-file-atomic@^2.0.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.2.tgz#a7181706dfba17855d221140a9c06e15fcdd87b9" + integrity sha512-s0b6vB3xIVRLWywa6X9TOMA7k9zio0TMOsl9ZnDkliA/cfJlpHXAscj0gbHVJiTdIuAYpIyqS5GW91fqm6gG5g== + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + signal-exit "^3.0.2" + +write-json-file@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/write-json-file/-/write-json-file-2.3.0.tgz#2b64c8a33004d54b8698c76d585a77ceb61da32f" + integrity sha1-K2TIozAE1UuGmMdtWFp3zrYdoy8= + dependencies: + detect-indent "^5.0.0" + graceful-fs "^4.1.2" + make-dir "^1.0.0" + pify "^3.0.0" + sort-keys "^2.0.0" + write-file-atomic "^2.0.0" + +write-pkg@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/write-pkg/-/write-pkg-3.2.0.tgz#0e178fe97820d389a8928bc79535dbe68c2cff21" + integrity sha512-tX2ifZ0YqEFOF1wjRW2Pk93NLsj02+n1UP5RvO6rCs0K6R2g1padvf006cY74PQJKMGS2r42NK7FD0dG6Y6paw== + dependencies: + sort-keys "^2.0.0" + write-json-file "^2.2.0" + +write@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" + integrity sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c= + dependencies: + mkdirp "^0.5.1" + +ws@^5.2.0: + version "5.2.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.2.tgz#dffef14866b8e8dc9133582514d1befaf96e980f" + integrity sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA== + dependencies: + async-limiter "~1.0.0" + +xdg-basedir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" + integrity sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ= + +xml-name-validator@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" + integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== + +xmlcreate@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/xmlcreate/-/xmlcreate-2.0.1.tgz#2ec38bd7b708d213fd1a90e2431c4af9c09f6a52" + integrity sha512-MjGsXhKG8YjTKrDCXseFo3ClbMGvUD4en29H2Cev1dv4P/chlpw6KdYmlCWDkhosBVKRDjM836+3e3pm1cBNJA== + +"xtend@>=4.0.0 <4.1.0-0", xtend@^4.0.0, xtend@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68= + +y18n@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" + integrity sha1-bRX7qITAhnnA136I53WegR4H+kE= + +y18n@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" + integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== + +yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= + +yallist@^3.0.0, yallist@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9" + integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A== + +yargs-parser@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.0.tgz#275ecf0d7ffe05c77e64e7c86e4cd94bf0e1228a" + integrity sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo= + dependencies: + camelcase "^3.0.0" + +yargs-parser@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-7.0.0.tgz#8d0ac42f16ea55debd332caf4c4038b3e3f5dfd9" + integrity sha1-jQrELxbqVd69MyyvTEA4s+P139k= + dependencies: + camelcase "^4.1.0" + +yargs@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.0.tgz#6ba318eb16961727f5d284f8ea003e8d6154d0c8" + integrity sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg= + dependencies: + camelcase "^3.0.0" + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + os-locale "^1.4.0" + read-pkg-up "^1.0.1" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^1.0.2" + which-module "^1.0.0" + y18n "^3.2.1" + yargs-parser "^5.0.0" + +yargs@^8.0.2: + version "8.0.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-8.0.2.tgz#6299a9055b1cefc969ff7e79c1d918dceb22c360" + integrity sha1-YpmpBVsc78lp/355wdkY3Osiw2A= + dependencies: + camelcase "^4.1.0" + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + os-locale "^2.0.0" + read-pkg-up "^2.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1" + yargs-parser "^7.0.0" + +yargs@~3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" + integrity sha1-9+572FfdfB0tOMDnTvvWgdFDH9E= + dependencies: + camelcase "^1.0.2" + cliui "^2.1.0" + decamelize "^1.0.0" + window-size "0.1.0" ADDED public/closed/ff_ddt_120_kit_loop_falling_chord_Gmin.wav Index: public/closed/ff_ddt_120_kit_loop_falling_chord_Gmin.wav ================================================================== --- public/closed/ff_ddt_120_kit_loop_falling_chord_Gmin.wav +++ public/closed/ff_ddt_120_kit_loop_falling_chord_Gmin.wav cannot compute difference between binary files ADDED public/closed/ff_ddt_synth_terrier_Gmin.wav Index: public/closed/ff_ddt_synth_terrier_Gmin.wav ================================================================== --- public/closed/ff_ddt_synth_terrier_Gmin.wav +++ public/closed/ff_ddt_synth_terrier_Gmin.wav cannot compute difference between binary files ADDED public/closed/pdh_120_bass_tease_Dmin.wav Index: public/closed/pdh_120_bass_tease_Dmin.wav ================================================================== --- public/closed/pdh_120_bass_tease_Dmin.wav +++ public/closed/pdh_120_bass_tease_Dmin.wav cannot compute difference between binary files ADDED public/closed/pdh_120_drum_loop_hidden_hat.wav Index: public/closed/pdh_120_drum_loop_hidden_hat.wav ================================================================== --- public/closed/pdh_120_drum_loop_hidden_hat.wav +++ public/closed/pdh_120_drum_loop_hidden_hat.wav cannot compute difference between binary files ADDED public/closed/pdh_hat_one_shot_opeen_synthetic_flint.wav Index: public/closed/pdh_hat_one_shot_opeen_synthetic_flint.wav ================================================================== --- public/closed/pdh_hat_one_shot_opeen_synthetic_flint.wav +++ public/closed/pdh_hat_one_shot_opeen_synthetic_flint.wav cannot compute difference between binary files ADDED public/closed/pdh_kick_one_shot_synthetic_low_alex.wav Index: public/closed/pdh_kick_one_shot_synthetic_low_alex.wav ================================================================== --- public/closed/pdh_kick_one_shot_synthetic_low_alex.wav +++ public/closed/pdh_kick_one_shot_synthetic_low_alex.wav cannot compute difference between binary files ADDED public/closed/pdh_snare_one_shot_synthetic_beef.wav Index: public/closed/pdh_snare_one_shot_synthetic_beef.wav ================================================================== --- public/closed/pdh_snare_one_shot_synthetic_beef.wav +++ public/closed/pdh_snare_one_shot_synthetic_beef.wav cannot compute difference between binary files ADDED public/closed/pdh_snare_one_shot_synthetic_crunch.wav Index: public/closed/pdh_snare_one_shot_synthetic_crunch.wav ================================================================== --- public/closed/pdh_snare_one_shot_synthetic_crunch.wav +++ public/closed/pdh_snare_one_shot_synthetic_crunch.wav cannot compute difference between binary files ADDED public/components/bitrhythm.tag Index: public/components/bitrhythm.tag ================================================================== --- public/components/bitrhythm.tag +++ public/components/bitrhythm.tag @@ -0,0 +1,389 @@ + + + +
+ + +
+ + + + +
+ +
+
+ + +
+
+
+
+
+
+ +
+ + + + + + + + + +
+ + +
+
+ +
+
+
+ + +
+ +
+
+ + +
+ +
+
+ +
+ +
+
+
+ +
+
+ +
+ + + + + +
+ ADDED public/components/dial.tag Index: public/components/dial.tag ================================================================== --- public/components/dial.tag +++ public/components/dial.tag @@ -0,0 +1,50 @@ + + + +
+ +
+
+ (x) +
+
+
+ + + +
ADDED public/components/number.tag Index: public/components/number.tag ================================================================== --- public/components/number.tag +++ public/components/number.tag @@ -0,0 +1,45 @@ + + + +
+ +
+
+ (x) +
+
+
+ + + +
ADDED public/components/piano.riot Index: public/components/piano.riot ================================================================== --- public/components/piano.riot +++ public/components/piano.riot @@ -0,0 +1,122 @@ + + +
+ +
+
+ +
+
+
+
+
+
+ Octave Size + +
+
+ + to + +
+
+ Locale + +
+
+ + + + + + +
ADDED public/components/rhythmroll.riot Index: public/components/rhythmroll.riot ================================================================== --- public/components/rhythmroll.riot +++ public/components/rhythmroll.riot @@ -0,0 +1,34 @@ + + + +
+
+ +
+
+
+ {key} +
+
+
+ + + +
+ + ADDED public/components/rhythmroll.tag Index: public/components/rhythmroll.tag ================================================================== --- public/components/rhythmroll.tag +++ public/components/rhythmroll.tag @@ -0,0 +1,25 @@ + + + +
+
+ +
+
+
+ {key} +
+
+
+ + + +
ADDED public/components/sample.tag Index: public/components/sample.tag ================================================================== --- public/components/sample.tag +++ public/components/sample.tag @@ -0,0 +1,67 @@ + + + + + +
+ { getLast(this.props.ti -1)} + (x) +
+
+
+ + +
ADDED public/examples/Korg-01W-16Ft-Piano-C1.wav Index: public/examples/Korg-01W-16Ft-Piano-C1.wav ================================================================== --- public/examples/Korg-01W-16Ft-Piano-C1.wav +++ public/examples/Korg-01W-16Ft-Piano-C1.wav cannot compute difference between binary files ADDED public/examples/basic.json Index: public/examples/basic.json ================================================================== --- public/examples/basic.json +++ public/examples/basic.json @@ -0,0 +1,1 @@ +{"keys":[{"freq":"523.25","top":0,"left":0,"width":"64px","height":"64px","color":"#ffffff","textColor":"#000000"},{"freq":"554.37","top":0,"left":0,"width":"64px","height":"64px","color":"#000000","textColor":"#FFFFFF"},{"freq":"587.33","top":0,"left":0,"width":"64px","height":"64px","color":"#FFFFFF","textColor":"#000000"},{"freq":"622.25","top":0,"left":0,"width":"64px","height":"64px","color":"#000000","textColor":"#FFFFFF"},{"freq":"659.25","top":0,"left":0,"width":"64px","height":"64px","color":"#FFFFFF","textColor":"#000000"},{"freq":"698.46","top":0,"left":0,"width":"64px","height":"64px","color":"#FFFFFF","textColor":"#000000"},{"freq":"739.99","top":0,"left":0,"width":"64px","height":"64px","color":"#000000","textColor":"#FFFFFF"},{"freq":"783.99","top":0,"left":0,"width":"64px","height":"64px","color":"#FFFFFF","textColor":"#000000"},{"freq":"830.61","top":0,"left":0,"width":"64px","height":"64px","color":"#000000","textColor":"#FFFFFF"},{"freq":"880","top":0,"left":0,"width":"64px","height":"64px","color":"#FFFFFF","textColor":"#000000"},{"freq":"932.33","top":0,"left":0,"width":"64px","height":"64px","color":"#000000","textColor":"#FFFFFF"},{"freq":"987.77","top":0,"left":0,"width":"64px","height":"64px","color":"#FFFFFF","textColor":"#000000"},{"freq":"1046.5","top":0,"left":0,"width":"64px","height":"64px","color":"#FFFFFF","textColor":"#000000"}]} ADDED public/json-url-master/LICENSE Index: public/json-url-master/LICENSE ================================================================== --- public/json-url-master/LICENSE +++ public/json-url-master/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) Facebook, Inc. and its affiliates. + +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. ADDED public/json-url-master/README.md Index: public/json-url-master/README.md ================================================================== --- public/json-url-master/README.md +++ public/json-url-master/README.md @@ -0,0 +1,112 @@ +# json-url + +[![npm downloads][downloads-image]][downloads-url] [![Build Status][travis-image]][travis-url] [![Dependency Status][daviddm-image]][daviddm-url] [![Coverage Status][coverage-image]][coverage-url] + +Generate URL-safe representations of some arbtirary JSON data in as small a space as possible that can be shared in a bookmark / link. + +Although designed to work in Node, a standalone client-side library is provided that can be used directly on the browser. + +## Usage + +### Compress + +``` + var codec = require('json-url')('lzw'); + var obj = { one: 1, two: 2, three: [1,2,3], four: 'red pineapples' }; + codec.compress(obj).then(result => console.log(result)); + /* Result: woTCo29uZQHCo3R3bwLCpXRocmVlwpMBAgPCpGZvdXLCrsSOZCBwacSDYXBwbGVz */ +``` + +### Decompress + +``` + var codec = require('json-url')('lzma'); + codec.decompress(someCompressedString).then(json => { /* operate on json */ }) +``` + +### Stats + +``` + var codec = require('json-url')('lzstring'); + codec.stats(obj).then( + ({ rawencoded, compressedencoded, compression }) => { + console.log(`Raw URI-encoded JSON string length: ${rawencoded}`); + console.log(`Compressed URI-encoded JSON string length: ${compressedencoded}`); + console.log(`Compression ratio (raw / compressed): ${compression}`); + } + ); +``` + +### Standalone Browser Bundle + +``` + + +``` + +To see it in action, download the source code and run `npm run example`, or simply visit [this link](http://jsbin.com/cayuhox). + +* The browser bundle is generated using Webpack and consists of multiple chunks, with the main chunk entry point located at `dist/browser/json-url.js`. Chunks must be located in the same folder as the main module itself. +* I've tried my best to reduce the bundle sizes, but the module (at least the entry) is still surprisingly large on the browser (56kb minified, 20kb gzipped). Most of it is due to the buffer.js shim, and partly due to the regenerator-runtime - I may revisit this later to try and improve efficiency. + +## Usage Notes + +* Although not all algorithms are asynchronous, all functions return Promises to ensure compatibility. +* Instantiate an instance with appropriate compression codec before using. +* Valid codecs: + * lzw + * lzma + * lzstring - runs lzstring against a stringified JSON instead of using MessagePack on JSON + * pack - this just uses MessagePack and converts the binary buffer into a Base64 URL-safe representation, without any other compression + +## Motivation + +Typically when you want to shorten a long URL with large amounts of data parameters, the approach is to generate a "short URL" where compression is achieved by using a third-party service which stores the true URL and redirects the user (e.g. bit.ly or goo.gl). + +However, if you want to: + +* share bookmarks with virtually unlimited combinations of state and/or +* want to avoid the third-party dependency + +you would encode the data structure (typically JSON) in your URL, but this often results in very large URLs. + +This approach differs by removing that third-party dependency and encodes it using common compression algorithms such as LZW or LZMA. + +Note: It is arguable that a custom dictionary / domain specific encoding would ultimately provide better compression, but here we want to +* avoid maintaining such a dictionary and/or +* retain cross-application compatibility (otherwise you need a shared dictionary) + +## Approach + +I explored several options, the most popular one being [MessagePack][1]. However, I noticed that it did not give the best possible compression as compared to [LZMA][2] and [LZW][3]. + +At first I tried to apply the binary compression directly on a stringified JSON, then I realised that packing it first resulted in better compression. + +For small JS objects, LZW largely outperformed LZMA, but for the most part you'd probably be looking to compress large JSON data rather than small amounts (otherwise a simple stringify + base64 is sufficient). You can choose to use whatever codec suits you best. + +In addition, there is now support for [LZSTRING][5], although the URI encoding still uses urlsafe-base64 because LZSTRING still uses unsafe characters via their `compressToURIEncodedString` method - notably the [`+` character][6] + +Finally, I went with [urlsafe-base64][4] to encode it in a URL-friendly format. + +## TODO + +Find a way to improve bundle sizes for browser usage. + +[1]: http://msgpack.org/index.html +[2]: https://www.npmjs.com/package/lzma +[3]: https://www.npmjs.com/package/node-lzw +[4]: https://www.npmjs.com/package/urlsafe-base64 +[5]: http://pieroxy.net/blog/pages/lz-string/index.html +[6]: https://github.com/pieroxy/lz-string/blob/master/libs/lz-string.js#L15 + +[downloads-image]: https://img.shields.io/npm/dm/json-url.svg?style=flat-square +[downloads-url]: https://www.npmjs.com/package/json-url +[travis-image]: https://travis-ci.org/masotime/json-url.svg?bxeranch=master +[travis-url]: https://travis-ci.org/masotime/json-url +[daviddm-image]: https://david-dm.org/masotime/json-url.svg?theme=shields.io +[daviddm-url]: https://david-dm.org/masotime/json-url +[coverage-image]: https://coveralls.io/repos/github/masotime/json-url/badge.svg?branch=master +[coverage-url]: https://coveralls.io/github/masotime/json-url?branch=master ADDED public/json-url-master/dist/browser/json-url-lzstring.js Index: public/json-url-master/dist/browser/json-url-lzstring.js ================================================================== --- public/json-url-master/dist/browser/json-url-lzstring.js +++ public/json-url-master/dist/browser/json-url-lzstring.js @@ -0,0 +1,1 @@ +(window.webpackJsonpJsonUrl=window.webpackJsonpJsonUrl||[]).push([[0],{16:function(o,r,n){var e,t=function(){function o(o,r){if(!t[o]){t[o]={};for(var n=0;n>>8,n[2*e+1]=i%256}return n},decompressFromUint8Array:function(o){if(null==o)return s.decompress(o);for(var n=new Array(o.length/2),e=0,t=n.length;e>=1}else{for(t=1,e=0;e>=1}0==--l&&(l=Math.pow(2,h),h++),delete p[u]}else for(t=i[u],e=0;e>=1;0==--l&&(l=Math.pow(2,h),h++),i[a]=f++,u=String(c)}if(""!==u){if(Object.prototype.hasOwnProperty.call(p,u)){if(u.charCodeAt(0)<256){for(e=0;e>=1}else{for(t=1,e=0;e>=1}0==--l&&(l=Math.pow(2,h),h++),delete p[u]}else for(t=i[u],e=0;e>=1;0==--l&&(l=Math.pow(2,h),h++)}for(t=2,e=0;e>=1;for(;;){if(m<<=1,w==r-1){d.push(n(m));break}w++}return d.join("")},decompress:function(o){return null==o?"":""==o?null:s._decompress(o.length,32768,(function(r){return o.charCodeAt(r)}))},_decompress:function(o,n,e){var t,s,i,p,c,a,u,l=[],f=4,h=4,d=3,m="",w=[],v={val:e(0),position:n,index:1};for(t=0;t<3;t+=1)l[t]=t;for(i=0,c=Math.pow(2,2),a=1;a!=c;)p=v.val&v.position,v.position>>=1,0==v.position&&(v.position=n,v.val=e(v.index++)),i|=(p>0?1:0)*a,a<<=1;switch(i){case 0:for(i=0,c=Math.pow(2,8),a=1;a!=c;)p=v.val&v.position,v.position>>=1,0==v.position&&(v.position=n,v.val=e(v.index++)),i|=(p>0?1:0)*a,a<<=1;u=r(i);break;case 1:for(i=0,c=Math.pow(2,16),a=1;a!=c;)p=v.val&v.position,v.position>>=1,0==v.position&&(v.position=n,v.val=e(v.index++)),i|=(p>0?1:0)*a,a<<=1;u=r(i);break;case 2:return""}for(l[3]=u,s=u,w.push(u);;){if(v.index>o)return"";for(i=0,c=Math.pow(2,d),a=1;a!=c;)p=v.val&v.position,v.position>>=1,0==v.position&&(v.position=n,v.val=e(v.index++)),i|=(p>0?1:0)*a,a<<=1;switch(u=i){case 0:for(i=0,c=Math.pow(2,8),a=1;a!=c;)p=v.val&v.position,v.position>>=1,0==v.position&&(v.position=n,v.val=e(v.index++)),i|=(p>0?1:0)*a,a<<=1;l[h++]=r(i),u=h-1,f--;break;case 1:for(i=0,c=Math.pow(2,16),a=1;a!=c;)p=v.val&v.position,v.position>>=1,0==v.position&&(v.position=n,v.val=e(v.index++)),i|=(p>0?1:0)*a,a<<=1;l[h++]=r(i),u=h-1,f--;break;case 2:return w.join("")}if(0==f&&(f=Math.pow(2,d),d++),l[u])m=l[u];else{if(u!==h)return null;m=s+s.charAt(0)}w.push(m),l[h++]=s+m.charAt(0),s=m,0==--f&&(f=Math.pow(2,d),d++)}}};return s}();void 0!==(e=function(){return t}.call(r,n,r,o))&&(o.exports=e)}}]); ADDED public/json-url-master/dist/browser/json-url-lzw.js Index: public/json-url-master/dist/browser/json-url-lzw.js ================================================================== --- public/json-url-master/dist/browser/json-url-lzw.js +++ public/json-url-master/dist/browser/json-url-lzw.js @@ -0,0 +1,1 @@ +(window.webpackJsonpJsonUrl=window.webpackJsonpJsonUrl||[]).push([[1],{17:function(n,o,t){"use strict";var r=function(){};r.prototype.encode=function(n){for(var o,t={},r=(n+"").split(""),e=[],p=r[0],h=256,c=1;c1?t[p]:p.charCodeAt(0)),t[p+o]=h,h++,p=o);e.push(p.length>1?t[p]:p.charCodeAt(0));for(c=0;c + + + json-url demo page + + + +
+

json-url demo

+ Proudly written in vanilla.js™ +
+
+
+ + +
+
+ + +
+ +
+

Result

+ +
+ +
+

Decompression

+ +
+
+ + + + ADDED public/json-url-master/karma.conf.js Index: public/json-url-master/karma.conf.js ================================================================== --- public/json-url-master/karma.conf.js +++ public/json-url-master/karma.conf.js @@ -0,0 +1,41 @@ +/* eslint-disable import/unambiguous */ +const webpackConfig = require('./webpack.config.js'); + +// karma-webpack 2.x breaking fix +delete webpackConfig.entry; + +// note: these mods mutate the original config +const MODS = { // eslint-disable-line no-unused-vars + dontAliasLzma(config) { + config.module.rules + .filter(rule => rule.use && rule.use.loader === 'babel-loader') + .forEach(rule => rule.use.options.plugins + .filter(plugin => plugin[0] === 'module-resolver') + .forEach(plugin => plugin[1].alias && delete plugin[1].alias.lzma) + ); + return config; + }, + dontUglify(config) { + config.plugins = []; + return config; + } +} + +module.exports = config => { + config.set({ + frameworks: ['mocha'], + files: ['test/index.js'], + reporters: ['progress'], + port: 9876, + colors: true, + logLevel: config.LOG_DEBUG, + browsers: ['ChromeHeadless'], + autoWatch: false, // if true, Karma will not exit after the tests + concurrency: Infinity, + preprocessors: { + // add webpack as preprocessor + 'test/index.js': ['webpack'], + }, + webpack: webpackConfig + }); +} ADDED public/json-url-master/package-lock.json Index: public/json-url-master/package-lock.json ================================================================== --- public/json-url-master/package-lock.json +++ public/json-url-master/package-lock.json @@ -0,0 +1,14124 @@ +{ + "name": "json-url", + "version": "3.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/cli": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.8.4.tgz", + "integrity": "sha512-XXLgAm6LBbaNxaGhMAznXXaxtCWfuv6PIDJ9Alsy9JYTOh+j2jJz+L/162kkfU1j/pTSxK1xGmlwI4pdIMkoag==", + "dev": true, + "requires": { + "chokidar": "^2.1.8", + "commander": "^4.0.1", + "convert-source-map": "^1.1.0", + "fs-readdir-recursive": "^1.1.0", + "glob": "^7.0.0", + "lodash": "^4.17.13", + "make-dir": "^2.1.0", + "slash": "^2.0.0", + "source-map": "^0.5.0" + }, + "dependencies": { + "commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true + } + } + }, + "@babel/code-frame": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", + "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", + "dev": true, + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/compat-data": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.9.0.tgz", + "integrity": "sha512-zeFQrr+284Ekvd9e7KAX954LkapWiOmQtsfHirhxqfdlX6MEC32iRE+pqUGlYIBchdevaCwvzxWGSy/YBNI85g==", + "dev": true, + "requires": { + "browserslist": "^4.9.1", + "invariant": "^2.2.4", + "semver": "^5.5.0" + }, + "dependencies": { + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, + "requires": { + "loose-envify": "^1.0.0" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "@babel/core": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.0.tgz", + "integrity": "sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.9.0", + "@babel/helper-module-transforms": "^7.9.0", + "@babel/helpers": "^7.9.0", + "@babel/parser": "^7.9.0", + "@babel/template": "^7.8.6", + "@babel/traverse": "^7.9.0", + "@babel/types": "^7.9.0", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.2", + "lodash": "^4.17.13", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.8.3" + } + }, + "@babel/generator": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.5.tgz", + "integrity": "sha512-GbNIxVB3ZJe3tLeDm1HSn2AhuD/mVcyLDpgtLXa5tplmWrJdF/elxB56XNqCuD6szyNkDi6wuoKXln3QeBmCHQ==", + "dev": true, + "requires": { + "@babel/types": "^7.9.5", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", + "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.9.5" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", + "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", + "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/highlight": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz", + "integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.9.0", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.9.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.4.tgz", + "integrity": "sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA==", + "dev": true + }, + "@babel/template": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", + "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.6", + "@babel/types": "^7.8.6" + } + }, + "@babel/traverse": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.5.tgz", + "integrity": "sha512-c4gH3jsvSuGUezlP6rzSJ6jf8fYjLj3hsMZRx/nX0h+fmHN0w+ekubRrHPqnMec0meycA2nwCsJ7dC8IPem2FQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.9.5", + "@babel/helper-function-name": "^7.9.5", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/parser": "^7.9.0", + "@babel/types": "^7.9.5", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + } + }, + "@babel/types": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.5.tgz", + "integrity": "sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.9.5", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "json5": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.4.4.tgz", + "integrity": "sha512-53UOLK6TVNqKxf7RUh8NE851EHRxOOeVXKbK2bivdb+iziMyk03Sr4eaE9OELCbyZAAafAKPDwF2TPUES5QbxQ==", + "dev": true, + "requires": { + "@babel/types": "^7.4.4", + "jsesc": "^2.5.1", + "lodash": "^4.17.11", + "source-map": "^0.5.0", + "trim-right": "^1.0.1" + }, + "dependencies": { + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + } + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.8.3.tgz", + "integrity": "sha512-6o+mJrZBxOoEX77Ezv9zwW7WV8DdluouRKNY/IR5u/YTMuKHgugHOzYWlYvYLpLA9nPsQCAAASpCIbjI9Mv+Uw==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + }, + "dependencies": { + "@babel/types": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.5.tgz", + "integrity": "sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.9.5", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + } + } + }, + "@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.8.3.tgz", + "integrity": "sha512-5eFOm2SyFPK4Rh3XMMRDjN7lBH0orh3ss0g3rTYZnBQ+r6YPj7lgDyCvPphynHvUrobJmeMignBr6Acw9mAPlw==", + "dev": true, + "requires": { + "@babel/helper-explode-assignable-expression": "^7.8.3", + "@babel/types": "^7.8.3" + }, + "dependencies": { + "@babel/types": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.5.tgz", + "integrity": "sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.9.5", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + } + } + }, + "@babel/helper-compilation-targets": { + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.8.7.tgz", + "integrity": "sha512-4mWm8DCK2LugIS+p1yArqvG1Pf162upsIsjE7cNBjez+NjliQpVhj20obE520nao0o14DaTnFJv+Fw5a0JpoUw==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.8.6", + "browserslist": "^4.9.1", + "invariant": "^2.2.4", + "levenary": "^1.1.1", + "semver": "^5.5.0" + }, + "dependencies": { + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, + "requires": { + "loose-envify": "^1.0.0" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "@babel/helper-create-class-features-plugin": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.9.5.tgz", + "integrity": "sha512-IipaxGaQmW4TfWoXdqjY0TzoXQ1HRS0kPpEgvjosb3u7Uedcq297xFqDQiCcQtRRwzIMif+N1MLVI8C5a4/PAA==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.9.5", + "@babel/helper-member-expression-to-functions": "^7.8.3", + "@babel/helper-optimise-call-expression": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-replace-supers": "^7.8.6", + "@babel/helper-split-export-declaration": "^7.8.3" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.8.3" + } + }, + "@babel/helper-function-name": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", + "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.9.5" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", + "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + }, + "@babel/helper-split-export-declaration": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", + "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/highlight": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz", + "integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.9.0", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.9.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.4.tgz", + "integrity": "sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA==", + "dev": true + }, + "@babel/template": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", + "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.6", + "@babel/types": "^7.8.6" + } + }, + "@babel/types": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.5.tgz", + "integrity": "sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.9.5", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + } + } + }, + "@babel/helper-create-regexp-features-plugin": { + "version": "7.8.8", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.8.8.tgz", + "integrity": "sha512-LYVPdwkrQEiX9+1R29Ld/wTrmQu1SSKYnuOk3g0CkcZMA1p0gsNxJFj/3gBdaJ7Cg0Fnek5z0DsMULePP7Lrqg==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.8.3", + "@babel/helper-regex": "^7.8.3", + "regexpu-core": "^4.7.0" + } + }, + "@babel/helper-define-map": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.8.3.tgz", + "integrity": "sha512-PoeBYtxoZGtct3md6xZOCWPcKuMuk3IHhgxsRRNtnNShebf4C8YonTSblsK4tvDbm+eJAw2HAPOfCr+Q/YRG/g==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.8.3", + "@babel/types": "^7.8.3", + "lodash": "^4.17.13" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.8.3" + } + }, + "@babel/helper-function-name": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", + "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.9.5" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", + "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/highlight": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz", + "integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.9.0", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.9.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.4.tgz", + "integrity": "sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA==", + "dev": true + }, + "@babel/template": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", + "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.6", + "@babel/types": "^7.8.6" + } + }, + "@babel/types": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.5.tgz", + "integrity": "sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.9.5", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + } + } + }, + "@babel/helper-explode-assignable-expression": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.8.3.tgz", + "integrity": "sha512-N+8eW86/Kj147bO9G2uclsg5pwfs/fqqY5rwgIL7eTBklgXjcOJ3btzS5iM6AitJcftnY7pm2lGsrJVYLGjzIw==", + "dev": true, + "requires": { + "@babel/traverse": "^7.8.3", + "@babel/types": "^7.8.3" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.8.3" + } + }, + "@babel/generator": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.5.tgz", + "integrity": "sha512-GbNIxVB3ZJe3tLeDm1HSn2AhuD/mVcyLDpgtLXa5tplmWrJdF/elxB56XNqCuD6szyNkDi6wuoKXln3QeBmCHQ==", + "dev": true, + "requires": { + "@babel/types": "^7.9.5", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", + "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.9.5" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", + "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", + "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/highlight": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz", + "integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.9.0", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.9.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.4.tgz", + "integrity": "sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA==", + "dev": true + }, + "@babel/template": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", + "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.6", + "@babel/types": "^7.8.6" + } + }, + "@babel/traverse": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.5.tgz", + "integrity": "sha512-c4gH3jsvSuGUezlP6rzSJ6jf8fYjLj3hsMZRx/nX0h+fmHN0w+ekubRrHPqnMec0meycA2nwCsJ7dC8IPem2FQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.9.5", + "@babel/helper-function-name": "^7.9.5", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/parser": "^7.9.0", + "@babel/types": "^7.9.5", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + } + }, + "@babel/types": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.5.tgz", + "integrity": "sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.9.5", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + } + } + }, + "@babel/helper-function-name": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz", + "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.0.0", + "@babel/template": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", + "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.8.3.tgz", + "integrity": "sha512-ky1JLOjcDUtSc+xkt0xhYff7Z6ILTAHKmZLHPxAhOP0Nd77O+3nCsd6uSVYur6nJnCI029CrNbYlc0LoPfAPQg==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + }, + "dependencies": { + "@babel/types": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.5.tgz", + "integrity": "sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.9.5", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + } + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz", + "integrity": "sha512-fO4Egq88utkQFjbPrSHGmGLFqmrshs11d46WI+WZDESt7Wu7wN2G2Iu+NMMZJFDOVRHAMIkB5SNh30NtwCA7RA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + }, + "dependencies": { + "@babel/types": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.5.tgz", + "integrity": "sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.9.5", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + } + } + }, + "@babel/helper-module-imports": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz", + "integrity": "sha512-R0Bx3jippsbAEtzkpZ/6FIiuzOURPcMjHp+Z6xPe6DtApDJx+w7UYyOLanZqO8+wKR9G10s/FmHXvxaMd9s6Kg==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + }, + "dependencies": { + "@babel/types": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.5.tgz", + "integrity": "sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.9.5", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + } + } + }, + "@babel/helper-module-transforms": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.9.0.tgz", + "integrity": "sha512-0FvKyu0gpPfIQ8EkxlrAydOWROdHpBmiCiRwLkUiBGhCUPRRbVD2/tm3sFr/c/GWFrQ/ffutGUAnx7V0FzT2wA==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.8.3", + "@babel/helper-replace-supers": "^7.8.6", + "@babel/helper-simple-access": "^7.8.3", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/template": "^7.8.6", + "@babel/types": "^7.9.0", + "lodash": "^4.17.13" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.8.3" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", + "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/highlight": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz", + "integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.9.0", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.9.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.4.tgz", + "integrity": "sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA==", + "dev": true + }, + "@babel/template": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", + "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.6", + "@babel/types": "^7.8.6" + } + }, + "@babel/types": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.5.tgz", + "integrity": "sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.9.5", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + } + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz", + "integrity": "sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + }, + "dependencies": { + "@babel/types": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.5.tgz", + "integrity": "sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.9.5", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + } + } + }, + "@babel/helper-plugin-utils": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz", + "integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==", + "dev": true + }, + "@babel/helper-regex": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.8.3.tgz", + "integrity": "sha512-BWt0QtYv/cg/NecOAZMdcn/waj/5P26DR4mVLXfFtDokSR6fyuG0Pj+e2FqtSME+MqED1khnSMulkmGl8qWiUQ==", + "dev": true, + "requires": { + "lodash": "^4.17.13" + } + }, + "@babel/helper-remap-async-to-generator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.8.3.tgz", + "integrity": "sha512-kgwDmw4fCg7AVgS4DukQR/roGp+jP+XluJE5hsRZwxCYGg+Rv9wSGErDWhlI90FODdYfd4xG4AQRiMDjjN0GzA==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.8.3", + "@babel/helper-wrap-function": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.8.3", + "@babel/types": "^7.8.3" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.8.3" + } + }, + "@babel/generator": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.5.tgz", + "integrity": "sha512-GbNIxVB3ZJe3tLeDm1HSn2AhuD/mVcyLDpgtLXa5tplmWrJdF/elxB56XNqCuD6szyNkDi6wuoKXln3QeBmCHQ==", + "dev": true, + "requires": { + "@babel/types": "^7.9.5", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", + "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.9.5" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", + "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", + "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/highlight": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz", + "integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.9.0", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.9.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.4.tgz", + "integrity": "sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA==", + "dev": true + }, + "@babel/template": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", + "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.6", + "@babel/types": "^7.8.6" + } + }, + "@babel/traverse": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.5.tgz", + "integrity": "sha512-c4gH3jsvSuGUezlP6rzSJ6jf8fYjLj3hsMZRx/nX0h+fmHN0w+ekubRrHPqnMec0meycA2nwCsJ7dC8IPem2FQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.9.5", + "@babel/helper-function-name": "^7.9.5", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/parser": "^7.9.0", + "@babel/types": "^7.9.5", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + } + }, + "@babel/types": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.5.tgz", + "integrity": "sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.9.5", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + } + } + }, + "@babel/helper-replace-supers": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.8.6.tgz", + "integrity": "sha512-PeMArdA4Sv/Wf4zXwBKPqVj7n9UF/xg6slNRtZW84FM7JpE1CbG8B612FyM4cxrf4fMAMGO0kR7voy1ForHHFA==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.8.3", + "@babel/helper-optimise-call-expression": "^7.8.3", + "@babel/traverse": "^7.8.6", + "@babel/types": "^7.8.6" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.8.3" + } + }, + "@babel/generator": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.5.tgz", + "integrity": "sha512-GbNIxVB3ZJe3tLeDm1HSn2AhuD/mVcyLDpgtLXa5tplmWrJdF/elxB56XNqCuD6szyNkDi6wuoKXln3QeBmCHQ==", + "dev": true, + "requires": { + "@babel/types": "^7.9.5", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", + "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.9.5" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", + "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", + "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/highlight": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz", + "integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.9.0", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.9.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.4.tgz", + "integrity": "sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA==", + "dev": true + }, + "@babel/template": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", + "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.6", + "@babel/types": "^7.8.6" + } + }, + "@babel/traverse": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.5.tgz", + "integrity": "sha512-c4gH3jsvSuGUezlP6rzSJ6jf8fYjLj3hsMZRx/nX0h+fmHN0w+ekubRrHPqnMec0meycA2nwCsJ7dC8IPem2FQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.9.5", + "@babel/helper-function-name": "^7.9.5", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/parser": "^7.9.0", + "@babel/types": "^7.9.5", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + } + }, + "@babel/types": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.5.tgz", + "integrity": "sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.9.5", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + } + } + }, + "@babel/helper-simple-access": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz", + "integrity": "sha512-VNGUDjx5cCWg4vvCTR8qQ7YJYZ+HBjxOgXEl7ounz+4Sn7+LMD3CFrCTEU6/qXKbA2nKg21CwhhBzO0RpRbdCw==", + "dev": true, + "requires": { + "@babel/template": "^7.8.3", + "@babel/types": "^7.8.3" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.8.3" + } + }, + "@babel/highlight": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz", + "integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.9.0", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.9.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.4.tgz", + "integrity": "sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA==", + "dev": true + }, + "@babel/template": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", + "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.6", + "@babel/types": "^7.8.6" + } + }, + "@babel/types": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.5.tgz", + "integrity": "sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.9.5", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + } + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz", + "integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==", + "dev": true, + "requires": { + "@babel/types": "^7.4.4" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz", + "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==", + "dev": true + }, + "@babel/helper-wrap-function": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.8.3.tgz", + "integrity": "sha512-LACJrbUET9cQDzb6kG7EeD7+7doC3JNvUgTEQOx2qaO1fKlzE/Bf05qs9w1oXQMmXlPO65lC3Tq9S6gZpTErEQ==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.8.3", + "@babel/types": "^7.8.3" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.8.3" + } + }, + "@babel/generator": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.5.tgz", + "integrity": "sha512-GbNIxVB3ZJe3tLeDm1HSn2AhuD/mVcyLDpgtLXa5tplmWrJdF/elxB56XNqCuD6szyNkDi6wuoKXln3QeBmCHQ==", + "dev": true, + "requires": { + "@babel/types": "^7.9.5", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", + "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.9.5" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", + "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", + "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/highlight": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz", + "integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.9.0", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.9.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.4.tgz", + "integrity": "sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA==", + "dev": true + }, + "@babel/template": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", + "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.6", + "@babel/types": "^7.8.6" + } + }, + "@babel/traverse": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.5.tgz", + "integrity": "sha512-c4gH3jsvSuGUezlP6rzSJ6jf8fYjLj3hsMZRx/nX0h+fmHN0w+ekubRrHPqnMec0meycA2nwCsJ7dC8IPem2FQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.9.5", + "@babel/helper-function-name": "^7.9.5", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/parser": "^7.9.0", + "@babel/types": "^7.9.5", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + } + }, + "@babel/types": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.5.tgz", + "integrity": "sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.9.5", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + } + } + }, + "@babel/helpers": { + "version": "7.9.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.9.2.tgz", + "integrity": "sha512-JwLvzlXVPjO8eU9c/wF9/zOIN7X6h8DYf7mG4CiFRZRvZNKEF5dQ3H3V+ASkHoIB3mWhatgl5ONhyqHRI6MppA==", + "dev": true, + "requires": { + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.9.0", + "@babel/types": "^7.9.0" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.8.3" + } + }, + "@babel/generator": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.5.tgz", + "integrity": "sha512-GbNIxVB3ZJe3tLeDm1HSn2AhuD/mVcyLDpgtLXa5tplmWrJdF/elxB56XNqCuD6szyNkDi6wuoKXln3QeBmCHQ==", + "dev": true, + "requires": { + "@babel/types": "^7.9.5", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", + "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.9.5" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", + "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", + "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/highlight": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz", + "integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.9.0", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.9.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.4.tgz", + "integrity": "sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA==", + "dev": true + }, + "@babel/template": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", + "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.6", + "@babel/types": "^7.8.6" + } + }, + "@babel/traverse": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.5.tgz", + "integrity": "sha512-c4gH3jsvSuGUezlP6rzSJ6jf8fYjLj3hsMZRx/nX0h+fmHN0w+ekubRrHPqnMec0meycA2nwCsJ7dC8IPem2FQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.9.5", + "@babel/helper-function-name": "^7.9.5", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/parser": "^7.9.0", + "@babel/types": "^7.9.5", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + } + }, + "@babel/types": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.5.tgz", + "integrity": "sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.9.5", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + } + } + }, + "@babel/highlight": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", + "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/node": { + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/node/-/node-7.8.7.tgz", + "integrity": "sha512-o8cBT3cfRPLwoPh7VBYonSeZypIawGUeVfOIt1xSDgcDdirRGDPZ7/x+FLhhgQmKp3PKbz5Juh9/BNP4Jzrr9Q==", + "dev": true, + "requires": { + "@babel/register": "^7.8.3", + "commander": "^4.0.1", + "core-js": "^3.2.1", + "lodash": "^4.17.13", + "node-environment-flags": "^1.0.5", + "regenerator-runtime": "^0.13.4", + "resolve": "^1.13.1", + "v8flags": "^3.1.1" + }, + "dependencies": { + "@babel/register": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.9.0.tgz", + "integrity": "sha512-Tv8Zyi2J2VRR8g7pC5gTeIN8Ihultbmk0ocyNz8H2nEZbmhp1N6q0A1UGsQbDvGP/sNinQKUHf3SqXwqjtFv4Q==", + "dev": true, + "requires": { + "find-cache-dir": "^2.0.0", + "lodash": "^4.17.13", + "make-dir": "^2.1.0", + "pirates": "^4.0.0", + "source-map-support": "^0.5.16" + } + }, + "commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true + }, + "core-js": { + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz", + "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==", + "dev": true + }, + "regenerator-runtime": { + "version": "0.13.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", + "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==", + "dev": true + }, + "resolve": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.16.0.tgz", + "integrity": "sha512-LarL/PIKJvc09k1jaeT4kQb/8/7P+qV4qSnN2K80AES+OHdfZELAKVOBjxsvtToT/uLOfFbvYvKfZmV8cee7nA==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-support": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz", + "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + } + } + }, + "@babel/parser": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.4.tgz", + "integrity": "sha512-5pCS4mOsL+ANsFZGdvNLybx4wtqAZJ0MJjMHxvzI3bvIsz6sQvzW8XX92EYIkiPtIvcfG3Aj+Ir5VNyjnZhP7w==", + "dev": true + }, + "@babel/plugin-proposal-async-generator-functions": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.8.3.tgz", + "integrity": "sha512-NZ9zLv848JsV3hs8ryEh7Uaz/0KsmPLqv0+PdkDJL1cJy0K4kOCFa8zc1E3mp+RHPQcpdfb/6GovEsW4VDrOMw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-remap-async-to-generator": "^7.8.3", + "@babel/plugin-syntax-async-generators": "^7.8.0" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-proposal-class-properties": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.8.3.tgz", + "integrity": "sha512-EqFhbo7IosdgPgZggHaNObkmO1kNUe3slaKu54d5OWvy+p9QIKOzK1GAEpAIsZtWVtPXUHSMcT4smvDrCfY4AA==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-proposal-decorators": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.8.3.tgz", + "integrity": "sha512-e3RvdvS4qPJVTe288DlXjwKflpfy1hr0j5dz5WpIYYeP7vQZg2WfAEIp8k5/Lwis/m5REXEteIz6rrcDtXXG7w==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-decorators": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-proposal-do-expressions": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-do-expressions/-/plugin-proposal-do-expressions-7.8.3.tgz", + "integrity": "sha512-NoMcN+0+SS1DVswjDCfz+Jfm9ViOYuFtv1lm0QInEugbEXK2iH3jeSq38WmIiTP+2QKqo2zt8xku77gqHINZkw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-do-expressions": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-proposal-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.8.3.tgz", + "integrity": "sha512-NyaBbyLFXFLT9FP+zk0kYlUlA8XtCUbehs67F0nnEg7KICgMc2mNkIeu9TYhKzyXMkrapZFwAhXLdnt4IYHy1w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-dynamic-import": "^7.8.0" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-proposal-export-default-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.8.3.tgz", + "integrity": "sha512-PYtv2S2OdCdp7GSPDg5ndGZFm9DmWFvuLoS5nBxZCgOBggluLnhTScspJxng96alHQzPyrrHxvC9/w4bFuspeA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-export-default-from": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-proposal-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-WKK+9jz6TWUTX1uej9/EUVOmM1sK7aHv6bZyxbUV3NJjbiIZRqJITeXGMo7D631J72PEnIORh5VOlFCSlrLicg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-proposal-function-bind": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-function-bind/-/plugin-proposal-function-bind-7.8.3.tgz", + "integrity": "sha512-6q7VAHJQa9x4P6Lm6h6KHoJUEhx2r1buFKseHICe0ogb1LWxducO4tsQp3hd/7BVBo485YBsn6tJnpuwWm/9cA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-function-bind": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-proposal-function-sent": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-function-sent/-/plugin-proposal-function-sent-7.8.3.tgz", + "integrity": "sha512-lu9wQjLnXd6Zy6eBKr0gE175xfD+da1rv2wOWEnZlD5KIxl894Tg34ppZ7ANR0jzQJMn+7pGuzSdy6JK4zGtKg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-wrap-function": "^7.8.3", + "@babel/plugin-syntax-function-sent": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-proposal-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.8.3.tgz", + "integrity": "sha512-KGhQNZ3TVCQG/MjRbAUwuH+14y9q0tpxs1nWWs3pbSleRdDro9SAMMDyye8HhY1gqZ7/NqIc8SKhya0wRDgP1Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.0" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-proposal-logical-assignment-operators": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.8.3.tgz", + "integrity": "sha512-TLPLojGZYBeeoesO2NQIMLUJKD9N5oJlxG6iHLx7l7EvNQP5DfzeyxdI2lMPo5I7ih4Jv/vxrlwIPf6aJw422Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-TS9MlfzXpXKt6YYomudb/KU7nQI6/xnapG6in1uZxoxDghuSMZsPb6D2fyUwNYSAp4l1iR7QtFOjkqcRYcUsfw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-proposal-numeric-separator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.8.3.tgz", + "integrity": "sha512-jWioO1s6R/R+wEHizfaScNsAx+xKgwTLNXSh7tTC4Usj3ItsPEhYkEpU4h+lpnBwq7NBVOJXfO6cRFYcX69JUQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.9.5.tgz", + "integrity": "sha512-VP2oXvAf7KCYTthbUHwBlewbl1Iq059f6seJGsxMizaCdgHIeczOr7FBqELhSqfkIl04Fi8okzWzl63UKbQmmg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.0", + "@babel/plugin-transform-parameters": "^7.9.5" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-proposal-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-0gkX7J7E+AtAw9fcwlVQj8peP61qhdg/89D5swOkjYbkboA2CVckn3kiyum1DE0wskGb7KJJxBdyEBApDLLVdw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.0" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-proposal-optional-chaining": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.9.0.tgz", + "integrity": "sha512-NDn5tu3tcv4W30jNhmc2hyD5c56G6cXx4TesJubhxrJeCvuuMpttxr0OnNCqbZGhFjLrg+NIhxxC+BK5F6yS3w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.0" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-proposal-pipeline-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-pipeline-operator/-/plugin-proposal-pipeline-operator-7.8.3.tgz", + "integrity": "sha512-Z0qV3aUYoLUAnVLdfLTlz/GJYfcrbX7Mhrp897Twik29wQseAFAAXQ4TPvN1oswVBHdN74sLPIn9HVfTXtjuQA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-pipeline-operator": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-proposal-throw-expressions": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-throw-expressions/-/plugin-proposal-throw-expressions-7.8.3.tgz", + "integrity": "sha512-tH40s9JnoR+r45ZXKWW+PC5xzPQfVJix3pR1D8Ty5l9sn5NnrbZUzw8MtnNxu/Bz7p0imyeSYj9FQVccEymOEg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-throw-expressions": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-proposal-unicode-property-regex": { + "version": "7.8.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.8.8.tgz", + "integrity": "sha512-EVhjVsMpbhLw9ZfHWSx2iy13Q8Z/eg8e8ccVWt23sWQK5l1UdkoLJPN5w69UA4uITGBnEZD2JOe4QOHycYKv8A==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.8.8", + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-syntax-decorators": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.8.3.tgz", + "integrity": "sha512-8Hg4dNNT9/LcA1zQlfwuKR8BUc/if7Q7NkTam9sGTcJphLwpf2g4S42uhspQrIrR+dpzE0dtTqBVFoHl8GtnnQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-syntax-do-expressions": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-do-expressions/-/plugin-syntax-do-expressions-7.8.3.tgz", + "integrity": "sha512-puRiUTVDQ69iRX41eeVWqOftZK31waWqZfwKB/TGzPfgi7097twx/DpwfOfyqEGqYtvpQF3jpHwT6UBzvSyAjw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-syntax-export-default-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.8.3.tgz", + "integrity": "sha512-a1qnnsr73KLNIQcQlcQ4ZHxqqfBKM6iNQZW2OMTyxNbA2WC7SHWHtGVpFzWtQAuS2pspkWVzdEBXXx8Ik0Za4w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-syntax-function-bind": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-function-bind/-/plugin-syntax-function-bind-7.8.3.tgz", + "integrity": "sha512-gEYag4Q3CfqlQcJQQw/KSWdV2husGOnIsOsRlyzkoaNqj2V/V/CSdSJDCGSl67oJ1bdIYP6TjORWPH561dSJpA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-syntax-function-sent": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-function-sent/-/plugin-syntax-function-sent-7.8.3.tgz", + "integrity": "sha512-NNEutF0x2PdWYij2bmf/i50dSq4SUdgFij4BZwj3I4qDZgql3dlFJRyvwGHAhwKYElUKHaP0wQ/yO1d/enpJaw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-syntax-import-meta": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.8.3.tgz", + "integrity": "sha512-vYiGd4wQ9gx0Lngb7+bPCwQXGK/PR6FeTIJ+TIOlq+OfOKG/kCAOO2+IBac3oMM9qV7/fU76hfcqxUaLKZf1hQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.8.3.tgz", + "integrity": "sha512-Zpg2Sgc++37kuFl6ppq2Q7Awc6E6AIW671x5PY8E/f7MCIyPPGK/EoeZXvvY3P42exZ3Q4/t3YOzP/HiN79jDg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.8.3.tgz", + "integrity": "sha512-H7dCMAdN83PcCmqmkHB5dtp+Xa9a6LKSvA2hiFBC/5alSHxM5VgWZXFqDi0YFe8XNGT6iCa+z4V4zSt/PdZ7Dw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-syntax-pipeline-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-pipeline-operator/-/plugin-syntax-pipeline-operator-7.8.3.tgz", + "integrity": "sha512-GhiBvlXZLWeP+MjKaEv33KmiR/QMCv4iCwz1AuuAp7pHxBvOxxyQmIPukh+N/py6PRLYG10bvRCNeenG34QbDA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-syntax-throw-expressions": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-throw-expressions/-/plugin-syntax-throw-expressions-7.8.3.tgz", + "integrity": "sha512-Mv3shY1i7ZssY4OY+eLZJAmNCwqTcpv2qOKO9x6irELSygfKWVSMXk0igJsA9UhU4hOdw0qMGkjj9TAk4MqzwQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-syntax-top-level-await": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.8.3.tgz", + "integrity": "sha512-kwj1j9lL/6Wd0hROD3b/OZZ7MSrZLqqn9RAZ5+cYYsflQ9HZBIKCUkr3+uL1MEJ1NePiUbf98jjiMQSv0NMR9g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-arrow-functions": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.8.3.tgz", + "integrity": "sha512-0MRF+KC8EqH4dbuITCWwPSzsyO3HIWWlm30v8BbbpOrS1B++isGxPnnuq/IZvOX5J2D/p7DQalQm+/2PnlKGxg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-async-to-generator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.8.3.tgz", + "integrity": "sha512-imt9tFLD9ogt56Dd5CI/6XgpukMwd/fLGSrix2httihVe7LOGVPhyhMh1BU5kDM7iHD08i8uUtmV2sWaBFlHVQ==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-remap-async-to-generator": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.8.3.tgz", + "integrity": "sha512-vo4F2OewqjbB1+yaJ7k2EJFHlTP3jR634Z9Cj9itpqNjuLXvhlVxgnjsHsdRgASR8xYDrx6onw4vW5H6We0Jmg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-block-scoping": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.8.3.tgz", + "integrity": "sha512-pGnYfm7RNRgYRi7bids5bHluENHqJhrV4bCZRwc5GamaWIIs07N4rZECcmJL6ZClwjDz1GbdMZFtPs27hTB06w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "lodash": "^4.17.13" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-classes": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.9.5.tgz", + "integrity": "sha512-x2kZoIuLC//O5iA7PEvecB105o7TLzZo8ofBVhP79N+DO3jaX+KYfww9TQcfBEZD0nikNyYcGB1IKtRq36rdmg==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.8.3", + "@babel/helper-define-map": "^7.8.3", + "@babel/helper-function-name": "^7.9.5", + "@babel/helper-optimise-call-expression": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-replace-supers": "^7.8.6", + "@babel/helper-split-export-declaration": "^7.8.3", + "globals": "^11.1.0" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.8.3" + } + }, + "@babel/helper-function-name": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", + "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.9.5" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", + "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + }, + "@babel/helper-split-export-declaration": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", + "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/highlight": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz", + "integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.9.0", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.9.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.4.tgz", + "integrity": "sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA==", + "dev": true + }, + "@babel/template": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", + "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.6", + "@babel/types": "^7.8.6" + } + }, + "@babel/types": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.5.tgz", + "integrity": "sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.9.5", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + } + } + }, + "@babel/plugin-transform-computed-properties": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.8.3.tgz", + "integrity": "sha512-O5hiIpSyOGdrQZRQ2ccwtTVkgUDBBiCuK//4RJ6UfePllUTCENOzKxfh6ulckXKc0DixTFLCfb2HVkNA7aDpzA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-destructuring": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.9.5.tgz", + "integrity": "sha512-j3OEsGel8nHL/iusv/mRd5fYZ3DrOxWC82x0ogmdN/vHfAP4MYw+AFKYanzWlktNwikKvlzUV//afBW5FTp17Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-dotall-regex": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.8.3.tgz", + "integrity": "sha512-kLs1j9Nn4MQoBYdRXH6AeaXMbEJFaFu/v1nQkvib6QzTj8MZI5OQzqmD83/2jEM1z0DLilra5aWO5YpyC0ALIw==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-duplicate-keys": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.8.3.tgz", + "integrity": "sha512-s8dHiBUbcbSgipS4SMFuWGqCvyge5V2ZeAWzR6INTVC3Ltjig/Vw1G2Gztv0vU/hRG9X8IvKvYdoksnUfgXOEQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.8.3.tgz", + "integrity": "sha512-zwIpuIymb3ACcInbksHaNcR12S++0MDLKkiqXHl3AzpgdKlFNhog+z/K0+TGW+b0w5pgTq4H6IwV/WhxbGYSjQ==", + "dev": true, + "requires": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-for-of": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.9.0.tgz", + "integrity": "sha512-lTAnWOpMwOXpyDx06N+ywmF3jNbafZEqZ96CGYabxHrxNX8l5ny7dt4bK/rGwAh9utyP2b2Hv7PlZh1AAS54FQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-function-name": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.8.3.tgz", + "integrity": "sha512-rO/OnDS78Eifbjn5Py9v8y0aR+aSYhDhqAwVfsTl0ERuMZyr05L1aFSCJnbv2mmsLkit/4ReeQ9N2BgLnOcPCQ==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.8.3" + } + }, + "@babel/helper-function-name": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", + "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.9.5" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", + "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + }, + "@babel/highlight": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz", + "integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.9.0", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.9.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.4.tgz", + "integrity": "sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA==", + "dev": true + }, + "@babel/template": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", + "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.6", + "@babel/types": "^7.8.6" + } + }, + "@babel/types": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.5.tgz", + "integrity": "sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.9.5", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + } + } + }, + "@babel/plugin-transform-literals": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.8.3.tgz", + "integrity": "sha512-3Tqf8JJ/qB7TeldGl+TT55+uQei9JfYaregDcEAyBZ7akutriFrt6C/wLYIer6OYhleVQvH/ntEhjE/xMmy10A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-member-expression-literals": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.8.3.tgz", + "integrity": "sha512-3Wk2EXhnw+rP+IDkK6BdtPKsUE5IeZ6QOGrPYvw52NwBStw9V1ZVzxgK6fSKSxqUvH9eQPR3tm3cOq79HlsKYA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-modules-amd": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.9.0.tgz", + "integrity": "sha512-vZgDDF003B14O8zJy0XXLnPH4sg+9X5hFBBGN1V+B2rgrB+J2xIypSN6Rk9imB2hSTHQi5OHLrFWsZab1GMk+Q==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.9.0", + "@babel/helper-plugin-utils": "^7.8.3", + "babel-plugin-dynamic-import-node": "^2.3.0" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + }, + "babel-plugin-dynamic-import-node": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz", + "integrity": "sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ==", + "dev": true, + "requires": { + "object.assign": "^4.1.0" + } + } + } + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.9.0.tgz", + "integrity": "sha512-qzlCrLnKqio4SlgJ6FMMLBe4bySNis8DFn1VkGmOcxG9gqEyPIOzeQrA//u0HAKrWpJlpZbZMPB1n/OPa4+n8g==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.9.0", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-simple-access": "^7.8.3", + "babel-plugin-dynamic-import-node": "^2.3.0" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + }, + "babel-plugin-dynamic-import-node": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz", + "integrity": "sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ==", + "dev": true, + "requires": { + "object.assign": "^4.1.0" + } + } + } + }, + "@babel/plugin-transform-modules-systemjs": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.9.0.tgz", + "integrity": "sha512-FsiAv/nao/ud2ZWy4wFacoLOm5uxl0ExSQ7ErvP7jpoihLR6Cq90ilOFyX9UXct3rbtKsAiZ9kFt5XGfPe/5SQ==", + "dev": true, + "requires": { + "@babel/helper-hoist-variables": "^7.8.3", + "@babel/helper-module-transforms": "^7.9.0", + "@babel/helper-plugin-utils": "^7.8.3", + "babel-plugin-dynamic-import-node": "^2.3.0" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + }, + "babel-plugin-dynamic-import-node": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz", + "integrity": "sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ==", + "dev": true, + "requires": { + "object.assign": "^4.1.0" + } + } + } + }, + "@babel/plugin-transform-modules-umd": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.9.0.tgz", + "integrity": "sha512-uTWkXkIVtg/JGRSIABdBoMsoIeoHQHPTL0Y2E7xf5Oj7sLqwVsNXOkNk0VJc7vF0IMBsPeikHxFjGe+qmwPtTQ==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.9.0", + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.8.3.tgz", + "integrity": "sha512-f+tF/8UVPU86TrCb06JoPWIdDpTNSGGcAtaD9mLP0aYGA0OS0j7j7DHJR0GTFrUZPUU6loZhbsVZgTh0N+Qdnw==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.8.3" + } + }, + "@babel/plugin-transform-new-target": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.8.3.tgz", + "integrity": "sha512-QuSGysibQpyxexRyui2vca+Cmbljo8bcRckgzYV4kRIsHpVeyeC3JDO63pY+xFZ6bWOBn7pfKZTqV4o/ix9sFw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-object-super": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.8.3.tgz", + "integrity": "sha512-57FXk+gItG/GejofIyLIgBKTas4+pEU47IXKDBWFTxdPd7F80H8zybyAY7UoblVfBhBGs2EKM+bJUu2+iUYPDQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-replace-supers": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-parameters": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.9.5.tgz", + "integrity": "sha512-0+1FhHnMfj6lIIhVvS4KGQJeuhe1GI//h5uptK4PvLt+BGBxsoUJbd3/IW002yk//6sZPlFgsG1hY6OHLcy6kA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-get-function-arity": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", + "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + }, + "@babel/types": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.5.tgz", + "integrity": "sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.9.5", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + } + } + }, + "@babel/plugin-transform-property-literals": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.8.3.tgz", + "integrity": "sha512-uGiiXAZMqEoQhRWMK17VospMZh5sXWg+dlh2soffpkAl96KAm+WZuJfa6lcELotSRmooLqg0MWdH6UUq85nmmg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-regenerator": { + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.8.7.tgz", + "integrity": "sha512-TIg+gAl4Z0a3WmD3mbYSk+J9ZUH6n/Yc57rtKRnlA/7rcCvpekHXe0CMZHP1gYp7/KLe9GHTuIba0vXmls6drA==", + "dev": true, + "requires": { + "regenerator-transform": "^0.14.2" + } + }, + "@babel/plugin-transform-reserved-words": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.8.3.tgz", + "integrity": "sha512-mwMxcycN3omKFDjDQUl+8zyMsBfjRFr0Zn/64I41pmjv4NJuqcYlEtezwYtw9TFd9WR1vN5kiM+O0gMZzO6L0A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-runtime": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.9.0.tgz", + "integrity": "sha512-pUu9VSf3kI1OqbWINQ7MaugnitRss1z533436waNXp+0N3ur3zfut37sXiQMxkuCF4VUjwZucen/quskCh7NHw==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "resolve": "^1.8.1", + "semver": "^5.5.1" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-shorthand-properties": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.8.3.tgz", + "integrity": "sha512-I9DI6Odg0JJwxCHzbzW08ggMdCezoWcuQRz3ptdudgwaHxTjxw5HgdFJmZIkIMlRymL6YiZcped4TTCB0JcC8w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.8.3.tgz", + "integrity": "sha512-CkuTU9mbmAoFOI1tklFWYYbzX5qCIZVXPVy0jpXgGwkplCndQAa58s2jr66fTeQnA64bDox0HL4U56CFYoyC7g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-sticky-regex": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.8.3.tgz", + "integrity": "sha512-9Spq0vGCD5Bb4Z/ZXXSK5wbbLFMG085qd2vhL1JYu1WcQ5bXqZBAYRzU1d+p79GcHs2szYv5pVQCX13QgldaWw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/helper-regex": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-template-literals": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.8.3.tgz", + "integrity": "sha512-820QBtykIQOLFT8NZOcTRJ1UNuztIELe4p9DCgvj4NK+PwluSJ49we7s9FB1HIGNIYT7wFUJ0ar2QpCDj0escQ==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-typeof-symbol": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.8.4.tgz", + "integrity": "sha512-2QKyfjGdvuNfHsb7qnBBlKclbD4CfshH2KvDabiijLMGXPHJXGxtDzwIF7bQP+T0ysw8fYTtxPafgfs/c1Lrqg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/plugin-transform-unicode-regex": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.8.3.tgz", + "integrity": "sha512-+ufgJjYdmWfSQ+6NS9VGUR2ns8cjJjYbrbi11mZBTaWm+Fui/ncTLFF28Ei1okavY+xkojGr1eJxNsWYeA5aZw==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + } + } + }, + "@babel/polyfill": { + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/polyfill/-/polyfill-7.8.7.tgz", + "integrity": "sha512-LeSfP9bNZH2UOZgcGcZ0PIHUt1ZuHub1L3CVmEyqLxCeDLm4C5Gi8jRH8ZX2PNpDhQCo0z6y/+DIs2JlliXW8w==", + "dev": true, + "requires": { + "core-js": "^2.6.5", + "regenerator-runtime": "^0.13.4" + }, + "dependencies": { + "core-js": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", + "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", + "dev": true + }, + "regenerator-runtime": { + "version": "0.13.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", + "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==", + "dev": true + } + } + }, + "@babel/preset-env": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.9.5.tgz", + "integrity": "sha512-eWGYeADTlPJH+wq1F0wNfPbVS1w1wtmMJiYk55Td5Yu28AsdR9AsC97sZ0Qq8fHqQuslVSIYSGJMcblr345GfQ==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.9.0", + "@babel/helper-compilation-targets": "^7.8.7", + "@babel/helper-module-imports": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-proposal-async-generator-functions": "^7.8.3", + "@babel/plugin-proposal-dynamic-import": "^7.8.3", + "@babel/plugin-proposal-json-strings": "^7.8.3", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-proposal-numeric-separator": "^7.8.3", + "@babel/plugin-proposal-object-rest-spread": "^7.9.5", + "@babel/plugin-proposal-optional-catch-binding": "^7.8.3", + "@babel/plugin-proposal-optional-chaining": "^7.9.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.8.3", + "@babel/plugin-syntax-async-generators": "^7.8.0", + "@babel/plugin-syntax-dynamic-import": "^7.8.0", + "@babel/plugin-syntax-json-strings": "^7.8.0", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0", + "@babel/plugin-syntax-numeric-separator": "^7.8.0", + "@babel/plugin-syntax-object-rest-spread": "^7.8.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.0", + "@babel/plugin-syntax-optional-chaining": "^7.8.0", + "@babel/plugin-syntax-top-level-await": "^7.8.3", + "@babel/plugin-transform-arrow-functions": "^7.8.3", + "@babel/plugin-transform-async-to-generator": "^7.8.3", + "@babel/plugin-transform-block-scoped-functions": "^7.8.3", + "@babel/plugin-transform-block-scoping": "^7.8.3", + "@babel/plugin-transform-classes": "^7.9.5", + "@babel/plugin-transform-computed-properties": "^7.8.3", + "@babel/plugin-transform-destructuring": "^7.9.5", + "@babel/plugin-transform-dotall-regex": "^7.8.3", + "@babel/plugin-transform-duplicate-keys": "^7.8.3", + "@babel/plugin-transform-exponentiation-operator": "^7.8.3", + "@babel/plugin-transform-for-of": "^7.9.0", + "@babel/plugin-transform-function-name": "^7.8.3", + "@babel/plugin-transform-literals": "^7.8.3", + "@babel/plugin-transform-member-expression-literals": "^7.8.3", + "@babel/plugin-transform-modules-amd": "^7.9.0", + "@babel/plugin-transform-modules-commonjs": "^7.9.0", + "@babel/plugin-transform-modules-systemjs": "^7.9.0", + "@babel/plugin-transform-modules-umd": "^7.9.0", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.8.3", + "@babel/plugin-transform-new-target": "^7.8.3", + "@babel/plugin-transform-object-super": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.9.5", + "@babel/plugin-transform-property-literals": "^7.8.3", + "@babel/plugin-transform-regenerator": "^7.8.7", + "@babel/plugin-transform-reserved-words": "^7.8.3", + "@babel/plugin-transform-shorthand-properties": "^7.8.3", + "@babel/plugin-transform-spread": "^7.8.3", + "@babel/plugin-transform-sticky-regex": "^7.8.3", + "@babel/plugin-transform-template-literals": "^7.8.3", + "@babel/plugin-transform-typeof-symbol": "^7.8.4", + "@babel/plugin-transform-unicode-regex": "^7.8.3", + "@babel/preset-modules": "^0.1.3", + "@babel/types": "^7.9.5", + "browserslist": "^4.9.1", + "core-js-compat": "^3.6.2", + "invariant": "^2.2.2", + "levenary": "^1.1.1", + "semver": "^5.5.0" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + }, + "@babel/types": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.5.tgz", + "integrity": "sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.9.5", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + } + } + }, + "@babel/preset-modules": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.3.tgz", + "integrity": "sha512-Ra3JXOHBq2xd56xSF7lMKXdjBn3T772Y1Wet3yWnkDly9zHvJki029tAFzvAAK5cf4YV3yoxuP61crYRol6SVg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", + "@babel/plugin-transform-dotall-regex": "^7.4.4", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + } + }, + "@babel/register": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.6.2.tgz", + "integrity": "sha512-xgZk2LRZvt6i2SAUWxc7ellk4+OYRgS3Zpsnr13nMS1Qo25w21Uu8o6vTOAqNaxiqrnv30KTYzh9YWY2k21CeQ==", + "dev": true, + "requires": { + "find-cache-dir": "^2.0.0", + "lodash": "^4.17.13", + "mkdirp": "^0.5.1", + "pirates": "^4.0.0", + "source-map-support": "^0.5.9" + } + }, + "@babel/runtime": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.6.3.tgz", + "integrity": "sha512-kq6anf9JGjW8Nt5rYfEuGRaEAaH1mkv3Bbu6rYvLOpPh/RusSJXuKPEAoZ7L7gybZkchE8+NV5g9vKF4AGAtsA==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.2" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", + "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==", + "dev": true + } + } + }, + "@babel/runtime-corejs2": { + "version": "7.9.2", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.9.2.tgz", + "integrity": "sha512-ayjSOxuK2GaSDJFCtLgHnYjuMyIpViNujWrZo8GUpN60/n7juzJKK5yOo6RFVb0zdU9ACJFK+MsZrUnj3OmXMw==", + "requires": { + "core-js": "^2.6.5", + "regenerator-runtime": "^0.13.4" + }, + "dependencies": { + "core-js": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", + "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==" + }, + "regenerator-runtime": { + "version": "0.13.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", + "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==" + } + } + }, + "@babel/template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.4.tgz", + "integrity": "sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.4.4", + "@babel/types": "^7.4.4" + } + }, + "@babel/traverse": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.4.4.tgz", + "integrity": "sha512-Gw6qqkw/e6AGzlyj9KnkabJX7VcubqPtkUQVAwkc0wUMldr3A/hezNB3Rc5eIvId95iSGkGIOe5hh1kMKf951A==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.4.4", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.4.4", + "@babel/parser": "^7.4.4", + "@babel/types": "^7.4.4", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.11" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + } + } + }, + "@babel/types": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.4.tgz", + "integrity": "sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.11", + "to-fast-properties": "^2.0.0" + }, + "dependencies": { + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + } + } + }, + "@types/component-emitter": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.10.tgz", + "integrity": "sha512-bsjleuRKWmGqajMerkzox19aGbscQX5rmmvvXl3wlIp5gMG1HgkiwPxsN5p070fBDKTNSPgojVbuY1+HWMbFhg==", + "dev": true + }, + "@types/cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-y7mImlc/rNkvCRmg8gC3/lj87S7pTUIJ6QGjwHR9WQJcFs+ZMTOaoPrkdFA/YdbuqVEmEbb5RdhVxMkAcgOnpg==", + "dev": true + }, + "@types/cors": { + "version": "2.8.10", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.10.tgz", + "integrity": "sha512-C7srjHiVG3Ey1nR6d511dtDkCEjxuN9W1HWAEjGq8kpcwmNM6JJkpC0xvabM7BXTG2wDq8Eu33iH9aQKa7IvLQ==", + "dev": true + }, + "@types/node": { + "version": "14.14.41", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.41.tgz", + "integrity": "sha512-dueRKfaJL4RTtSa7bWeTK1M+VH+Gns73oCgzvYfHZywRCoPSd8EkXBL0mZ9unPTveBn+D9phZBaxuzpwjWkW0g==", + "dev": true + }, + "@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, + "@webassemblyjs/ast": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", + "integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==", + "dev": true, + "requires": { + "@webassemblyjs/helper-module-context": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/wast-parser": "1.9.0" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz", + "integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==", + "dev": true + }, + "@webassemblyjs/helper-api-error": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz", + "integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==", + "dev": true + }, + "@webassemblyjs/helper-buffer": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz", + "integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==", + "dev": true + }, + "@webassemblyjs/helper-code-frame": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz", + "integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==", + "dev": true, + "requires": { + "@webassemblyjs/wast-printer": "1.9.0" + } + }, + "@webassemblyjs/helper-fsm": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz", + "integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==", + "dev": true + }, + "@webassemblyjs/helper-module-context": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz", + "integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0" + } + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz", + "integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==", + "dev": true + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz", + "integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0" + } + }, + "@webassemblyjs/ieee754": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz", + "integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==", + "dev": true, + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz", + "integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==", + "dev": true, + "requires": { + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/utf8": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz", + "integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==", + "dev": true + }, + "@webassemblyjs/wasm-edit": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz", + "integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/helper-wasm-section": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0", + "@webassemblyjs/wasm-opt": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0", + "@webassemblyjs/wast-printer": "1.9.0" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz", + "integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/ieee754": "1.9.0", + "@webassemblyjs/leb128": "1.9.0", + "@webassemblyjs/utf8": "1.9.0" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz", + "integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz", + "integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-api-error": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/ieee754": "1.9.0", + "@webassemblyjs/leb128": "1.9.0", + "@webassemblyjs/utf8": "1.9.0" + } + }, + "@webassemblyjs/wast-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz", + "integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/floating-point-hex-parser": "1.9.0", + "@webassemblyjs/helper-api-error": "1.9.0", + "@webassemblyjs/helper-code-frame": "1.9.0", + "@webassemblyjs/helper-fsm": "1.9.0", + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz", + "integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/wast-parser": "1.9.0", + "@xtuc/long": "4.2.2" + } + }, + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "dev": true, + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + }, + "dependencies": { + "mime-db": { + "version": "1.47.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz", + "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==", + "dev": true + }, + "mime-types": { + "version": "2.1.30", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz", + "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==", + "dev": true, + "requires": { + "mime-db": "1.47.0" + } + } + } + }, + "acorn": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", + "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==", + "dev": true + }, + "acorn-jsx": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.1.0.tgz", + "integrity": "sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw==", + "dev": true + }, + "ajv": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", + "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", + "dev": true, + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "dependencies": { + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + } + } + }, + "ajv-errors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", + "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", + "dev": true + }, + "ajv-keywords": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", + "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", + "dev": true + }, + "align-text": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", + "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", + "dev": true, + "requires": { + "kind-of": "^3.0.2", + "longest": "^1.0.1", + "repeat-string": "^1.5.2" + } + }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "ansi-escapes": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.2.1.tgz", + "integrity": "sha512-Cg3ymMAdN10wOk/VYfLV7KCQyv7EDirJ64500sU7n9UlmioEtDuU5Gd+hj73hXSU/ex7tHJSssmyftDdkMLO8Q==", + "dev": true, + "requires": { + "type-fest": "^0.5.2" + } + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "append-transform": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz", + "integrity": "sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==", + "dev": true, + "requires": { + "default-require-extensions": "^2.0.0" + } + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true + }, + "archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", + "dev": true + }, + "argparse": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", + "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true + }, + "array-includes": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", + "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.7.0" + } + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "asn1.js": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", + "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", + "dev": true, + "requires": { + "object-assign": "^4.1.1", + "util": "0.10.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "requires": { + "inherits": "2.0.1" + } + } + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, + "async": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.5.0.tgz", + "integrity": "sha512-e+lJAJeNWuPCNyxZKOBdaJGyLGHugXVQtrAwtuAe2vhxTYxFTKE73p8JuTmdH0qdQZtDvI4dhJwjZc5zsfIsYw==", + "dev": true, + "requires": { + "lodash": "^4.14.0" + } + }, + "async-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", + "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true + }, + "aws4": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", + "dev": true + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + } + }, + "babel-eslint": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-9.0.0.tgz", + "integrity": "sha512-itv1MwE3TMbY0QtNfeL7wzak1mV47Uy+n6HtSOO4Xd7rvmO+tsGQSgyOEEgo6Y2vHZKZphaoelNeSVj4vkLA1g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", + "eslint-scope": "3.7.1", + "eslint-visitor-keys": "^1.0.0" + }, + "dependencies": { + "eslint-scope": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", + "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + } + } + }, + "babel-loader": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.1.0.tgz", + "integrity": "sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw==", + "dev": true, + "requires": { + "find-cache-dir": "^2.1.0", + "loader-utils": "^1.4.0", + "mkdirp": "^0.5.3", + "pify": "^4.0.1", + "schema-utils": "^2.6.5" + }, + "dependencies": { + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true + }, + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + } + } + }, + "babel-messages": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", + "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-add-module-exports": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/babel-plugin-add-module-exports/-/babel-plugin-add-module-exports-0.2.1.tgz", + "integrity": "sha1-mumh9KjcZ/DN7E9K7aHkOl/2XiU=", + "dev": true + }, + "babel-plugin-dynamic-import-node": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-1.1.0.tgz", + "integrity": "sha512-tTfZbM9Ecwj3GK50mnPrUpinTwA4xXmDiQGCk/aBYbvl1+X8YqldK86wZ1owVJ4u3mrKbRlXMma80J18qwiaTQ==", + "dev": true, + "requires": { + "babel-plugin-syntax-dynamic-import": "^6.18.0", + "babel-template": "^6.26.0", + "babel-types": "^6.26.0" + } + }, + "babel-plugin-istanbul": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz", + "integrity": "sha512-5LphC0USA8t4i1zCtjbbNb6jJj/9+X6P37Qfirc/70EQ34xKlMW+a1RHGwxGI+SwWpNwZ27HqvzAobeqaXwiZw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "find-up": "^3.0.0", + "istanbul-lib-instrument": "^3.3.0", + "test-exclude": "^5.2.3" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + } + } + }, + "babel-plugin-module-resolver": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-module-resolver/-/babel-plugin-module-resolver-3.2.0.tgz", + "integrity": "sha512-tjR0GvSndzPew/Iayf4uICWZqjBwnlMWjSx6brryfQ81F9rxBVqwDJtFCV8oOs0+vJeefK9TmdZtkIFdFe1UnA==", + "dev": true, + "requires": { + "find-babel-config": "^1.1.0", + "glob": "^7.1.2", + "pkg-up": "^2.0.0", + "reselect": "^3.0.1", + "resolve": "^1.4.0" + } + }, + "babel-plugin-syntax-dynamic-import": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz", + "integrity": "sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo=", + "dev": true + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "dev": true, + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "babel-template": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", + "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "lodash": "^4.17.4" + } + }, + "babel-traverse": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", + "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", + "dev": true, + "requires": { + "babel-code-frame": "^6.26.0", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "debug": "^2.6.8", + "globals": "^9.18.0", + "invariant": "^2.2.2", + "lodash": "^4.17.4" + } + }, + "babel-types": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" + } + }, + "babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + } + } + }, + "base64-arraybuffer": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz", + "integrity": "sha1-mBjHngWbE1X5fgQooBfIOOkLqBI=", + "dev": true + }, + "base64-js": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", + "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", + "dev": true + }, + "base64id": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "big.js": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.1.3.tgz", + "integrity": "sha1-TK2iGTZS6zyp7I5VyQFWacmAaXg=", + "dev": true + }, + "binary-extensions": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.10.0.tgz", + "integrity": "sha1-muuabF6IY4qtFx4Wf1kAq+JINdA=", + "dev": true + }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "optional": true, + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "bl": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz", + "integrity": "sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g==", + "requires": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + }, + "dependencies": { + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "bluebird": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz", + "integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw=" + }, + "bn.js": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "dev": true + }, + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "dev": true, + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "dependencies": { + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "dev": true + } + } + }, + "brace-expansion": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", + "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==", + "dev": true + } + } + }, + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "randombytes": "^2.0.1" + } + }, + "browserify-sign": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", + "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", + "dev": true, + "requires": { + "bn.js": "^4.1.1", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.2", + "elliptic": "^6.0.0", + "inherits": "^2.0.1", + "parse-asn1": "^5.0.0" + } + }, + "browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true, + "requires": { + "pako": "~1.0.5" + } + }, + "browserslist": { + "version": "4.11.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.11.1.tgz", + "integrity": "sha512-DCTr3kDrKEYNw6Jb9HFxVLQNaue8z+0ZfRBRjmCunKDEXEBajKDj2Y+Uelg+Pi29OnvaSGwjOsnRyNEkXzHg5g==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001038", + "electron-to-chromium": "^1.3.390", + "node-releases": "^1.1.53", + "pkg-up": "^2.0.0" + } + }, + "buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "dev": true + }, + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "dev": true + }, + "cacache": { + "version": "12.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", + "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", + "dev": true, + "requires": { + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "infer-owner": "^1.0.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + }, + "dependencies": { + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", + "dev": true + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + } + } + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "caching-transform": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-3.0.2.tgz", + "integrity": "sha512-Mtgcv3lh3U0zRii/6qVgQODdPA4G3zhG+jtbCWj39RXuUFTMzH0vcdMtaJS1jPowd+It2Pqr6y3NJMQqOqCE2w==", + "dev": true, + "requires": { + "hasha": "^3.0.0", + "make-dir": "^2.0.0", + "package-hash": "^3.0.0", + "write-file-atomic": "^2.4.2" + }, + "dependencies": { + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + } + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camelcase": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30001211", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001211.tgz", + "integrity": "sha512-v3GXWKofIkN3PkSidLI5d1oqeKNsam9nQkqieoMhP87nxOY0RPDC8X2+jcv8pjV4dRozPLSoMqNii9sDViOlIg==", + "dev": true + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "center-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", + "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", + "dev": true, + "requires": { + "align-text": "^0.1.3", + "lazy-cache": "^1.0.3" + } + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + } + }, + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "chrome-trace-event": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", + "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, + "cliui": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", + "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", + "dev": true, + "requires": { + "center-align": "^0.1.1", + "right-align": "^0.1.1", + "wordwrap": "0.0.2" + }, + "dependencies": { + "wordwrap": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", + "dev": true + } + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true + }, + "combined-stream": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", + "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", + "dev": true + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "connect": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", + "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", + "dev": true, + "requires": { + "debug": "2.6.9", + "finalhandler": "1.1.2", + "parseurl": "~1.3.3", + "utils-merge": "1.0.1" + } + }, + "console-browserify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", + "dev": true + }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "dev": true + }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true + }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==", + "dev": true + }, + "copy-concurrently": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", + "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", + "dev": true, + "requires": { + "aproba": "^1.1.1", + "fs-write-stream-atomic": "^1.0.8", + "iferr": "^0.1.5", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.0" + } + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, + "core-js": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.1.tgz", + "integrity": "sha1-rmh03GaTd4m4B1T/VCjfZoGcpQs=", + "dev": true + }, + "core-js-compat": { + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.6.5.tgz", + "integrity": "sha512-7ItTKOhOZbznhXAQ2g/slGg1PJV5zDO/WdkTwi7UEOJmkvsE32PWvx6mKtDjiMpjnR2CNf6BAD6sSxIlv7ptng==", + "dev": true, + "requires": { + "browserslist": "^4.8.5", + "semver": "7.0.0" + }, + "dependencies": { + "semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", + "dev": true + } + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dev": true, + "requires": { + "object-assign": "^4", + "vary": "^1" + } + }, + "coveralls": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.0.2.tgz", + "integrity": "sha512-Tv0LKe/MkBOilH2v7WBiTBdudg2ChfGbdXafc/s330djpF3zKOmuehTeRwjXWc7pzfj9FrDUTA7tEx6Div8NFw==", + "dev": true, + "requires": { + "growl": "~> 1.10.0", + "js-yaml": "^3.11.0", + "lcov-parse": "^0.0.10", + "log-driver": "^1.2.7", + "minimist": "^1.2.0", + "request": "^2.85.0" + }, + "dependencies": { + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + } + } + }, + "cp-file": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-6.2.0.tgz", + "integrity": "sha512-fmvV4caBnofhPe8kOcitBwSn2f39QLjnAnGq3gO9dfd75mUytzKNZB1hde6QHunW2Rt+OwuBOMc3i1tNElbszA==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "make-dir": "^2.0.0", + "nested-error-stacks": "^2.0.0", + "pify": "^4.0.1", + "safe-buffer": "^5.0.1" + }, + "dependencies": { + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + } + } + }, + "create-ecdh": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", + "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "elliptic": "^6.0.0" + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "requires": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + } + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dev": true, + "requires": { + "array-find-index": "^1.0.1" + } + }, + "custom-event": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", + "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=", + "dev": true + }, + "cyclist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", + "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", + "dev": true + }, + "d": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "dev": true, + "requires": { + "es5-ext": "^0.10.9" + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "date-format": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-3.0.0.tgz", + "integrity": "sha512-eyTcpKOcamdhWJXj56DpQMo1ylSQpcGtGKXcU0Tb97+K56/CF5amAqqqNj0+KvA0iw2ynxtHWFsPDSClCxe48w==", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "default-require-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", + "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=", + "dev": true, + "requires": { + "strip-bom": "^3.0.0" + } + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + } + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true + }, + "des.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", + "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", + "dev": true + }, + "di": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", + "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=", + "dev": true + }, + "diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true + }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "dom-serialize": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", + "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=", + "dev": true, + "requires": { + "custom-event": "~1.0.0", + "ent": "~2.2.0", + "extend": "^3.0.0", + "void-elements": "^2.0.0" + } + }, + "domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", + "dev": true + }, + "duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "dev": true, + "requires": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "electron-to-chromium": { + "version": "1.3.408", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.408.tgz", + "integrity": "sha512-vn1zWIxIdyl0MR72lr81/7kHYTRlDRjJT4ocp8dtb85VhH46J3lNqDMEBljAKPKgguqjK0+WAbf3IL6ZKw72kQ==", + "dev": true + }, + "elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + } + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", + "dev": true + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true + }, + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "engine.io": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-4.1.1.tgz", + "integrity": "sha512-t2E9wLlssQjGw0nluF6aYyfX8LwYU8Jj0xct+pAhfWfv/YrBn6TSNtEYsgxHIfaMqfrLx07czcMg9bMN6di+3w==", + "dev": true, + "requires": { + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.4.1", + "cors": "~2.8.5", + "debug": "~4.3.1", + "engine.io-parser": "~4.0.0", + "ws": "~7.4.2" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "engine.io-parser": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-4.0.2.tgz", + "integrity": "sha512-sHfEQv6nmtJrq6TKuIz5kyEKH/qSdK56H/A+7DnAuUPWosnIZAS2NHNcPLmyjtY3cGS/MqJdZbUjW97JU72iYg==", + "dev": true, + "requires": { + "base64-arraybuffer": "0.1.4" + } + }, + "enhanced-resolve": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", + "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.5.0", + "tapable": "^1.0.0" + }, + "dependencies": { + "memory-fs": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", + "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + } + } + }, + "ent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", + "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", + "dev": true + }, + "errno": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.4.tgz", + "integrity": "sha1-uJbiOp5ei6M4cfyZar02NfyaHH0=", + "dev": true, + "requires": { + "prr": "~0.0.0" + } + }, + "error-ex": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", + "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.16.0.tgz", + "integrity": "sha512-xdQnfykZ9JMEiasTAJZJdMWCQ1Vm00NBw79/AWi7ELfZuuPCSOMDZbT9mkOfSctVtfhb+sAAzrm+j//GjjLHLg==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.0", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.0", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-inspect": "^1.6.0", + "object-keys": "^1.1.1", + "string.prototype.trimleft": "^2.1.0", + "string.prototype.trimright": "^2.1.0" + }, + "dependencies": { + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + } + } + }, + "es-to-primitive": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", + "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "es5-ext": { + "version": "0.10.30", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.30.tgz", + "integrity": "sha1-cUGhaDZpfbq/qq7uQUlc4p9SyTk=", + "dev": true, + "requires": { + "es6-iterator": "2", + "es6-symbol": "~3.1" + } + }, + "es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true + }, + "es6-iterator": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz", + "integrity": "sha1-jjGcnwRTv1ddN0lAplWSDlnKVRI=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "^0.10.14", + "es6-symbol": "^3.1" + } + }, + "es6-symbol": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", + "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "eslint": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.6.0.tgz", + "integrity": "sha512-PpEBq7b6qY/qrOmpYQ/jTMDYfuQMELR4g4WI1M/NaSDDD/bdcMb+dj4Hgks7p41kW2caXsPsEZAEAyAgjVVC0g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.10.0", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^1.4.3", + "eslint-visitor-keys": "^1.1.0", + "espree": "^6.1.2", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^11.7.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^7.0.0", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.14", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^6.1.2", + "strip-ansi": "^5.2.0", + "strip-json-comments": "^3.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "glob-parent": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", + "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "eslint-import-resolver-babel-module": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-babel-module/-/eslint-import-resolver-babel-module-5.1.0.tgz", + "integrity": "sha512-fnWkQ9+fVjQ4H9qk5sH8zUfC8TPyWJAakLPjLqUgdlexhyT6PGk8AieXuEvdeskIXLOcO2WLI4kothFBigjFjA==", + "dev": true, + "requires": { + "pkg-up": "^2.0.0", + "resolve": "^1.10.0" + }, + "dependencies": { + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "resolve": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", + "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + } + } + }, + "eslint-import-resolver-node": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz", + "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "resolve": "^1.5.0" + }, + "dependencies": { + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "resolve": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", + "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + } + } + }, + "eslint-module-utils": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.4.1.tgz", + "integrity": "sha512-H6DOj+ejw7Tesdgbfs4jeS4YMFrT8uI8xwd1gtQqXssaR0EQ26L+2O/w6wkYFy2MymON0fTwHmXBvvfLNZVZEw==", + "dev": true, + "requires": { + "debug": "^2.6.8", + "pkg-dir": "^2.0.0" + } + }, + "eslint-plugin-import": { + "version": "2.18.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.18.2.tgz", + "integrity": "sha512-5ohpsHAiUBRNaBWAF08izwUGlbrJoJJ+W9/TBwsGoR1MnlgfwMIKrFeSjWbt6moabiXW9xNvtFz+97KHRfI4HQ==", + "dev": true, + "requires": { + "array-includes": "^3.0.3", + "contains-path": "^0.1.0", + "debug": "^2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.2", + "eslint-module-utils": "^2.4.0", + "has": "^1.0.3", + "minimatch": "^3.0.4", + "object.values": "^1.1.0", + "read-pkg-up": "^2.0.0", + "resolve": "^1.11.0" + }, + "dependencies": { + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "resolve": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", + "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + } + } + }, + "eslint-scope": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", + "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", + "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "eslint-visitor-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", + "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", + "dev": true + }, + "espree": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.2.tgz", + "integrity": "sha512-2iUPuuPP+yW1PZaMSDM9eyVf8D5P0Hi8h83YtZ5bPc/zHYjII5khoixIUTMO794NOY8F/ThF1Bo8ncZILarUTA==", + "dev": true, + "requires": { + "acorn": "^7.1.0", + "acorn-jsx": "^5.1.0", + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "acorn": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", + "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", + "dev": true + } + } + }, + "esprima": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", + "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", + "dev": true + }, + "esquery": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", + "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "dev": true, + "requires": { + "estraverse": "^4.0.0" + } + }, + "esrecurse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz", + "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=", + "dev": true, + "requires": { + "estraverse": "^4.1.0", + "object-assign": "^4.0.1" + } + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true + }, + "events": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", + "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", + "dev": true + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "figgy-pudding": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", + "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", + "dev": true + }, + "figures": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.1.0.tgz", + "integrity": "sha512-ravh8VRXqHuMvZt/d8GblBeqDMkdJMBdv/2KntFH+ra5MXkO7nxNKpzQ3n6QD/2da1kH0aWmNISdvhM7gl2gVg==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "dev": true, + "requires": { + "flat-cache": "^2.0.1" + } + }, + "file-size": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/file-size/-/file-size-0.0.5.tgz", + "integrity": "sha1-BX1Dw6Ptc12j+Q1gUqs4Dx5tXjs=", + "dev": true + }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true, + "optional": true + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + } + }, + "find-babel-config": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/find-babel-config/-/find-babel-config-1.2.0.tgz", + "integrity": "sha512-jB2CHJeqy6a820ssiqwrKMeyC6nNdmrcgkKWJWmpoxpE8RKciYJXCcXRq1h2AzCo5I5BJeN2tkGEO3hLTuePRA==", + "dev": true, + "requires": { + "json5": "^0.5.1", + "path-exists": "^3.0.0" + } + }, + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + } + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "findup-sync": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", + "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", + "dev": true, + "requires": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + } + }, + "flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true + }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "requires": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + }, + "dependencies": { + "glob": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.5.tgz", + "integrity": "sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "flatted": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.0.tgz", + "integrity": "sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg==", + "dev": true + }, + "flush-write-stream": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", + "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" + }, + "dependencies": { + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "follow-redirects": { + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.3.tgz", + "integrity": "sha512-DUgl6+HDzB0iEptNQEXLx/KhTmDb8tZUHSeLqpnjpknR70H0nC2t9N73BK6fN4hOvJ84pKlIQVQ4k5FFlBedKA==", + "dev": true + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "foreground-child": { + "version": "1.5.6", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz", + "integrity": "sha1-T9ca0t/elnibmApcCilZN8svXOk=", + "dev": true, + "requires": { + "cross-spawn": "^4", + "signal-exit": "^3.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", + "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "which": "^1.2.9" + } + } + } + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "fs-access": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fs-access/-/fs-access-1.0.1.tgz", + "integrity": "sha1-1qh/JiJxzv6+wwxVNAf7mV2od3o=", + "dev": true, + "requires": { + "null-check": "^1.0.0" + } + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "dependencies": { + "graceful-fs": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", + "dev": true + } + } + }, + "fs-readdir-recursive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", + "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", + "dev": true + }, + "fs-write-stream-atomic": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", + "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.12.tgz", + "integrity": "sha512-Ggd/Ktt7E7I8pxZRbGIs7vwqAPscSESMrCSkx2FtWeqmheJgCo2R74fTsZFCifr0VTPwqRpPv17+6b8Zp7th0Q==", + "dev": true, + "optional": true, + "requires": { + "bindings": "^1.5.0", + "nan": "^2.12.1", + "node-pre-gyp": "*" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true, + "optional": true + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "dev": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true, + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "optional": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true, + "optional": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true, + "optional": true + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "dev": true, + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true, + "optional": true + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "optional": true, + "requires": { + "ms": "^2.1.1" + } + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", + "dev": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.6.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "dev": true, + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "dev": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.3.tgz", + "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==", + "dev": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "optional": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true, + "optional": true + }, + "minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.9.0" + } + }, + "mkdirp": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.3.tgz", + "integrity": "sha512-P+2gwrFqx8lhew375MQHHeTlY8AuOJSrGf0R5ddkEndUkmwpgUob/vQuBD1V22/Cw1/lJr4x+EjllSezBThzBg==", + "dev": true, + "optional": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true, + "optional": true + }, + "needle": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/needle/-/needle-2.3.3.tgz", + "integrity": "sha512-EkY0GeSq87rWp1hoq/sH/wnTWgFVhYlnIkbJ0YJFfRgEFlz2RraCjBpFQ+vrEgEdp0ThfyHADmkChEhcb7PKyw==", + "dev": true, + "optional": true, + "requires": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.14.0.tgz", + "integrity": "sha512-+CvDC7ZttU/sSt9rFjix/P05iS43qHCOOGzcr3Ry99bXG7VX953+vFyEuph/tfqoYu8dttBkE86JSKBO2OzcxA==", + "dev": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4.4.2" + } + }, + "nopt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", + "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", + "dev": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.1.tgz", + "integrity": "sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==", + "dev": true, + "optional": true, + "requires": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npm-normalize-package-bin": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", + "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==", + "dev": true, + "optional": true + }, + "npm-packlist": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz", + "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", + "dev": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1", + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "optional": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "dev": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "optional": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "optional": true + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true, + "optional": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true, + "optional": true + }, + "tar": { + "version": "4.4.13", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", + "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", + "dev": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true, + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true, + "optional": true + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "optional": true + } + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "gensync": { + "version": "1.0.0-beta.1", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", + "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "requires": { + "global-prefix": "^3.0.0" + }, + "dependencies": { + "global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "requires": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + } + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + } + }, + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "dev": true + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "dev": true, + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + }, + "dependencies": { + "ajv": { + "version": "6.5.5", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.5.tgz", + "integrity": "sha512-7q7gtRQDJSyuEHjuVgHoUa2VuemFiCMrfQc9Tc08XTAc4Zj/5U1buQJ0HU6i7fKjXU09SVgSmxa4sLvuvS8Iyg==", + "dev": true, + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + } + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", + "dev": true + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "hasha": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-3.0.0.tgz", + "integrity": "sha1-UqMvq4Vp1BymmmH/GiFPjrfIvTk=", + "dev": true, + "requires": { + "is-stream": "^1.0.1" + } + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "requires": { + "parse-passwd": "^1.0.0" + } + }, + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dev": true, + "requires": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "dev": true + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", + "dev": true + }, + "iferr": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", + "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", + "dev": true + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "import-fresh": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.1.0.tgz", + "integrity": "sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "import-local": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", + "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", + "dev": true, + "requires": { + "pkg-dir": "^3.0.0", + "resolve-cwd": "^2.0.0" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + } + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ini": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz", + "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==", + "dev": true + }, + "inquirer": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.0.0.tgz", + "integrity": "sha512-rSdC7zelHdRQFkWnhsMu2+2SO41mpv2oF2zy4tMhmiLWkcKbOAs87fWAJhVXttKVwhdZvymvnuM95EyEXg2/tQ==", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "chalk": "^2.4.2", + "cli-cursor": "^3.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.15", + "mute-stream": "0.0.8", + "run-async": "^2.2.0", + "rxjs": "^6.4.0", + "string-width": "^4.1.0", + "strip-ansi": "^5.1.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.1.0.tgz", + "integrity": "sha512-NrX+1dVVh+6Y9dnQ19pR0pP4FiEIlUvdTGn8pw6CKTNq5sgib2nIhmUNT5TAmhWmvKr3WcxBcP3E8nWezuipuQ==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^5.2.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "interpret": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", + "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==", + "dev": true + }, + "invariant": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz", + "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=", + "dev": true, + "requires": { + "loose-envify": "^1.0.0" + } + }, + "invert-kv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", + "dev": true + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-buffer": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz", + "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=", + "dev": true + }, + "is-builtin-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "dev": true, + "requires": { + "builtin-modules": "^1.0.0" + } + }, + "is-callable": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", + "dev": true + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "dev": true, + "requires": { + "has": "^1.0.1" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-symbol": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", + "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.0" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isbinaryfile": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.6.tgz", + "integrity": "sha512-ORrEy+SNVqUhrCaal4hA4fBzhggQQ+BaLntyPOdoEiwlKZW9BZiJXjg3RMiruE4tPEI3pyVPpySHQF/dKWperg==", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "istanbul-lib-coverage": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", + "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", + "dev": true + }, + "istanbul-lib-hook": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-2.0.7.tgz", + "integrity": "sha512-vrRztU9VRRFDyC+aklfLoeXyNdTfga2EI3udDGn4cZ6fpSXpHLV9X6CHvfoMCPtggg8zvDDmC4b9xfu0z6/llA==", + "dev": true, + "requires": { + "append-transform": "^1.0.0" + } + }, + "istanbul-lib-instrument": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", + "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", + "dev": true, + "requires": { + "@babel/generator": "^7.4.0", + "@babel/parser": "^7.4.3", + "@babel/template": "^7.4.0", + "@babel/traverse": "^7.4.3", + "@babel/types": "^7.4.0", + "istanbul-lib-coverage": "^2.0.5", + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "istanbul-lib-report": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", + "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^2.0.5", + "make-dir": "^2.1.0", + "supports-color": "^6.1.0" + }, + "dependencies": { + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "istanbul-lib-source-maps": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", + "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^2.0.5", + "make-dir": "^2.1.0", + "rimraf": "^2.6.3", + "source-map": "^0.6.1" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "istanbul-reports": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.7.tgz", + "integrity": "sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0" + } + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "dev": true + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + } + } + }, + "karma": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/karma/-/karma-6.3.2.tgz", + "integrity": "sha512-fo4Wt0S99/8vylZMxNj4cBFyOBBnC1bewZ0QOlePij/2SZVWxqbyLeIddY13q6URa2EpLRW8ixvFRUMjkmo1bw==", + "dev": true, + "requires": { + "body-parser": "^1.19.0", + "braces": "^3.0.2", + "chokidar": "^3.4.2", + "colors": "^1.4.0", + "connect": "^3.7.0", + "di": "^0.0.1", + "dom-serialize": "^2.2.1", + "glob": "^7.1.6", + "graceful-fs": "^4.2.4", + "http-proxy": "^1.18.1", + "isbinaryfile": "^4.0.6", + "lodash": "^4.17.19", + "log4js": "^6.2.1", + "mime": "^2.4.5", + "minimatch": "^3.0.4", + "qjobs": "^1.2.0", + "range-parser": "^1.2.1", + "rimraf": "^3.0.2", + "socket.io": "^3.1.0", + "source-map": "^0.6.1", + "tmp": "0.2.1", + "ua-parser-js": "^0.7.23", + "yargs": "^16.1.1" + }, + "dependencies": { + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "chokidar": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", + "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.3.1", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "graceful-fs": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", + "dev": true + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "mime": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", + "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==", + "dev": true + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true + }, + "readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dev": true, + "requires": { + "rimraf": "^3.0.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + } + } + }, + "karma-chrome-launcher": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-2.2.0.tgz", + "integrity": "sha512-uf/ZVpAabDBPvdPdveyk1EPgbnloPvFFGgmRhYLTDH7gEB4nZdSBk8yTU47w1g/drLSx5uMOkjKk7IWKfWg/+w==", + "dev": true, + "requires": { + "fs-access": "^1.0.0", + "which": "^1.2.1" + } + }, + "karma-mocha": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/karma-mocha/-/karma-mocha-2.0.0.tgz", + "integrity": "sha512-qiZkZDJnn2kb9t2m4LoM4cYJHJVPoxvAYYe0B+go5s+A/3vc/3psUT05zW4yFz4vT0xHf+XzTTery8zdr8GWgA==", + "dev": true, + "requires": { + "minimist": "^1.2.3" + }, + "dependencies": { + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + } + } + }, + "karma-webpack": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/karma-webpack/-/karma-webpack-3.0.5.tgz", + "integrity": "sha512-nRudGJWstvVuA6Tbju9tyGUfXTtI1UXMXoRHVmM2/78D0q6s/Ye2IC157PKNDC15PWFGR0mVIRtWLAdcfsRJoA==", + "dev": true, + "requires": { + "async": "^2.0.0", + "babel-runtime": "^6.0.0", + "loader-utils": "^1.0.0", + "lodash": "^4.0.0", + "source-map": "^0.5.6", + "webpack-dev-middleware": "^2.0.6" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + }, + "lazy-cache": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", + "dev": true + }, + "lcid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "dev": true, + "requires": { + "invert-kv": "^2.0.0" + } + }, + "lcov-parse": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-0.0.10.tgz", + "integrity": "sha1-GwuP+ayceIklBYK3C3ExXZ2m2aM=", + "dev": true + }, + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true + }, + "levenary": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/levenary/-/levenary-1.1.1.tgz", + "integrity": "sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ==", + "dev": true, + "requires": { + "leven": "^3.1.0" + } + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + } + }, + "loader-runner": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", + "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", + "dev": true + }, + "loader-utils": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz", + "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=", + "dev": true, + "requires": { + "big.js": "^3.1.3", + "emojis-list": "^2.0.0", + "json5": "^0.5.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", + "dev": true + }, + "log-driver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", + "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==", + "dev": true + }, + "log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true, + "requires": { + "chalk": "^2.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "log4js": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.3.0.tgz", + "integrity": "sha512-Mc8jNuSFImQUIateBFwdOQcmC6Q5maU0VVvdC2R6XMb66/VnT+7WS4D/0EeNMZu1YODmJe5NIn2XftCzEocUgw==", + "dev": true, + "requires": { + "date-format": "^3.0.0", + "debug": "^4.1.1", + "flatted": "^2.0.1", + "rfdc": "^1.1.4", + "streamroller": "^2.2.4" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "flatted": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "loglevelnext": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/loglevelnext/-/loglevelnext-1.0.5.tgz", + "integrity": "sha512-V/73qkPuJmx4BcBF19xPBr+0ZRVBhc4POxvZTZdMeXpJ4NItXSJ/MSwuFT0kQJlCbXvdlZoQQ/418bS1y9Jh6A==", + "dev": true, + "requires": { + "es6-symbol": "^3.1.1", + "object.assign": "^4.1.0" + } + }, + "longest": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", + "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", + "dev": true + }, + "loose-envify": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", + "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", + "dev": true, + "requires": { + "js-tokens": "^3.0.0" + } + }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "dev": true, + "requires": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" + } + }, + "lru-cache": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", + "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "lz-string": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz", + "integrity": "sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY=" + }, + "lzma": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/lzma/-/lzma-2.3.2.tgz", + "integrity": "sha1-N4OySFi5wOdHoN88vx+1/KqSxEE=" + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "dependencies": { + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "dev": true, + "requires": { + "p-defer": "^1.0.0" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==", + "dev": true + } + } + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true + }, + "mem": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", + "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", + "dev": true, + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^2.0.0", + "p-is-promise": "^2.0.0" + } + }, + "memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "merge-source-map": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", + "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", + "dev": true, + "requires": { + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + } + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + }, + "mime-db": { + "version": "1.37.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", + "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==", + "dev": true + }, + "mime-types": { + "version": "2.1.21", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", + "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", + "dev": true, + "requires": { + "mime-db": "~1.37.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "mississippi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", + "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", + "dev": true, + "requires": { + "concat-stream": "^1.5.0", + "duplexify": "^3.4.2", + "end-of-stream": "^1.1.0", + "flush-write-stream": "^1.0.0", + "from2": "^2.1.0", + "parallel-transform": "^1.1.0", + "pump": "^3.0.0", + "pumpify": "^1.3.3", + "stream-each": "^1.1.0", + "through2": "^2.0.0" + } + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + }, + "dependencies": { + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + } + } + }, + "mocha": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.3.2.tgz", + "integrity": "sha512-UdmISwr/5w+uXLPKspgoV7/RXZwKRTiTjJ2/AC5ZiEztIoOYdfKb19+9jNmEInzx5pBsCyJQzarAxqIGBNYJhg==", + "dev": true, + "requires": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.1", + "debug": "4.3.1", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.1.6", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "4.0.0", + "log-symbols": "4.0.0", + "minimatch": "3.0.4", + "ms": "2.1.3", + "nanoid": "3.1.20", + "serialize-javascript": "5.0.1", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "which": "2.0.2", + "wide-align": "1.1.3", + "workerpool": "6.1.0", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "chokidar": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", + "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.3.1", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "js-yaml": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", + "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "log-symbols": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", + "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", + "dev": true, + "requires": { + "chalk": "^4.0.0" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "serialize-javascript": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", + "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true + } + } + }, + "move-concurrently": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", + "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", + "dev": true, + "requires": { + "aproba": "^1.1.1", + "copy-concurrently": "^1.0.0", + "fs-write-stream-atomic": "^1.0.8", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.3" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "msgpack5": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/msgpack5/-/msgpack5-4.5.1.tgz", + "integrity": "sha512-zC1vkcliryc4JGlL6OfpHumSYUHWFGimSI+OgfRCjTFLmKA2/foR9rMTOhWiqfOrfxJOctrpWPvrppf8XynJxw==", + "requires": { + "bl": "^2.0.1", + "inherits": "^2.0.3", + "readable-stream": "^2.3.6", + "safe-buffer": "^5.1.2" + }, + "dependencies": { + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } + } + } + } + }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", + "dev": true, + "optional": true + }, + "nanoid": { + "version": "3.1.20", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", + "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==", + "dev": true + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + } + } + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "dev": true + }, + "neo-async": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.0.tgz", + "integrity": "sha512-MFh0d/Wa7vkKO3Y3LlacqAEeHK0mckVqzDieUKTT+KGxi+zIpeVsFxymkIiRpbpDziHc290Xr9A1O4Om7otoRA==", + "dev": true + }, + "nested-error-stacks": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz", + "integrity": "sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug==", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node-environment-flags": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", + "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", + "dev": true, + "requires": { + "object.getownpropertydescriptors": "^2.0.3", + "semver": "^5.7.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "node-libs-browser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", + "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", + "dev": true, + "requires": { + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^3.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "0.0.1", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.11.0", + "vm-browserify": "^1.0.1" + } + }, + "node-lzw": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/node-lzw/-/node-lzw-0.3.1.tgz", + "integrity": "sha1-9Q43lol2rKgzIAKLkfEB30pDay0=" + }, + "node-modules-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", + "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", + "dev": true + }, + "node-releases": { + "version": "1.1.53", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.53.tgz", + "integrity": "sha512-wp8zyQVwef2hpZ/dJH7SfSrIPD6YoJz6BDQDpGEkcA0s3LpAQoxBIYmfIq6QAhC1DhwsyCgTaTTcONwX8qzCuQ==", + "dev": true + }, + "normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "is-builtin-module": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "null-check": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/null-check/-/null-check-1.0.0.tgz", + "integrity": "sha1-l33/1xdgErnsMNKjnbXPcqBDnt0=", + "dev": true + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "nyc": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-14.1.1.tgz", + "integrity": "sha512-OI0vm6ZGUnoGZv/tLdZ2esSVzDwUC88SNs+6JoSOMVxA+gKMB8Tk7jBwgemLx4O40lhhvZCVw1C+OYLOBOPXWw==", + "dev": true, + "requires": { + "archy": "^1.0.0", + "caching-transform": "^3.0.2", + "convert-source-map": "^1.6.0", + "cp-file": "^6.2.0", + "find-cache-dir": "^2.1.0", + "find-up": "^3.0.0", + "foreground-child": "^1.5.6", + "glob": "^7.1.3", + "istanbul-lib-coverage": "^2.0.5", + "istanbul-lib-hook": "^2.0.7", + "istanbul-lib-instrument": "^3.3.0", + "istanbul-lib-report": "^2.0.8", + "istanbul-lib-source-maps": "^3.0.6", + "istanbul-reports": "^2.2.4", + "js-yaml": "^3.13.1", + "make-dir": "^2.1.0", + "merge-source-map": "^1.1.0", + "resolve-from": "^4.0.0", + "rimraf": "^2.6.3", + "signal-exit": "^3.0.2", + "spawn-wrap": "^1.4.2", + "test-exclude": "^5.2.3", + "uuid": "^3.3.2", + "yargs": "^13.2.2", + "yargs-parser": "^13.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "cliui": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "dev": true, + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + }, + "dependencies": { + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + } + } + }, + "convert-source-map": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", + "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "invert-kv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", + "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", + "dev": true, + "requires": { + "@babel/generator": "^7.4.0", + "@babel/parser": "^7.4.3", + "@babel/template": "^7.4.0", + "@babel/traverse": "^7.4.3", + "@babel/types": "^7.4.0", + "istanbul-lib-coverage": "^2.0.5", + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.0.0.tgz", + "integrity": "sha512-0UewU+9rFapKFnlbirLi3byoOuhrSsli/z/ihNnvM24vgF+8sNBiI1LZPBSH9wJKUwaUbw+s3hToDLCXkrghrQ==", + "dev": true + } + } + }, + "lcid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "dev": true, + "requires": { + "invert-kv": "^2.0.0" + } + }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "mem": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", + "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", + "dev": true, + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^2.0.0", + "p-is-promise": "^2.0.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "os-locale": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", + "dev": true, + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "p-limit": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", + "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + } + }, + "read-pkg-up": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", + "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", + "dev": true, + "requires": { + "find-up": "^3.0.0", + "read-pkg": "^3.0.0" + } + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "test-exclude": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz", + "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==", + "dev": true, + "requires": { + "glob": "^7.1.3", + "minimatch": "^3.0.4", + "read-pkg-up": "^4.0.0", + "require-main-filename": "^2.0.0" + } + }, + "yargs": { + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.2.tgz", + "integrity": "sha512-WyEoxgyTD3w5XRpAQNYUB9ycVH/PQrToaTXdYXRdOXvEy1l19br+VJsc0vcO8PTGg5ro/l/GY7F/JMEBmI0BxA==", + "dev": true, + "requires": { + "cliui": "^4.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "os-locale": "^3.1.0", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.0.0" + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "object-inspect": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", + "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==", + "dev": true + }, + "object-keys": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", + "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==", + "dev": true + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "object.getownpropertydescriptors": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", + "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", + "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "is-callable": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", + "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "dev": true + }, + "is-regex": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", + "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "object-inspect": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", + "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "string.prototype.trimleft": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz", + "integrity": "sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5", + "string.prototype.trimstart": "^1.0.0" + } + }, + "string.prototype.trimright": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz", + "integrity": "sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5", + "string.prototype.trimend": "^1.0.0" + } + } + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "object.values": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.0.tgz", + "integrity": "sha512-8mf0nKLAoFX6VlNVdhGj31SVYpaNFtUnuoOXWyFEstsWRgU837AK+JYM0iAxwkSzGRbwn8cbFmgbyxj1j4VbXg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.12.0", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + }, + "dependencies": { + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + } + } + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" + } + }, + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", + "dev": true + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "os-locale": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", + "dev": true, + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "p-defer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "p-is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", + "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", + "dev": true + }, + "p-limit": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz", + "integrity": "sha1-sH/y2aXYi+yAYDWJWiurZqJ5iLw=", + "dev": true + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "package-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-3.0.0.tgz", + "integrity": "sha512-lOtmukMDVvtkL84rJHI7dpTYq+0rli8N2wlnqUcBuDWCfVhRUfOmnR9SsoHFMLpACvEV60dX7rd0rFaYDZI+FA==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.15", + "hasha": "^3.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + }, + "dependencies": { + "graceful-fs": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", + "dev": true + } + } + }, + "pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true + }, + "parallel-transform": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", + "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", + "dev": true, + "requires": { + "cyclist": "^1.0.1", + "inherits": "^2.0.3", + "readable-stream": "^2.1.5" + } + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-asn1": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", + "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", + "dev": true, + "requires": { + "asn1.js": "^4.0.0", + "browserify-aes": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", + "dev": true + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "^2.0.0" + } + }, + "pbkdf2": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", + "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", + "dev": true, + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "picomatch": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", + "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==", + "dev": true + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pirates": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", + "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", + "dev": true, + "requires": { + "node-modules-regexp": "^1.0.0" + } + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } + }, + "pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", + "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + } + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "private": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", + "dev": true + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "dev": true + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", + "dev": true + }, + "prr": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/prr/-/prr-0.0.0.tgz", + "integrity": "sha1-GoS4WQgyVQFBGFPQCB7j+obikmo=", + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "psl": { + "version": "1.1.29", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz", + "integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==", + "dev": true + }, + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==", + "dev": true + } + } + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "dev": true, + "requires": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + }, + "dependencies": { + "pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + }, + "qjobs": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", + "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", + "dev": true + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true + }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "dev": true + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=", + "dev": true + }, + "raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "dev": true, + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + } + } + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.0.3", + "util-deprecate": "~1.0.1" + } + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + }, + "regenerate": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", + "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", + "dev": true + }, + "regenerate-unicode-properties": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz", + "integrity": "sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==", + "dev": true, + "requires": { + "regenerate": "^1.4.0" + } + }, + "regenerator-runtime": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz", + "integrity": "sha512-/aA0kLeRb5N9K0d4fw7ooEbI+xDe+DKD499EQqygGqeS8N3xto15p09uY2xj7ixP81sNPXvRLnAQIqdVStgb1A==", + "dev": true + }, + "regenerator-transform": { + "version": "0.14.4", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.4.tgz", + "integrity": "sha512-EaJaKPBI9GvKpvUz2mz4fhx7WPgvwRLY9v3hlNHWmAuJHI13T4nwKnNvm5RWJzEdnI5g5UwtOww+S8IdoUC2bw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.8.4", + "private": "^0.1.8" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.9.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.2.tgz", + "integrity": "sha512-NE2DtOdufG7R5vnfQUTehdTfNycfUANEtCa9PssN9O/xmTzP4E08UI797ixaei6hBEVL9BI/PsdJS5x7mWoB9Q==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "regenerator-runtime": { + "version": "0.13.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", + "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==", + "dev": true + } + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "dev": true + }, + "regexpu-core": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.0.tgz", + "integrity": "sha512-TQ4KXRnIn6tz6tjnrXEkD/sshygKH/j5KzK86X8MkeHyZ8qst/LZ89j3X4/8HEIfHANTFIP/AbXakeRhWIl5YQ==", + "dev": true, + "requires": { + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^8.2.0", + "regjsgen": "^0.5.1", + "regjsparser": "^0.6.4", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.2.0" + } + }, + "regjsgen": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.1.tgz", + "integrity": "sha512-5qxzGZjDs9w4tzT3TPhCJqWdCc3RLYwy9J2NB0nm5Lz+S273lvWcpjaTGHsT1dc6Hhfq41uSEOw8wBmxrKOuyg==", + "dev": true + }, + "regjsparser": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.4.tgz", + "integrity": "sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw==", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + } + } + }, + "release-zalgo": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", + "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", + "dev": true, + "requires": { + "es6-error": "^4.0.1" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", + "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "dev": true + }, + "reselect": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-3.0.1.tgz", + "integrity": "sha1-79qpjqdFEyTQkrKyFjpqHXqaIUc=", + "dev": true + }, + "resolve": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", + "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "resolve-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", + "dev": true, + "requires": { + "resolve-from": "^3.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + } + } + }, + "resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + }, + "dependencies": { + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "requires": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + } + } + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", + "dev": true + }, + "right-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", + "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", + "dev": true, + "requires": { + "align-text": "^0.1.1" + } + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + }, + "dependencies": { + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "dev": true, + "requires": { + "is-promise": "^2.1.0" + } + }, + "run-queue": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", + "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", + "dev": true, + "requires": { + "aproba": "^1.1.1" + } + }, + "rxjs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz", + "integrity": "sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "schema-utils": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.6.5.tgz", + "integrity": "sha512-5KXuwKziQrTVHh8j/Uxz+QUbxkaLW9X/86NBlx/gnKgtsZA2GIVMUn17qWhRFwF8jdYb3Dig5hRO/W5mZqy6SQ==", + "dev": true, + "requires": { + "ajv": "^6.12.0", + "ajv-keywords": "^3.4.1" + }, + "dependencies": { + "ajv": { + "version": "6.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz", + "integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "fast-deep-equal": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", + "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + } + } + }, + "semver": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", + "dev": true + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true + }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + } + } + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + } + }, + "socket.io": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-3.1.2.tgz", + "integrity": "sha512-JubKZnTQ4Z8G4IZWtaAZSiRP3I/inpy8c/Bsx2jrwGrTbKeVU5xd6qkKMHpChYeM3dWZSO0QACiGK+obhBNwYw==", + "dev": true, + "requires": { + "@types/cookie": "^0.4.0", + "@types/cors": "^2.8.8", + "@types/node": ">=10.0.0", + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "debug": "~4.3.1", + "engine.io": "~4.1.0", + "socket.io-adapter": "~2.1.0", + "socket.io-parser": "~4.0.3" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "socket.io-adapter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.1.0.tgz", + "integrity": "sha512-+vDov/aTsLjViYTwS9fPy5pEtTkrbEKsw2M+oVSoFGw6OD1IpvlV1VPhUzNbofCQ8oyMbdYJqDtGdmHQK6TdPg==", + "dev": true + }, + "socket.io-parser": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.4.tgz", + "integrity": "sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g==", + "dev": true, + "requires": { + "@types/component-emitter": "^1.2.10", + "component-emitter": "~1.3.0", + "debug": "~4.3.1" + }, + "dependencies": { + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "source-list-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.0.tgz", + "integrity": "sha512-I2UmuJSRr/T8jisiROLU3A3ltr+swpniSmNPI4Ml3ZCX6tVnDsuZzK7F2hl5jTqbZBWCEKlj5HRQiPExXLgE8A==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-resolve": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "dev": true, + "requires": { + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.5.15", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.15.tgz", + "integrity": "sha512-wYF5aX1J0+V51BDT3Om7uXNn0ct2FWiV4bvwiGVefxkm+1S1o5jsecE5lb2U28DDblzxzxeIDbTVpXHI9D/9hA==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "spawn-wrap": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-1.4.3.tgz", + "integrity": "sha512-IgB8md0QW/+tWqcavuFgKYR/qIRvJkRLPJDFaoXtLLUaVcCDK0+HeFTkmQHj3eprcYhc+gOl0aEA1w7qZlYezw==", + "dev": true, + "requires": { + "foreground-child": "^1.5.6", + "mkdirp": "^0.5.0", + "os-homedir": "^1.0.1", + "rimraf": "^2.6.2", + "signal-exit": "^3.0.2", + "which": "^1.3.0" + } + }, + "spdx-correct": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", + "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", + "dev": true, + "requires": { + "spdx-license-ids": "^1.0.2" + } + }, + "spdx-expression-parse": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", + "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=", + "dev": true + }, + "spdx-license-ids": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", + "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", + "dev": true + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.15.2.tgz", + "integrity": "sha512-Ra/OXQtuh0/enyl4ETZAfTaeksa6BXks5ZcjpSUNrjBr0DvrJKX+1fsKDPpT9TBXgHAFsa4510aNVgI8g/+SzA==", + "dev": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "ssri": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz", + "integrity": "sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==", + "dev": true, + "requires": { + "figgy-pudding": "^3.5.1" + } + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "static-server": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/static-server/-/static-server-2.0.5.tgz", + "integrity": "sha512-viJEDD+PvcchOKBtyRQ145ko1kuuEwXjXus1wmonmFD+zdwUWVthn/G+7+PEtHxUI2TzEWufLs9sPqgMaoJsJA==", + "dev": true, + "requires": { + "chalk": "^0.5.1", + "commander": "^2.3.0", + "file-size": "0.0.5", + "mime": "^1.2.11" + }, + "dependencies": { + "ansi-regex": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", + "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=", + "dev": true + }, + "ansi-styles": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz", + "integrity": "sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94=", + "dev": true + }, + "chalk": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz", + "integrity": "sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ=", + "dev": true, + "requires": { + "ansi-styles": "^1.1.0", + "escape-string-regexp": "^1.0.0", + "has-ansi": "^0.1.0", + "strip-ansi": "^0.3.0", + "supports-color": "^0.2.0" + } + }, + "has-ansi": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz", + "integrity": "sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4=", + "dev": true, + "requires": { + "ansi-regex": "^0.2.0" + } + }, + "strip-ansi": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz", + "integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=", + "dev": true, + "requires": { + "ansi-regex": "^0.2.1" + } + }, + "supports-color": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz", + "integrity": "sha1-2S3iaU6z9nMjlz1649i1W0wiGQo=", + "dev": true + } + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true + }, + "stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "dev": true, + "requires": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-each": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", + "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "stream-shift": "^1.0.0" + } + }, + "stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dev": true, + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + }, + "dependencies": { + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", + "dev": true + }, + "streamroller": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-2.2.4.tgz", + "integrity": "sha512-OG79qm3AujAM9ImoqgWEY1xG4HX+Lw+yY6qZj9R1K2mhF5bEmQ849wvrb+4vt4jLMLzwXttJlQbOdPOQVRv7DQ==", + "dev": true, + "requires": { + "date-format": "^2.1.0", + "debug": "^4.1.1", + "fs-extra": "^8.1.0" + }, + "dependencies": { + "date-format": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-2.1.0.tgz", + "integrity": "sha512-bYQuGLeFxhkxNOF3rcMtiZxvCBAquGzZm6oWA1oZ0g2THUzivaRhv8uOhdr19LmoobSOLoIAxeUK2RdbM8IFTA==", + "dev": true + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string.prototype.trimend": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", + "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", + "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "is-callable": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", + "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "dev": true + }, + "is-regex": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", + "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "object-inspect": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", + "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "string.prototype.trimleft": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz", + "integrity": "sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5", + "string.prototype.trimstart": "^1.0.0" + } + }, + "string.prototype.trimright": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz", + "integrity": "sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5", + "string.prototype.trimend": "^1.0.0" + } + } + } + }, + "string.prototype.trimleft": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz", + "integrity": "sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + }, + "string.prototype.trimright": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz", + "integrity": "sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + }, + "string.prototype.trimstart": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", + "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", + "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "is-callable": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", + "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "dev": true + }, + "is-regex": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", + "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "object-inspect": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", + "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "string.prototype.trimleft": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz", + "integrity": "sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5", + "string.prototype.trimstart": "^1.0.0" + } + }, + "string.prototype.trimright": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz", + "integrity": "sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5", + "string.prototype.trimend": "^1.0.0" + } + } + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "strip-json-comments": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", + "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", + "dev": true + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + }, + "table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "dev": true, + "requires": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "dev": true + }, + "terser": { + "version": "4.6.11", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.11.tgz", + "integrity": "sha512-76Ynm7OXUG5xhOpblhytE7X58oeNSmC8xnNhjWVo8CksHit0U0kO4hfNbPrrYwowLWFgM2n9L176VNx2QaHmtA==", + "dev": true, + "requires": { + "commander": "^2.20.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.12" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "terser-webpack-plugin": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz", + "integrity": "sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw==", + "dev": true, + "requires": { + "cacache": "^12.0.2", + "find-cache-dir": "^2.1.0", + "is-wsl": "^1.1.0", + "schema-utils": "^1.0.0", + "serialize-javascript": "^4.0.0", + "source-map": "^0.6.1", + "terser": "^4.1.2", + "webpack-sources": "^1.4.0", + "worker-farm": "^1.7.0" + }, + "dependencies": { + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + }, + "serialize-javascript": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "dev": true, + "requires": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + } + } + } + }, + "test-exclude": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz", + "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==", + "dev": true, + "requires": { + "glob": "^7.1.3", + "minimatch": "^3.0.4", + "read-pkg-up": "^4.0.0", + "require-main-filename": "^2.0.0" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "glob": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.5.tgz", + "integrity": "sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + } + }, + "read-pkg-up": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", + "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", + "dev": true, + "requires": { + "find-up": "^3.0.0", + "read-pkg": "^3.0.0" + } + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + } + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + }, + "dependencies": { + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "timers-browserify": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", + "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", + "dev": true, + "requires": { + "setimmediate": "^1.0.4" + } + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, + "to-fast-properties": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", + "dev": true + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + } + } + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "dev": true + }, + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "dev": true, + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + } + }, + "trim-right": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", + "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", + "dev": true + }, + "tslib": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", + "dev": true + }, + "tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", + "dev": true + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "type-fest": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.5.2.tgz", + "integrity": "sha512-DWkS49EQKVX//Tbupb9TFa19c7+MK1XmzkrZUR8TAktmE/DizXoaoJV6TZ/tSIPXipqNiRI6CyAe7x69Jb6RSw==", + "dev": true + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "dependencies": { + "mime-db": { + "version": "1.47.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz", + "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==", + "dev": true + }, + "mime-types": { + "version": "2.1.30", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz", + "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==", + "dev": true, + "requires": { + "mime-db": "1.47.0" + } + } + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "ua-parser-js": { + "version": "0.7.28", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.28.tgz", + "integrity": "sha512-6Gurc1n//gjp9eQNXjD9O3M/sMwVtN5S8Lv9bvOYBfKfDNiIIhqiyi01vMBO45u4zkDE420w/e0se7Vs+sIg+g==", + "dev": true + }, + "uglify-js": { + "version": "2.8.29", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", + "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", + "dev": true, + "requires": { + "source-map": "~0.5.1", + "uglify-to-browserify": "~1.0.0", + "yargs": "~3.10.0" + }, + "dependencies": { + "yargs": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "dev": true, + "requires": { + "camelcase": "^1.0.2", + "cliui": "^2.1.0", + "decamelize": "^1.0.0", + "window-size": "0.1.0" + } + } + } + }, + "uglify-to-browserify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", + "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", + "dev": true, + "optional": true + }, + "uglifyjs-webpack-plugin": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-0.4.6.tgz", + "integrity": "sha1-uVH0q7a9YX5m9j64kUmOORdj4wk=", + "dev": true, + "requires": { + "source-map": "^0.5.6", + "uglify-js": "^2.8.29", + "webpack-sources": "^1.0.1" + } + }, + "unicode-canonical-property-names-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", + "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", + "dev": true + }, + "unicode-match-property-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", + "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", + "dev": true, + "requires": { + "unicode-canonical-property-names-ecmascript": "^1.0.4", + "unicode-property-aliases-ecmascript": "^1.0.4" + } + }, + "unicode-match-property-value-ecmascript": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz", + "integrity": "sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==", + "dev": true + }, + "unicode-property-aliases-ecmascript": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz", + "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==", + "dev": true + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, + "unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "dev": true, + "requires": { + "unique-slug": "^2.0.0" + } + }, + "unique-slug": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4" + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "upath": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.2.tgz", + "integrity": "sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==", + "dev": true + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + } + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + } + } + }, + "url-join": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-2.0.5.tgz", + "integrity": "sha1-WvIvGMBSoACkjXuCxenC4v7tpyg=", + "dev": true + }, + "urlsafe-base64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/urlsafe-base64/-/urlsafe-base64-1.0.0.tgz", + "integrity": "sha1-I/iQaabGL0bPOh07ABac77kL4MY=" + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "util": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", + "dev": true, + "requires": { + "inherits": "2.0.3" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "dev": true + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true + }, + "v8-compile-cache": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", + "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", + "dev": true + }, + "v8flags": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.1.3.tgz", + "integrity": "sha512-amh9CCg3ZxkzQ48Mhcb8iX7xpAfYJgePHxWMQCBWECpOSqJUXgY26ncA61UTV0BkPqfhcy6mzwCIoP4ygxpW8w==", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "validate-npm-package-license": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", + "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", + "dev": true, + "requires": { + "spdx-correct": "~1.0.0", + "spdx-expression-parse": "~1.0.0" + } + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "dev": true + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + } + } + }, + "vm-browserify": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", + "dev": true + }, + "void-elements": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", + "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=", + "dev": true + }, + "watchpack": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.1.tgz", + "integrity": "sha512-+IF9hfUFOrYOOaKyfaI7h7dquUIOgyEMoQMLA7OP5FxegKA2+XdXThAZ9TU2kucfhDH7rfMHs1oPYziVGWRnZA==", + "dev": true, + "requires": { + "chokidar": "^2.1.8", + "graceful-fs": "^4.1.2", + "neo-async": "^2.5.0" + } + }, + "webpack": { + "version": "4.42.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.42.1.tgz", + "integrity": "sha512-SGfYMigqEfdGchGhFFJ9KyRpQKnipvEvjc1TwrXEPCM6H5Wywu10ka8o3KGrMzSMxMQKt8aCHUFh5DaQ9UmyRg==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-module-context": "1.9.0", + "@webassemblyjs/wasm-edit": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0", + "acorn": "^6.2.1", + "ajv": "^6.10.2", + "ajv-keywords": "^3.4.1", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^4.1.0", + "eslint-scope": "^4.0.3", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^2.4.0", + "loader-utils": "^1.2.3", + "memory-fs": "^0.4.1", + "micromatch": "^3.1.10", + "mkdirp": "^0.5.3", + "neo-async": "^2.6.1", + "node-libs-browser": "^2.2.1", + "schema-utils": "^1.0.0", + "tapable": "^1.1.3", + "terser-webpack-plugin": "^1.4.3", + "watchpack": "^1.6.0", + "webpack-sources": "^1.4.1" + }, + "dependencies": { + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true + }, + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true + }, + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "neo-async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", + "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", + "dev": true + }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "dev": true, + "requires": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + } + } + } + }, + "webpack-cli": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.11.tgz", + "integrity": "sha512-dXlfuml7xvAFwYUPsrtQAA9e4DOe58gnzSxhgrO/ZM/gyXTBowrsYeubyN4mqGhYdpXMFNyQ6emjJS9M7OBd4g==", + "dev": true, + "requires": { + "chalk": "2.4.2", + "cross-spawn": "6.0.5", + "enhanced-resolve": "4.1.0", + "findup-sync": "3.0.0", + "global-modules": "2.0.0", + "import-local": "2.0.0", + "interpret": "1.2.0", + "loader-utils": "1.2.3", + "supports-color": "6.1.0", + "v8-compile-cache": "2.0.3", + "yargs": "13.2.4" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "enhanced-resolve": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz", + "integrity": "sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.4.0", + "tapable": "^1.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", + "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "v8-compile-cache": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz", + "integrity": "sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w==", + "dev": true + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, + "yargs": { + "version": "13.2.4", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.4.tgz", + "integrity": "sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "os-locale": "^3.1.0", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.0" + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "webpack-dev-middleware": { + "version": "2.0.6", + "resolved": "http://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-2.0.6.tgz", + "integrity": "sha512-tj5LLD9r4tDuRIDa5Mu9lnY2qBBehAITv6A9irqXhw/HQquZgTx3BCd57zYbU2gMDnncA49ufK2qVQSbaKJwOw==", + "dev": true, + "requires": { + "loud-rejection": "^1.6.0", + "memory-fs": "~0.4.1", + "mime": "^2.1.0", + "path-is-absolute": "^1.0.0", + "range-parser": "^1.0.3", + "url-join": "^2.0.2", + "webpack-log": "^1.0.1" + }, + "dependencies": { + "mime": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.0.tgz", + "integrity": "sha512-ikBcWwyqXQSHKtciCcctu9YfPbFYZ4+gbHEmE0Q8jzcTYQg5dHCr3g2wwAZjPoJfQVXZq6KXAjpXOTf5/cjT7w==", + "dev": true + } + } + }, + "webpack-log": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-1.2.0.tgz", + "integrity": "sha512-U9AnICnu50HXtiqiDxuli5gLB5PGBo7VvcHx36jRZHwK4vzOYLbImqT4lwWwoMHdQWwEKw736fCHEekokTEKHA==", + "dev": true, + "requires": { + "chalk": "^2.1.0", + "log-symbols": "^2.1.0", + "loglevelnext": "^1.0.1", + "uuid": "^3.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "webpack-sources": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.0.1.tgz", + "integrity": "sha512-05tMxipUCwHqYaVS8xc7sYPTly8PzXayRCB4dTxLhWTqlKUiwH6ezmEe0OSreL1c30LAuA3Zqmc+uEBUGFJDjw==", + "dev": true, + "requires": { + "source-list-map": "^2.0.0", + "source-map": "~0.5.3" + } + }, + "which": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", + "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "window-size": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", + "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", + "dev": true + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "worker-farm": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", + "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", + "dev": true, + "requires": { + "errno": "~0.1.7" + }, + "dependencies": { + "errno": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", + "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", + "dev": true, + "requires": { + "prr": "~1.0.1" + } + }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true + } + } + }, + "workerpool": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz", + "integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==", + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } + }, + "write-file-atomic": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.2.tgz", + "integrity": "sha512-s0b6vB3xIVRLWywa6X9TOMA7k9zio0TMOsl9ZnDkliA/cfJlpHXAscj0gbHVJiTdIuAYpIyqS5GW91fqm6gG5g==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, + "ws": { + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz", + "integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==", + "dev": true + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + }, + "y18n": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", + "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + } + } + }, + "yargs-parser": { + "version": "20.2.7", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.7.tgz", + "integrity": "sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==", + "dev": true + }, + "yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "requires": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "dependencies": { + "camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true + }, + "decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true + } + } + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true + } + } +} ADDED public/json-url-master/package.json Index: public/json-url-master/package.json ================================================================== --- public/json-url-master/package.json +++ public/json-url-master/package.json @@ -0,0 +1,82 @@ +{ + "name": "json-url", + "version": "3.0.0", + "description": "Compress JSON into compact base64 URI-friendly notation", + "main": "dist/node/index.js", + "browser": "dist/browser/json-url-single.js", + "scripts": { + "lint": "eslint src/*", + "compile": "rm -rf dist/; mkdir dist & wait & npm run compile:node & npm run compile:webpack & npm run compile:webpack:single", + "compile:node": "babel --plugins @babel/plugin-transform-runtime,add-module-exports -d dist/node src src/main", + "compile:webpack": "webpack", + "compile:webpack:single": "webpack --config webpack.config.single.js", + "prepublish": "npm test && npm run compile", + "test": "npm run lint && npm run test:node && npm run test:karma", + "test:node": "BABEL_ENV=test nyc mocha test/index.js --timeout 120000", + "test:karma": "karma start --single-run", + "perf": "babel-node test/perf.js", + "coverage": "nyc report --reporter=text-lcov | coveralls", + "example": "open http://localhost:8000/examples/browser/test.html & static-server --port 8000" + }, + "repository": { + "type": "git", + "url": "https://github.com/masotime/json-url" + }, + "author": "Benjamin Goh ", + "license": "ISC", + "dependencies": { + "@babel/runtime-corejs2": "^7.0.0", + "bluebird": "^3.0.6", + "lz-string": "^1.4.4", + "lzma": "^2.3.2", + "msgpack5": "^4.2.1", + "node-lzw": "^0.3.1", + "urlsafe-base64": "^1.0.0" + }, + "devDependencies": { + "@babel/cli": "^7.0.0", + "@babel/core": "^7.0.0", + "@babel/node": "^7.0.0", + "@babel/plugin-proposal-class-properties": "^7.0.0", + "@babel/plugin-proposal-decorators": "^7.0.0", + "@babel/plugin-proposal-do-expressions": "^7.0.0", + "@babel/plugin-proposal-export-default-from": "^7.0.0", + "@babel/plugin-proposal-export-namespace-from": "^7.0.0", + "@babel/plugin-proposal-function-bind": "^7.0.0", + "@babel/plugin-proposal-function-sent": "^7.0.0", + "@babel/plugin-proposal-json-strings": "^7.0.0", + "@babel/plugin-proposal-logical-assignment-operators": "^7.0.0", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0", + "@babel/plugin-proposal-numeric-separator": "^7.0.0", + "@babel/plugin-proposal-optional-chaining": "^7.0.0", + "@babel/plugin-proposal-pipeline-operator": "^7.0.0", + "@babel/plugin-proposal-throw-expressions": "^7.0.0", + "@babel/plugin-syntax-dynamic-import": "^7.0.0", + "@babel/plugin-syntax-import-meta": "^7.0.0", + "@babel/plugin-transform-runtime": "^7.0.0", + "@babel/polyfill": "^7.0.0", + "@babel/preset-env": "^7.0.0", + "@babel/register": "^7.6.2", + "@babel/runtime": "^7.6.3", + "babel-eslint": "^9.0.0", + "babel-loader": "^8.0.0", + "babel-plugin-add-module-exports": "^0", + "babel-plugin-dynamic-import-node": "^1.1.0", + "babel-plugin-istanbul": "^5.2.0", + "babel-plugin-module-resolver": "^3.2.0", + "coveralls": "^3.0.2", + "eslint": "^6.6.0", + "eslint-import-resolver-babel-module": "^5.1.0", + "eslint-plugin-import": "^2.18.2", + "karma": "^6.3.2", + "karma-chrome-launcher": "^2.2.0", + "karma-mocha": "^2.0.0", + "karma-webpack": "^3.0.5", + "mocha": "^8.3.2", + "nyc": "^14.1.1", + "static-server": "^2.0.5", + "uglifyjs-webpack-plugin": "^0.4.6", + "webpack": "^4.42.1", + "webpack-cli": "^3.3.11" + } +} ADDED public/json-url-master/src/main/browser-index.js Index: public/json-url-master/src/main/browser-index.js ================================================================== --- public/json-url-master/src/main/browser-index.js +++ public/json-url-master/src/main/browser-index.js @@ -0,0 +1,20 @@ +/* global document */ +import createClient from './index.js'; + +// adapted from https://github.com/webpack/webpack/issues/595 +function getCurrentScriptSrc() { + if (document.currentScript) return document.currentScript.src; + + // this is unreliable if the script is loaded asynchronously + const scripts = document.getElementsByTagName('script'); + return scripts[scripts.length-1].src; +} + +function derivePath(scriptSrc) { + return scriptSrc.substring(0, scriptSrc.lastIndexOf('/')); +} + +// allows webpack to dynamically load chunks on the same path as where the index script is loaded. +__webpack_public_path__ = derivePath(getCurrentScriptSrc()) + '/'; // eslint-disable-line + +export default createClient; ADDED public/json-url-master/src/main/codecs/index.js Index: public/json-url-master/src/main/codecs/index.js ================================================================== --- public/json-url-master/src/main/codecs/index.js +++ public/json-url-master/src/main/codecs/index.js @@ -0,0 +1,8 @@ +import lzma from 'main/codecs/lzma'; +import lzstring from 'main/codecs/lzstring'; +import lzw from 'main/codecs/lzw'; +import pack from 'main/codecs/pack'; + +export default { + lzma, lzstring, lzw, pack +}; ADDED public/json-url-master/src/main/codecs/lzma.js Index: public/json-url-master/src/main/codecs/lzma.js ================================================================== --- public/json-url-master/src/main/codecs/lzma.js +++ public/json-url-master/src/main/codecs/lzma.js @@ -0,0 +1,24 @@ +import LOADERS from 'main/loaders'; + +export default { + pack: true, + encode: true, + compress: async input => { + const lzma = await LOADERS.lzma(); + return new Promise((ok, fail) => + lzma.compress(input, 9, (byteArray, err) => { + if (err) return fail(err); + return ok(Buffer.from(byteArray)); + }) + ) + }, + decompress: async input => { + const lzma = await LOADERS.lzma(); + return new Promise((ok, fail) => + lzma.decompress(input, (byteArray, err) => { + if (err) return fail(err); + return ok(Buffer.from(byteArray)); + }) + ) + } +}; ADDED public/json-url-master/src/main/codecs/lzstring.js Index: public/json-url-master/src/main/codecs/lzstring.js ================================================================== --- public/json-url-master/src/main/codecs/lzstring.js +++ public/json-url-master/src/main/codecs/lzstring.js @@ -0,0 +1,8 @@ +import LOADERS from 'main/loaders'; + +export default { + pack: false, + encode: true, + compress: async string => Buffer.from((await LOADERS.lzstring()).compressToUint8Array(string)), + decompress: async buffer => (await LOADERS.lzstring()).decompressFromUint8Array(buffer) +}; ADDED public/json-url-master/src/main/codecs/lzw.js Index: public/json-url-master/src/main/codecs/lzw.js ================================================================== --- public/json-url-master/src/main/codecs/lzw.js +++ public/json-url-master/src/main/codecs/lzw.js @@ -0,0 +1,8 @@ +import LOADERS from 'main/loaders'; + +export default { + pack: true, + encode: true, + compress: async input => Buffer.from((await LOADERS.lzw()).encode(input.toString('binary'))), + decompress: async input => Buffer.from((await LOADERS.lzw()).decode(input), 'binary') +}; ADDED public/json-url-master/src/main/codecs/pack.js Index: public/json-url-master/src/main/codecs/pack.js ================================================================== --- public/json-url-master/src/main/codecs/pack.js +++ public/json-url-master/src/main/codecs/pack.js @@ -0,0 +1,6 @@ +export default { + pack: true, + encode: true, + compress: async _ => _, + decompress: async _ => _ +}; ADDED public/json-url-master/src/main/index.js Index: public/json-url-master/src/main/index.js ================================================================== --- public/json-url-master/src/main/index.js +++ public/json-url-master/src/main/index.js @@ -0,0 +1,39 @@ +import ALGORITHMS from 'main/codecs'; +import LOADERS from 'main/loaders'; + +const twoDigitPercentage = val => Math.floor(val * 10000) / 10000; + +export default function createClient(algorithm) { + if (!Object.prototype.hasOwnProperty.call(ALGORITHMS, algorithm)) throw new Error(`No such algorithm ${algorithm}`); + + const { pack, encode } = ALGORITHMS[algorithm]; + + async function compress(json) { + const packed = pack ? (await LOADERS.msgpack()).encode(json) : JSON.stringify(json); + const compressed = await ALGORITHMS[algorithm].compress(packed); + const encoded = encode ? (await LOADERS.safe64()).encode(compressed) : compressed; + return encoded; + } + + async function decompress(string) { + const decoded = encode ? (await LOADERS.safe64()).decode(string) : string; + const decompressed = await ALGORITHMS[algorithm].decompress(decoded); + const unpacked = pack ? (await LOADERS.msgpack()).decode(decompressed) : JSON.parse(decompressed); + return unpacked; + } + + async function stats(json) { + const raw = JSON.stringify(json); + const rawencoded = encodeURIComponent(raw); + const compressed = await compress(json); + + return { + raw: raw.length, + rawencoded: rawencoded.length, + compressedencoded: compressed.length, + compression: twoDigitPercentage(rawencoded.length / compressed.length) + }; + } + + return { compress, decompress, stats }; +} ADDED public/json-url-master/src/main/loaders.js Index: public/json-url-master/src/main/loaders.js ================================================================== --- public/json-url-master/src/main/loaders.js +++ public/json-url-master/src/main/loaders.js @@ -0,0 +1,25 @@ +// centralize all chunks in one file +export default { + async msgpack() { + const module = await import(/* webpackChunkName: "msgpack" */ 'msgpack5'); + const factory = module.default || module; + return factory(); + }, + async safe64() { + return await import(/* webpackChunkName: "safe64" */ 'urlsafe-base64'); + }, + async lzma() { + const lzma = await import(/* webpackChunkName: "lzma" */ 'lzma'); + + // this special condition is present because the web minified version has a slightly different export + return lzma.compress ? lzma : lzma.LZMA; + }, + async lzstring() { + return await import(/* webpackChunkName: "lzstring" */ 'lz-string'); + }, + async lzw() { + const module = await import(/* webpackChunkName: "lzw" */ 'node-lzw'); + const lzw = module.default || module; + return lzw; + } +}; ADDED public/json-url-master/test/index.js Index: public/json-url-master/test/index.js ================================================================== --- public/json-url-master/test/index.js +++ public/json-url-master/test/index.js @@ -0,0 +1,35 @@ +/* global describe, it */ +import assert from 'assert'; +import createClient from 'main'; +import { validate } from 'urlsafe-base64'; +import samples from './samples.json' + +describe('json-url', () => { + samples.forEach(sample => { + describe(`When attempting to compress ${JSON.stringify(sample).slice(0, 50)}...`, () => { + ['pack', 'lzw', 'lzma', 'lzstring'].forEach(algorithm => { + describe(`using the ${algorithm} algorithm`, () => { + const client = createClient(algorithm); + + it('compresses JSON via #compress to base64 format', async () => { + const compressed = await client.compress(sample); + assert.ok(validate(compressed), `${compressed} is not valid base64`); + }); + + it('can decompress JSON compressed via #compress using #decompress', async () => { + const compressed = await client.compress(sample); + const decompressed = await client.decompress(compressed); + assert.equal(JSON.stringify(decompressed), JSON.stringify(sample)); + }); + + it('returns stats { rawencoded, compressedencoded, compression } via #stats', async () => { + const result = await client.stats(sample); + assert.ok(result['rawencoded']); + assert.ok(result['compressedencoded']); + assert.ok(result['compression']); + }); + }); // each algorithm + }); + }); // each sample + }); +}); ADDED public/json-url-master/test/perf.js Index: public/json-url-master/test/perf.js ================================================================== --- public/json-url-master/test/perf.js +++ public/json-url-master/test/perf.js @@ -0,0 +1,30 @@ +import jsonUrl from 'main/index.js'; +import samples from './samples.json'; +import ALGORITHMS from 'main/compress'; + +const algorithms = Object.keys(ALGORITHMS); + +async function main() { + + const results = new Array(samples.length); + + for (const algorithm of algorithms) { + const lib = jsonUrl(algorithm); + let counter = 0; + for (const datum of samples) { + const { raw, rawencoded, compressedencoded, compression } = await lib.stats(datum); + results[counter] = results[counter] || {}; + results[counter].raw = raw; + results[counter].rawencoded = rawencoded; + results[counter][algorithm] = { + ratio: compression, + compressed: compressedencoded + }; + counter += 1; + } + } + + console.log(JSON.stringify(results, null, 2)); +} + +main(); ADDED public/json-url-master/test/samples.json Index: public/json-url-master/test/samples.json ================================================================== --- public/json-url-master/test/samples.json +++ public/json-url-master/test/samples.json @@ -0,0 +1,398 @@ +[ + { + "filters": { + "amenities": [4, 55, 23], + "budget_max": 80000, + "budget_min": 50000, + "event_types": [1, 2, 3], + "neighborhoods": [4, 55, 502] + }, + "page": 1, + "search_fields": { + "end_time": "11:00pm", + "guests": "50", + "region": 8, + "start_date": "11-23-2015", + "start_time": "8:00pm" + }, + "search_for_name": "Name Search Test" + }, + { + "setup": { + "protocol": "NVP" + }, + "use": { + "master": { + "stage": "NO" + } + }, + "common_request_params": { + "version": "123", + "method": "SetExpressCheckout" + }, + "NVP": { + "SetExpressCheckout": { + "AMT": "16", + "CANCELURL": "http://xotoolslvs01.qa.paypal.com/ectest/cancel.html", + "L_AMT0": "8", + "L_NAME0": "Test Item fewarwerwerw", + "L_QTY0": "2", + "PAYMENTACTION": "Sale", + "RETURNURL": "http://xotoolslvs01.qa.paypal.com/ectest/return.html", + "_custom0__name": "L_DESC0", + "_custom0": "hello worldhello worldhello worldhello worldhello worldhello worldhello worldhello worldhello worldhello world" + } + } + }, + { + "zh": { + "name": "China", + "continent": "Asia", + "flagColors": [ + "red", + "yellow" + ], + "leader": { + "name": "习 近平-习", + "title": "President", + "term": 137 + }, + "population": 1370000000 + }, + "in": { + "name": "India", + "continent": "", + "a": true, + "b": false, + "c": null, + "emptyArray": [], + "emptyObject": {}, + "flagColors": [ + "orange", + "white", + "green" + ], + "leader": { + "name": "Narendra\nModi.", + "title": "Prime Minister", + "term": 119 + }, + "population": 1190000000 + }, + "array": [ + "asdf", + [ + 3, + 4 + ] + ] + }, + { + "one": 1 + }, + { + "one": 1, + "two": 2, + "three": 3 + }, + { + "_id": "55d54e11bf8bf51e99245818", + "index": 0, + "guid": "f1205498-83a2-4f9d-ba60-ded5585c0e67", + "isActive": false, + "balance": "$2,370.15", + "picture": "http://placehold.it/32x32", + "age": 28, + "eyeColor": "green", + "name": { + "first": "Jill", + "last": "Pennington" + }, + "company": "GAZAK", + "email": "jill.pennington@gazak.co.uk", + "phone": "+1 (998) 584-3321", + "address": "517 Coles Street, Skyland, Montana, 7661", + "about": "Pariatur tempor consequat amet do incididunt aute nulla. Pariatur reprehenderit nostrud quis mollit duis ipsum ut consequat mollit qui. Ullamco reprehenderit nostrud nulla nisi ipsum adipisicing esse. Et ullamco in reprehenderit fugiat consectetur sunt laborum est. Magna sit consectetur commodo tempor dolore sint id dolor Lorem Lorem. Ex nisi ea occaecat nisi. Voluptate enim in aliquip laborum consectetur eu commodo enim excepteur ex.", + "registered": "Saturday, July 26, 2014 3:55 PM", + "latitude": "74.180645", + "longitude": "-80.748226", + "tags": [ + "anim", + "est", + "excepteur", + "esse", + "voluptate", + "nulla", + "anim", + "custom_tag" + ], + "range": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9 + ], + "friends": [ + { + "id": 0, + "name": "Frazier Schwartz" + }, + { + "id": 1, + "name": "Ellis Fuller" + }, + { + "id": 2, + "name": "Laurel Hill" + } + ], + "greeting": "Hello, Jill! You have 9 unread messages.", + "favoriteFruit": "apple" + }, + { + "_id": "55d54e11e47640367e1e8a29", + "index": 1, + "guid": "edb46838-ba45-4de1-8a8a-71a7503d5a2d", + "isActive": true, + "balance": "$3,282.70", + "picture": "http://placehold.it/32x32", + "age": 35, + "eyeColor": "brown", + "name": { + "first": "Eliza", + "last": "Mcdaniel" + }, + "company": "GENMOM", + "email": "eliza.mcdaniel@genmom.name", + "phone": "+1 (991) 496-2864", + "address": "532 Jewel Street, Outlook, Utah, 2237", + "about": "Aliquip ea et mollit in excepteur anim duis adipisicing laboris esse occaecat. Mollit tempor et duis sit tempor irure sint sit id enim eiusmod. Amet consectetur esse commodo nostrud dolore excepteur in laboris aliqua cillum elit velit adipisicing deserunt. Ut excepteur ad quis ea velit aliqua tempor consectetur.", + "registered": "Sunday, August 17, 2014 1:04 AM", + "latitude": "-39.904477", + "longitude": "71.117407", + "tags": [ + "anim", + "est", + "excepteur", + "esse", + "voluptate", + "nulla", + "anim", + "custom_tag" + ], + "range": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9 + ], + "friends": [ + { + "id": 0, + "name": "Frazier Schwartz" + }, + { + "id": 1, + "name": "Ellis Fuller" + }, + { + "id": 2, + "name": "Laurel Hill" + } + ], + "greeting": "Hello, Eliza! You have 9 unread messages.", + "favoriteFruit": "banana" + }, + { + "_id": "55d54e118f4a1f5c6749e9fa", + "index": 2, + "guid": "854040fa-6f9d-481b-990e-d2877dbee2d4", + "isActive": false, + "balance": "$3,010.47", + "picture": "http://placehold.it/32x32", + "age": 40, + "eyeColor": "brown", + "name": { + "first": "Robert", + "last": "Burch" + }, + "company": "ACRODANCE", + "email": "robert.burch@acrodance.biz", + "phone": "+1 (876) 431-2360", + "address": "139 Cornelia Street, Collins, Oklahoma, 671", + "about": "Voluptate anim est velit reprehenderit sit ut magna non commodo. Commodo veniam sit non commodo nisi enim. Sint adipisicing culpa cillum exercitation irure consequat laboris laborum.", + "registered": "Wednesday, September 17, 2014 9:16 AM", + "latitude": "-18.778534", + "longitude": "-77.0815", + "tags": [ + "anim", + "est", + "excepteur", + "esse", + "voluptate", + "nulla", + "anim", + "custom_tag" + ], + "range": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9 + ], + "friends": [ + { + "id": 0, + "name": "Frazier Schwartz" + }, + { + "id": 1, + "name": "Ellis Fuller" + }, + { + "id": 2, + "name": "Laurel Hill" + } + ], + "greeting": "Hello, Robert! You have 6 unread messages.", + "favoriteFruit": "strawberry" + }, + { + "_id": "55d54e1161c743c696e550b9", + "index": 3, + "guid": "a9bc9cc1-f159-44c0-af72-0832a4a05ed6", + "isActive": false, + "balance": "$2,632.61", + "picture": "http://placehold.it/32x32", + "age": 32, + "eyeColor": "green", + "name": { + "first": "Mae", + "last": "Fowler" + }, + "company": "JUNIPOOR", + "email": "mae.fowler@junipoor.org", + "phone": "+1 (825) 426-2682", + "address": "316 Pineapple Street, Hegins, New York, 5565", + "about": "Voluptate elit non magna excepteur velit voluptate. Eu aliqua Lorem eiusmod ut quis amet cillum consequat. Do magna ex laborum incididunt est proident dolore tempor in ullamco. Commodo irure labore nulla voluptate in voluptate minim mollit enim aliqua minim excepteur ad esse.", + "registered": "Thursday, June 18, 2015 10:05 PM", + "latitude": "-62.526412", + "longitude": "-54.420474", + "tags": [ + "anim", + "est", + "excepteur", + "esse", + "voluptate", + "nulla", + "anim", + "custom_tag" + ], + "range": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9 + ], + "friends": [ + { + "id": 0, + "name": "Frazier Schwartz" + }, + { + "id": 1, + "name": "Ellis Fuller" + }, + { + "id": 2, + "name": "Laurel Hill" + } + ], + "greeting": "Hello, Mae! You have 9 unread messages.", + "favoriteFruit": "banana" + }, + { + "_id": "55d54e1134a6c7726d4311b7", + "index": 4, + "guid": "7b5cbc42-3c27-41fd-bec4-08e34581ce26", + "isActive": false, + "balance": "$2,232.78", + "picture": "http://placehold.it/32x32", + "age": 39, + "eyeColor": "blue", + "name": { + "first": "Casey", + "last": "Evans" + }, + "company": "NETERIA", + "email": "casey.evans@neteria.ca", + "phone": "+1 (989) 576-2758", + "address": "940 Norfolk Street, Keller, Iowa, 6578", + "about": "Do Lorem ullamco laborum ex qui qui ea ullamco deserunt aliquip reprehenderit sint dolore. Amet est dolor minim officia. Non irure sint mollit aute sunt ad enim id ullamco amet excepteur minim. Deserunt cillum esse do cupidatat cupidatat dolor nostrud proident pariatur laborum minim incididunt. Adipisicing eiusmod nulla aliquip in ea commodo anim irure ex qui culpa sint. Cupidatat fugiat est laboris culpa occaecat veniam qui eiusmod. Laborum qui dolore est ipsum anim.", + "registered": "Monday, August 25, 2014 11:26 PM", + "latitude": "52.117994", + "longitude": "-9.442317", + "tags": [ + "anim", + "est", + "excepteur", + "esse", + "voluptate", + "nulla", + "anim", + "custom_tag" + ], + "range": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9 + ], + "friends": [ + { + "id": 0, + "name": "Frazier Schwartz" + }, + { + "id": 1, + "name": "Ellis Fuller" + }, + { + "id": 2, + "name": "Laurel Hill" + } + ], + "greeting": "Hello, Casey! You have 5 unread messages.", + "favoriteFruit": "apple" + } +] ADDED public/json-url-master/webpack.config.js Index: public/json-url-master/webpack.config.js ================================================================== --- public/json-url-master/webpack.config.js +++ public/json-url-master/webpack.config.js @@ -0,0 +1,47 @@ +/* eslint-disable import/unambiguous */ +const UglifyJSPlugin = require('uglifyjs-webpack-plugin'); + +module.exports = { + entry: './src/main/browser-index.js', + output: { + library: 'JsonUrl', + libraryTarget: 'umd', + libraryExport: 'default', + filename: 'json-url.js', + chunkFilename: 'json-url-[name].js', + path: __dirname + '/dist/browser' + }, + module: { + rules: [ + { + test: /\.js$/, + exclude: /(node_modules|bower_components)/, + use: { + loader: 'babel-loader', + options: { + babelrc: false, + presets: ['@babel/preset-env'], + plugins: [ + '@babel/plugin-syntax-dynamic-import', + ['module-resolver', + { + root: ["src"], + alias: { + lzma: require.resolve('lzma/src/lzma_worker-min'), + bluebird: require.resolve('bluebird/js/browser/bluebird.core.min.js') + } + } + ], + '@babel/plugin-transform-runtime', + ] + } + } + } + ], + }, + plugins: [ + new UglifyJSPlugin({ + comments: false + }) + ] +}; ADDED public/json-url-master/webpack.config.single.js Index: public/json-url-master/webpack.config.single.js ================================================================== --- public/json-url-master/webpack.config.single.js +++ public/json-url-master/webpack.config.single.js @@ -0,0 +1,56 @@ +/* eslint-disable import/unambiguous */ +const webpack = require('webpack'); +const UglifyJSPlugin = require('uglifyjs-webpack-plugin'); + +module.exports = { + entry: './src/main/browser-index.js', + output: { + library: 'JsonUrl', + libraryTarget: 'umd', + libraryExport: 'default', + filename: 'json-url-single.js', + path: __dirname + '/dist/browser' + }, + module: { + rules: [ + { + test: /\.js$/, + exclude: /(node_modules|bower_components)/, + use: { + loader: 'babel-loader', + options: { + babelrc: false, + presets: ['@babel/preset-env'], + plugins: [ + '@babel/plugin-syntax-dynamic-import', + ['module-resolver', + { + root: ["src"], + alias: { + lzma: require.resolve('lzma/src/lzma_worker-min'), + bluebird: require.resolve('bluebird/js/browser/bluebird.core.min.js') + } + } + ], + '@babel/plugin-transform-runtime', + ] + } + } + } + ], + }, + node: { + global: false + }, + plugins: [ + new UglifyJSPlugin({ + comments: false + }), + new webpack.optimize.LimitChunkCountPlugin({ + maxChunks: 1 + }), + new webpack.DefinePlugin({ + global: 'window' + }) + ] +}; ADDED public/misc.js Index: public/misc.js ================================================================== --- public/misc.js +++ public/misc.js @@ -0,0 +1,271 @@ + +function initWinamp(preset) { + var can = document.getElementById("visual"); + can.height = window.innerHeight - document.getElementById("header-playback").clientHeight - 75; + can.width = window.innerWidth; + var can_container = document.getElementById("canvas-container"); + can_container.width = window.innerWidth; + var visualizer = window.butterchurn.default.createVisualizer(Tone.getContext().rawContext, can, { + height: window.innerHeight - document.getElementById("header-playback").clientHeight - 75, + width: window.innerWidth, + meshWidth: 24, + meshHeight: 18, + }); + visualizer.connectAudio(Tone.getContext().destination); + const presets = window.butterchurnPresets.getPresets(); + const presetParam = presets[preset]; + visualizer.loadPreset(presetParam, 0.0); // 2nd argument is the number of seconds to blend presets + return visualizer; +} + +function guard(range) { + var state = null; + return function (val) { + if ((val >= range[0]) && (val <= range[1])) { + state = val; + return val; + } else { + return state; + } + } +} + +function hex2bin(hex) { + var letters = hex.replace('`1','a'); + letters = hex.replace('`2','b'); + letters = hex.replace('`3','c'); + letters = hex.replace('`4','d'); + letters = hex.replace('`5','e'); + letters = hex.replace('`6','f'); + letters = letters.split(''); + var bin = ""; + letters.map(function(letter) { + if (letter == "0") { + bin += "0000"; + } + if (letter == "1") { + bin += "0001"; + } + else if (letter == "2") { + bin += "0010"; + } + else if (letter == "3") { + bin += "0011"; + } + else if (letter == "4") { + bin += "0100"; + } + else if (letter == "5") { + bin += "0101"; + } + else if (letter == "6") { + bin += "0110"; + } + else if (letter == "7") { + bin += "0111"; + } + else if (letter == "8") { + bin += "1000"; + } + else if (letter == "9") { + bin += "1001"; + } + else if (letter == "a") { + bin += "1010"; + } + else if (letter == "b") { + bin += "1011"; + } + else if (letter == "c") { + bin += "1100"; + } + else if (letter == "d") { + bin += "1101"; + } + else if (letter == "e") { + bin += "1110"; + } + else if (letter == "f") { + bin += "1111"; + } + + }) + return bin; +} + + +function pattern_clean(p) { + if (!p) { + return ""; + } + p = p.replace(/ /g, ""); + var fc = p.split('')[0]; + if (fc== "p") { + var ptype = "xo"; + var l = (p.length - 1); + } + else if (fc== "b") { + var l = (p.length - 1); + var ptype = "bin"; + } + else { + var ptype = "hex"; + var l = (p.length) * 4; + } + + if (ptype == "bin") { + var fp = p.substring(1); + } else if (ptype == "xo") { + var fp = p.substr(1); + fp = fp.replace(/x/g, "1"); + } else { + var fp = hex2bin(p); + } + + return fp; +} + +function download(data, filename, type) { + var file = new Blob([data], { type: type }); + if (window.navigator.msSaveOrOpenBlob) // IE10+ + window.navigator.msSaveOrOpenBlob(file, filename); + else { // Others + var a = document.createElement("a"), + url = URL.createObjectURL(file); + a.href = url; + a.download = filename; + document.body.appendChild(a); + a.click(); + setTimeout(function () { + document.body.removeChild(a); + window.URL.revokeObjectURL(url); + }, 0); + } +} + +// https://stackoverflow.com/questions/15762768/javascript-math-round-to-two-decimal-places +function roundTo(n, digits) { + var negative = false; + if (digits === undefined) { + digits = 0; + } + if (n < 0) { + negative = true; + n = n * -1; + } + var multiplicator = Math.pow(10, digits); + n = parseFloat((n * multiplicator).toFixed(11)); + n = (Math.round(n) / multiplicator).toFixed(digits); + if (negative) { + n = (n * -1).toFixed(digits); + } + return n; +} + + +function knob(options) { + options = options || {}; + var context = {}; + context.ramp = options.ramp || [0 , 1]; + context.count_skip = options.speed || 4; + context.step = options.step || 0.01; + context.reverse = options.reverse || true; + context.number = options.number || null; + + context.current_count = 0; + context.index = 0; + context.val = window.cellx.cellx(options.initial || 0.5) + + function changeContext() { + context.next_val = context.ramp[context.index + 1]; + + context.val(context.ramp[context.index]); + if (context.val() > context.next_val) { + context.direction = -1; + } else { + context.direction = 1; + } + } + + changeContext(); + + return { + "cell": context.val, + "push": function (val) { + context.ramp.push(val); + }, + "replace": function (val) { + context.ramp = val; + }, + "speed": function (val) { + context.count_skip = val; + }, + "step": function (val) { + context.step = val; + }, + "up": function (val) { + val = val || 0.1; + context.ramp.push(context.ramp[context.ramp.length - 1] + val); + }, + "down": function (val) { + val = val || -0.1; + context.ramp.push(context.ramp[context.ramp.length - 1] + val); + }, + "move": function () { + if (context.current_count >= context.count_skip) { + context.current_count = 1; + + if (context.direction == 1) { + var cmp = function () { + return (context.val() >= context.next_val); + }; + } else { + var cmp = function () { + return (context.next_val >= context.val()); + }; + } + + if (cmp()) { + context.val(context.next_val); + context.index = context.index + 1; + if (context.index === context.ramp.length -1) { + if (context.reverse) { + context.index = 0; + context.ramp = context.ramp.reverse(); + } else { + context.index = context.index - 1; + } + } + changeContext(); + context.val(context.val() + context.step * context.direction); + if (context.number) context.number(context.val()); + } else { + context.val(context.val() + context.step * context.direction); + if (context.number) context.number(context.val()); + } + } else { + context.current_count += 1; + } + + return context.val(); + } + } +} + +function timedKnob(options) { + options = options || {}; + var context = {}; + context.interval = options.interval || 100; + context.knob = knob(options); + + context.timer = setInterval(function () { + context.knob.move(); + }, context.interval); + + context.knob["clear"] = function () { + clearInterval(context.timer); + } + + return context.knob; +} + ADDED public/nexus-js/CHANGELOG.md Index: public/nexus-js/CHANGELOG.md ================================================================== --- public/nexus-js/CHANGELOG.md +++ public/nexus-js/CHANGELOG.md @@ -0,0 +1,34 @@ +# Changelog + +All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. + +### [2.1.6](https://github.com/nexus-js/ui/compare/v2.1.5...v2.1.6) (2020-08-29) + +### [2.1.5](https://github.com/nexus-js/ui/compare/v2.1.4...v2.1.5) (2020-07-26) + +### [2.1.4](https://github.com/nexus-js/ui/compare/v2.1.3...v2.1.4) (2020-06-05) + +### [2.1.3](https://github.com/nexus-js/ui/compare/v2.1.2...v2.1.3) (2020-05-17) + + +### Bug Fixes + +* ([#138](https://github.com/nexus-js/ui/issues/138)) [#179](https://github.com/nexus-js/ui/issues/179) ([f08069c](https://github.com/nexus-js/ui/commit/f08069c1473b783dd802b1291cc02863e8b6a997)) +* Nexus.tune.createScale() does not produce expected scale ([#138](https://github.com/nexus-js/ui/issues/138)) ([449fbd5](https://github.com/nexus-js/ui/commit/449fbd5be320bc63bd6f385b2fe6ee33b8a18d85)) +* numberOfSliders does not change number of sliders for Multislider ([#161](https://github.com/nexus-js/ui/issues/161)) ([bdb3700](https://github.com/nexus-js/ui/commit/bdb370014a3a2d01f485adaa87632b38eb23dd92)) + +### [2.1.2](https://github.com/nexus-js/ui/compare/v2.1.1...v2.1.2) (2020-03-31) + +### [2.1.1](https://github.com/nexus-js/ui/compare/v2.1.0...v2.1.1) (2020-03-31) + +## [2.1.0](https://github.com/nexus-js/ui/compare/v2.0.13...v2.1.0) (2020-03-31) + + +### Features + +* add padding to sequencer ([#150](https://github.com/nexus-js/ui/issues/150)) [#178](https://github.com/nexus-js/ui/issues/178) ([1672cc3](https://github.com/nexus-js/ui/commit/1672cc36c57cc2c2531c01121b0226a918473307)) +* add padding to sequencer ([#150](https://github.com/nexus-js/ui/issues/150)) [#178](https://github.com/nexus-js/ui/issues/178) ([b50f1b6](https://github.com/nexus-js/ui/commit/b50f1b6940296befeb995364a6654c682fdb66e7)) +* support for vertical orientation ([#115](https://github.com/nexus-js/ui/issues/115)) ([bb24906](https://github.com/nexus-js/ui/commit/bb24906be84e343fb1168c9cac1e893375670439)) +* support for vertical orientation ([#115](https://github.com/nexus-js/ui/issues/115)) ([2dd86ad](https://github.com/nexus-js/ui/commit/2dd86ad45ba940483d018078a3b8283d5e916ae6)) + +### [2.0.13](https://github.com/nexus-js/ui/compare/v2.0.12...v2.0.13) (2020-03-17) ADDED public/nexus-js/CODE_OF_CONDUCT.md Index: public/nexus-js/CODE_OF_CONDUCT.md ================================================================== --- public/nexus-js/CODE_OF_CONDUCT.md +++ public/nexus-js/CODE_OF_CONDUCT.md @@ -0,0 +1,46 @@ +# Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting active members of the project team. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/4/ ADDED public/nexus-js/CONTRIBUTING.md Index: public/nexus-js/CONTRIBUTING.md ================================================================== --- public/nexus-js/CONTRIBUTING.md +++ public/nexus-js/CONTRIBUTING.md @@ -0,0 +1,23 @@ +# Contributing + +A pre-emptive thank you for contributing! Open Source projects like this one survive with the active participation of community members who can help push it forward. + +When contributing to this repository, please first discuss the change you wish to make via issue, email, or any other method with the owners of this repository before making a change. + +## Pull Request Process + +Before sending a Pull Request, please make sure that you're assigned the task on a GitHub issue. + +* A Pull Request has a higher chance of being accepted if the work has been acknowledged and assigned by the team. +* If a relevant issue exists, please discuss on the issue and get it assigned to yourself on Github. +* If no relevant issue exists, open a new issue and get it assigned to yourself on GitHub. +* Please do not commit any build / install dependencies directly to the repo. +* Whenever possible, update the JSDocs annotations and/or README.md with relevant changes. Online documentation is generated by running `npm run docgen`. +* Increase the version numbers in any examples files and the README.md to the new version that this Pull Request would represent. The versioning scheme we use is [SemVer](http://semver.org/). + * We use [standard-version](https://github.com/conventional-changelog/standard-version) to automatically bump versions in the package.json and write to the CHANGELOG. + * Call it using `npm run release`. +* Please respond to discussion during Review of your Pull Request. + +## Code of Conduct + +This project and everyone participating in it is governed by the [Code of Conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. ADDED public/nexus-js/README.md Index: public/nexus-js/README.md ================================================================== --- public/nexus-js/README.md +++ public/nexus-js/README.md @@ -0,0 +1,11 @@ +# NexusUI + +##### Version 2 + +NexusUI is a JavaScript toolkit of web audio interfaces and other helper methods for building instruments in the browser. + +For more info, see the [website](http://nexus-js.github.io/ui/). + +For documentation and tutorials, see [the API](http://nexus-js.github.io/ui/api/). + +Join us on our [Discord](https://discord.gg/gFMXnyK) to chat about NexusUI current and future developments. Also join us if you need help using any of the components. ADDED public/nexus-js/api/api.json Index: public/nexus-js/api/api.json ================================================================== --- public/nexus-js/api/api.json +++ public/nexus-js/api/api.json @@ -0,0 +1,22193 @@ +[ + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Button Template", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 16, + "offset": 15 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 16, + "offset": 15 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 16, + "offset": 15 + } + } + }, + "tags": [], + "loc": { + "start": { + "line": 8, + "column": 0 + }, + "end": { + "line": 10, + "column": 2 + } + }, + "context": { + "loc": { + "start": { + "line": 12, + "column": 0 + }, + "end": { + "line": 222, + "column": 1 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/components/buttontemplate.js" + }, + "augments": [ + { + "title": "augments", + "name": "Interface" + } + ], + "examples": [], + "params": [ + { + "title": "param", + "name": "args", + "lineNumber": 14 + }, + { + "title": "param", + "name": "options", + "lineNumber": 14 + }, + { + "title": "param", + "name": "defaults", + "lineNumber": 14 + } + ], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "ButtonTemplate", + "kind": "class", + "members": { + "global": [], + "inner": [], + "instance": [ + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Whether the button is on (pressed) or off (not pressed)", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 56, + "offset": 55 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 56, + "offset": 55 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 56, + "offset": 55 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "boolean" + } + }, + { + "title": "example", + "description": "button.state = true;", + "lineNumber": 3 + } + ], + "loc": { + "start": { + "line": 141, + "column": 2 + }, + "end": { + "line": 145, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 146, + "column": 2 + }, + "end": { + "line": 148, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/components/buttontemplate.js" + }, + "augments": [], + "examples": [ + { + "description": "button.state = true;" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "state", + "kind": "member", + "memberof": "ButtonTemplate", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "ButtonTemplate", + "kind": "class" + }, + { + "name": "state", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "ButtonTemplate#state" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Change the button to its alternate state (off=>on, on=>off), or flip it to a specified state.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 94, + "offset": 93 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 94, + "offset": 93 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 94, + "offset": 93 + } + } + }, + "tags": [ + { + "title": "param", + "description": "{boolean} (Optional) State to flip to.", + "lineNumber": 2, + "type": null, + "name": "value" + }, + { + "title": "example", + "description": "button.flip();", + "lineNumber": 3 + } + ], + "loc": { + "start": { + "line": 163, + "column": 2 + }, + "end": { + "line": 167, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 168, + "column": 2 + }, + "end": { + "line": 180, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/components/buttontemplate.js" + }, + "augments": [], + "examples": [ + { + "description": "button.flip();" + } + ], + "params": [ + { + "title": "param", + "name": "value", + "lineNumber": 2, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "{boolean} (Optional) State to flip to.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 39, + "offset": 38 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 39, + "offset": 38 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 39, + "offset": 38 + } + } + } + } + ], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "flip", + "kind": "function", + "memberof": "ButtonTemplate", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "ButtonTemplate", + "kind": "class" + }, + { + "name": "flip", + "kind": "function", + "scope": "instance" + } + ], + "namespace": "ButtonTemplate#flip" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Turn the button's state to true.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 33, + "offset": 32 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 33, + "offset": 32 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 33, + "offset": 32 + } + } + }, + "tags": [ + { + "title": "example", + "description": "button.turnOn();", + "lineNumber": 2 + } + ], + "loc": { + "start": { + "line": 182, + "column": 2 + }, + "end": { + "line": 185, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 186, + "column": 2 + }, + "end": { + "line": 200, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/components/buttontemplate.js" + }, + "augments": [], + "examples": [ + { + "description": "button.turnOn();" + } + ], + "params": [ + { + "title": "param", + "name": "emitting", + "lineNumber": 186 + } + ], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "turnOn", + "kind": "function", + "memberof": "ButtonTemplate", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "ButtonTemplate", + "kind": "class" + }, + { + "name": "turnOn", + "kind": "function", + "scope": "instance" + } + ], + "namespace": "ButtonTemplate#turnOn" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Turn the button's state to false.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 34, + "offset": 33 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 34, + "offset": 33 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 34, + "offset": 33 + } + } + }, + "tags": [ + { + "title": "example", + "description": "button.turnOff();", + "lineNumber": 2 + } + ], + "loc": { + "start": { + "line": 202, + "column": 2 + }, + "end": { + "line": 205, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 206, + "column": 2 + }, + "end": { + "line": 220, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/components/buttontemplate.js" + }, + "augments": [], + "examples": [ + { + "description": "button.turnOff();" + } + ], + "params": [ + { + "title": "param", + "name": "emitting", + "lineNumber": 206 + } + ], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "turnOff", + "kind": "function", + "memberof": "ButtonTemplate", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "ButtonTemplate", + "kind": "class" + }, + { + "name": "turnOff", + "kind": "function", + "scope": "instance" + } + ], + "namespace": "ButtonTemplate#turnOff" + } + ], + "events": [], + "static": [] + }, + "path": [ + { + "name": "ButtonTemplate", + "kind": "class" + } + ], + "namespace": "ButtonTemplate" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "The slider's current value. If set manually, will update the interface and trigger the output event.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 101, + "offset": 100 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 101, + "offset": 100 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 101, + "offset": 100 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "number" + } + }, + { + "title": "example", + "description": "slider.value = 10;", + "lineNumber": 3 + } + ], + "loc": { + "start": { + "line": 185, + "column": 2 + }, + "end": { + "line": 189, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 190, + "column": 2 + }, + "end": { + "line": 192, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/components/slidertemplate.js" + }, + "augments": [], + "examples": [ + { + "description": "slider.value = 10;" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "value", + "kind": "member", + "memberof": "SliderTemplate", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "value", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "#value" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Lower limit of the sliders's output range", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 42, + "offset": 41 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 42, + "offset": 41 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 42, + "offset": 41 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "number" + } + }, + { + "title": "example", + "description": "slider.min = 1000;", + "lineNumber": 3 + } + ], + "loc": { + "start": { + "line": 199, + "column": 2 + }, + "end": { + "line": 203, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 204, + "column": 2 + }, + "end": { + "line": 206, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/components/slidertemplate.js" + }, + "augments": [], + "examples": [ + { + "description": "slider.min = 1000;" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "min", + "kind": "member", + "memberof": "SliderTemplate", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "min", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "#min" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Upper limit of the slider's output range", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 41, + "offset": 40 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 41, + "offset": 40 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 41, + "offset": 40 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "number" + } + }, + { + "title": "example", + "description": "slider.max = 1000;", + "lineNumber": 3 + } + ], + "loc": { + "start": { + "line": 211, + "column": 2 + }, + "end": { + "line": 215, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 216, + "column": 2 + }, + "end": { + "line": 218, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/components/slidertemplate.js" + }, + "augments": [], + "examples": [ + { + "description": "slider.max = 1000;" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "max", + "kind": "member", + "memberof": "SliderTemplate", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "max", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "#max" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "The increment that the slider's value changes by.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 50, + "offset": 49 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 50, + "offset": 49 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 50, + "offset": 49 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "number" + } + }, + { + "title": "example", + "description": "slider.step = 5;", + "lineNumber": 3 + } + ], + "loc": { + "start": { + "line": 223, + "column": 2 + }, + "end": { + "line": 227, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 228, + "column": 2 + }, + "end": { + "line": 230, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/components/slidertemplate.js" + }, + "augments": [], + "examples": [ + { + "description": "slider.step = 5;" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "step", + "kind": "member", + "memberof": "SliderTemplate", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "step", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "#step" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Absolute mode (slider's value jumps to mouse click position) or relative mode (mouse drag changes value relative to its current position). Default: \"relative\".", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 160, + "offset": 159 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 160, + "offset": 159 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 160, + "offset": 159 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "string" + } + }, + { + "title": "example", + "description": "slider.mode = \"relative\";", + "lineNumber": 3 + } + ], + "loc": { + "start": { + "line": 235, + "column": 2 + }, + "end": { + "line": 239, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 240, + "column": 2 + }, + "end": { + "line": 242, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/components/slidertemplate.js" + }, + "augments": [], + "examples": [ + { + "description": "slider.mode = \"relative\";" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "mode", + "kind": "member", + "memberof": "SliderTemplate", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "mode", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "#mode" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Interface", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 10, + "offset": 9 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 10, + "offset": 9 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 10, + "offset": 9 + } + } + }, + "tags": [], + "loc": { + "start": { + "line": 11, + "column": 0 + }, + "end": { + "line": 13, + "column": 2 + } + }, + "context": { + "loc": { + "start": { + "line": 14, + "column": 0 + }, + "end": { + "line": 306, + "column": 1 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/core/interface.js" + }, + "augments": [ + { + "title": "augments", + "name": "EventEmitter" + } + ], + "examples": [], + "params": [ + { + "title": "param", + "name": "args", + "lineNumber": 16 + }, + { + "title": "param", + "name": "options", + "lineNumber": 16 + }, + { + "title": "param", + "name": "defaults", + "lineNumber": 16 + } + ], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "Interface", + "kind": "class", + "members": { + "global": [], + "inner": [], + "instance": [ + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Resize the interface", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 21, + "offset": 20 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 21, + "offset": 20 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 21, + "offset": 20 + } + } + }, + "tags": [ + { + "title": "param", + "description": "{number} New width in pixels", + "lineNumber": 2, + "type": null, + "name": "width" + }, + { + "title": "param", + "description": "{number} New height in pixels", + "lineNumber": 3, + "type": null, + "name": "height" + }, + { + "title": "example", + "description": "button.resize(100,100);", + "lineNumber": 5 + } + ], + "loc": { + "start": { + "line": 257, + "column": 2 + }, + "end": { + "line": 264, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 265, + "column": 2 + }, + "end": { + "line": 273, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/core/interface.js" + }, + "augments": [], + "examples": [ + { + "description": "button.resize(100,100);" + } + ], + "params": [ + { + "title": "param", + "name": "width", + "lineNumber": 2, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "{number} New width in pixels", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 29, + "offset": 28 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 29, + "offset": 28 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 29, + "offset": 28 + } + } + } + }, + { + "title": "param", + "name": "height", + "lineNumber": 3, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "{number} New height in pixels", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 30, + "offset": 29 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 30, + "offset": 29 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 30, + "offset": 29 + } + } + } + } + ], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "resize", + "kind": "function", + "memberof": "Interface", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Interface", + "kind": "class" + }, + { + "name": "resize", + "kind": "function", + "scope": "instance" + } + ], + "namespace": "Interface#resize" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Remove the interface from the page and cancel its event listener(s).", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 69, + "offset": 68 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 69, + "offset": 68 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 69, + "offset": 68 + } + } + }, + "tags": [ + { + "title": "example", + "description": "button.destroy();", + "lineNumber": 3 + } + ], + "loc": { + "start": { + "line": 281, + "column": 2 + }, + "end": { + "line": 286, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 287, + "column": 2 + }, + "end": { + "line": 295, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/core/interface.js" + }, + "augments": [], + "examples": [ + { + "description": "button.destroy();" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "destroy", + "kind": "function", + "memberof": "Interface", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Interface", + "kind": "class" + }, + { + "name": "destroy", + "kind": "function", + "scope": "instance" + } + ], + "namespace": "Interface#destroy" + } + ], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Interface", + "kind": "class" + } + ], + "namespace": "Interface" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Circular button with optional aftertouch.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 42, + "offset": 41 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 42, + "offset": 41 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 42, + "offset": 41 + } + } + }, + "tags": [ + { + "title": "description", + "description": "Circular button with optional aftertouch.", + "lineNumber": 3 + }, + { + "title": "demo", + "description": "", + "lineNumber": 5 + }, + { + "title": "example", + "description": "var button = new Nexus.Button('#target')", + "lineNumber": 7 + }, + { + "title": "example", + "description": "var button = new Nexus.Button('#target',{\n 'size': [80,80],\n 'mode': 'aftertouch',\n 'state': false\n})", + "lineNumber": 10 + }, + { + "title": "output", + "description": "change\nFires any time the interface's value changes.
\nIn button mode, toggle mode, and impulse mode, the output data is a boolean describing the state of the button.
\nIn aftertouch mode, the output data is an object containing x (0-1) and y (0-1) positions of aftertouch.", + "lineNumber": 17 + }, + { + "title": "outputexample", + "description": "button.on('change',function(v) {\n // v is the value of the button\n console.log(v);\n})", + "lineNumber": 23 + } + ], + "loc": { + "start": { + "line": 6, + "column": 0 + }, + "end": { + "line": 35, + "column": 2 + } + }, + "context": { + "loc": { + "start": { + "line": 37, + "column": 0 + }, + "end": { + "line": 120, + "column": 1 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/button.js" + }, + "augments": [ + { + "title": "augments", + "name": "ButtonTemplate" + } + ], + "examples": [ + { + "description": "var button = new Nexus.Button('#target')" + }, + { + "description": "var button = new Nexus.Button('#target',{\n 'size': [80,80],\n 'mode': 'aftertouch',\n 'state': false\n})" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "Button", + "kind": "class", + "members": { + "global": [], + "inner": [], + "instance": [ + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Interaction mode: supports \"button\", \"aftertouch\", \"impulse\", or \"toggle\"", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 74, + "offset": 73 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 74, + "offset": 73 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 74, + "offset": 73 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "string" + } + }, + { + "title": "example", + "description": "button.mode = 'toggle';", + "lineNumber": 3 + } + ], + "loc": { + "start": { + "line": 53, + "column": 4 + }, + "end": { + "line": 57, + "column": 6 + } + }, + "context": { + "loc": { + "start": { + "line": 58, + "column": 4 + }, + "end": { + "line": 58, + "column": 35 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/button.js" + }, + "augments": [], + "examples": [ + { + "description": "button.mode = 'toggle';" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "mode", + "memberof": "Button", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Button", + "kind": "class" + }, + { + "name": "mode", + "scope": "instance" + } + ], + "namespace": "Button#mode" + } + ], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Button", + "kind": "class" + } + ], + "namespace": "Button" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Dial with radial or linear interaction.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 40, + "offset": 39 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 40, + "offset": 39 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 40, + "offset": 39 + } + } + }, + "tags": [ + { + "title": "description", + "description": "Dial with radial or linear interaction.", + "lineNumber": 4 + }, + { + "title": "demo", + "description": "", + "lineNumber": 6 + }, + { + "title": "example", + "description": "var dial = new Nexus.Dial('#target')", + "lineNumber": 8 + }, + { + "title": "example", + "description": "var dial = new Nexus.Dial('#target',{\n 'size': [75,75],\n 'interaction': 'radial', // \"radial\", \"vertical\", or \"horizontal\"\n 'mode': 'relative', // \"absolute\" or \"relative\"\n 'min': 0,\n 'max': 1,\n 'step': 0,\n 'value': 0\n})", + "lineNumber": 11 + }, + { + "title": "output", + "description": "change\nFires any time the interface's value changes.
\nThe event data is the number value of the interface.", + "lineNumber": 22 + }, + { + "title": "outputexample", + "description": "dial.on('change',function(v) {\n console.log(v);\n})", + "lineNumber": 27 + }, + { + "title": "tutorial", + "description": "Dial\nygGMxq", + "lineNumber": 32 + } + ], + "loc": { + "start": { + "line": 9, + "column": 0 + }, + "end": { + "line": 45, + "column": 2 + } + }, + "context": { + "loc": { + "start": { + "line": 47, + "column": 0 + }, + "end": { + "line": 379, + "column": 1 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/dial.js" + }, + "augments": [ + { + "title": "augments", + "name": "Interface" + } + ], + "examples": [ + { + "description": "var dial = new Nexus.Dial('#target')" + }, + { + "description": "var dial = new Nexus.Dial('#target',{\n 'size': [75,75],\n 'interaction': 'radial', // \"radial\", \"vertical\", or \"horizontal\"\n 'mode': 'relative', // \"absolute\" or \"relative\"\n 'min': 0,\n 'max': 1,\n 'step': 0,\n 'value': 0\n})" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "Dial", + "kind": "class", + "members": { + "global": [], + "inner": [], + "instance": [ + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Dial's value. When set, it will automatically be adjust to fit min/max/step settings of the interface.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 103, + "offset": 102 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 103, + "offset": 102 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 103, + "offset": 102 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "number" + } + }, + { + "title": "example", + "description": "dial.value = 10;", + "lineNumber": 3 + } + ], + "loc": { + "start": { + "line": 301, + "column": 4 + }, + "end": { + "line": 305, + "column": 6 + } + }, + "context": { + "loc": { + "start": { + "line": 306, + "column": 4 + }, + "end": { + "line": 308, + "column": 5 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/dial.js" + }, + "augments": [], + "examples": [ + { + "description": "dial.value = 10;" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "value", + "kind": "member", + "memberof": "Dial", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Dial", + "kind": "class" + }, + { + "name": "value", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "Dial#value" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Lower limit of the dial's output range", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 39, + "offset": 38 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 39, + "offset": 38 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 39, + "offset": 38 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "number" + } + }, + { + "title": "example", + "description": "dial.min = 1000;", + "lineNumber": 3 + } + ], + "loc": { + "start": { + "line": 316, + "column": 4 + }, + "end": { + "line": 320, + "column": 6 + } + }, + "context": { + "loc": { + "start": { + "line": 321, + "column": 4 + }, + "end": { + "line": 323, + "column": 5 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/dial.js" + }, + "augments": [], + "examples": [ + { + "description": "dial.min = 1000;" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "min", + "kind": "member", + "memberof": "Dial", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Dial", + "kind": "class" + }, + { + "name": "min", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "Dial#min" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Upper limit of the dial's output range", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 39, + "offset": 38 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 39, + "offset": 38 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 39, + "offset": 38 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "number" + } + }, + { + "title": "example", + "description": "dial.max = 1000;", + "lineNumber": 3 + } + ], + "loc": { + "start": { + "line": 328, + "column": 4 + }, + "end": { + "line": 332, + "column": 6 + } + }, + "context": { + "loc": { + "start": { + "line": 333, + "column": 4 + }, + "end": { + "line": 335, + "column": 5 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/dial.js" + }, + "augments": [], + "examples": [ + { + "description": "dial.max = 1000;" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "max", + "kind": "member", + "memberof": "Dial", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Dial", + "kind": "class" + }, + { + "name": "max", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "Dial#max" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "The increment that the dial's value changes by.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 48, + "offset": 47 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 48, + "offset": 47 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 48, + "offset": 47 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "number" + } + }, + { + "title": "example", + "description": "dial.step = 5;", + "lineNumber": 3 + } + ], + "loc": { + "start": { + "line": 340, + "column": 4 + }, + "end": { + "line": 344, + "column": 6 + } + }, + "context": { + "loc": { + "start": { + "line": 345, + "column": 4 + }, + "end": { + "line": 347, + "column": 5 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/dial.js" + }, + "augments": [], + "examples": [ + { + "description": "dial.step = 5;" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "step", + "kind": "member", + "memberof": "Dial", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Dial", + "kind": "class" + }, + { + "name": "step", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "Dial#step" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Absolute mode (dial's value jumps to mouse click position) or relative mode (mouse drag changes value relative to its current position). Default: \"relative\".", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 158, + "offset": 157 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 158, + "offset": 157 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 158, + "offset": 157 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "string" + } + }, + { + "title": "example", + "description": "dial.mode = \"relative\";", + "lineNumber": 3 + } + ], + "loc": { + "start": { + "line": 352, + "column": 4 + }, + "end": { + "line": 356, + "column": 6 + } + }, + "context": { + "loc": { + "start": { + "line": 357, + "column": 4 + }, + "end": { + "line": 359, + "column": 5 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/dial.js" + }, + "augments": [], + "examples": [ + { + "description": "dial.mode = \"relative\";" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "mode", + "kind": "member", + "memberof": "Dial", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Dial", + "kind": "class" + }, + { + "name": "mode", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "Dial#mode" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Normalized value of the dial.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 30, + "offset": 29 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 30, + "offset": 29 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 30, + "offset": 29 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "number" + } + }, + { + "title": "example", + "description": "dial.normalized = 0.5;", + "lineNumber": 3 + } + ], + "loc": { + "start": { + "line": 365, + "column": 2 + }, + "end": { + "line": 369, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 370, + "column": 2 + }, + "end": { + "line": 372, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/dial.js" + }, + "augments": [], + "examples": [ + { + "description": "dial.normalized = 0.5;" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "normalized", + "kind": "member", + "memberof": "Dial", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Dial", + "kind": "class" + }, + { + "name": "normalized", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "Dial#normalized" + } + ], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Dial", + "kind": "class" + } + ], + "namespace": "Dial" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Interactive linear ramp visualization.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 39, + "offset": 38 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 39, + "offset": 38 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 39, + "offset": 38 + } + } + }, + "tags": [ + { + "title": "description", + "description": "Interactive linear ramp visualization.", + "lineNumber": 3 + }, + { + "title": "demo", + "description": "", + "lineNumber": 5 + }, + { + "title": "example", + "description": "var envelope = new Nexus.Envelope('#target')", + "lineNumber": 7 + }, + { + "title": "example", + "description": "var envelope = new Nexus.Envelope('#target',{\n 'size': [300,150],\n 'noNewPoints': false,\n 'points': [\n {\n x: 0.1,\n y: 0.4\n },\n {\n x: 0.35,\n y: 0.6\n },\n {\n x: 0.65,\n y: 0.2\n },\n {\n x: 0.9,\n y: 0.4\n },\n ]\n})", + "lineNumber": 10 + }, + { + "title": "output", + "description": "change\nFires any time a node is moved.
\nThe event data is an array of point locations. Each item in the array is an object containing x and y properties describing the location of a point on the envelope.", + "lineNumber": 34 + }, + { + "title": "outputexample", + "description": "envelope.on('change',function(v) {\n console.log(v);\n})", + "lineNumber": 39 + } + ], + "loc": { + "start": { + "line": 81, + "column": 0 + }, + "end": { + "line": 125, + "column": 2 + } + }, + "context": { + "loc": { + "start": { + "line": 127, + "column": 0 + }, + "end": { + "line": 479, + "column": 1 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/envelope.js" + }, + "augments": [ + { + "title": "augments", + "name": "Interface" + } + ], + "examples": [ + { + "description": "var envelope = new Nexus.Envelope('#target')" + }, + { + "description": "var envelope = new Nexus.Envelope('#target',{\n 'size': [300,150],\n 'noNewPoints': false,\n 'points': [\n {\n x: 0.1,\n y: 0.4\n },\n {\n x: 0.35,\n y: 0.6\n },\n {\n x: 0.65,\n y: 0.2\n },\n {\n x: 0.9,\n y: 0.4\n },\n ]\n})" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "Envelope", + "kind": "class", + "members": { + "global": [], + "inner": [], + "instance": [ + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Sort the this.points array from left-most point to right-most point. You should not regularly need to use this, however it may be useful if the points get unordered.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 166, + "offset": 165 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 166, + "offset": 165 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 166, + "offset": 165 + } + } + }, + "tags": [], + "loc": { + "start": { + "line": 357, + "column": 2 + }, + "end": { + "line": 359, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 360, + "column": 2 + }, + "end": { + "line": 364, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/envelope.js" + }, + "augments": [], + "examples": [], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "sortPoints", + "kind": "function", + "memberof": "Envelope", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Envelope", + "kind": "class" + }, + { + "name": "sortPoints", + "kind": "function", + "scope": "instance" + } + ], + "namespace": "Envelope#sortPoints" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Add a breakpoint on the envelope.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 34, + "offset": 33 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 34, + "offset": 33 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 34, + "offset": 33 + } + } + }, + "tags": [ + { + "title": "param", + "description": "{number} x location of the point, normalized (0-1)", + "lineNumber": 2, + "type": null, + "name": "x" + }, + { + "title": "param", + "description": "{number} y location of the point, normalized (0-1)", + "lineNumber": 3, + "type": null, + "name": "y" + } + ], + "loc": { + "start": { + "line": 367, + "column": 2 + }, + "end": { + "line": 371, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 372, + "column": 2 + }, + "end": { + "line": 395, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/envelope.js" + }, + "augments": [], + "examples": [], + "params": [ + { + "title": "param", + "name": "x", + "lineNumber": 2, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "{number} x location of the point, normalized (0-1)", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 51, + "offset": 50 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 51, + "offset": 50 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 51, + "offset": 50 + } + } + } + }, + { + "title": "param", + "name": "y", + "lineNumber": 3, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "{number} y location of the point, normalized (0-1)", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 51, + "offset": 50 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 51, + "offset": 50 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 51, + "offset": 50 + } + } + } + } + ], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "addPoint", + "kind": "function", + "memberof": "Envelope", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Envelope", + "kind": "class" + }, + { + "name": "addPoint", + "kind": "function", + "scope": "instance" + } + ], + "namespace": "Envelope#addPoint" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Find the level at a certain x location on the envelope.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 56, + "offset": 55 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 56, + "offset": 55 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 56, + "offset": 55 + } + } + }, + "tags": [ + { + "title": "param", + "description": "{number} The x location to find the level of, normalized 0-1", + "lineNumber": 2, + "type": null, + "name": "x" + } + ], + "loc": { + "start": { + "line": 398, + "column": 2 + }, + "end": { + "line": 401, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 402, + "column": 2 + }, + "end": { + "line": 418, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/envelope.js" + }, + "augments": [], + "examples": [], + "params": [ + { + "title": "param", + "name": "x", + "lineNumber": 2, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "{number} The x location to find the level of, normalized 0-1", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 61, + "offset": 60 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 61, + "offset": 60 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 61, + "offset": 60 + } + } + } + } + ], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "scan", + "kind": "function", + "memberof": "Envelope", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Envelope", + "kind": "class" + }, + { + "name": "scan", + "kind": "function", + "scope": "instance" + } + ], + "namespace": "Envelope#scan" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Move a breakpoint on the envelope.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 35, + "offset": 34 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 35, + "offset": 34 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 35, + "offset": 34 + } + } + }, + "tags": [ + { + "title": "param", + "description": "{number} The index of the breakpoint to move", + "lineNumber": 2, + "type": null, + "name": "index" + }, + { + "title": "param", + "description": "{number} New x location, normalized 0-1", + "lineNumber": 3, + "type": null, + "name": "x" + }, + { + "title": "param", + "description": "{number} New y location, normalized 0-1", + "lineNumber": 4, + "type": null, + "name": "y" + } + ], + "loc": { + "start": { + "line": 421, + "column": 2 + }, + "end": { + "line": 426, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 427, + "column": 2 + }, + "end": { + "line": 433, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/envelope.js" + }, + "augments": [], + "examples": [], + "params": [ + { + "title": "param", + "name": "index", + "lineNumber": 2, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "{number} The index of the breakpoint to move", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 45, + "offset": 44 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 45, + "offset": 44 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 45, + "offset": 44 + } + } + } + }, + { + "title": "param", + "name": "x", + "lineNumber": 3, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "{number} New x location, normalized 0-1", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 40, + "offset": 39 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 40, + "offset": 39 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 40, + "offset": 39 + } + } + } + }, + { + "title": "param", + "name": "y", + "lineNumber": 4, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "{number} New y location, normalized 0-1", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 40, + "offset": 39 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 40, + "offset": 39 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 40, + "offset": 39 + } + } + } + } + ], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "movePoint", + "kind": "function", + "memberof": "Envelope", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Envelope", + "kind": "class" + }, + { + "name": "movePoint", + "kind": "function", + "scope": "instance" + } + ], + "namespace": "Envelope#movePoint" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Move a breakpoint on the envelope by a certain amount.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 55, + "offset": 54 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 55, + "offset": 54 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 55, + "offset": 54 + } + } + }, + "tags": [ + { + "title": "param", + "description": "{number} The index of the breakpoint to move", + "lineNumber": 2, + "type": null, + "name": "index" + }, + { + "title": "param", + "description": "{number} X displacement, normalized 0-1", + "lineNumber": 3, + "type": null, + "name": "xOffset" + }, + { + "title": "param", + "description": "{number} Y displacement, normalized 0-1", + "lineNumber": 4, + "type": null, + "name": "yOffset" + } + ], + "loc": { + "start": { + "line": 436, + "column": 2 + }, + "end": { + "line": 441, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 442, + "column": 2 + }, + "end": { + "line": 448, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/envelope.js" + }, + "augments": [], + "examples": [], + "params": [ + { + "title": "param", + "name": "index", + "lineNumber": 2, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "{number} The index of the breakpoint to move", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 45, + "offset": 44 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 45, + "offset": 44 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 45, + "offset": 44 + } + } + } + }, + { + "title": "param", + "name": "xOffset", + "lineNumber": 3, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "{number} X displacement, normalized 0-1", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 40, + "offset": 39 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 40, + "offset": 39 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 40, + "offset": 39 + } + } + } + }, + { + "title": "param", + "name": "yOffset", + "lineNumber": 4, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "{number} Y displacement, normalized 0-1", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 40, + "offset": 39 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 40, + "offset": 39 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 40, + "offset": 39 + } + } + } + } + ], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "adjustPoint", + "kind": "function", + "memberof": "Envelope", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Envelope", + "kind": "class" + }, + { + "name": "adjustPoint", + "kind": "function", + "scope": "instance" + } + ], + "namespace": "Envelope#adjustPoint" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Remove a breakpoint from the envelope.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 39, + "offset": 38 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 39, + "offset": 38 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 39, + "offset": 38 + } + } + }, + "tags": [ + { + "title": "param", + "description": "{number} Index of the breakpoint to remove", + "lineNumber": 2, + "type": null, + "name": "index" + } + ], + "loc": { + "start": { + "line": 451, + "column": 2 + }, + "end": { + "line": 454, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 455, + "column": 2 + }, + "end": { + "line": 460, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/envelope.js" + }, + "augments": [], + "examples": [], + "params": [ + { + "title": "param", + "name": "index", + "lineNumber": 2, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "{number} Index of the breakpoint to remove", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 43, + "offset": 42 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 43, + "offset": 42 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 43, + "offset": 42 + } + } + } + } + ], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "destroyPoint", + "kind": "function", + "memberof": "Envelope", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Envelope", + "kind": "class" + }, + { + "name": "destroyPoint", + "kind": "function", + "scope": "instance" + } + ], + "namespace": "Envelope#destroyPoint" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Remove all existing breakpoints and add an entirely new set of breakpoints.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 76, + "offset": 75 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 76, + "offset": 75 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 76, + "offset": 75 + } + } + }, + "tags": [ + { + "title": "param", + "description": "{array} An array of objects with x/y properties (normalized 0-1). Each object in the array specifices the x/y location of a new breakpoint to be added.", + "lineNumber": 2, + "type": null, + "name": "allPoints" + } + ], + "loc": { + "start": { + "line": 463, + "column": 2 + }, + "end": { + "line": 466, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 467, + "column": 2 + }, + "end": { + "line": 477, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/envelope.js" + }, + "augments": [], + "examples": [], + "params": [ + { + "title": "param", + "name": "allPoints", + "lineNumber": 2, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "{array} An array of objects with x/y properties (normalized 0-1). Each object in the array specifices the x/y location of a new breakpoint to be added.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 152, + "offset": 151 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 152, + "offset": 151 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 152, + "offset": 151 + } + } + } + } + ], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "setPoints", + "kind": "function", + "memberof": "Envelope", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Envelope", + "kind": "class" + }, + { + "name": "setPoints", + "kind": "function", + "scope": "instance" + } + ], + "namespace": "Envelope#setPoints" + } + ], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Envelope", + "kind": "class" + } + ], + "namespace": "Envelope" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Stereo decibel meter", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 21, + "offset": 20 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 21, + "offset": 20 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 21, + "offset": 20 + } + } + }, + "tags": [ + { + "title": "description", + "description": "Stereo decibel meter", + "lineNumber": 3 + }, + { + "title": "demo", + "description": "", + "lineNumber": 5 + }, + { + "title": "example", + "description": "var meter = new Nexus.Meter('#target')\nmeter.connect(myWebAudioNode)", + "lineNumber": 7 + }, + { + "title": "example", + "description": "var meter = new Nexus.Meter('#target', {\n size: [75,75]\n})\nmeter.connect(myWebAudioNode)", + "lineNumber": 11 + }, + { + "title": "output", + "description": " \nNo events", + "lineNumber": 17 + } + ], + "loc": { + "start": { + "line": 7, + "column": 0 + }, + "end": { + "line": 28, + "column": 3 + } + }, + "context": { + "loc": { + "start": { + "line": 30, + "column": 0 + }, + "end": { + "line": 181, + "column": 1 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/meter.js" + }, + "augments": [ + { + "title": "augments", + "name": "Interface" + } + ], + "examples": [ + { + "description": "var meter = new Nexus.Meter('#target')\nmeter.connect(myWebAudioNode)" + }, + { + "description": "var meter = new Nexus.Meter('#target', {\n size: [75,75]\n})\nmeter.connect(myWebAudioNode)" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "Meter", + "kind": "class", + "members": { + "global": [], + "inner": [], + "instance": [ + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Equivalent to \"patching in\" an audio node to visualize.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 56, + "offset": 55 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 56, + "offset": 55 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 56, + "offset": 55 + } + } + }, + "tags": [ + { + "title": "param", + "description": "{AudioNode} The audio node to visualize", + "lineNumber": 2, + "type": null, + "name": "node" + }, + { + "title": "param", + "description": "{number} (optional) The number of channels in the source node to watch. If not specified, the interface will look for a .channelCount property on the input node. If it does not exist, the interface will default to 1 channel.", + "lineNumber": 3, + "type": null, + "name": "channels" + }, + { + "title": "example", + "description": "meter.connect( Tone.Master, 2 );", + "lineNumber": 4 + } + ], + "loc": { + "start": { + "line": 121, + "column": 2 + }, + "end": { + "line": 126, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 127, + "column": 2 + }, + "end": { + "line": 155, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/meter.js" + }, + "augments": [], + "examples": [ + { + "description": "meter.connect( Tone.Master, 2 );" + } + ], + "params": [ + { + "title": "param", + "name": "node", + "lineNumber": 2, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "{AudioNode} The audio node to visualize", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 40, + "offset": 39 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 40, + "offset": 39 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 40, + "offset": 39 + } + } + } + }, + { + "title": "param", + "name": "channels", + "lineNumber": 3, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "{number} (optional) The number of channels in the source node to watch. If not specified, the interface will look for a .channelCount property on the input node. If it does not exist, the interface will default to 1 channel.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 225, + "offset": 224 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 225, + "offset": 224 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 225, + "offset": 224 + } + } + } + } + ], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "connect", + "kind": "function", + "memberof": "Meter", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Meter", + "kind": "class" + }, + { + "name": "connect", + "kind": "function", + "scope": "instance" + } + ], + "namespace": "Meter#connect" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Stop visualizing the source node and disconnect it.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 52, + "offset": 51 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 52, + "offset": 51 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 52, + "offset": 51 + } + } + }, + "tags": [], + "loc": { + "start": { + "line": 157, + "column": 2 + }, + "end": { + "line": 159, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 160, + "column": 2 + }, + "end": { + "line": 171, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/meter.js" + }, + "augments": [], + "examples": [], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "disconnect", + "kind": "function", + "memberof": "Meter", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Meter", + "kind": "class" + }, + { + "name": "disconnect", + "kind": "function", + "scope": "instance" + } + ], + "namespace": "Meter#disconnect" + } + ], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Meter", + "kind": "class" + } + ], + "namespace": "Meter" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Multislider", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 12, + "offset": 11 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 12, + "offset": 11 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 12, + "offset": 11 + } + } + }, + "tags": [ + { + "title": "description", + "description": "Multislider", + "lineNumber": 3 + }, + { + "title": "demo", + "description": "", + "lineNumber": 5 + }, + { + "title": "example", + "description": "var multislider = new Nexus.Multislider('#target')", + "lineNumber": 7 + }, + { + "title": "example", + "description": "var multislider = new Nexus.Multislider('#target',{\n 'size': [200,100],\n 'numberOfSliders': 5,\n 'min': 0,\n 'max': 1,\n 'step': 0,\n 'candycane': 3,\n 'values': [0.9,0.8,0.7,0.6,0.5,0.4,0.3,0.2,0.1],\n 'smoothing': 0,\n 'mode': 'bar' // 'bar' or 'line'\n})", + "lineNumber": 10 + }, + { + "title": "output", + "description": "change\nFires any time the interface's value changes.
\nThe event data is an object containing index and value properties", + "lineNumber": 23 + }, + { + "title": "outputexample", + "description": "multislider.on('change',function(v) {\n console.log(v);\n})", + "lineNumber": 28 + } + ], + "loc": { + "start": { + "line": 7, + "column": 0 + }, + "end": { + "line": 40, + "column": 3 + } + }, + "context": { + "loc": { + "start": { + "line": 42, + "column": 0 + }, + "end": { + "line": 443, + "column": 1 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/multislider.js" + }, + "augments": [ + { + "title": "augments", + "name": "Interface" + } + ], + "examples": [ + { + "description": "var multislider = new Nexus.Multislider('#target')" + }, + { + "description": "var multislider = new Nexus.Multislider('#target',{\n 'size': [200,100],\n 'numberOfSliders': 5,\n 'min': 0,\n 'max': 1,\n 'step': 0,\n 'candycane': 3,\n 'values': [0.9,0.8,0.7,0.6,0.5,0.4,0.3,0.2,0.1],\n 'smoothing': 0,\n 'mode': 'bar' // 'bar' or 'line'\n})" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "Multislider", + "kind": "class", + "members": { + "global": [], + "inner": [], + "instance": [ + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Applies a simple low-pass filter to the multislider as it is interacted with. A smoothing of 0 will be no smoothing. A smoothing of 1 will smooth 1 slider on each side of the interaction. A smoothing of 2 will smooth 2 sliders on each side, and so on.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 252, + "offset": 251 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 252, + "offset": 251 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 252, + "offset": 251 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "Number" + } + } + ], + "loc": { + "start": { + "line": 78, + "column": 4 + }, + "end": { + "line": 81, + "column": 6 + } + }, + "context": { + "loc": { + "start": { + "line": 82, + "column": 4 + }, + "end": { + "line": 82, + "column": 45 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/multislider.js" + }, + "augments": [], + "examples": [], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "smoothing", + "memberof": "Multislider", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Multislider", + "kind": "class" + }, + { + "name": "smoothing", + "scope": "instance" + } + ], + "namespace": "Multislider#smoothing" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Get the number of sliders", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 26, + "offset": 25 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 26, + "offset": 25 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 26, + "offset": 25 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "Number" + } + } + ], + "loc": { + "start": { + "line": 358, + "column": 2 + }, + "end": { + "line": 361, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 362, + "column": 2 + }, + "end": { + "line": 364, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/multislider.js" + }, + "augments": [], + "examples": [], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "numberOfSliders", + "kind": "member", + "memberof": "Multislider", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Multislider", + "kind": "class" + }, + { + "name": "numberOfSliders", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "Multislider#numberOfSliders" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Lower limit of the multislider's output range", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 46, + "offset": 45 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 46, + "offset": 45 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 46, + "offset": 45 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "number" + } + }, + { + "title": "example", + "description": "multislider.min = 1000;", + "lineNumber": 3 + } + ], + "loc": { + "start": { + "line": 366, + "column": 2 + }, + "end": { + "line": 370, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 371, + "column": 2 + }, + "end": { + "line": 373, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/multislider.js" + }, + "augments": [], + "examples": [ + { + "description": "multislider.min = 1000;" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "min", + "kind": "member", + "memberof": "Multislider", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Multislider", + "kind": "class" + }, + { + "name": "min", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "Multislider#min" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Upper limit of the multislider's output range", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 46, + "offset": 45 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 46, + "offset": 45 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 46, + "offset": 45 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "number" + } + }, + { + "title": "example", + "description": "multislider.max = 1000;", + "lineNumber": 3 + } + ], + "loc": { + "start": { + "line": 380, + "column": 2 + }, + "end": { + "line": 384, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 385, + "column": 2 + }, + "end": { + "line": 387, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/multislider.js" + }, + "augments": [], + "examples": [ + { + "description": "multislider.max = 1000;" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "max", + "kind": "member", + "memberof": "Multislider", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Multislider", + "kind": "class" + }, + { + "name": "max", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "Multislider#max" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "The increment that the multislider's value changes by.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 55, + "offset": 54 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 55, + "offset": 54 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 55, + "offset": 54 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "number" + } + }, + { + "title": "example", + "description": "multislider.step = 5;", + "lineNumber": 3 + } + ], + "loc": { + "start": { + "line": 394, + "column": 2 + }, + "end": { + "line": 398, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 399, + "column": 2 + }, + "end": { + "line": 401, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/multislider.js" + }, + "augments": [], + "examples": [ + { + "description": "multislider.step = 5;" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "step", + "kind": "member", + "memberof": "Multislider", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Multislider", + "kind": "class" + }, + { + "name": "step", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "Multislider#step" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Set the value of an individual slider", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 38, + "offset": 37 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 38, + "offset": 37 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 38, + "offset": 37 + } + } + }, + "tags": [ + { + "title": "param", + "description": "{number} Slider index", + "lineNumber": 2, + "type": null, + "name": "index" + }, + { + "title": "param", + "description": "{number} New slider value", + "lineNumber": 3, + "type": null, + "name": "value" + }, + { + "title": "example", + "description": "// Set the first slider to value 0.5\nmultislider.setSlider(0,0.5)", + "lineNumber": 4 + } + ], + "loc": { + "start": { + "line": 408, + "column": 2 + }, + "end": { + "line": 415, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 416, + "column": 2 + }, + "end": { + "line": 423, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/multislider.js" + }, + "augments": [], + "examples": [ + { + "description": "// Set the first slider to value 0.5\nmultislider.setSlider(0,0.5)" + } + ], + "params": [ + { + "title": "param", + "name": "index", + "lineNumber": 2, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "{number} Slider index", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 22, + "offset": 21 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 22, + "offset": 21 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 22, + "offset": 21 + } + } + } + }, + { + "title": "param", + "name": "value", + "lineNumber": 3, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "{number} New slider value", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 26, + "offset": 25 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 26, + "offset": 25 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 26, + "offset": 25 + } + } + } + } + ], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "setSlider", + "kind": "function", + "memberof": "Multislider", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Multislider", + "kind": "class" + }, + { + "name": "setSlider", + "kind": "function", + "scope": "instance" + } + ], + "namespace": "Multislider#setSlider" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Set the value of all sliders at once. If the size of the input array does not match the current number of sliders, the value array will repeat until all sliders have been set. I.e. an input array of length 1 will set all sliders to that value.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 244, + "offset": 243 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 244, + "offset": 243 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 244, + "offset": 243 + } + } + }, + "tags": [ + { + "title": "param", + "description": "{Array} All slider values", + "lineNumber": 2, + "type": null, + "name": "values" + }, + { + "title": "example", + "description": "multislider.setAllSliders([0.2,0.3,0.4,0.5,0.6])", + "lineNumber": 3 + } + ], + "loc": { + "start": { + "line": 425, + "column": 2 + }, + "end": { + "line": 430, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 431, + "column": 2 + }, + "end": { + "line": 442, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/multislider.js" + }, + "augments": [], + "examples": [ + { + "description": "multislider.setAllSliders([0.2,0.3,0.4,0.5,0.6])" + } + ], + "params": [ + { + "title": "param", + "name": "values", + "lineNumber": 2, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "{Array} All slider values", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 26, + "offset": 25 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 26, + "offset": 25 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 26, + "offset": 25 + } + } + } + } + ], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "setAllSliders", + "kind": "function", + "memberof": "Multislider", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Multislider", + "kind": "class" + }, + { + "name": "setAllSliders", + "kind": "function", + "scope": "instance" + } + ], + "namespace": "Multislider#setAllSliders" + } + ], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Multislider", + "kind": "class" + } + ], + "namespace": "Multislider" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "The current values of the slider. NOTE: Use this only to get the current values. Setting this array will not update the multislider. To set the multislider's values, use setSlider() or setAllSliders()", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 201, + "offset": 200 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 201, + "offset": 200 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 201, + "offset": 200 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "Array" + } + } + ], + "loc": { + "start": { + "line": 67, + "column": 4 + }, + "end": { + "line": 70, + "column": 6 + } + }, + "context": { + "loc": { + "start": { + "line": 71, + "column": 4 + }, + "end": { + "line": 71, + "column": 36 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/multislider.js" + }, + "augments": [], + "examples": [], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "vs", + "kind": "constant", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "vs", + "kind": "constant" + } + ], + "namespace": "vs" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Number interface which is controllable by dragging or typing.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 62, + "offset": 61 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 62, + "offset": 61 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 62, + "offset": 61 + } + } + }, + "tags": [ + { + "title": "description", + "description": "Number interface which is controllable by dragging or typing.", + "lineNumber": 3 + }, + { + "title": "demo", + "description": "", + "lineNumber": 5 + }, + { + "title": "example", + "description": "var number = new Nexus.Number('#target')", + "lineNumber": 7 + }, + { + "title": "example", + "description": "var number = new Nexus.Number('#target',{\n 'size': [60,30],\n 'value': 0,\n 'min': 0,\n 'max': 20000,\n 'step': 1\n})", + "lineNumber": 10 + }, + { + "title": "output", + "description": "change\nFires any time the interface's value changes.
\nThe event data is the number value of the interface.", + "lineNumber": 19 + }, + { + "title": "outputexample", + "description": "number.on('change',function(v) {\n console.log(v);\n})", + "lineNumber": 24 + } + ], + "loc": { + "start": { + "line": 8, + "column": 0 + }, + "end": { + "line": 38, + "column": 2 + } + }, + "context": { + "loc": { + "start": { + "line": 41, + "column": 0 + }, + "end": { + "line": 262, + "column": 1 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/number.js" + }, + "augments": [ + { + "title": "augments", + "name": "Interface" + } + ], + "examples": [ + { + "description": "var number = new Nexus.Number('#target')" + }, + { + "description": "var number = new Nexus.Number('#target',{\n 'size': [60,30],\n 'value': 0,\n 'min': 0,\n 'max': 20000,\n 'step': 1\n})" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "Number", + "kind": "class", + "members": { + "global": [], + "inner": [], + "instance": [ + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Connect this number interface to a dial or slider", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 50, + "offset": 49 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 50, + "offset": 49 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 50, + "offset": 49 + } + } + }, + "tags": [ + { + "title": "param", + "description": "Element to connect to.", + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "Interface" + }, + "name": "element" + }, + { + "title": "example", + "description": "number.link(slider)", + "lineNumber": 3 + } + ], + "loc": { + "start": { + "line": 181, + "column": 2 + }, + "end": { + "line": 185, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 186, + "column": 2 + }, + "end": { + "line": 205, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/number.js" + }, + "augments": [], + "examples": [ + { + "description": "number.link(slider)" + } + ], + "params": [ + { + "title": "param", + "name": "destination", + "lineNumber": 186 + }, + { + "title": "param", + "name": "element", + "lineNumber": 2, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Element to connect to.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 23, + "offset": 22 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 23, + "offset": 22 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 23, + "offset": 22 + } + } + }, + "type": { + "type": "NameExpression", + "name": "Interface" + } + } + ], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "link", + "kind": "function", + "memberof": "Number", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Number", + "kind": "class" + }, + { + "name": "link", + "kind": "function", + "scope": "instance" + } + ], + "namespace": "Number#link" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "The interface's current value. If set manually, will update the interface and trigger the output event.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 104, + "offset": 103 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 104, + "offset": 103 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 104, + "offset": 103 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "number" + } + }, + { + "title": "example", + "description": "number.value = 10;", + "lineNumber": 3 + } + ], + "loc": { + "start": { + "line": 212, + "column": 2 + }, + "end": { + "line": 216, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 217, + "column": 2 + }, + "end": { + "line": 219, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/number.js" + }, + "augments": [], + "examples": [ + { + "description": "number.value = 10;" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "value", + "kind": "member", + "memberof": "Number", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Number", + "kind": "class" + }, + { + "name": "value", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "Number#value" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Lower limit of the number's output range", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 41, + "offset": 40 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 41, + "offset": 40 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 41, + "offset": 40 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "number" + } + }, + { + "title": "example", + "description": "number.min = 1000;", + "lineNumber": 3 + } + ], + "loc": { + "start": { + "line": 226, + "column": 2 + }, + "end": { + "line": 230, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 231, + "column": 2 + }, + "end": { + "line": 233, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/number.js" + }, + "augments": [], + "examples": [ + { + "description": "number.min = 1000;" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "min", + "kind": "member", + "memberof": "Number", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Number", + "kind": "class" + }, + { + "name": "min", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "Number#min" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Upper limit of the number's output range", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 41, + "offset": 40 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 41, + "offset": 40 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 41, + "offset": 40 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "number" + } + }, + { + "title": "example", + "description": "number.max = 1000;", + "lineNumber": 3 + } + ], + "loc": { + "start": { + "line": 238, + "column": 2 + }, + "end": { + "line": 242, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 243, + "column": 2 + }, + "end": { + "line": 245, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/number.js" + }, + "augments": [], + "examples": [ + { + "description": "number.max = 1000;" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "max", + "kind": "member", + "memberof": "Number", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Number", + "kind": "class" + }, + { + "name": "max", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "Number#max" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "The increment that the number's value changes by.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 50, + "offset": 49 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 50, + "offset": 49 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 50, + "offset": 49 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "number" + } + }, + { + "title": "example", + "description": "number.step = 5;", + "lineNumber": 3 + } + ], + "loc": { + "start": { + "line": 250, + "column": 2 + }, + "end": { + "line": 254, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 255, + "column": 2 + }, + "end": { + "line": 257, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/number.js" + }, + "augments": [], + "examples": [ + { + "description": "number.step = 5;" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "step", + "kind": "member", + "memberof": "Number", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Number", + "kind": "class" + }, + { + "name": "step", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "Number#step" + } + ], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Number", + "kind": "class" + } + ], + "namespace": "Number" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Visualizes a waveform's stream of values.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 42, + "offset": 41 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 42, + "offset": 41 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 42, + "offset": 41 + } + } + }, + "tags": [ + { + "title": "description", + "description": "Visualizes a waveform's stream of values.", + "lineNumber": 3 + }, + { + "title": "demo", + "description": "", + "lineNumber": 5 + }, + { + "title": "example", + "description": "var oscilloscope = new Nexus.Oscilloscope('#target')\noscilloscope.connect(myWebAudioNode)", + "lineNumber": 7 + }, + { + "title": "example", + "description": "var oscilloscope = new Nexus.Oscilloscope('#target',{\n 'size': [300,150]\n})\noscilloscope.connect(myWebAudioNode)", + "lineNumber": 11 + }, + { + "title": "output", + "description": " \nNo events", + "lineNumber": 17 + } + ], + "loc": { + "start": { + "line": 6, + "column": 0 + }, + "end": { + "line": 27, + "column": 3 + } + }, + "context": { + "loc": { + "start": { + "line": 29, + "column": 0 + }, + "end": { + "line": 162, + "column": 1 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/oscilloscope.js" + }, + "augments": [ + { + "title": "augments", + "name": "Interface" + } + ], + "examples": [ + { + "description": "var oscilloscope = new Nexus.Oscilloscope('#target')\noscilloscope.connect(myWebAudioNode)" + }, + { + "description": "var oscilloscope = new Nexus.Oscilloscope('#target',{\n 'size': [300,150]\n})\noscilloscope.connect(myWebAudioNode)" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "Oscilloscope", + "kind": "class", + "members": { + "global": [], + "inner": [], + "instance": [ + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Equivalent to \"patching in\" an audio node to visualize.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 56, + "offset": 55 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 56, + "offset": 55 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 56, + "offset": 55 + } + } + }, + "tags": [ + { + "title": "param", + "description": "{AudioNode} The audio node to visualize", + "lineNumber": 2, + "type": null, + "name": "node" + }, + { + "title": "example", + "description": "oscilloscope.connect( Tone.Master );", + "lineNumber": 3 + } + ], + "loc": { + "start": { + "line": 114, + "column": 2 + }, + "end": { + "line": 118, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 120, + "column": 2 + }, + "end": { + "line": 137, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/oscilloscope.js" + }, + "augments": [], + "examples": [ + { + "description": "oscilloscope.connect( Tone.Master );" + } + ], + "params": [ + { + "title": "param", + "name": "node", + "lineNumber": 2, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "{AudioNode} The audio node to visualize", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 40, + "offset": 39 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 40, + "offset": 39 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 40, + "offset": 39 + } + } + } + } + ], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "connect", + "kind": "function", + "memberof": "Oscilloscope", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Oscilloscope", + "kind": "class" + }, + { + "name": "connect", + "kind": "function", + "scope": "instance" + } + ], + "namespace": "Oscilloscope#connect" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Stop visualizing the source node and disconnect it.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 52, + "offset": 51 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 52, + "offset": 51 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 52, + "offset": 51 + } + } + }, + "tags": [], + "loc": { + "start": { + "line": 139, + "column": 2 + }, + "end": { + "line": 141, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 142, + "column": 2 + }, + "end": { + "line": 152, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/oscilloscope.js" + }, + "augments": [], + "examples": [], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "disconnect", + "kind": "function", + "memberof": "Oscilloscope", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Oscilloscope", + "kind": "class" + }, + { + "name": "disconnect", + "kind": "function", + "scope": "instance" + } + ], + "namespace": "Oscilloscope#disconnect" + } + ], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Oscilloscope", + "kind": "class" + } + ], + "namespace": "Oscilloscope" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Stereo crossfader.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 19, + "offset": 18 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 19, + "offset": 18 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 19, + "offset": 18 + } + } + }, + "tags": [ + { + "title": "description", + "description": "Stereo crossfader.", + "lineNumber": 3 + }, + { + "title": "demo", + "description": "", + "lineNumber": 5 + }, + { + "title": "example", + "description": "var pan = new Nexus.Pan('#target')", + "lineNumber": 7 + }, + { + "title": "output", + "description": "change\nFires any time the interface's value changes.
\nThe event data is an object containing the interface's value (-1 to 1), as well as L and R amplitude values (0-1) for left and right speakers, calculated by a square-root crossfade algorithm.", + "lineNumber": 10 + }, + { + "title": "outputexample", + "description": "pan.on('change',function(v) {\n console.log(v);\n})", + "lineNumber": 15 + } + ], + "loc": { + "start": { + "line": 9, + "column": 0 + }, + "end": { + "line": 30, + "column": 2 + } + }, + "context": { + "loc": { + "start": { + "line": 32, + "column": 0 + }, + "end": { + "line": 217, + "column": 1 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/pan.js" + }, + "augments": [ + { + "title": "augments", + "name": "Interface" + } + ], + "examples": [ + { + "description": "var pan = new Nexus.Pan('#target')" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "Pan", + "kind": "class", + "members": { + "global": [], + "inner": [], + "instance": [ + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "The position of crossfader, from -1 (left) to 1 (right). Setting this value updates the interface and triggers the output event.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 129, + "offset": 128 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 129, + "offset": 128 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 129, + "offset": 128 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "number" + } + } + ], + "loc": { + "start": { + "line": 194, + "column": 2 + }, + "end": { + "line": 197, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 198, + "column": 2 + }, + "end": { + "line": 200, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/pan.js" + }, + "augments": [], + "examples": [], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "value", + "kind": "member", + "memberof": "Pan", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Pan", + "kind": "class" + }, + { + "name": "value", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "Pan#value" + } + ], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Pan", + "kind": "class" + } + ], + "namespace": "Pan" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Interface for moving a sound around an array of speakers. Speaker locations can be customized. The interface calculates the closeness of the sound source to each speaker and returns that distance as a numeric value.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 216, + "offset": 215 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 216, + "offset": 215 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 216, + "offset": 215 + } + } + }, + "tags": [ + { + "title": "description", + "description": "Interface for moving a sound around an array of speakers. Speaker locations can be customized. The interface calculates the closeness of the sound source to each speaker and returns that distance as a numeric value.", + "lineNumber": 3 + }, + { + "title": "demo", + "description": "", + "lineNumber": 5 + }, + { + "title": "example", + "description": "var pan2d = new Nexus.Pan2d('#target')", + "lineNumber": 7 + }, + { + "title": "example", + "description": "var pan2d = new Nexus.Pan2D('#target',{\n 'size': [200,200],\n 'range': 0.5, // detection radius of each speaker\n 'mode': 'absolute', // 'absolute' or 'relative' sound movement\n 'speakers': [ // the speaker [x,y] positions\n [0.5,0.2],\n [0.75,0.25],\n [0.8,0.5],\n [0.75,0.75],\n [0.5,0.8],\n [0.25,0.75]\n [0.2,0.5],\n [0.25,0.25]\n ]\n})", + "lineNumber": 10 + }, + { + "title": "output", + "description": "change\nFires any time the \"source\" node's position changes.
\nThe event data is an array of the amplitudes (0-1), representing the level of each speaker (as calculated by its distance to the audio source).", + "lineNumber": 27 + }, + { + "title": "outputexample", + "description": "pan2d.on('change',function(v) {\n console.log(v);\n})", + "lineNumber": 32 + } + ], + "loc": { + "start": { + "line": 9, + "column": 0 + }, + "end": { + "line": 46, + "column": 2 + } + }, + "context": { + "loc": { + "start": { + "line": 48, + "column": 0 + }, + "end": { + "line": 275, + "column": 1 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/pan2d.js" + }, + "augments": [ + { + "title": "augments", + "name": "Interface" + } + ], + "examples": [ + { + "description": "var pan2d = new Nexus.Pan2d('#target')" + }, + { + "description": "var pan2d = new Nexus.Pan2D('#target',{\n 'size': [200,200],\n 'range': 0.5, // detection radius of each speaker\n 'mode': 'absolute', // 'absolute' or 'relative' sound movement\n 'speakers': [ // the speaker [x,y] positions\n [0.5,0.2],\n [0.75,0.25],\n [0.8,0.5],\n [0.75,0.75],\n [0.5,0.8],\n [0.25,0.75]\n [0.2,0.5],\n [0.25,0.25]\n ]\n})" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "Pan2D", + "kind": "class", + "members": { + "global": [], + "inner": [], + "instance": [ + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Absolute or relative mouse interaction. In \"absolute\" mode, the source node will jump to your mouse position on mouse click. In \"relative\" mode, it does not.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 158, + "offset": 157 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 158, + "offset": 157 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 158, + "offset": 157 + } + } + }, + "tags": [], + "loc": { + "start": { + "line": 77, + "column": 4 + }, + "end": { + "line": 79, + "column": 6 + } + }, + "context": { + "loc": { + "start": { + "line": 80, + "column": 4 + }, + "end": { + "line": 80, + "column": 35 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/pan2d.js" + }, + "augments": [], + "examples": [], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "mode", + "memberof": "Pan2D", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Pan2D", + "kind": "class" + }, + { + "name": "mode", + "scope": "instance" + } + ], + "namespace": "Pan2D#mode" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "An array of speaker locations. Update this with .moveSpeaker() or .moveAllSpeakers()", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 85, + "offset": 84 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 85, + "offset": 84 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 85, + "offset": 84 + } + } + }, + "tags": [], + "loc": { + "start": { + "line": 89, + "column": 4 + }, + "end": { + "line": 91, + "column": 6 + } + }, + "context": { + "loc": { + "start": { + "line": 92, + "column": 4 + }, + "end": { + "line": 92, + "column": 43 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/pan2d.js" + }, + "augments": [], + "examples": [], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "speakers", + "memberof": "Pan2D", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Pan2D", + "kind": "class" + }, + { + "name": "speakers", + "scope": "instance" + } + ], + "namespace": "Pan2D#speakers" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Rewrite: The maximum distance from a speaker that the source node can be for it to be heard from that speaker. A low range (0.1) will result in speakers only playing when the sound is very close it. Default is 0.5 (half of the interface).", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 239, + "offset": 238 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 239, + "offset": 238 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 239, + "offset": 238 + } + } + }, + "tags": [], + "loc": { + "start": { + "line": 94, + "column": 4 + }, + "end": { + "line": 96, + "column": 6 + } + }, + "context": { + "loc": { + "start": { + "line": 97, + "column": 4 + }, + "end": { + "line": 97, + "column": 37 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/pan2d.js" + }, + "augments": [], + "examples": [], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "range", + "memberof": "Pan2D", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Pan2D", + "kind": "class" + }, + { + "name": "range", + "scope": "instance" + } + ], + "namespace": "Pan2D#range" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "The current levels for each speaker. This is calculated when a source node or speaker node is moved through interaction or programatically.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 140, + "offset": 139 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 140, + "offset": 139 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 140, + "offset": 139 + } + } + }, + "tags": [], + "loc": { + "start": { + "line": 99, + "column": 4 + }, + "end": { + "line": 101, + "column": 6 + } + }, + "context": { + "loc": { + "start": { + "line": 102, + "column": 4 + }, + "end": { + "line": 102, + "column": 21 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/pan2d.js" + }, + "augments": [], + "examples": [], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "levels", + "memberof": "Pan2D", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Pan2D", + "kind": "class" + }, + { + "name": "levels", + "scope": "instance" + } + ], + "namespace": "Pan2D#levels" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Move the audio source node and trigger the output event.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 57, + "offset": 56 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 57, + "offset": 56 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 57, + "offset": 56 + } + } + }, + "tags": [ + { + "title": "param", + "description": "{number} New x location, normalized 0-1", + "lineNumber": 2, + "type": null, + "name": "x" + }, + { + "title": "param", + "description": "{number} New y location, normalized 0-1", + "lineNumber": 3, + "type": null, + "name": "y" + } + ], + "loc": { + "start": { + "line": 232, + "column": 2 + }, + "end": { + "line": 236, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 237, + "column": 2 + }, + "end": { + "line": 247, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/pan2d.js" + }, + "augments": [], + "examples": [], + "params": [ + { + "title": "param", + "name": "x", + "lineNumber": 2, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "{number} New x location, normalized 0-1", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 40, + "offset": 39 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 40, + "offset": 39 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 40, + "offset": 39 + } + } + } + }, + { + "title": "param", + "name": "y", + "lineNumber": 3, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "{number} New y location, normalized 0-1", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 40, + "offset": 39 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 40, + "offset": 39 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 40, + "offset": 39 + } + } + } + } + ], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "moveSource", + "kind": "function", + "memberof": "Pan2D", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Pan2D", + "kind": "class" + }, + { + "name": "moveSource", + "kind": "function", + "scope": "instance" + } + ], + "namespace": "Pan2D#moveSource" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Move a speaker node and trigger the output event.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 50, + "offset": 49 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 50, + "offset": 49 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 50, + "offset": 49 + } + } + }, + "tags": [ + { + "title": "param", + "description": "{number} Index of the speaker to move", + "lineNumber": 2, + "type": null, + "name": "index" + }, + { + "title": "param", + "description": "{number} New x location, normalized 0-1", + "lineNumber": 3, + "type": null, + "name": "x" + }, + { + "title": "param", + "description": "{number} New y location, normalized 0-1", + "lineNumber": 4, + "type": null, + "name": "y" + } + ], + "loc": { + "start": { + "line": 249, + "column": 2 + }, + "end": { + "line": 254, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 255, + "column": 2 + }, + "end": { + "line": 264, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/pan2d.js" + }, + "augments": [], + "examples": [], + "params": [ + { + "title": "param", + "name": "index", + "lineNumber": 2, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "{number} Index of the speaker to move", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 38, + "offset": 37 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 38, + "offset": 37 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 38, + "offset": 37 + } + } + } + }, + { + "title": "param", + "name": "x", + "lineNumber": 3, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "{number} New x location, normalized 0-1", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 40, + "offset": 39 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 40, + "offset": 39 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 40, + "offset": 39 + } + } + } + }, + { + "title": "param", + "name": "y", + "lineNumber": 4, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "{number} New y location, normalized 0-1", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 40, + "offset": 39 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 40, + "offset": 39 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 40, + "offset": 39 + } + } + } + } + ], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "moveSpeaker", + "kind": "function", + "memberof": "Pan2D", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Pan2D", + "kind": "class" + }, + { + "name": "moveSpeaker", + "kind": "function", + "scope": "instance" + } + ], + "namespace": "Pan2D#moveSpeaker" + } + ], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Pan2D", + "kind": "class" + } + ], + "namespace": "Pan2D" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Set all speaker locations", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 26, + "offset": 25 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 26, + "offset": 25 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 26, + "offset": 25 + } + } + }, + "tags": [ + { + "title": "param", + "description": "{Array} Array of speaker locations. Each item in the array should be an array of normalized x and y coordinates.\n\nsetSpeakers(locations) {\n\n}", + "lineNumber": 2, + "type": null, + "name": "locations" + } + ], + "loc": { + "start": { + "line": 266, + "column": 2 + }, + "end": { + "line": 273, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 255, + "column": 2 + }, + "end": { + "line": 264, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/pan2d.js" + }, + "augments": [], + "examples": [], + "params": [ + { + "title": "param", + "name": "locations", + "lineNumber": 2, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "{Array} Array of speaker locations. Each item in the array should be an array of normalized x and y coordinates.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 113, + "offset": 112 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 113, + "offset": 112 + }, + "indent": [] + } + }, + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "setSpeakers(locations) {", + "position": { + "start": { + "line": 3, + "column": 1, + "offset": 114 + }, + "end": { + "line": 3, + "column": 25, + "offset": 138 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 3, + "column": 1, + "offset": 114 + }, + "end": { + "line": 3, + "column": 25, + "offset": 138 + }, + "indent": [] + } + }, + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "}", + "position": { + "start": { + "line": 5, + "column": 1, + "offset": 140 + }, + "end": { + "line": 5, + "column": 2, + "offset": 141 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 5, + "column": 1, + "offset": 140 + }, + "end": { + "line": 5, + "column": 2, + "offset": 141 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 5, + "column": 2, + "offset": 141 + } + } + } + } + ], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [], + "namespace": "" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Piano keyboard interface", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 25, + "offset": 24 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 25, + "offset": 24 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 25, + "offset": 24 + } + } + }, + "tags": [ + { + "title": "description", + "description": "Piano keyboard interface", + "lineNumber": 3 + }, + { + "title": "demo", + "description": "
", + "lineNumber": 5 + }, + { + "title": "example", + "description": "var piano = new Nexus.Piano('#target')", + "lineNumber": 7 + }, + { + "title": "example", + "description": "var piano = new Nexus.Piano('#target',{\n 'size': [500,125],\n 'mode': 'button', // 'button', 'toggle', or 'impulse'\n 'lowNote': 24,\n 'highNote': 60\n})", + "lineNumber": 10 + }, + { + "title": "output", + "description": "change\nFires any time a new key is pressed or released
\nThe event data is an object containing note and state properties.", + "lineNumber": 18 + }, + { + "title": "outputexample", + "description": "piano.on('change',function(v) {\n console.log(v);\n})", + "lineNumber": 23 + } + ], + "loc": { + "start": { + "line": 132, + "column": 0 + }, + "end": { + "line": 160, + "column": 2 + } + }, + "context": { + "loc": { + "start": { + "line": 162, + "column": 0 + }, + "end": { + "line": 434, + "column": 1 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/piano.js" + }, + "augments": [ + { + "title": "augments", + "name": "Interface" + } + ], + "examples": [ + { + "description": "var piano = new Nexus.Piano('#target')" + }, + { + "description": "var piano = new Nexus.Piano('#target',{\n 'size': [500,125],\n 'mode': 'button', // 'button', 'toggle', or 'impulse'\n 'lowNote': 24,\n 'highNote': 60\n})" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "Piano", + "kind": "class", + "members": { + "global": [], + "inner": [], + "instance": [ + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Define the pitch range (lowest and highest note) of the piano keyboard.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 72, + "offset": 71 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 72, + "offset": 71 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 72, + "offset": 71 + } + } + }, + "tags": [ + { + "title": "param", + "description": "{number} MIDI note value of the lowest note on the keyboard", + "lineNumber": 2, + "type": null, + "name": "low" + }, + { + "title": "param", + "description": "{number} MIDI note value of the highest note on the keyboard", + "lineNumber": 3, + "type": null, + "name": "high" + } + ], + "loc": { + "start": { + "line": 404, + "column": 2 + }, + "end": { + "line": 408, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 409, + "column": 2 + }, + "end": { + "line": 414, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/piano.js" + }, + "augments": [], + "examples": [], + "params": [ + { + "title": "param", + "name": "low", + "lineNumber": 2, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "{number} MIDI note value of the lowest note on the keyboard", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 60, + "offset": 59 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 60, + "offset": 59 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 60, + "offset": 59 + } + } + } + }, + { + "title": "param", + "name": "high", + "lineNumber": 3, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "{number} MIDI note value of the highest note on the keyboard", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 61, + "offset": 60 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 61, + "offset": 60 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 61, + "offset": 60 + } + } + } + } + ], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "setRange", + "kind": "function", + "memberof": "Piano", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Piano", + "kind": "class" + }, + { + "name": "setRange", + "kind": "function", + "scope": "instance" + } + ], + "namespace": "Piano#setRange" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Turn a key on or off using its MIDI note value;", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 48, + "offset": 47 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 48, + "offset": 47 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 48, + "offset": 47 + } + } + }, + "tags": [ + { + "title": "param", + "description": "{number} MIDI note value of the key to change", + "lineNumber": 2, + "type": null, + "name": "note" + }, + { + "title": "param", + "description": "{boolean} Whether the note should turn on or off", + "lineNumber": 3, + "type": null, + "name": "on" + } + ], + "loc": { + "start": { + "line": 416, + "column": 2 + }, + "end": { + "line": 420, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 421, + "column": 2 + }, + "end": { + "line": 423, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/piano.js" + }, + "augments": [], + "examples": [], + "params": [ + { + "title": "param", + "name": "note", + "lineNumber": 2, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "{number} MIDI note value of the key to change", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 46, + "offset": 45 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 46, + "offset": 45 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 46, + "offset": 45 + } + } + } + }, + { + "title": "param", + "name": "on", + "lineNumber": 3, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "{boolean} Whether the note should turn on or off", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 49, + "offset": 48 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 49, + "offset": 48 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 49, + "offset": 48 + } + } + } + } + ], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "toggleKey", + "kind": "function", + "memberof": "Piano", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Piano", + "kind": "class" + }, + { + "name": "toggleKey", + "kind": "function", + "scope": "instance" + } + ], + "namespace": "Piano#toggleKey" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Turn a key on or off using its key index on the piano interface.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 65, + "offset": 64 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 65, + "offset": 64 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 65, + "offset": 64 + } + } + }, + "tags": [ + { + "title": "param", + "description": "{number} Index of the key to change", + "lineNumber": 2, + "type": null, + "name": "index" + }, + { + "title": "param", + "description": "{boolean} Whether the note should turn on or off", + "lineNumber": 3, + "type": null, + "name": "on" + } + ], + "loc": { + "start": { + "line": 425, + "column": 2 + }, + "end": { + "line": 429, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 430, + "column": 2 + }, + "end": { + "line": 432, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/piano.js" + }, + "augments": [], + "examples": [], + "params": [ + { + "title": "param", + "name": "index", + "lineNumber": 2, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "{number} Index of the key to change", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 36, + "offset": 35 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 36, + "offset": 35 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 36, + "offset": 35 + } + } + } + }, + { + "title": "param", + "name": "on", + "lineNumber": 3, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "{boolean} Whether the note should turn on or off", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 49, + "offset": 48 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 49, + "offset": 48 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 49, + "offset": 48 + } + } + } + } + ], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "toggleIndex", + "kind": "function", + "memberof": "Piano", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Piano", + "kind": "class" + }, + { + "name": "toggleIndex", + "kind": "function", + "scope": "instance" + } + ], + "namespace": "Piano#toggleIndex" + } + ], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Piano", + "kind": "class" + } + ], + "namespace": "Piano" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Two-dimensional touch slider.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 30, + "offset": 29 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 30, + "offset": 29 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 30, + "offset": 29 + } + } + }, + "tags": [ + { + "title": "description", + "description": "Two-dimensional touch slider.", + "lineNumber": 3 + }, + { + "title": "demo", + "description": "", + "lineNumber": 5 + }, + { + "title": "example", + "description": "var position = new Nexus.Position('#target')", + "lineNumber": 7 + }, + { + "title": "example", + "description": "var position = new Nexus.Position('#target',{\n 'size': [200,200],\n 'mode': 'absolute', // \"absolute\" or \"relative\"\n 'x': 0.5, // initial x value\n 'minX': 0,\n 'maxX': 1,\n 'stepX': 0,\n 'y': 0.5, // initial y value\n 'minY': 0,\n 'maxY': 1,\n 'stepY': 0\n})", + "lineNumber": 10 + }, + { + "title": "output", + "description": "change\nFires any time the interface's value changes.
\nThe event data is an object with x and y properties containing the x and y values of the interface.", + "lineNumber": 24 + }, + { + "title": "outputexample", + "description": "position.on('change',function(v) {\n console.log(v);\n})", + "lineNumber": 29 + } + ], + "loc": { + "start": { + "line": 9, + "column": 0 + }, + "end": { + "line": 44, + "column": 2 + } + }, + "context": { + "loc": { + "start": { + "line": 46, + "column": 0 + }, + "end": { + "line": 301, + "column": 1 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/position.js" + }, + "augments": [ + { + "title": "augments", + "name": "Interface" + } + ], + "examples": [ + { + "description": "var position = new Nexus.Position('#target')" + }, + { + "description": "var position = new Nexus.Position('#target',{\n 'size': [200,200],\n 'mode': 'absolute', // \"absolute\" or \"relative\"\n 'x': 0.5, // initial x value\n 'minX': 0,\n 'maxX': 1,\n 'stepX': 0,\n 'y': 0.5, // initial y value\n 'minY': 0,\n 'maxY': 1,\n 'stepY': 0\n})" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "Position", + "kind": "class", + "members": { + "global": [], + "inner": [], + "instance": [ + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "The interface's x value. When set, it will automatically adjust to fit min/max/step settings of the interface.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 111, + "offset": 110 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 111, + "offset": 110 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 111, + "offset": 110 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "object" + } + }, + { + "title": "example", + "description": "position.x = 0.5;", + "lineNumber": 3 + } + ], + "loc": { + "start": { + "line": 155, + "column": 2 + }, + "end": { + "line": 159, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 161, + "column": 2 + }, + "end": { + "line": 163, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/position.js" + }, + "augments": [], + "examples": [ + { + "description": "position.x = 0.5;" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "x", + "kind": "member", + "memberof": "Position", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Position", + "kind": "class" + }, + { + "name": "x", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "Position#x" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "The interface's y values. When set, it will automatically adjust to fit min/max/step settings of the interface.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 112, + "offset": 111 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 112, + "offset": 111 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 112, + "offset": 111 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "object" + } + }, + { + "title": "example", + "description": "position.x = 0.5;", + "lineNumber": 3 + } + ], + "loc": { + "start": { + "line": 174, + "column": 2 + }, + "end": { + "line": 178, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 180, + "column": 2 + }, + "end": { + "line": 182, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/position.js" + }, + "augments": [], + "examples": [ + { + "description": "position.x = 0.5;" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "y", + "kind": "member", + "memberof": "Position", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Position", + "kind": "class" + }, + { + "name": "y", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "Position#y" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "The lower limit of value on the x axis", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 39, + "offset": 38 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 39, + "offset": 38 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 39, + "offset": 38 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "object" + } + } + ], + "loc": { + "start": { + "line": 202, + "column": 2 + }, + "end": { + "line": 205, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 206, + "column": 2 + }, + "end": { + "line": 208, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/position.js" + }, + "augments": [], + "examples": [], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "minX", + "kind": "member", + "memberof": "Position", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Position", + "kind": "class" + }, + { + "name": "minX", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "Position#minX" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "The lower limit of value on the y axis", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 39, + "offset": 38 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 39, + "offset": 38 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 39, + "offset": 38 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "object" + } + } + ], + "loc": { + "start": { + "line": 215, + "column": 2 + }, + "end": { + "line": 218, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 219, + "column": 2 + }, + "end": { + "line": 221, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/position.js" + }, + "augments": [], + "examples": [], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "minY", + "kind": "member", + "memberof": "Position", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Position", + "kind": "class" + }, + { + "name": "minY", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "Position#minY" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "The upper limit of value on the x axis", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 39, + "offset": 38 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 39, + "offset": 38 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 39, + "offset": 38 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "object" + } + } + ], + "loc": { + "start": { + "line": 229, + "column": 2 + }, + "end": { + "line": 232, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 233, + "column": 2 + }, + "end": { + "line": 235, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/position.js" + }, + "augments": [], + "examples": [], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "maxX", + "kind": "member", + "memberof": "Position", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Position", + "kind": "class" + }, + { + "name": "maxX", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "Position#maxX" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "The upper limit of value on the y axis", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 39, + "offset": 38 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 39, + "offset": 38 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 39, + "offset": 38 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "object" + } + } + ], + "loc": { + "start": { + "line": 243, + "column": 2 + }, + "end": { + "line": 246, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 247, + "column": 2 + }, + "end": { + "line": 249, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/position.js" + }, + "augments": [], + "examples": [], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "maxY", + "kind": "member", + "memberof": "Position", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Position", + "kind": "class" + }, + { + "name": "maxY", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "Position#maxY" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "The incremental step of values on the x axis", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 45, + "offset": 44 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 45, + "offset": 44 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 45, + "offset": 44 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "object" + } + } + ], + "loc": { + "start": { + "line": 257, + "column": 2 + }, + "end": { + "line": 260, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 261, + "column": 2 + }, + "end": { + "line": 263, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/position.js" + }, + "augments": [], + "examples": [], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "stepX", + "kind": "member", + "memberof": "Position", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Position", + "kind": "class" + }, + { + "name": "stepX", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "Position#stepX" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "The incremental step of values on the y axis", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 45, + "offset": 44 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 45, + "offset": 44 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 45, + "offset": 44 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "object" + } + } + ], + "loc": { + "start": { + "line": 271, + "column": 2 + }, + "end": { + "line": 274, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 275, + "column": 2 + }, + "end": { + "line": 277, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/position.js" + }, + "augments": [], + "examples": [], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "stepY", + "kind": "member", + "memberof": "Position", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Position", + "kind": "class" + }, + { + "name": "stepY", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "Position#stepY" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Absolute mode (position's value jumps to mouse click position) or relative mode (mouse drag changes value relative to its current position). Default: \"absolute\".", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 162, + "offset": 161 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 162, + "offset": 161 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 162, + "offset": 161 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "string" + } + }, + { + "title": "example", + "description": "position.mode = \"relative\";", + "lineNumber": 3 + } + ], + "loc": { + "start": { + "line": 285, + "column": 2 + }, + "end": { + "line": 289, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 290, + "column": 2 + }, + "end": { + "line": 292, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/position.js" + }, + "augments": [], + "examples": [ + { + "description": "position.mode = \"relative\";" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "mode", + "kind": "member", + "memberof": "Position", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Position", + "kind": "class" + }, + { + "name": "mode", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "Position#mode" + } + ], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Position", + "kind": "class" + } + ], + "namespace": "Position" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "An array of buttons. By default, selecting one button will deselect all other buttons, but this can be customized using the API below.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 135, + "offset": 134 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 135, + "offset": 134 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 135, + "offset": 134 + } + } + }, + "tags": [ + { + "title": "description", + "description": "An array of buttons. By default, selecting one button will deselect all other buttons, but this can be customized using the API below.", + "lineNumber": 3 + }, + { + "title": "demo", + "description": "
", + "lineNumber": 5 + }, + { + "title": "example", + "description": "var radiobutton = new Nexus.RadioButton('#target')", + "lineNumber": 7 + }, + { + "title": "example", + "description": "var radiobutton = new Nexus.RadioButton('#target',{\n 'size': [120,25],\n 'numberOfButtons': 4,\n 'active': -1\n})", + "lineNumber": 10 + }, + { + "title": "output", + "description": "change\nFires any time the interface's value changes.
\nThe event data an integer, the index of the button that is currently on. If no button is selected, the value will be -1.", + "lineNumber": 17 + }, + { + "title": "outputexample", + "description": "radiobutton.on('change',function(v) {\n console.log(v);\n})", + "lineNumber": 22 + } + ], + "loc": { + "start": { + "line": 7, + "column": 0 + }, + "end": { + "line": 34, + "column": 3 + } + }, + "context": { + "loc": { + "start": { + "line": 36, + "column": 0 + }, + "end": { + "line": 164, + "column": 1 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/radiobutton.js" + }, + "augments": [ + { + "title": "augments", + "name": "Interface" + } + ], + "examples": [ + { + "description": "var radiobutton = new Nexus.RadioButton('#target')" + }, + { + "description": "var radiobutton = new Nexus.RadioButton('#target',{\n 'size': [120,25],\n 'numberOfButtons': 4,\n 'active': -1\n})" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "RadioButton", + "kind": "class", + "members": { + "global": [], + "inner": [], + "instance": [ + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Select one button and deselect all other buttons.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 50, + "offset": 49 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 50, + "offset": 49 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 50, + "offset": 49 + } + } + }, + "tags": [ + { + "title": "param", + "description": "{number} The index of the button to select", + "lineNumber": 2, + "type": null, + "name": "index" + } + ], + "loc": { + "start": { + "line": 123, + "column": 2 + }, + "end": { + "line": 126, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 127, + "column": 2 + }, + "end": { + "line": 133, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/radiobutton.js" + }, + "augments": [], + "examples": [], + "params": [ + { + "title": "param", + "name": "index", + "lineNumber": 2, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "{number} The index of the button to select", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 43, + "offset": 42 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 43, + "offset": 42 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 43, + "offset": 42 + } + } + } + } + ], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "select", + "kind": "function", + "memberof": "RadioButton", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "RadioButton", + "kind": "class" + }, + { + "name": "select", + "kind": "function", + "scope": "instance" + } + ], + "namespace": "RadioButton#select" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Deselect all buttons.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 22, + "offset": 21 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 22, + "offset": 21 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 22, + "offset": 21 + } + } + }, + "tags": [], + "loc": { + "start": { + "line": 135, + "column": 2 + }, + "end": { + "line": 137, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 138, + "column": 2 + }, + "end": { + "line": 142, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/radiobutton.js" + }, + "augments": [], + "examples": [], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "deselect", + "kind": "function", + "memberof": "RadioButton", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "RadioButton", + "kind": "class" + }, + { + "name": "deselect", + "kind": "function", + "scope": "instance" + } + ], + "namespace": "RadioButton#deselect" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Update how many buttons are in the interface", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 45, + "offset": 44 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 45, + "offset": 44 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 45, + "offset": 44 + } + } + }, + "tags": [ + { + "title": "param", + "description": "How many buttons are in the interface", + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "number" + }, + "name": "buttons" + } + ], + "loc": { + "start": { + "line": 148, + "column": 2 + }, + "end": { + "line": 151, + "column": 5 + } + }, + "context": { + "loc": { + "start": { + "line": 152, + "column": 2 + }, + "end": { + "line": 163, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/radiobutton.js" + }, + "augments": [], + "examples": [], + "params": [ + { + "title": "param", + "name": "buttons", + "lineNumber": 2, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "How many buttons are in the interface", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 38, + "offset": 37 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 38, + "offset": 37 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 38, + "offset": 37 + } + } + }, + "type": { + "type": "NameExpression", + "name": "number" + } + } + ], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "numberOfButtons", + "kind": "member", + "memberof": "RadioButton", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "RadioButton", + "kind": "class" + }, + { + "name": "numberOfButtons", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "RadioButton#numberOfButtons" + } + ], + "events": [], + "static": [] + }, + "path": [ + { + "name": "RadioButton", + "kind": "class" + } + ], + "namespace": "RadioButton" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Dropdown menu", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 14, + "offset": 13 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 14, + "offset": 13 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 14, + "offset": 13 + } + } + }, + "tags": [ + { + "title": "description", + "description": "Dropdown menu", + "lineNumber": 3 + }, + { + "title": "demo", + "description": "", + "lineNumber": 5 + }, + { + "title": "example", + "description": "var select = new Nexus.Select('#target')", + "lineNumber": 7 + }, + { + "title": "example", + "description": "var select = new Nexus.Select('#target',{\n 'size': [100,30],\n 'options': ['default','options']\n})", + "lineNumber": 10 + }, + { + "title": "output", + "description": "change\nFires any time the interface's value changes.
\nThe event data is an object containing the text value of the selected option, as well as the numeric index of the selection.", + "lineNumber": 16 + }, + { + "title": "outputexample", + "description": "select.on('change',function(v) {\n console.log(v);\n})", + "lineNumber": 21 + } + ], + "loc": { + "start": { + "line": 5, + "column": 0 + }, + "end": { + "line": 32, + "column": 2 + } + }, + "context": { + "loc": { + "start": { + "line": 35, + "column": 0 + }, + "end": { + "line": 185, + "column": 1 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/select.js" + }, + "augments": [ + { + "title": "augments", + "name": "Interface" + } + ], + "examples": [ + { + "description": "var select = new Nexus.Select('#target')" + }, + { + "description": "var select = new Nexus.Select('#target',{\n 'size': [100,30],\n 'options': ['default','options']\n})" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "Select", + "kind": "class", + "members": { + "global": [], + "inner": [], + "instance": [ + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Update the list of options. This removes all existing options and creates a new list of options.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 97, + "offset": 96 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 97, + "offset": 96 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 97, + "offset": 96 + } + } + }, + "tags": [ + { + "title": "param", + "description": "New array of options", + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "array" + }, + "name": "options" + } + ], + "loc": { + "start": { + "line": 113, + "column": 2 + }, + "end": { + "line": 116, + "column": 5 + } + }, + "context": { + "loc": { + "start": { + "line": 118, + "column": 2 + }, + "end": { + "line": 144, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/select.js" + }, + "augments": [], + "examples": [], + "params": [ + { + "title": "param", + "name": "options", + "lineNumber": 2, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "New array of options", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 21, + "offset": 20 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 21, + "offset": 20 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 21, + "offset": 20 + } + } + }, + "type": { + "type": "NameExpression", + "name": "array" + } + } + ], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "defineOptions", + "kind": "function", + "memberof": "Select", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Select", + "kind": "class" + }, + { + "name": "defineOptions", + "kind": "function", + "scope": "instance" + } + ], + "namespace": "Select#defineOptions" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "The text of the option that is currently selected. If set, will update the interface and trigger the output event.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 115, + "offset": 114 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 115, + "offset": 114 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 115, + "offset": 114 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "String" + } + }, + { + "title": "example", + "description": "select.value = \"sawtooth\";", + "lineNumber": 3 + } + ], + "loc": { + "start": { + "line": 147, + "column": 2 + }, + "end": { + "line": 151, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 152, + "column": 2 + }, + "end": { + "line": 154, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/select.js" + }, + "augments": [], + "examples": [ + { + "description": "select.value = \"sawtooth\";" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "value", + "kind": "member", + "memberof": "Select", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Select", + "kind": "class" + }, + { + "name": "value", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "Select#value" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "The numeric index of the option that is currently selected. If set, will update the interface and trigger the output event.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 124, + "offset": 123 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 124, + "offset": 123 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 124, + "offset": 123 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "number" + } + }, + { + "title": "example", + "description": "select.selectedIndex = 2;", + "lineNumber": 3 + } + ], + "loc": { + "start": { + "line": 166, + "column": 2 + }, + "end": { + "line": 170, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 171, + "column": 2 + }, + "end": { + "line": 173, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/select.js" + }, + "augments": [], + "examples": [ + { + "description": "select.selectedIndex = 2;" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "selectedIndex", + "kind": "member", + "memberof": "Select", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Select", + "kind": "class" + }, + { + "name": "selectedIndex", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "Select#selectedIndex" + } + ], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Select", + "kind": "class" + } + ], + "namespace": "Select" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Amount of row padding", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 22, + "offset": 21 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 22, + "offset": 21 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 22, + "offset": 21 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "number" + } + } + ], + "loc": { + "start": { + "line": 33, + "column": 4 + }, + "end": { + "line": 36, + "column": 7 + } + }, + "context": { + "loc": { + "start": { + "line": 37, + "column": 4 + }, + "end": { + "line": 37, + "column": 70 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/sequencer.js" + }, + "augments": [], + "examples": [], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "paddingRow", + "memberof": "MatrixCell", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "paddingRow", + "scope": "instance" + } + ], + "namespace": "#paddingRow" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Amount of column padding", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 25, + "offset": 24 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 25, + "offset": 24 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 25, + "offset": 24 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "number" + } + } + ], + "loc": { + "start": { + "line": 39, + "column": 4 + }, + "end": { + "line": 42, + "column": 7 + } + }, + "context": { + "loc": { + "start": { + "line": 43, + "column": 4 + }, + "end": { + "line": 43, + "column": 79 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/sequencer.js" + }, + "augments": [], + "examples": [], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "paddingColumn", + "memberof": "MatrixCell", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "paddingColumn", + "scope": "instance" + } + ], + "namespace": "#paddingColumn" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Grid of buttons with built-in step sequencer.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 46, + "offset": 45 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 46, + "offset": 45 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 46, + "offset": 45 + } + } + }, + "tags": [ + { + "title": "description", + "description": "Grid of buttons with built-in step sequencer.", + "lineNumber": 3 + }, + { + "title": "demo", + "description": "
", + "lineNumber": 5 + }, + { + "title": "example", + "description": "var sequencer = new Nexus.Sequencer('#target')", + "lineNumber": 7 + }, + { + "title": "example", + "description": "var sequencer = new Nexus.Sequencer('#target',{\n 'size': [400,200],\n 'mode': 'toggle',\n 'rows': 5,\n 'columns': 10,\n 'paddingRow': 10,\n 'paddingColumn': 20\n})", + "lineNumber": 10 + }, + { + "title": "output", + "description": "change\nFires whenever a value is received. For example, when clicking a cell from off to on.
\nThe event data is an object containing row (number), column (number), and state (boolean) properties.", + "lineNumber": 20 + }, + { + "title": "outputexample", + "description": "sequencer.on('change',function(v) {\n console.log(v);\n})", + "lineNumber": 25 + }, + { + "title": "output", + "description": "step\nFires any time the sequencer steps to the next column, in sequece mode.
\nThe event data is an array containing all values in the column, bottom row first.", + "lineNumber": 30 + }, + { + "title": "outputexample", + "description": "sequencer.on('step',function(v) {\n console.log(v);\n})", + "lineNumber": 35 + } + ], + "loc": { + "start": { + "line": 134, + "column": 0 + }, + "end": { + "line": 173, + "column": 3 + } + }, + "context": { + "loc": { + "start": { + "line": 175, + "column": 0 + }, + "end": { + "line": 452, + "column": 1 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/sequencer.js" + }, + "augments": [ + { + "title": "augments", + "name": "Interface" + } + ], + "examples": [ + { + "description": "var sequencer = new Nexus.Sequencer('#target')" + }, + { + "description": "var sequencer = new Nexus.Sequencer('#target',{\n 'size': [400,200],\n 'mode': 'toggle',\n 'rows': 5,\n 'columns': 10,\n 'paddingRow': 10,\n 'paddingColumn': 20\n})" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "Sequencer", + "kind": "class", + "members": { + "global": [], + "inner": [], + "instance": [ + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Button interaction mode: see Button", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 36, + "offset": 35 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 36, + "offset": 35 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 36, + "offset": 35 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "string" + } + }, + { + "title": "example", + "description": "button.mode = 'toggle';", + "lineNumber": 3 + } + ], + "loc": { + "start": { + "line": 190, + "column": 4 + }, + "end": { + "line": 194, + "column": 7 + } + }, + "context": { + "loc": { + "start": { + "line": 195, + "column": 4 + }, + "end": { + "line": 195, + "column": 35 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/sequencer.js" + }, + "augments": [], + "examples": [ + { + "description": "button.mode = 'toggle';" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "mode", + "memberof": "Sequencer", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Sequencer", + "kind": "class" + }, + { + "name": "mode", + "scope": "instance" + } + ], + "namespace": "Sequencer#mode" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "The interval object which controls timing and sequence scheduling.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 67, + "offset": 66 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 67, + "offset": 66 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 67, + "offset": 66 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "interval" + } + } + ], + "loc": { + "start": { + "line": 197, + "column": 4 + }, + "end": { + "line": 200, + "column": 7 + } + }, + "context": { + "loc": { + "start": { + "line": 201, + "column": 4 + }, + "end": { + "line": 201, + "column": 60 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/sequencer.js" + }, + "augments": [], + "examples": [], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "interval", + "memberof": "Sequencer", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Sequencer", + "kind": "class" + }, + { + "name": "interval", + "scope": "instance" + } + ], + "namespace": "Sequencer#interval" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "A Matrix model containing methods for manipulating the sequencer's array of values. To learn how to manipulate the matrix, read about the matrix model.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 152, + "offset": 151 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 152, + "offset": 151 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 152, + "offset": 151 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "matrix" + } + } + ], + "loc": { + "start": { + "line": 203, + "column": 4 + }, + "end": { + "line": 206, + "column": 7 + } + }, + "context": { + "loc": { + "start": { + "line": 207, + "column": 4 + }, + "end": { + "line": 207, + "column": 77 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/sequencer.js" + }, + "augments": [], + "examples": [], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "matrix", + "memberof": "Sequencer", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Sequencer", + "kind": "class" + }, + { + "name": "matrix", + "scope": "instance" + } + ], + "namespace": "Sequencer#matrix" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "A Counter model which the sequencer steps through. For example, you could use this model to step through the sequencer in reverse, randomly, or in a drunk walk.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 161, + "offset": 160 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 161, + "offset": 160 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 161, + "offset": 160 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "counter" + } + } + ], + "loc": { + "start": { + "line": 210, + "column": 4 + }, + "end": { + "line": 213, + "column": 7 + } + }, + "context": { + "loc": { + "start": { + "line": 214, + "column": 4 + }, + "end": { + "line": 214, + "column": 53 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/sequencer.js" + }, + "augments": [], + "examples": [], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "stepper", + "memberof": "Sequencer", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Sequencer", + "kind": "class" + }, + { + "name": "stepper", + "scope": "instance" + } + ], + "namespace": "Sequencer#stepper" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Start sequencing", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 17, + "offset": 16 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 17, + "offset": 16 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 17, + "offset": 16 + } + } + }, + "tags": [ + { + "title": "param", + "description": "Beat tempo in milliseconds", + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "number" + }, + "name": "ms" + } + ], + "loc": { + "start": { + "line": 342, + "column": 2 + }, + "end": { + "line": 345, + "column": 5 + } + }, + "context": { + "loc": { + "start": { + "line": 346, + "column": 2 + }, + "end": { + "line": 352, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/sequencer.js" + }, + "augments": [], + "examples": [], + "params": [ + { + "title": "param", + "name": "ms", + "lineNumber": 2, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Beat tempo in milliseconds", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 27, + "offset": 26 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 27, + "offset": 26 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 27, + "offset": 26 + } + } + }, + "type": { + "type": "NameExpression", + "name": "number" + } + } + ], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "start", + "kind": "function", + "memberof": "Sequencer", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Sequencer", + "kind": "class" + }, + { + "name": "start", + "kind": "function", + "scope": "instance" + } + ], + "namespace": "Sequencer#start" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Stop sequencing", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 16, + "offset": 15 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 16, + "offset": 15 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 16, + "offset": 15 + } + } + }, + "tags": [], + "loc": { + "start": { + "line": 354, + "column": 2 + }, + "end": { + "line": 356, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 357, + "column": 2 + }, + "end": { + "line": 359, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/sequencer.js" + }, + "augments": [], + "examples": [], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "stop", + "kind": "function", + "memberof": "Sequencer", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Sequencer", + "kind": "class" + }, + { + "name": "stop", + "kind": "function", + "scope": "instance" + } + ], + "namespace": "Sequencer#stop" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Manually jump to the next column and trigger the 'change' event. The \"next\" column is determined by your mode of sequencing.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 125, + "offset": 124 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 125, + "offset": 124 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 125, + "offset": 124 + } + } + }, + "tags": [], + "loc": { + "start": { + "line": 361, + "column": 2 + }, + "end": { + "line": 363, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 364, + "column": 2 + }, + "end": { + "line": 368, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/sequencer.js" + }, + "augments": [], + "examples": [], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "next", + "kind": "function", + "memberof": "Sequencer", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Sequencer", + "kind": "class" + }, + { + "name": "next", + "kind": "function", + "scope": "instance" + } + ], + "namespace": "Sequencer#next" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Number of rows in the sequencer", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 32, + "offset": 31 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 32, + "offset": 31 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 32, + "offset": 31 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "number" + } + } + ], + "loc": { + "start": { + "line": 422, + "column": 2 + }, + "end": { + "line": 425, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 426, + "column": 2 + }, + "end": { + "line": 428, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/sequencer.js" + }, + "augments": [], + "examples": [], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "rows", + "kind": "member", + "memberof": "Sequencer", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Sequencer", + "kind": "class" + }, + { + "name": "rows", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "Sequencer#rows" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Number of columns in the sequencer", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 35, + "offset": 34 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 35, + "offset": 34 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 35, + "offset": 34 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "number" + } + } + ], + "loc": { + "start": { + "line": 437, + "column": 2 + }, + "end": { + "line": 440, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 441, + "column": 2 + }, + "end": { + "line": 443, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/sequencer.js" + }, + "augments": [], + "examples": [], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "columns", + "kind": "member", + "memberof": "Sequencer", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Sequencer", + "kind": "class" + }, + { + "name": "columns", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "Sequencer#columns" + } + ], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Sequencer", + "kind": "class" + } + ], + "namespace": "Sequencer" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Horizontal or vertical slider with settable interaction modes.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 63, + "offset": 62 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 63, + "offset": 62 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 63, + "offset": 62 + } + } + }, + "tags": [ + { + "title": "description", + "description": "Horizontal or vertical slider with settable interaction modes.", + "lineNumber": 3 + }, + { + "title": "demo", + "description": "", + "lineNumber": 5 + }, + { + "title": "example", + "description": "var slider = new Nexus.Slider('#target')", + "lineNumber": 7 + }, + { + "title": "example", + "description": "var slider = new Nexus.Slider('#target',{\n 'size': [120,20],\n 'mode': 'relative', // 'relative' or 'absolute'\n 'min': 0,\n 'max': 1,\n 'step': 0,\n 'value': 0\n})", + "lineNumber": 10 + }, + { + "title": "output", + "description": "change\nFires when the interface's value changes.
\nEvent data: number The number value of the interface.", + "lineNumber": 20 + }, + { + "title": "outputexample", + "description": "slider.on('change',function(v) {\n console.log(v);\n})", + "lineNumber": 25 + } + ], + "loc": { + "start": { + "line": 8, + "column": 0 + }, + "end": { + "line": 39, + "column": 2 + } + }, + "context": { + "loc": { + "start": { + "line": 41, + "column": 0 + }, + "end": { + "line": 277, + "column": 1 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/slider.js" + }, + "augments": [ + { + "title": "augments", + "name": "Interface" + } + ], + "examples": [ + { + "description": "var slider = new Nexus.Slider('#target')" + }, + { + "description": "var slider = new Nexus.Slider('#target',{\n 'size': [120,20],\n 'mode': 'relative', // 'relative' or 'absolute'\n 'min': 0,\n 'max': 1,\n 'step': 0,\n 'value': 0\n})" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "Slider", + "kind": "class", + "members": { + "global": [], + "inner": [], + "instance": [ + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "The slider's current value. If set manually, will update the interface and trigger the output event.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 101, + "offset": 100 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 101, + "offset": 100 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 101, + "offset": 100 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "number" + } + }, + { + "title": "example", + "description": "slider.value = 10;", + "lineNumber": 3 + } + ], + "loc": { + "start": { + "line": 212, + "column": 2 + }, + "end": { + "line": 216, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 217, + "column": 2 + }, + "end": { + "line": 219, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/slider.js" + }, + "augments": [], + "examples": [ + { + "description": "slider.value = 10;" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "value", + "kind": "member", + "memberof": "Slider", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Slider", + "kind": "class" + }, + { + "name": "value", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "Slider#value" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Lower limit of the sliders's output range", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 42, + "offset": 41 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 42, + "offset": 41 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 42, + "offset": 41 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "number" + } + }, + { + "title": "example", + "description": "slider.min = 1000;", + "lineNumber": 3 + } + ], + "loc": { + "start": { + "line": 227, + "column": 2 + }, + "end": { + "line": 231, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 232, + "column": 2 + }, + "end": { + "line": 234, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/slider.js" + }, + "augments": [], + "examples": [ + { + "description": "slider.min = 1000;" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "min", + "kind": "member", + "memberof": "Slider", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Slider", + "kind": "class" + }, + { + "name": "min", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "Slider#min" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Upper limit of the slider's output range", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 41, + "offset": 40 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 41, + "offset": 40 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 41, + "offset": 40 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "number" + } + }, + { + "title": "example", + "description": "slider.max = 1000;", + "lineNumber": 3 + } + ], + "loc": { + "start": { + "line": 239, + "column": 2 + }, + "end": { + "line": 243, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 244, + "column": 2 + }, + "end": { + "line": 246, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/slider.js" + }, + "augments": [], + "examples": [ + { + "description": "slider.max = 1000;" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "max", + "kind": "member", + "memberof": "Slider", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Slider", + "kind": "class" + }, + { + "name": "max", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "Slider#max" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "The increment that the slider's value changes by.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 50, + "offset": 49 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 50, + "offset": 49 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 50, + "offset": 49 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "number" + } + }, + { + "title": "example", + "description": "slider.step = 5;", + "lineNumber": 3 + } + ], + "loc": { + "start": { + "line": 251, + "column": 2 + }, + "end": { + "line": 255, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 256, + "column": 2 + }, + "end": { + "line": 258, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/slider.js" + }, + "augments": [], + "examples": [ + { + "description": "slider.step = 5;" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "step", + "kind": "member", + "memberof": "Slider", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Slider", + "kind": "class" + }, + { + "name": "step", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "Slider#step" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Absolute mode (slider's value jumps to mouse click position) or relative mode (mouse drag changes value relative to its current position). Default: \"relative\".", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 160, + "offset": 159 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 160, + "offset": 159 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 160, + "offset": 159 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "string" + } + }, + { + "title": "example", + "description": "slider.mode = \"relative\";", + "lineNumber": 3 + } + ], + "loc": { + "start": { + "line": 263, + "column": 2 + }, + "end": { + "line": 267, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 268, + "column": 2 + }, + "end": { + "line": 270, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/slider.js" + }, + "augments": [], + "examples": [ + { + "description": "slider.mode = \"relative\";" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "mode", + "kind": "member", + "memberof": "Slider", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Slider", + "kind": "class" + }, + { + "name": "mode", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "Slider#mode" + } + ], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Slider", + "kind": "class" + } + ], + "namespace": "Slider" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Audio spectrum visualization", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 29, + "offset": 28 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 29, + "offset": 28 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 29, + "offset": 28 + } + } + }, + "tags": [ + { + "title": "description", + "description": "Audio spectrum visualization", + "lineNumber": 3 + }, + { + "title": "demo", + "description": "", + "lineNumber": 5 + }, + { + "title": "example", + "description": "var spectrogram = new Nexus.Spectrogram('#target')\nspectrogram.connect(myWebAudioNode)", + "lineNumber": 7 + }, + { + "title": "example", + "description": "var spectrogram = new Nexus.Spectrogram('#target',{\n 'size': [300,150]\n})\nspectrogram.connect(myWebAudioNode)", + "lineNumber": 11 + }, + { + "title": "output", + "description": " \nNo events", + "lineNumber": 17 + } + ], + "loc": { + "start": { + "line": 6, + "column": 0 + }, + "end": { + "line": 27, + "column": 3 + } + }, + "context": { + "loc": { + "start": { + "line": 29, + "column": 0 + }, + "end": { + "line": 154, + "column": 1 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/spectrogram.js" + }, + "augments": [ + { + "title": "augments", + "name": "Interface" + } + ], + "examples": [ + { + "description": "var spectrogram = new Nexus.Spectrogram('#target')\nspectrogram.connect(myWebAudioNode)" + }, + { + "description": "var spectrogram = new Nexus.Spectrogram('#target',{\n 'size': [300,150]\n})\nspectrogram.connect(myWebAudioNode)" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "Spectrogram", + "kind": "class", + "members": { + "global": [], + "inner": [], + "instance": [ + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Equivalent to \"patching in\" an audio node to visualize.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 56, + "offset": 55 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 56, + "offset": 55 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 56, + "offset": 55 + } + } + }, + "tags": [ + { + "title": "param", + "description": "{AudioNode} The audio node to visualize", + "lineNumber": 2, + "type": null, + "name": "node" + }, + { + "title": "example", + "description": "spectrogram.connect( Tone.Master );", + "lineNumber": 3 + } + ], + "loc": { + "start": { + "line": 108, + "column": 2 + }, + "end": { + "line": 112, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 113, + "column": 2 + }, + "end": { + "line": 129, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/spectrogram.js" + }, + "augments": [], + "examples": [ + { + "description": "spectrogram.connect( Tone.Master );" + } + ], + "params": [ + { + "title": "param", + "name": "node", + "lineNumber": 2, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "{AudioNode} The audio node to visualize", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 40, + "offset": 39 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 40, + "offset": 39 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 40, + "offset": 39 + } + } + } + } + ], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "connect", + "kind": "function", + "memberof": "Spectrogram", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Spectrogram", + "kind": "class" + }, + { + "name": "connect", + "kind": "function", + "scope": "instance" + } + ], + "namespace": "Spectrogram#connect" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Stop visualizing the source node and disconnect it.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 52, + "offset": 51 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 52, + "offset": 51 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 52, + "offset": 51 + } + } + }, + "tags": [], + "loc": { + "start": { + "line": 131, + "column": 2 + }, + "end": { + "line": 133, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 134, + "column": 2 + }, + "end": { + "line": 144, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/spectrogram.js" + }, + "augments": [], + "examples": [], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "disconnect", + "kind": "function", + "memberof": "Spectrogram", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Spectrogram", + "kind": "class" + }, + { + "name": "disconnect", + "kind": "function", + "scope": "instance" + } + ], + "namespace": "Spectrogram#disconnect" + } + ], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Spectrogram", + "kind": "class" + } + ], + "namespace": "Spectrogram" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Text button", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 12, + "offset": 11 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 12, + "offset": 11 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 12, + "offset": 11 + } + } + }, + "tags": [ + { + "title": "description", + "description": "Text button", + "lineNumber": 3 + }, + { + "title": "demo", + "description": "", + "lineNumber": 5 + }, + { + "title": "example", + "description": "var textbutton = new Nexus.TextButton('#target')", + "lineNumber": 7 + }, + { + "title": "example", + "description": "var textbutton = new Nexus.TextButton('#target',{\n 'size': [150,50],\n 'state': false,\n 'text': 'Play',\n 'alternateText': 'Stop'\n})", + "lineNumber": 10 + }, + { + "title": "output", + "description": "change\nFires any time the interface's value changes.
\nThe event data is a string of the text on the button at the moment it was clicked.", + "lineNumber": 18 + }, + { + "title": "outputexample", + "description": "textbutton.on('change',function(v) {\n console.log(v);\n})", + "lineNumber": 23 + } + ], + "loc": { + "start": { + "line": 5, + "column": 0 + }, + "end": { + "line": 33, + "column": 2 + } + }, + "context": { + "loc": { + "start": { + "line": 35, + "column": 0 + }, + "end": { + "line": 154, + "column": 1 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/textbutton.js" + }, + "augments": [ + { + "title": "augments", + "name": "ButtonTemplate" + } + ], + "examples": [ + { + "description": "var textbutton = new Nexus.TextButton('#target')" + }, + { + "description": "var textbutton = new Nexus.TextButton('#target',{\n 'size': [150,50],\n 'state': false,\n 'text': 'Play',\n 'alternateText': 'Stop'\n})" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "TextButton", + "kind": "class", + "members": { + "global": [], + "inner": [], + "instance": [ + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "The text to display when the button is in its \"on\" state. If set, this puts the button in \"toggle\" mode.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 105, + "offset": 104 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 105, + "offset": 104 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 105, + "offset": 104 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "String" + } + } + ], + "loc": { + "start": { + "line": 120, + "column": 2 + }, + "end": { + "line": 123, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 124, + "column": 2 + }, + "end": { + "line": 126, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/textbutton.js" + }, + "augments": [], + "examples": [], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "alternateText", + "kind": "member", + "memberof": "TextButton", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "TextButton", + "kind": "class" + }, + { + "name": "alternateText", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "TextButton#alternateText" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "The text to display. (If .alternateText exists, then this .text will only be displayed when the button is in its \"off\" state.)", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 127, + "offset": 126 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 127, + "offset": 126 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 127, + "offset": 126 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "String" + } + } + ], + "loc": { + "start": { + "line": 139, + "column": 2 + }, + "end": { + "line": 142, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 143, + "column": 2 + }, + "end": { + "line": 145, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/textbutton.js" + }, + "augments": [], + "examples": [], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "text", + "kind": "member", + "memberof": "TextButton", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "TextButton", + "kind": "class" + }, + { + "name": "text", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "TextButton#text" + } + ], + "events": [], + "static": [] + }, + "path": [ + { + "name": "TextButton", + "kind": "class" + } + ], + "namespace": "TextButton" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Device tilt sensor with 2 or 3 axes (depending on your device and browser).", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 76, + "offset": 75 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 76, + "offset": 75 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 76, + "offset": 75 + } + } + }, + "tags": [ + { + "title": "description", + "description": "Device tilt sensor with 2 or 3 axes (depending on your device and browser).", + "lineNumber": 3 + }, + { + "title": "demo", + "description": "", + "lineNumber": 5 + }, + { + "title": "example", + "description": "var tilt = new Nexus.Tilt('#target')", + "lineNumber": 7 + }, + { + "title": "output", + "description": "change\nFires at a regular interval, as long as this interface is active (see the interface's .active property)
\nThe event data is an object containing x (number) and y (number) properties which represent the current tilt state of the device.", + "lineNumber": 10 + }, + { + "title": "outputexample", + "description": "tilt.on('change',function(v) {\n console.log(v);\n})", + "lineNumber": 15 + } + ], + "loc": { + "start": { + "line": 7, + "column": 0 + }, + "end": { + "line": 28, + "column": 2 + } + }, + "context": { + "loc": { + "start": { + "line": 30, + "column": 0 + }, + "end": { + "line": 309, + "column": 1 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/tilt.js" + }, + "augments": [ + { + "title": "augments", + "name": "Interface" + } + ], + "examples": [ + { + "description": "var tilt = new Nexus.Tilt('#target')" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "Tilt", + "kind": "class", + "members": { + "global": [], + "inner": [], + "instance": [ + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Whether the interface is on (emitting values) or off (paused & not emitting values). Setting this property will update it.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 123, + "offset": 122 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 123, + "offset": 122 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 123, + "offset": 122 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "boolean" + } + } + ], + "loc": { + "start": { + "line": 291, + "column": 2 + }, + "end": { + "line": 294, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 296, + "column": 2 + }, + "end": { + "line": 298, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/tilt.js" + }, + "augments": [], + "examples": [], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "active", + "kind": "member", + "memberof": "Tilt", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Tilt", + "kind": "class" + }, + { + "name": "active", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "Tilt#active" + } + ], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Tilt", + "kind": "class" + } + ], + "namespace": "Tilt" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Binary switch", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 14, + "offset": 13 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 14, + "offset": 13 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 14, + "offset": 13 + } + } + }, + "tags": [ + { + "title": "description", + "description": "Binary switch", + "lineNumber": 3 + }, + { + "title": "demo", + "description": "", + "lineNumber": 5 + }, + { + "title": "example", + "description": "var toggle = new Nexus.Toggle('#target')", + "lineNumber": 7 + }, + { + "title": "example", + "description": "var toggle = new Nexus.Toggle('#target',{\n 'size': [40,20],\n 'state': false\n})", + "lineNumber": 10 + }, + { + "title": "output", + "description": "change\nFires any time the interface's value changes.
\nParameter: The boolean state of the interface.", + "lineNumber": 16 + }, + { + "title": "outputexample", + "description": "toggle.on('change',function(v) {\n console.log(v);\n})", + "lineNumber": 21 + } + ], + "loc": { + "start": { + "line": 7, + "column": 0 + }, + "end": { + "line": 34, + "column": 2 + } + }, + "context": { + "loc": { + "start": { + "line": 35, + "column": 0 + }, + "end": { + "line": 131, + "column": 1 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/toggle.js" + }, + "augments": [ + { + "title": "augments", + "name": "Interface" + } + ], + "examples": [ + { + "description": "var toggle = new Nexus.Toggle('#target')" + }, + { + "description": "var toggle = new Nexus.Toggle('#target',{\n 'size': [40,20],\n 'state': false\n})" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "Toggle", + "kind": "class", + "members": { + "global": [], + "inner": [], + "instance": [ + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Whether the toggle is currently on or off. Setting this property will update the toggle interface and trigger the output event.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 128, + "offset": 127 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 128, + "offset": 127 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 128, + "offset": 127 + } + } + }, + "tags": [ + { + "title": "type", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "boolean" + } + }, + { + "title": "example", + "description": "toggle.state = false;", + "lineNumber": 3 + } + ], + "loc": { + "start": { + "line": 106, + "column": 2 + }, + "end": { + "line": 110, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 111, + "column": 2 + }, + "end": { + "line": 113, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/toggle.js" + }, + "augments": [], + "examples": [ + { + "description": "toggle.state = false;" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "state", + "kind": "member", + "memberof": "Toggle", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Toggle", + "kind": "class" + }, + { + "name": "state", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "Toggle#state" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Switch the toggle state to its opposite state", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 46, + "offset": 45 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 46, + "offset": 45 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 46, + "offset": 45 + } + } + }, + "tags": [ + { + "title": "example", + "description": "toggle.flip();", + "lineNumber": 2 + } + ], + "loc": { + "start": { + "line": 121, + "column": 2 + }, + "end": { + "line": 125, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 126, + "column": 2 + }, + "end": { + "line": 129, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/interfaces/toggle.js" + }, + "augments": [], + "examples": [ + { + "description": "toggle.flip();" + } + ], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "flip", + "kind": "function", + "memberof": "Toggle", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Toggle", + "kind": "class" + }, + { + "name": "flip", + "kind": "function", + "scope": "instance" + } + ], + "namespace": "Toggle#flip" + } + ], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Toggle", + "kind": "class" + } + ], + "namespace": "Toggle" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "NexusUI => created as Nexus", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 28, + "offset": 27 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 28, + "offset": 27 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 28, + "offset": 27 + } + } + }, + "tags": [], + "loc": { + "start": { + "line": 19, + "column": 0 + }, + "end": { + "line": 21, + "column": 2 + } + }, + "context": { + "loc": { + "start": { + "line": 23, + "column": 0 + }, + "end": { + "line": 104, + "column": 1 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/main.js" + }, + "augments": [], + "examples": [], + "params": [ + { + "title": "param", + "name": "context", + "lineNumber": 25 + } + ], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "NexusUI", + "kind": "class", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "NexusUI", + "kind": "class" + } + ], + "namespace": "NexusUI" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Creates an abstract model of a steppable range slider with start and end values which are constricted by a minimum, maximum, and step size.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 140, + "offset": 139 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 140, + "offset": 139 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 140, + "offset": 139 + } + } + }, + "tags": [ + { + "title": "param", + "description": "minimum", + "lineNumber": 2, + "type": { + "type": "OptionalType", + "expression": { + "type": "NameExpression", + "name": "number" + } + }, + "name": "min", + "default": "0" + }, + { + "title": "param", + "description": "maximum", + "lineNumber": 3, + "type": { + "type": "OptionalType", + "expression": { + "type": "NameExpression", + "name": "number" + } + }, + "name": "max", + "default": "1" + }, + { + "title": "param", + "description": null, + "lineNumber": 4, + "type": { + "type": "OptionalType", + "expression": { + "type": "NameExpression", + "name": "number" + } + }, + "name": "step", + "default": "0" + }, + { + "title": "returns", + "description": "Step", + "lineNumber": 5, + "type": { + "type": "NameExpression", + "name": "Object" + } + } + ], + "loc": { + "start": { + "line": 5, + "column": 0 + }, + "end": { + "line": 11, + "column": 2 + } + }, + "context": { + "loc": { + "start": { + "line": 13, + "column": 0 + }, + "end": { + "line": 84, + "column": 1 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/models/range.js" + }, + "augments": [], + "examples": [], + "params": [ + { + "title": "param", + "name": "min", + "lineNumber": 2, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "minimum", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 8, + "offset": 7 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 8, + "offset": 7 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 8, + "offset": 7 + } + } + }, + "type": { + "type": "NameExpression", + "name": "number" + }, + "default": "0" + }, + { + "title": "param", + "name": "max", + "lineNumber": 3, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "maximum", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 8, + "offset": 7 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 8, + "offset": 7 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 8, + "offset": 7 + } + } + }, + "type": { + "type": "NameExpression", + "name": "number" + }, + "default": "1" + }, + { + "title": "param", + "name": "step", + "lineNumber": 4, + "type": { + "type": "NameExpression", + "name": "number" + }, + "default": "0" + } + ], + "properties": [], + "returns": [ + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Step", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 5, + "offset": 4 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 5, + "offset": 4 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 5, + "offset": 4 + } + } + }, + "title": "returns", + "type": { + "type": "NameExpression", + "name": "Object" + } + } + ], + "sees": [], + "throws": [], + "todos": [], + "name": "Range", + "kind": "class", + "members": { + "global": [], + "inner": [], + "instance": [ + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "{number} Minimum value of the range", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 36, + "offset": 35 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 36, + "offset": 35 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 36, + "offset": 35 + } + } + }, + "tags": [], + "loc": { + "start": { + "line": 17, + "column": 4 + }, + "end": { + "line": 19, + "column": 6 + } + }, + "context": { + "loc": { + "start": { + "line": 20, + "column": 4 + }, + "end": { + "line": 20, + "column": 19 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/models/range.js" + }, + "augments": [], + "examples": [], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "min", + "memberof": "Range", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Range", + "kind": "class" + }, + { + "name": "min", + "scope": "instance" + } + ], + "namespace": "Range#min" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "{number} Maximum value of the range", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 36, + "offset": 35 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 36, + "offset": 35 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 36, + "offset": 35 + } + } + }, + "tags": [], + "loc": { + "start": { + "line": 22, + "column": 4 + }, + "end": { + "line": 24, + "column": 6 + } + }, + "context": { + "loc": { + "start": { + "line": 25, + "column": 4 + }, + "end": { + "line": 25, + "column": 19 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/models/range.js" + }, + "augments": [], + "examples": [], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "max", + "memberof": "Range", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Range", + "kind": "class" + }, + { + "name": "max", + "scope": "instance" + } + ], + "namespace": "Range#max" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "{Step} Start value of the range selection", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 42, + "offset": 41 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 42, + "offset": 41 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 42, + "offset": 41 + } + } + }, + "tags": [], + "loc": { + "start": { + "line": 27, + "column": 4 + }, + "end": { + "line": 29, + "column": 6 + } + }, + "context": { + "loc": { + "start": { + "line": 30, + "column": 4 + }, + "end": { + "line": 30, + "column": 40 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/models/range.js" + }, + "augments": [], + "examples": [], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "start", + "memberof": "Range", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Range", + "kind": "class" + }, + { + "name": "start", + "scope": "instance" + } + ], + "namespace": "Range#start" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "{Step} End value of the range selection", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 40, + "offset": 39 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 40, + "offset": 39 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 40, + "offset": 39 + } + } + }, + "tags": [], + "loc": { + "start": { + "line": 32, + "column": 4 + }, + "end": { + "line": 34, + "column": 6 + } + }, + "context": { + "loc": { + "start": { + "line": 35, + "column": 4 + }, + "end": { + "line": 35, + "column": 38 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/models/range.js" + }, + "augments": [], + "examples": [], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "end", + "memberof": "Range", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Range", + "kind": "class" + }, + { + "name": "end", + "scope": "instance" + } + ], + "namespace": "Range#end" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "{number} Center of the range selection", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 39, + "offset": 38 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 39, + "offset": 38 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 39, + "offset": 38 + } + } + }, + "tags": [], + "loc": { + "start": { + "line": 38, + "column": 2 + }, + "end": { + "line": 40, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 41, + "column": 2 + }, + "end": { + "line": 43, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/models/range.js" + }, + "augments": [], + "examples": [], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "center", + "kind": "member", + "memberof": "Range", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Range", + "kind": "class" + }, + { + "name": "center", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "Range#center" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "{number} Size of the range selection", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 37, + "offset": 36 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 37, + "offset": 36 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 37, + "offset": 36 + } + } + }, + "tags": [], + "loc": { + "start": { + "line": 54, + "column": 2 + }, + "end": { + "line": 56, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 57, + "column": 2 + }, + "end": { + "line": 59, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/models/range.js" + }, + "augments": [], + "examples": [], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "size", + "kind": "member", + "memberof": "Range", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Range", + "kind": "class" + }, + { + "name": "size", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "Range#size" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Move the range selection", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 25, + "offset": 24 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 25, + "offset": 24 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 25, + "offset": 24 + } + } + }, + "tags": [ + { + "title": "param", + "description": "New start value of the range selection", + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "number" + }, + "name": "start" + }, + { + "title": "param", + "description": "New end value of the range selection", + "lineNumber": 3, + "type": { + "type": "NameExpression", + "name": "number" + }, + "name": "end" + } + ], + "loc": { + "start": { + "line": 70, + "column": 2 + }, + "end": { + "line": 74, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 75, + "column": 2 + }, + "end": { + "line": 82, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/models/range.js" + }, + "augments": [], + "examples": [], + "params": [ + { + "title": "param", + "name": "start", + "lineNumber": 2, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "New start value of the range selection", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 39, + "offset": 38 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 39, + "offset": 38 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 39, + "offset": 38 + } + } + }, + "type": { + "type": "NameExpression", + "name": "number" + } + }, + { + "title": "param", + "name": "end", + "lineNumber": 3, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "New end value of the range selection", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 37, + "offset": 36 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 37, + "offset": 36 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 37, + "offset": 36 + } + } + }, + "type": { + "type": "NameExpression", + "name": "number" + } + } + ], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "move", + "kind": "function", + "memberof": "Range", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Range", + "kind": "class" + }, + { + "name": "move", + "kind": "function", + "scope": "instance" + } + ], + "namespace": "Range#move" + } + ], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Range", + "kind": "class" + } + ], + "namespace": "Range" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Creates a steppable value with minimum, maximum, and step size. This is used in many interfaces to constrict their values to certain ranges.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 141, + "offset": 140 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 141, + "offset": 140 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 141, + "offset": 140 + } + } + }, + "tags": [ + { + "title": "param", + "description": "minimum", + "lineNumber": 2, + "type": { + "type": "OptionalType", + "expression": { + "type": "NameExpression", + "name": "number" + } + }, + "name": "min", + "default": "0" + }, + { + "title": "param", + "description": "maximum", + "lineNumber": 3, + "type": { + "type": "OptionalType", + "expression": { + "type": "NameExpression", + "name": "number" + } + }, + "name": "max", + "default": "1" + }, + { + "title": "param", + "description": null, + "lineNumber": 4, + "type": { + "type": "OptionalType", + "expression": { + "type": "NameExpression", + "name": "number" + } + }, + "name": "step", + "default": "0" + }, + { + "title": "param", + "description": "initial value", + "lineNumber": 5, + "type": { + "type": "OptionalType", + "expression": { + "type": "NameExpression", + "name": "number" + } + }, + "name": "value", + "default": "0" + }, + { + "title": "returns", + "description": "Step", + "lineNumber": 6, + "type": { + "type": "NameExpression", + "name": "Object" + } + } + ], + "loc": { + "start": { + "line": 5, + "column": 0 + }, + "end": { + "line": 12, + "column": 2 + } + }, + "context": { + "loc": { + "start": { + "line": 14, + "column": 0 + }, + "end": { + "line": 66, + "column": 1 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/models/step.js" + }, + "augments": [], + "examples": [], + "params": [ + { + "title": "param", + "name": "min", + "lineNumber": 2, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "minimum", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 8, + "offset": 7 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 8, + "offset": 7 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 8, + "offset": 7 + } + } + }, + "type": { + "type": "NameExpression", + "name": "number" + }, + "default": "0" + }, + { + "title": "param", + "name": "max", + "lineNumber": 3, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "maximum", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 8, + "offset": 7 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 8, + "offset": 7 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 8, + "offset": 7 + } + } + }, + "type": { + "type": "NameExpression", + "name": "number" + }, + "default": "1" + }, + { + "title": "param", + "name": "step", + "lineNumber": 4, + "type": { + "type": "NameExpression", + "name": "number" + }, + "default": "0" + }, + { + "title": "param", + "name": "value", + "lineNumber": 5, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "initial value", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 14, + "offset": 13 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 14, + "offset": 13 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 14, + "offset": 13 + } + } + }, + "type": { + "type": "NameExpression", + "name": "number" + }, + "default": "0" + } + ], + "properties": [], + "returns": [ + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Step", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 5, + "offset": 4 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 5, + "offset": 4 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 5, + "offset": 4 + } + } + }, + "title": "returns", + "type": { + "type": "NameExpression", + "name": "Object" + } + } + ], + "sees": [], + "throws": [], + "todos": [], + "name": "Step", + "kind": "class", + "members": { + "global": [], + "inner": [], + "instance": [ + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Update with a new value. The value will be auto-adjusted to fit the min/max/step.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 82, + "offset": 81 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 82, + "offset": 81 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 82, + "offset": 81 + } + } + }, + "tags": [ + { + "title": "param", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "number" + }, + "name": "value" + } + ], + "loc": { + "start": { + "line": 29, + "column": 2 + }, + "end": { + "line": 32, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 34, + "column": 2 + }, + "end": { + "line": 48, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/models/step.js" + }, + "augments": [], + "examples": [], + "params": [ + { + "title": "param", + "name": "value", + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "number" + } + } + ], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "update", + "kind": "function", + "memberof": "Step", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Step", + "kind": "class" + }, + { + "name": "update", + "kind": "function", + "scope": "instance" + } + ], + "namespace": "Step#update" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Update with a normalized value 0-1.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 36, + "offset": 35 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 36, + "offset": 35 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 36, + "offset": 35 + } + } + }, + "tags": [ + { + "title": "param", + "description": null, + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "number" + }, + "name": "value" + } + ], + "loc": { + "start": { + "line": 50, + "column": 2 + }, + "end": { + "line": 53, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 54, + "column": 2 + }, + "end": { + "line": 57, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/models/step.js" + }, + "augments": [], + "examples": [], + "params": [ + { + "title": "param", + "name": "value", + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "number" + } + } + ], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "updateNormal", + "kind": "function", + "memberof": "Step", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Step", + "kind": "class" + }, + { + "name": "updateNormal", + "kind": "function", + "scope": "instance" + } + ], + "namespace": "Step#updateNormal" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Get a normalized version of this.value . Not settable.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 55, + "offset": 54 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 55, + "offset": 54 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 55, + "offset": 54 + } + } + }, + "tags": [], + "loc": { + "start": { + "line": 59, + "column": 2 + }, + "end": { + "line": 61, + "column": 4 + } + }, + "context": { + "loc": { + "start": { + "line": 62, + "column": 2 + }, + "end": { + "line": 64, + "column": 3 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/models/step.js" + }, + "augments": [], + "examples": [], + "params": [], + "properties": [], + "returns": [], + "sees": [], + "throws": [], + "todos": [], + "name": "normalized", + "kind": "member", + "memberof": "Step", + "scope": "instance", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Step", + "kind": "class" + }, + { + "name": "normalized", + "kind": "member", + "scope": "instance" + } + ], + "namespace": "Step#normalized" + } + ], + "events": [], + "static": [] + }, + "path": [ + { + "name": "Step", + "kind": "class" + } + ], + "namespace": "Step" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Limit a number to within a minimum and maximum", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 47, + "offset": 46 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 47, + "offset": 46 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 47, + "offset": 46 + } + } + }, + "tags": [ + { + "title": "param", + "description": "Input value", + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "number" + }, + "name": "value" + }, + { + "title": "param", + "description": "Lower limit", + "lineNumber": 3, + "type": { + "type": "NameExpression", + "name": "number" + }, + "name": "min" + }, + { + "title": "param", + "description": "Upper limit", + "lineNumber": 4, + "type": { + "type": "NameExpression", + "name": "number" + }, + "name": "max" + }, + { + "title": "return", + "description": "The input value constrained within the lower and upper limits", + "lineNumber": 5, + "type": { + "type": "NameExpression", + "name": "number" + } + }, + { + "title": "example", + "description": "Nexus.clip(11,0,10) // returns 10\nNexus.clip(-1,0,10) // returns 0\nNexus.clip(5,0,10) // returns 5", + "lineNumber": 6 + } + ], + "loc": { + "start": { + "line": 3, + "column": 0 + }, + "end": { + "line": 13, + "column": 3 + } + }, + "context": { + "loc": { + "start": { + "line": 15, + "column": 0 + }, + "end": { + "line": 17, + "column": 2 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/util/math.js" + }, + "augments": [], + "examples": [ + { + "description": "Nexus.clip(11,0,10) // returns 10\nNexus.clip(-1,0,10) // returns 0\nNexus.clip(5,0,10) // returns 5" + } + ], + "params": [ + { + "title": "param", + "name": "value", + "lineNumber": 2, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Input value", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 12, + "offset": 11 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 12, + "offset": 11 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 12, + "offset": 11 + } + } + }, + "type": { + "type": "NameExpression", + "name": "number" + } + }, + { + "title": "param", + "name": "min", + "lineNumber": 3, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Lower limit", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 12, + "offset": 11 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 12, + "offset": 11 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 12, + "offset": 11 + } + } + }, + "type": { + "type": "NameExpression", + "name": "number" + } + }, + { + "title": "param", + "name": "max", + "lineNumber": 4, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Upper limit", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 12, + "offset": 11 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 12, + "offset": 11 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 12, + "offset": 11 + } + } + }, + "type": { + "type": "NameExpression", + "name": "number" + } + } + ], + "properties": [], + "returns": [ + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "The input value constrained within the lower and upper limits", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 62, + "offset": 61 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 62, + "offset": 61 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 62, + "offset": 61 + } + } + }, + "title": "returns", + "type": { + "type": "NameExpression", + "name": "number" + } + } + ], + "sees": [], + "throws": [], + "todos": [], + "name": "clip", + "kind": "function", + "memberof": "math", + "scope": "static", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "clip", + "kind": "function", + "scope": "static" + } + ], + "namespace": ".clip" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Scale a value from one range to another range.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 47, + "offset": 46 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 47, + "offset": 46 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 47, + "offset": 46 + } + } + }, + "tags": [ + { + "title": "param", + "description": "Input value", + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "number" + }, + "name": "inNum" + }, + { + "title": "param", + "description": "Input range minimum", + "lineNumber": 3, + "type": { + "type": "NameExpression", + "name": "number" + }, + "name": "inMin" + }, + { + "title": "param", + "description": "Input range maximum", + "lineNumber": 4, + "type": { + "type": "NameExpression", + "name": "number" + }, + "name": "inMax" + }, + { + "title": "param", + "description": "Output range minimum", + "lineNumber": 5, + "type": { + "type": "NameExpression", + "name": "number" + }, + "name": "outMin" + }, + { + "title": "param", + "description": "Output range maximum", + "lineNumber": 6, + "type": { + "type": "NameExpression", + "name": "number" + }, + "name": "outMax" + }, + { + "title": "return", + "description": "The input value scaled to its new range", + "lineNumber": 7, + "type": { + "type": "NameExpression", + "name": "number" + } + }, + { + "title": "example", + "description": "Nexus.scale(0.5,0,1,0,10) // returns 5\nNexus.scale(0.9,0,1,1,0) // returns 0.1", + "lineNumber": 8 + } + ], + "loc": { + "start": { + "line": 23, + "column": 0 + }, + "end": { + "line": 34, + "column": 3 + } + }, + "context": { + "loc": { + "start": { + "line": 35, + "column": 0 + }, + "end": { + "line": 40, + "column": 2 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/util/math.js" + }, + "augments": [], + "examples": [ + { + "description": "Nexus.scale(0.5,0,1,0,10) // returns 5\nNexus.scale(0.9,0,1,1,0) // returns 0.1" + } + ], + "params": [ + { + "title": "param", + "name": "inNum", + "lineNumber": 2, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Input value", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 12, + "offset": 11 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 12, + "offset": 11 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 12, + "offset": 11 + } + } + }, + "type": { + "type": "NameExpression", + "name": "number" + } + }, + { + "title": "param", + "name": "inMin", + "lineNumber": 3, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Input range minimum", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 20, + "offset": 19 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 20, + "offset": 19 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 20, + "offset": 19 + } + } + }, + "type": { + "type": "NameExpression", + "name": "number" + } + }, + { + "title": "param", + "name": "inMax", + "lineNumber": 4, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Input range maximum", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 20, + "offset": 19 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 20, + "offset": 19 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 20, + "offset": 19 + } + } + }, + "type": { + "type": "NameExpression", + "name": "number" + } + }, + { + "title": "param", + "name": "outMin", + "lineNumber": 5, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Output range minimum", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 21, + "offset": 20 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 21, + "offset": 20 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 21, + "offset": 20 + } + } + }, + "type": { + "type": "NameExpression", + "name": "number" + } + }, + { + "title": "param", + "name": "outMax", + "lineNumber": 6, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Output range maximum", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 21, + "offset": 20 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 21, + "offset": 20 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 21, + "offset": 20 + } + } + }, + "type": { + "type": "NameExpression", + "name": "number" + } + } + ], + "properties": [], + "returns": [ + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "The input value scaled to its new range", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 40, + "offset": 39 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 40, + "offset": 39 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 40, + "offset": 39 + } + } + }, + "title": "returns", + "type": { + "type": "NameExpression", + "name": "number" + } + } + ], + "sees": [], + "throws": [], + "todos": [], + "name": "scale", + "kind": "function", + "memberof": "math", + "scope": "static", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "scale", + "kind": "function", + "scope": "static" + } + ], + "namespace": ".scale" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Convert a MIDi note number to a frequency value in equal temperament.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 70, + "offset": 69 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 70, + "offset": 69 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 70, + "offset": 69 + } + } + }, + "tags": [ + { + "title": "param", + "description": "MIDI note value", + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "number" + }, + "name": "midi" + }, + { + "title": "return", + "description": "Frequence value", + "lineNumber": 3, + "type": { + "type": "NameExpression", + "name": "number" + } + }, + { + "title": "example", + "description": "Nexus.mtof(60) // returns the frequency number of Middle C", + "lineNumber": 4 + } + ], + "loc": { + "start": { + "line": 77, + "column": 0 + }, + "end": { + "line": 83, + "column": 3 + } + }, + "context": { + "loc": { + "start": { + "line": 84, + "column": 0 + }, + "end": { + "line": 86, + "column": 2 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/util/math.js" + }, + "augments": [], + "examples": [ + { + "description": "Nexus.mtof(60) // returns the frequency number of Middle C" + } + ], + "params": [ + { + "title": "param", + "name": "midi", + "lineNumber": 2, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "MIDI note value", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 16, + "offset": 15 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 16, + "offset": 15 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 16, + "offset": 15 + } + } + }, + "type": { + "type": "NameExpression", + "name": "number" + } + } + ], + "properties": [], + "returns": [ + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Frequence value", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 16, + "offset": 15 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 16, + "offset": 15 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 16, + "offset": 15 + } + } + }, + "title": "returns", + "type": { + "type": "NameExpression", + "name": "number" + } + } + ], + "sees": [], + "throws": [], + "todos": [], + "name": "mtof", + "kind": "function", + "memberof": "math", + "scope": "static", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "mtof", + "kind": "function", + "scope": "static" + } + ], + "namespace": ".mtof" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Interpolate between two numbers", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 32, + "offset": 31 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 32, + "offset": 31 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 32, + "offset": 31 + } + } + }, + "tags": [ + { + "title": "param", + "description": "Interpolation index (0-1)", + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "number" + }, + "name": "loc" + }, + { + "title": "param", + "description": "Lower value", + "lineNumber": 3, + "type": { + "type": "NameExpression", + "name": "number" + }, + "name": "min" + }, + { + "title": "param", + "description": "Upper value", + "lineNumber": 4, + "type": { + "type": "NameExpression", + "name": "number" + }, + "name": "max" + }, + { + "title": "return", + "description": "Interpolated value", + "lineNumber": 5, + "type": { + "type": "NameExpression", + "name": "number" + } + }, + { + "title": "example", + "description": "Nexus.interp(0.5,2,4) // returns 3\nNexus.interp(0.1,0,10) // returns 1", + "lineNumber": 6 + } + ], + "loc": { + "start": { + "line": 88, + "column": 0 + }, + "end": { + "line": 97, + "column": 3 + } + }, + "context": { + "loc": { + "start": { + "line": 98, + "column": 0 + }, + "end": { + "line": 100, + "column": 2 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/util/math.js" + }, + "augments": [], + "examples": [ + { + "description": "Nexus.interp(0.5,2,4) // returns 3\nNexus.interp(0.1,0,10) // returns 1" + } + ], + "params": [ + { + "title": "param", + "name": "loc", + "lineNumber": 2, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Interpolation index (0-1)", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 26, + "offset": 25 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 26, + "offset": 25 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 26, + "offset": 25 + } + } + }, + "type": { + "type": "NameExpression", + "name": "number" + } + }, + { + "title": "param", + "name": "min", + "lineNumber": 3, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Lower value", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 12, + "offset": 11 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 12, + "offset": 11 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 12, + "offset": 11 + } + } + }, + "type": { + "type": "NameExpression", + "name": "number" + } + }, + { + "title": "param", + "name": "max", + "lineNumber": 4, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Upper value", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 12, + "offset": 11 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 12, + "offset": 11 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 12, + "offset": 11 + } + } + }, + "type": { + "type": "NameExpression", + "name": "number" + } + } + ], + "properties": [], + "returns": [ + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Interpolated value", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 19, + "offset": 18 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 19, + "offset": 18 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 19, + "offset": 18 + } + } + }, + "title": "returns", + "type": { + "type": "NameExpression", + "name": "number" + } + } + ], + "sees": [], + "throws": [], + "todos": [], + "name": "interp", + "kind": "function", + "memberof": "math", + "scope": "static", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "interp", + "kind": "function", + "scope": "static" + } + ], + "namespace": ".interp" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Return a random choice from a list of arguments", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 48, + "offset": 47 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 48, + "offset": 47 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 48, + "offset": 47 + } + } + }, + "tags": [ + { + "title": "return", + "description": "One random argument", + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "various" + } + }, + { + "title": "example", + "description": "Nexus.pick(1,2,3,4) // returns 1, 2, 3, or 4\nNexus.pick(function1,function2) // returns either function1 or function2", + "lineNumber": 3 + } + ], + "loc": { + "start": { + "line": 102, + "column": 0 + }, + "end": { + "line": 108, + "column": 3 + } + }, + "context": { + "loc": { + "start": { + "line": 109, + "column": 0 + }, + "end": { + "line": 111, + "column": 2 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/util/math.js" + }, + "augments": [], + "examples": [ + { + "description": "Nexus.pick(1,2,3,4) // returns 1, 2, 3, or 4\nNexus.pick(function1,function2) // returns either function1 or function2" + } + ], + "params": [], + "properties": [], + "returns": [ + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "One random argument", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 20, + "offset": 19 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 20, + "offset": 19 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 20, + "offset": 19 + } + } + }, + "title": "returns", + "type": { + "type": "NameExpression", + "name": "various" + } + } + ], + "sees": [], + "throws": [], + "todos": [], + "name": "pick", + "kind": "function", + "memberof": "math", + "scope": "static", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "pick", + "kind": "function", + "scope": "static" + } + ], + "namespace": ".pick" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Returns an octave multiplier for frequency values", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 50, + "offset": 49 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 50, + "offset": 49 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 50, + "offset": 49 + } + } + }, + "tags": [ + { + "title": "param", + "description": "Relative octave number (e.g. -1 for one octave down, 1 for one octave up)", + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "number" + }, + "name": "num" + }, + { + "title": "return", + "description": "Octave multiplier", + "lineNumber": 3, + "type": { + "type": "NameExpression", + "name": "number" + } + }, + { + "title": "example", + "description": "Nexus.octave(-1) // returns 0.5\nNexus.octave(0) // returns 1\nNexus.octave(1) // returns 2\nNexus.octave(2) // returns 4", + "lineNumber": 4 + } + ], + "loc": { + "start": { + "line": 113, + "column": 0 + }, + "end": { + "line": 122, + "column": 3 + } + }, + "context": { + "loc": { + "start": { + "line": 123, + "column": 0 + }, + "end": { + "line": 125, + "column": 2 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/util/math.js" + }, + "augments": [], + "examples": [ + { + "description": "Nexus.octave(-1) // returns 0.5\nNexus.octave(0) // returns 1\nNexus.octave(1) // returns 2\nNexus.octave(2) // returns 4" + } + ], + "params": [ + { + "title": "param", + "name": "num", + "lineNumber": 2, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Relative octave number (e.g. -1 for one octave down, 1 for one octave up)", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 74, + "offset": 73 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 74, + "offset": 73 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 74, + "offset": 73 + } + } + }, + "type": { + "type": "NameExpression", + "name": "number" + } + } + ], + "properties": [], + "returns": [ + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Octave multiplier", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 18, + "offset": 17 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 18, + "offset": 17 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 18, + "offset": 17 + } + } + }, + "title": "returns", + "type": { + "type": "NameExpression", + "name": "number" + } + } + ], + "sees": [], + "throws": [], + "todos": [], + "name": "octave", + "kind": "function", + "memberof": "math", + "scope": "static", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "octave", + "kind": "function", + "scope": "static" + } + ], + "namespace": ".octave" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Random integer generator. If no second argument is given, will return random integer from 0 to bound1.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 103, + "offset": 102 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 103, + "offset": 102 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 103, + "offset": 102 + } + } + }, + "tags": [ + { + "title": "param", + "description": "Minimum random value", + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "number" + }, + "name": "bound1" + }, + { + "title": "param", + "description": "Maximum random value", + "lineNumber": 3, + "type": { + "type": "NameExpression", + "name": "number" + }, + "name": "bound2" + }, + { + "title": "return", + "description": "Random integer between lower and upper boundary", + "lineNumber": 4, + "type": { + "type": "NameExpression", + "name": "number" + } + }, + { + "title": "example", + "description": "Nexus.ri(10) // returns random int from 0 to 10\nNexus.ri(20,2000) // returns random int from 20 to 2000", + "lineNumber": 5 + } + ], + "loc": { + "start": { + "line": 127, + "column": 0 + }, + "end": { + "line": 135, + "column": 3 + } + }, + "context": { + "loc": { + "start": { + "line": 136, + "column": 0 + }, + "end": { + "line": 144, + "column": 2 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/util/math.js" + }, + "augments": [], + "examples": [ + { + "description": "Nexus.ri(10) // returns random int from 0 to 10\nNexus.ri(20,2000) // returns random int from 20 to 2000" + } + ], + "params": [ + { + "title": "param", + "name": "bound1", + "lineNumber": 2, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Minimum random value", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 21, + "offset": 20 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 21, + "offset": 20 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 21, + "offset": 20 + } + } + }, + "type": { + "type": "NameExpression", + "name": "number" + } + }, + { + "title": "param", + "name": "bound2", + "lineNumber": 3, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Maximum random value", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 21, + "offset": 20 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 21, + "offset": 20 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 21, + "offset": 20 + } + } + }, + "type": { + "type": "NameExpression", + "name": "number" + } + } + ], + "properties": [], + "returns": [ + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Random integer between lower and upper boundary", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 48, + "offset": 47 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 48, + "offset": 47 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 48, + "offset": 47 + } + } + }, + "title": "returns", + "type": { + "type": "NameExpression", + "name": "number" + } + } + ], + "sees": [], + "throws": [], + "todos": [], + "name": "ri", + "kind": "function", + "memberof": "math", + "scope": "static", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "ri", + "kind": "function", + "scope": "static" + } + ], + "namespace": ".ri" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Random float number generator. If no second argument is given, will return random float from 0 to bound1.", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 106, + "offset": 105 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 106, + "offset": 105 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 106, + "offset": 105 + } + } + }, + "tags": [ + { + "title": "param", + "description": "Minimum random value", + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "number" + }, + "name": "bound1" + }, + { + "title": "param", + "description": "Maximum random value", + "lineNumber": 3, + "type": { + "type": "NameExpression", + "name": "number" + }, + "name": "bound2" + }, + { + "title": "return", + "description": "Random float between lower and upper boundary", + "lineNumber": 4, + "type": { + "type": "NameExpression", + "name": "number" + } + }, + { + "title": "example", + "description": "Nexus.rf(1) // returns random float from 0 to 1\nNexus.rf(1,2) // returns random float from 1 to 2", + "lineNumber": 5 + } + ], + "loc": { + "start": { + "line": 146, + "column": 0 + }, + "end": { + "line": 154, + "column": 3 + } + }, + "context": { + "loc": { + "start": { + "line": 155, + "column": 0 + }, + "end": { + "line": 163, + "column": 2 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/util/math.js" + }, + "augments": [], + "examples": [ + { + "description": "Nexus.rf(1) // returns random float from 0 to 1\nNexus.rf(1,2) // returns random float from 1 to 2" + } + ], + "params": [ + { + "title": "param", + "name": "bound1", + "lineNumber": 2, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Minimum random value", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 21, + "offset": 20 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 21, + "offset": 20 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 21, + "offset": 20 + } + } + }, + "type": { + "type": "NameExpression", + "name": "number" + } + }, + { + "title": "param", + "name": "bound2", + "lineNumber": 3, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Maximum random value", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 21, + "offset": 20 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 21, + "offset": 20 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 21, + "offset": 20 + } + } + }, + "type": { + "type": "NameExpression", + "name": "number" + } + } + ], + "properties": [], + "returns": [ + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Random float between lower and upper boundary", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 46, + "offset": 45 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 46, + "offset": 45 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 46, + "offset": 45 + } + } + }, + "title": "returns", + "type": { + "type": "NameExpression", + "name": "number" + } + } + ], + "sees": [], + "throws": [], + "todos": [], + "name": "rf", + "kind": "function", + "memberof": "math", + "scope": "static", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "rf", + "kind": "function", + "scope": "static" + } + ], + "namespace": ".rf" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Average an array of numbers", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 28, + "offset": 27 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 28, + "offset": 27 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 28, + "offset": 27 + } + } + }, + "tags": [ + { + "title": "param", + "description": "Array of numbers to average", + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "Array" + }, + "name": "data" + }, + { + "title": "return", + "description": "Average of the input data", + "lineNumber": 3, + "type": { + "type": "NameExpression", + "name": "number" + } + }, + { + "title": "example", + "description": "Nexus.average([0,2,4,6,8,10]) // returns 5", + "lineNumber": 4 + } + ], + "loc": { + "start": { + "line": 174, + "column": 0 + }, + "end": { + "line": 180, + "column": 3 + } + }, + "context": { + "loc": { + "start": { + "line": 181, + "column": 0 + }, + "end": { + "line": 187, + "column": 2 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/util/math.js" + }, + "augments": [], + "examples": [ + { + "description": "Nexus.average([0,2,4,6,8,10]) // returns 5" + } + ], + "params": [ + { + "title": "param", + "name": "data", + "lineNumber": 2, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Array of numbers to average", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 28, + "offset": 27 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 28, + "offset": 27 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 28, + "offset": 27 + } + } + }, + "type": { + "type": "NameExpression", + "name": "Array" + } + } + ], + "properties": [], + "returns": [ + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Average of the input data", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 26, + "offset": 25 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 26, + "offset": 25 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 26, + "offset": 25 + } + } + }, + "title": "returns", + "type": { + "type": "NameExpression", + "name": "number" + } + } + ], + "sees": [], + "throws": [], + "todos": [], + "name": "average", + "kind": "function", + "memberof": "math", + "scope": "static", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "average", + "kind": "function", + "scope": "static" + } + ], + "namespace": ".average" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Get the distance from one (x,y) point to another (x,y) point", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 61, + "offset": 60 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 61, + "offset": 60 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 61, + "offset": 60 + } + } + }, + "tags": [ + { + "title": "param", + "description": "x of first point", + "lineNumber": 2, + "type": { + "type": "NameExpression", + "name": "number" + }, + "name": "x1" + }, + { + "title": "param", + "description": "y of first point", + "lineNumber": 3, + "type": { + "type": "NameExpression", + "name": "number" + }, + "name": "y1" + }, + { + "title": "param", + "description": "x of second point", + "lineNumber": 4, + "type": { + "type": "NameExpression", + "name": "number" + }, + "name": "x2" + }, + { + "title": "param", + "description": "y of second poiny", + "lineNumber": 5, + "type": { + "type": "NameExpression", + "name": "number" + }, + "name": "y2" + }, + { + "title": "return", + "description": "Distance", + "lineNumber": 6, + "type": { + "type": "NameExpression", + "name": "number" + } + }, + { + "title": "example", + "description": "Nexus.distance(0,0,3,4) // returns 5", + "lineNumber": 7 + } + ], + "loc": { + "start": { + "line": 189, + "column": 0 + }, + "end": { + "line": 198, + "column": 3 + } + }, + "context": { + "loc": { + "start": { + "line": 199, + "column": 0 + }, + "end": { + "line": 203, + "column": 2 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/util/math.js" + }, + "augments": [], + "examples": [ + { + "description": "Nexus.distance(0,0,3,4) // returns 5" + } + ], + "params": [ + { + "title": "param", + "name": "x1", + "lineNumber": 2, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "x of first point", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 17, + "offset": 16 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 17, + "offset": 16 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 17, + "offset": 16 + } + } + }, + "type": { + "type": "NameExpression", + "name": "number" + } + }, + { + "title": "param", + "name": "y1", + "lineNumber": 3, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "y of first point", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 17, + "offset": 16 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 17, + "offset": 16 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 17, + "offset": 16 + } + } + }, + "type": { + "type": "NameExpression", + "name": "number" + } + }, + { + "title": "param", + "name": "x2", + "lineNumber": 4, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "x of second point", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 18, + "offset": 17 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 18, + "offset": 17 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 18, + "offset": 17 + } + } + }, + "type": { + "type": "NameExpression", + "name": "number" + } + }, + { + "title": "param", + "name": "y2", + "lineNumber": 5, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "y of second poiny", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 18, + "offset": 17 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 18, + "offset": 17 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 18, + "offset": 17 + } + } + }, + "type": { + "type": "NameExpression", + "name": "number" + } + } + ], + "properties": [], + "returns": [ + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Distance", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 9, + "offset": 8 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 9, + "offset": 8 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 9, + "offset": 8 + } + } + }, + "title": "returns", + "type": { + "type": "NameExpression", + "name": "number" + } + } + ], + "sees": [], + "throws": [], + "todos": [], + "name": "distance", + "kind": "function", + "memberof": "math", + "scope": "static", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "distance", + "kind": "function", + "scope": "static" + } + ], + "namespace": ".distance" + }, + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Flip a coin, returning either 0 or 1 according to a probability", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 64, + "offset": 63 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 64, + "offset": 63 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 64, + "offset": 63 + } + } + }, + "tags": [ + { + "title": "param", + "description": "Likelihood of returning 1", + "lineNumber": 2, + "type": { + "type": "OptionalType", + "expression": { + "type": "NameExpression", + "name": "number" + } + }, + "name": "odds", + "default": "0.5" + }, + { + "title": "return", + "description": "1 or 0", + "lineNumber": 3, + "type": { + "type": "NameExpression", + "name": "number" + } + }, + { + "title": "example", + "description": "Nexus.coin(0.1) // returns 1 (10% of the time) or 0 (90% of the time)", + "lineNumber": 4 + } + ], + "loc": { + "start": { + "line": 209, + "column": 0 + }, + "end": { + "line": 215, + "column": 3 + } + }, + "context": { + "loc": { + "start": { + "line": 216, + "column": 0 + }, + "end": { + "line": 222, + "column": 2 + } + }, + "file": "/Users/tatecarson/webDev/ui/lib/util/math.js" + }, + "augments": [], + "examples": [ + { + "description": "Nexus.coin(0.1) // returns 1 (10% of the time) or 0 (90% of the time)" + } + ], + "params": [ + { + "title": "param", + "name": "odds", + "lineNumber": 2, + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "Likelihood of returning 1", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 26, + "offset": 25 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 26, + "offset": 25 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 26, + "offset": 25 + } + } + }, + "type": { + "type": "NameExpression", + "name": "number" + }, + "default": "0.5" + } + ], + "properties": [], + "returns": [ + { + "description": { + "type": "root", + "children": [ + { + "type": "paragraph", + "children": [ + { + "type": "text", + "value": "1 or 0", + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 7, + "offset": 6 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 7, + "offset": 6 + }, + "indent": [] + } + } + ], + "position": { + "start": { + "line": 1, + "column": 1, + "offset": 0 + }, + "end": { + "line": 1, + "column": 7, + "offset": 6 + } + } + }, + "title": "returns", + "type": { + "type": "NameExpression", + "name": "number" + } + } + ], + "sees": [], + "throws": [], + "todos": [], + "name": "coin", + "kind": "function", + "memberof": "math", + "scope": "static", + "members": { + "global": [], + "inner": [], + "instance": [], + "events": [], + "static": [] + }, + "path": [ + { + "name": "coin", + "kind": "function", + "scope": "static" + } + ], + "namespace": ".coin" + } +] ADDED public/nexus-js/api/index.html Index: public/nexus-js/api/index.html ================================================================== --- public/nexus-js/api/index.html +++ public/nexus-js/api/index.html @@ -0,0 +1,2241 @@ + + + + + + NexusUI API + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ADDED public/nexus-js/api/js/Tone9.js Index: public/nexus-js/api/js/Tone9.js ================================================================== --- public/nexus-js/api/js/Tone9.js +++ public/nexus-js/api/js/Tone9.js @@ -0,0 +1,22214 @@ +(function(root, factory){ + + //UMD + if ( typeof define === "function" && define.amd ) { + define(function() { + return factory(); + }); + } else if (typeof module === "object") { + module.exports = factory(); + } else { + root.Tone = factory(); + } + +}(this, function(){ + + "use strict"; + + var Tone; + //constructs the main Tone object + function Main(func){ + Tone = func(); + } + //invokes each of the modules with the main Tone object as the argument + function Module(func){ + func(Tone); + } /** + * Tone.js + * @author Yotam Mann + * @license http://opensource.org/licenses/MIT MIT License + * @copyright 2014-2017 Yotam Mann + */ + Main(function () { + + ////////////////////////////////////////////////////////////////////////// + // WEB AUDIO CONTEXT + /////////////////////////////////////////////////////////////////////////// + function isUndef(val) { + return typeof val === 'undefined'; + } + function isFunction(val) { + return typeof val === 'function'; + } + var audioContext; + //polyfill for AudioContext and OfflineAudioContext + if (isUndef(window.AudioContext)) { + window.AudioContext = window.webkitAudioContext; + } + if (isUndef(window.OfflineAudioContext)) { + window.OfflineAudioContext = window.webkitOfflineAudioContext; + } + if (!isUndef(AudioContext)) { + audioContext = new AudioContext(); + } else { + throw new Error('Web Audio is not supported in this browser'); + } + //SHIMS//////////////////////////////////////////////////////////////////// + if (!isFunction(AudioContext.prototype.createGain)) { + AudioContext.prototype.createGain = AudioContext.prototype.createGainNode; + } + if (!isFunction(AudioContext.prototype.createDelay)) { + AudioContext.prototype.createDelay = AudioContext.prototype.createDelayNode; + } + if (!isFunction(AudioContext.prototype.createPeriodicWave)) { + AudioContext.prototype.createPeriodicWave = AudioContext.prototype.createWaveTable; + } + if (!isFunction(AudioBufferSourceNode.prototype.start)) { + AudioBufferSourceNode.prototype.start = AudioBufferSourceNode.prototype.noteGrainOn; + } + if (!isFunction(AudioBufferSourceNode.prototype.stop)) { + AudioBufferSourceNode.prototype.stop = AudioBufferSourceNode.prototype.noteOff; + } + if (!isFunction(OscillatorNode.prototype.start)) { + OscillatorNode.prototype.start = OscillatorNode.prototype.noteOn; + } + if (!isFunction(OscillatorNode.prototype.stop)) { + OscillatorNode.prototype.stop = OscillatorNode.prototype.noteOff; + } + if (!isFunction(OscillatorNode.prototype.setPeriodicWave)) { + OscillatorNode.prototype.setPeriodicWave = OscillatorNode.prototype.setWaveTable; + } + //extend the connect function to include Tones + if (isUndef(AudioNode.prototype._nativeConnect)) { + AudioNode.prototype._nativeConnect = AudioNode.prototype.connect; + AudioNode.prototype.connect = function (B, outNum, inNum) { + if (B.input) { + if (Array.isArray(B.input)) { + if (isUndef(inNum)) { + inNum = 0; + } + this.connect(B.input[inNum]); + } else { + this.connect(B.input, outNum, inNum); + } + } else { + try { + if (B instanceof AudioNode) { + this._nativeConnect(B, outNum, inNum); + } else { + this._nativeConnect(B, outNum); + } + } catch (e) { + throw new Error('error connecting to node: ' + B); + } + } + }; + } + /////////////////////////////////////////////////////////////////////////// + // TONE + /////////////////////////////////////////////////////////////////////////// + /** + * @class Tone is the base class of all other classes. It provides + * a lot of methods and functionality to all classes that extend + * it. + * + * @constructor + * @alias Tone + * @param {number} [inputs=1] the number of input nodes + * @param {number} [outputs=1] the number of output nodes + */ + var Tone = function (inputs, outputs) { + /** + * the input node(s) + * @type {GainNode|Array} + */ + if (isUndef(inputs) || inputs === 1) { + this.input = this.context.createGain(); + } else if (inputs > 1) { + this.input = new Array(inputs); + } + /** + * the output node(s) + * @type {GainNode|Array} + */ + if (isUndef(outputs) || outputs === 1) { + this.output = this.context.createGain(); + } else if (outputs > 1) { + this.output = new Array(inputs); + } + }; + /** + * Set the parameters at once. Either pass in an + * object mapping parameters to values, or to set a + * single parameter, by passing in a string and value. + * The last argument is an optional ramp time which + * will ramp any signal values to their destination value + * over the duration of the rampTime. + * @param {Object|string} params + * @param {number=} value + * @param {Time=} rampTime + * @returns {Tone} this + * @example + * //set values using an object + * filter.set({ + * "frequency" : 300, + * "type" : highpass + * }); + * @example + * filter.set("type", "highpass"); + * @example + * //ramp to the value 220 over 3 seconds. + * oscillator.set({ + * "frequency" : 220 + * }, 3); + */ + Tone.prototype.set = function (params, value, rampTime) { + if (this.isObject(params)) { + rampTime = value; + } else if (this.isString(params)) { + var tmpObj = {}; + tmpObj[params] = value; + params = tmpObj; + } + paramLoop: + for (var attr in params) { + value = params[attr]; + var parent = this; + if (attr.indexOf('.') !== -1) { + var attrSplit = attr.split('.'); + for (var i = 0; i < attrSplit.length - 1; i++) { + parent = parent[attrSplit[i]]; + if (parent instanceof Tone) { + attrSplit.splice(0, i + 1); + var innerParam = attrSplit.join('.'); + parent.set(innerParam, value); + continue paramLoop; + } + } + attr = attrSplit[attrSplit.length - 1]; + } + var param = parent[attr]; + if (isUndef(param)) { + continue; + } + if (Tone.Signal && param instanceof Tone.Signal || Tone.Param && param instanceof Tone.Param) { + if (param.value !== value) { + if (isUndef(rampTime)) { + param.value = value; + } else { + param.rampTo(value, rampTime); + } + } + } else if (param instanceof AudioParam) { + if (param.value !== value) { + param.value = value; + } + } else if (param instanceof Tone) { + param.set(value); + } else if (param !== value) { + parent[attr] = value; + } + } + return this; + }; + /** + * Get the object's attributes. Given no arguments get + * will return all available object properties and their corresponding + * values. Pass in a single attribute to retrieve or an array + * of attributes. The attribute strings can also include a "." + * to access deeper properties. + * @example + * osc.get(); + * //returns {"type" : "sine", "frequency" : 440, ...etc} + * @example + * osc.get("type"); + * //returns { "type" : "sine"} + * @example + * //use dot notation to access deep properties + * synth.get(["envelope.attack", "envelope.release"]); + * //returns {"envelope" : {"attack" : 0.2, "release" : 0.4}} + * @param {Array=|string|undefined} params the parameters to get, otherwise will return + * all available. + * @returns {Object} + */ + Tone.prototype.get = function (params) { + if (isUndef(params)) { + params = this._collectDefaults(this.constructor); + } else if (this.isString(params)) { + params = [params]; + } + var ret = {}; + for (var i = 0; i < params.length; i++) { + var attr = params[i]; + var parent = this; + var subRet = ret; + if (attr.indexOf('.') !== -1) { + var attrSplit = attr.split('.'); + for (var j = 0; j < attrSplit.length - 1; j++) { + var subAttr = attrSplit[j]; + subRet[subAttr] = subRet[subAttr] || {}; + subRet = subRet[subAttr]; + parent = parent[subAttr]; + } + attr = attrSplit[attrSplit.length - 1]; + } + var param = parent[attr]; + if (this.isObject(params[attr])) { + subRet[attr] = param.get(); + } else if (Tone.Signal && param instanceof Tone.Signal) { + subRet[attr] = param.value; + } else if (Tone.Param && param instanceof Tone.Param) { + subRet[attr] = param.value; + } else if (param instanceof AudioParam) { + subRet[attr] = param.value; + } else if (param instanceof Tone) { + subRet[attr] = param.get(); + } else if (!isFunction(param) && !isUndef(param)) { + subRet[attr] = param; + } + } + return ret; + }; + /** + * collect all of the default attributes in one + * @private + * @param {function} constr the constructor to find the defaults from + * @return {Array} all of the attributes which belong to the class + */ + Tone.prototype._collectDefaults = function (constr) { + var ret = []; + if (!isUndef(constr.defaults)) { + ret = Object.keys(constr.defaults); + } + if (!isUndef(constr._super)) { + var superDefs = this._collectDefaults(constr._super); + //filter out repeats + for (var i = 0; i < superDefs.length; i++) { + if (ret.indexOf(superDefs[i]) === -1) { + ret.push(superDefs[i]); + } + } + } + return ret; + }; + /** + * @returns {string} returns the name of the class as a string + */ + Tone.prototype.toString = function () { + for (var className in Tone) { + var isLetter = className[0].match(/^[A-Z]$/); + var sameConstructor = Tone[className] === this.constructor; + if (isFunction(Tone[className]) && isLetter && sameConstructor) { + return className; + } + } + return 'Tone'; + }; + /////////////////////////////////////////////////////////////////////////// + // CLASS VARS + /////////////////////////////////////////////////////////////////////////// + /** + * A static pointer to the audio context accessible as Tone.context. + * @type {AudioContext} + */ + Tone.context = audioContext; + /** + * The audio context. + * @type {AudioContext} + */ + Tone.prototype.context = Tone.context; + /** + * the default buffer size + * @type {number} + * @static + * @const + */ + Tone.prototype.bufferSize = 2048; + /** + * The delay time of a single frame (128 samples according to the spec). + * @type {number} + * @static + * @const + */ + Tone.prototype.blockTime = 128 / Tone.context.sampleRate; + /** + * The time of a single sample + * @type {number} + * @static + * @const + */ + Tone.prototype.sampleTime = 1 / Tone.context.sampleRate; + /** + * The number of inputs feeding into the AudioNode. + * For source nodes, this will be 0. + * @memberOf Tone# + * @name numberOfInputs + * @readOnly + */ + Object.defineProperty(Tone.prototype, 'numberOfInputs', { + get: function () { + if (this.input) { + if (this.isArray(this.input)) { + return this.input.length; + } else { + return 1; + } + } else { + return 0; + } + } + }); + /** + * The number of outputs coming out of the AudioNode. + * For source nodes, this will be 0. + * @memberOf Tone# + * @name numberOfInputs + * @readOnly + */ + Object.defineProperty(Tone.prototype, 'numberOfOutputs', { + get: function () { + if (this.output) { + if (this.isArray(this.output)) { + return this.output.length; + } else { + return 1; + } + } else { + return 0; + } + } + }); + /////////////////////////////////////////////////////////////////////////// + // CONNECTIONS + /////////////////////////////////////////////////////////////////////////// + /** + * disconnect and dispose + * @returns {Tone} this + */ + Tone.prototype.dispose = function () { + if (!this.isUndef(this.input)) { + if (this.input instanceof AudioNode) { + this.input.disconnect(); + } + this.input = null; + } + if (!this.isUndef(this.output)) { + if (this.output instanceof AudioNode) { + this.output.disconnect(); + } + this.output = null; + } + return this; + }; + /** + * a silent connection to the DesinationNode + * which will ensure that anything connected to it + * will not be garbage collected + * + * @private + */ + var _silentNode = null; + /** + * makes a connection to ensure that the node will not be garbage collected + * until 'dispose' is explicitly called + * + * use carefully. circumvents JS and WebAudio's normal Garbage Collection behavior + * @returns {Tone} this + */ + Tone.prototype.noGC = function () { + this.output.connect(_silentNode); + return this; + }; + AudioNode.prototype.noGC = function () { + this.connect(_silentNode); + return this; + }; + /** + * connect the output of a ToneNode to an AudioParam, AudioNode, or ToneNode + * @param {Tone | AudioParam | AudioNode} unit + * @param {number} [outputNum=0] optionally which output to connect from + * @param {number} [inputNum=0] optionally which input to connect to + * @returns {Tone} this + */ + Tone.prototype.connect = function (unit, outputNum, inputNum) { + if (Array.isArray(this.output)) { + outputNum = this.defaultArg(outputNum, 0); + this.output[outputNum].connect(unit, 0, inputNum); + } else { + this.output.connect(unit, outputNum, inputNum); + } + return this; + }; + /** + * disconnect the output + * @param {Number|AudioNode} output Either the output index to disconnect + * if the output is an array, or the + * node to disconnect from. + * @returns {Tone} this + */ + Tone.prototype.disconnect = function (output) { + if (Array.isArray(this.output)) { + output = this.defaultArg(output, 0); + this.output[output].disconnect(); + } else if (!this.isUndef(output)) { + this.output.disconnect(output); + } else { + this.output.disconnect(); + } + return this; + }; + /** + * connect together all of the arguments in series + * @param {...AudioParam|Tone|AudioNode} nodes + * @returns {Tone} this + */ + Tone.prototype.connectSeries = function () { + if (arguments.length > 1) { + var currentUnit = arguments[0]; + for (var i = 1; i < arguments.length; i++) { + var toUnit = arguments[i]; + currentUnit.connect(toUnit); + currentUnit = toUnit; + } + } + return this; + }; + /** + * Connect the output of this node to the rest of the nodes in series. + * @example + * //connect a node to an effect, panVol and then to the master output + * node.chain(effect, panVol, Tone.Master); + * @param {...AudioParam|Tone|AudioNode} nodes + * @returns {Tone} this + */ + Tone.prototype.chain = function () { + if (arguments.length > 0) { + var currentUnit = this; + for (var i = 0; i < arguments.length; i++) { + var toUnit = arguments[i]; + currentUnit.connect(toUnit); + currentUnit = toUnit; + } + } + return this; + }; + /** + * connect the output of this node to the rest of the nodes in parallel. + * @param {...AudioParam|Tone|AudioNode} nodes + * @returns {Tone} this + */ + Tone.prototype.fan = function () { + if (arguments.length > 0) { + for (var i = 0; i < arguments.length; i++) { + this.connect(arguments[i]); + } + } + return this; + }; + //give native nodes chain and fan methods + AudioNode.prototype.chain = Tone.prototype.chain; + AudioNode.prototype.fan = Tone.prototype.fan; + /////////////////////////////////////////////////////////////////////////// + // UTILITIES / HELPERS / MATHS + /////////////////////////////////////////////////////////////////////////// + /** + * If the `given` parameter is undefined, use the `fallback`. + * If both `given` and `fallback` are object literals, it will + * return a deep copy which includes all of the parameters from both + * objects. If a parameter is undefined in given, it will return + * the fallback property. + *

+ * WARNING: if object is self referential, it will go into an an + * infinite recursive loop. + * + * @param {*} given + * @param {*} fallback + * @return {*} + */ + Tone.prototype.defaultArg = function (given, fallback) { + if (this.isObject(given) && this.isObject(fallback)) { + var ret = {}; + //make a deep copy of the given object + for (var givenProp in given) { + ret[givenProp] = this.defaultArg(fallback[givenProp], given[givenProp]); + } + for (var fallbackProp in fallback) { + ret[fallbackProp] = this.defaultArg(given[fallbackProp], fallback[fallbackProp]); + } + return ret; + } else { + return isUndef(given) ? fallback : given; + } + }; + /** + * returns the args as an options object with given arguments + * mapped to the names provided. + * + * if the args given is an array containing only one object, it is assumed + * that that's already the options object and will just return it. + * + * @param {Array} values the 'arguments' object of the function + * @param {Array} keys the names of the arguments as they + * should appear in the options object + * @param {Object=} defaults optional defaults to mixin to the returned + * options object + * @return {Object} the options object with the names mapped to the arguments + */ + Tone.prototype.optionsObject = function (values, keys, defaults) { + var options = {}; + if (values.length === 1 && this.isObject(values[0])) { + options = values[0]; + } else { + for (var i = 0; i < keys.length; i++) { + options[keys[i]] = values[i]; + } + } + if (!this.isUndef(defaults)) { + return this.defaultArg(options, defaults); + } else { + return options; + } + }; + /////////////////////////////////////////////////////////////////////////// + // TYPE CHECKING + /////////////////////////////////////////////////////////////////////////// + /** + * test if the arg is undefined + * @param {*} arg the argument to test + * @returns {boolean} true if the arg is undefined + * @function + */ + Tone.prototype.isUndef = isUndef; + /** + * test if the arg is a function + * @param {*} arg the argument to test + * @returns {boolean} true if the arg is a function + * @function + */ + Tone.prototype.isFunction = isFunction; + /** + * Test if the argument is a number. + * @param {*} arg the argument to test + * @returns {boolean} true if the arg is a number + */ + Tone.prototype.isNumber = function (arg) { + return typeof arg === 'number'; + }; + /** + * Test if the given argument is an object literal (i.e. `{}`); + * @param {*} arg the argument to test + * @returns {boolean} true if the arg is an object literal. + */ + Tone.prototype.isObject = function (arg) { + return Object.prototype.toString.call(arg) === '[object Object]' && arg.constructor === Object; + }; + /** + * Test if the argument is a boolean. + * @param {*} arg the argument to test + * @returns {boolean} true if the arg is a boolean + */ + Tone.prototype.isBoolean = function (arg) { + return typeof arg === 'boolean'; + }; + /** + * Test if the argument is an Array + * @param {*} arg the argument to test + * @returns {boolean} true if the arg is an array + */ + Tone.prototype.isArray = function (arg) { + return Array.isArray(arg); + }; + /** + * Test if the argument is a string. + * @param {*} arg the argument to test + * @returns {boolean} true if the arg is a string + */ + Tone.prototype.isString = function (arg) { + return typeof arg === 'string'; + }; + /** + * An empty function. + * @static + */ + Tone.noOp = function () { + }; + /** + * Make the property not writable. Internal use only. + * @private + * @param {string} property the property to make not writable + */ + Tone.prototype._readOnly = function (property) { + if (Array.isArray(property)) { + for (var i = 0; i < property.length; i++) { + this._readOnly(property[i]); + } + } else { + Object.defineProperty(this, property, { + writable: false, + enumerable: true + }); + } + }; + /** + * Make an attribute writeable. Interal use only. + * @private + * @param {string} property the property to make writable + */ + Tone.prototype._writable = function (property) { + if (Array.isArray(property)) { + for (var i = 0; i < property.length; i++) { + this._writable(property[i]); + } + } else { + Object.defineProperty(this, property, { writable: true }); + } + }; + /** + * Possible play states. + * @enum {string} + */ + Tone.State = { + Started: 'started', + Stopped: 'stopped', + Paused: 'paused' + }; + /////////////////////////////////////////////////////////////////////////// + // GAIN CONVERSIONS + /////////////////////////////////////////////////////////////////////////// + /** + * Equal power gain scale. Good for cross-fading. + * @param {NormalRange} percent (0-1) + * @return {Number} output gain (0-1) + */ + Tone.prototype.equalPowerScale = function (percent) { + var piFactor = 0.5 * Math.PI; + return Math.sin(percent * piFactor); + }; + /** + * Convert decibels into gain. + * @param {Decibels} db + * @return {Number} + */ + Tone.prototype.dbToGain = function (db) { + return Math.pow(2, db / 6); + }; + /** + * Convert gain to decibels. + * @param {Number} gain (0-1) + * @return {Decibels} + */ + Tone.prototype.gainToDb = function (gain) { + return 20 * (Math.log(gain) / Math.LN10); + }; + /** + * Convert an interval (in semitones) to a frequency ratio. + * @param {Interval} interval the number of semitones above the base note + * @return {number} the frequency ratio + * @example + * tone.intervalToFrequencyRatio(0); // 1 + * tone.intervalToFrequencyRatio(12); // 2 + * tone.intervalToFrequencyRatio(-12); // 0.5 + */ + Tone.prototype.intervalToFrequencyRatio = function (interval) { + return Math.pow(2, interval / 12); + }; + /////////////////////////////////////////////////////////////////////////// + // TIMING + /////////////////////////////////////////////////////////////////////////// + /** + * Return the current time of the AudioContext clock. + * @return {Number} the currentTime from the AudioContext + */ + Tone.prototype.now = function () { + return this.context.currentTime; + }; + /** + * Return the current time of the AudioContext clock. + * @return {Number} the currentTime from the AudioContext + * @static + */ + Tone.now = function () { + return Tone.context.currentTime; + }; + /////////////////////////////////////////////////////////////////////////// + // INHERITANCE + /////////////////////////////////////////////////////////////////////////// + /** + * have a child inherit all of Tone's (or a parent's) prototype + * to inherit the parent's properties, make sure to call + * Parent.call(this) in the child's constructor + * + * based on closure library's inherit function + * + * @static + * @param {function} child + * @param {function=} parent (optional) parent to inherit from + * if no parent is supplied, the child + * will inherit from Tone + */ + Tone.extend = function (child, parent) { + if (isUndef(parent)) { + parent = Tone; + } + function TempConstructor() { + } + TempConstructor.prototype = parent.prototype; + child.prototype = new TempConstructor(); + /** @override */ + child.prototype.constructor = child; + child._super = parent; + }; + /////////////////////////////////////////////////////////////////////////// + // CONTEXT + /////////////////////////////////////////////////////////////////////////// + /** + * array of callbacks to be invoked when a new context is added + * @private + * @private + */ + var newContextCallbacks = []; + /** + * invoke this callback when a new context is added + * will be invoked initially with the first context + * @private + * @static + * @param {function(AudioContext)} callback the callback to be invoked + * with the audio context + */ + Tone._initAudioContext = function (callback) { + //invoke the callback with the existing AudioContext + callback(Tone.context); + //add it to the array + newContextCallbacks.push(callback); + }; + /** + * Tone automatically creates a context on init, but if you are working + * with other libraries which also create an AudioContext, it can be + * useful to set your own. If you are going to set your own context, + * be sure to do it at the start of your code, before creating any objects. + * @static + * @param {AudioContext} ctx The new audio context to set + */ + Tone.setContext = function (ctx) { + //set the prototypes + Tone.prototype.context = ctx; + Tone.context = ctx; + //invoke all the callbacks + for (var i = 0; i < newContextCallbacks.length; i++) { + newContextCallbacks[i](ctx); + } + }; + //setup the context + Tone._initAudioContext(function (audioContext) { + //set the blockTime + Tone.prototype.blockTime = 128 / audioContext.sampleRate; + Tone.prototype.sampleTime = 1 / audioContext.sampleRate; + _silentNode = audioContext.createGain(); + _silentNode.gain.value = 0; + _silentNode.connect(audioContext.destination); + }); + Tone.version = 'r9'; + // allow optional silencing of this log + if (!window.TONE_SILENCE_VERSION_LOGGING) { + console.log('%c * Tone.js ' + Tone.version + ' * ', 'background: #000; color: #fff'); + } + return Tone; + }); + Module(function (Tone) { + + /** + * @class Base class for all Signals. Used Internally. + * + * @constructor + * @extends {Tone} + */ + Tone.SignalBase = function () { + }; + Tone.extend(Tone.SignalBase); + /** + * When signals connect to other signals or AudioParams, + * they take over the output value of that signal or AudioParam. + * For all other nodes, the behavior is the same as a default connect. + * + * @override + * @param {AudioParam|AudioNode|Tone.Signal|Tone} node + * @param {number} [outputNumber=0] The output number to connect from. + * @param {number} [inputNumber=0] The input number to connect to. + * @returns {Tone.SignalBase} this + */ + Tone.SignalBase.prototype.connect = function (node, outputNumber, inputNumber) { + //zero it out so that the signal can have full control + if (Tone.Signal && Tone.Signal === node.constructor || Tone.Param && Tone.Param === node.constructor || Tone.TimelineSignal && Tone.TimelineSignal === node.constructor) { + //cancel changes + node._param.cancelScheduledValues(0); + //reset the value + node._param.value = 0; + //mark the value as overridden + node.overridden = true; + } else if (node instanceof AudioParam) { + node.cancelScheduledValues(0); + node.value = 0; + } + Tone.prototype.connect.call(this, node, outputNumber, inputNumber); + return this; + }; + return Tone.SignalBase; + }); + Module(function (Tone) { + + /** + * @class Wraps the native Web Audio API + * [WaveShaperNode](http://webaudio.github.io/web-audio-api/#the-waveshapernode-interface). + * + * @extends {Tone.SignalBase} + * @constructor + * @param {function|Array|Number} mapping The function used to define the values. + * The mapping function should take two arguments: + * the first is the value at the current position + * and the second is the array position. + * If the argument is an array, that array will be + * set as the wave shaping function. The input + * signal is an AudioRange [-1, 1] value and the output + * signal can take on any numerical values. + * + * @param {Number} [bufferLen=1024] The length of the WaveShaperNode buffer. + * @example + * var timesTwo = new Tone.WaveShaper(function(val){ + * return val * 2; + * }, 2048); + * @example + * //a waveshaper can also be constructed with an array of values + * var invert = new Tone.WaveShaper([1, -1]); + */ + Tone.WaveShaper = function (mapping, bufferLen) { + /** + * the waveshaper + * @type {WaveShaperNode} + * @private + */ + this._shaper = this.input = this.output = this.context.createWaveShaper(); + /** + * the waveshapers curve + * @type {Float32Array} + * @private + */ + this._curve = null; + if (Array.isArray(mapping)) { + this.curve = mapping; + } else if (isFinite(mapping) || this.isUndef(mapping)) { + this._curve = new Float32Array(this.defaultArg(mapping, 1024)); + } else if (this.isFunction(mapping)) { + this._curve = new Float32Array(this.defaultArg(bufferLen, 1024)); + this.setMap(mapping); + } + }; + Tone.extend(Tone.WaveShaper, Tone.SignalBase); + /** + * Uses a mapping function to set the value of the curve. + * @param {function} mapping The function used to define the values. + * The mapping function take two arguments: + * the first is the value at the current position + * which goes from -1 to 1 over the number of elements + * in the curve array. The second argument is the array position. + * @returns {Tone.WaveShaper} this + * @example + * //map the input signal from [-1, 1] to [0, 10] + * shaper.setMap(function(val, index){ + * return (val + 1) * 5; + * }) + */ + Tone.WaveShaper.prototype.setMap = function (mapping) { + for (var i = 0, len = this._curve.length; i < len; i++) { + var normalized = i / (len - 1) * 2 - 1; + this._curve[i] = mapping(normalized, i); + } + this._shaper.curve = this._curve; + return this; + }; + /** + * The array to set as the waveshaper curve. For linear curves + * array length does not make much difference, but for complex curves + * longer arrays will provide smoother interpolation. + * @memberOf Tone.WaveShaper# + * @type {Array} + * @name curve + */ + Object.defineProperty(Tone.WaveShaper.prototype, 'curve', { + get: function () { + return this._shaper.curve; + }, + set: function (mapping) { + this._curve = new Float32Array(mapping); + this._shaper.curve = this._curve; + } + }); + /** + * Specifies what type of oversampling (if any) should be used when + * applying the shaping curve. Can either be "none", "2x" or "4x". + * @memberOf Tone.WaveShaper# + * @type {string} + * @name oversample + */ + Object.defineProperty(Tone.WaveShaper.prototype, 'oversample', { + get: function () { + return this._shaper.oversample; + }, + set: function (oversampling) { + if ([ + 'none', + '2x', + '4x' + ].indexOf(oversampling) !== -1) { + this._shaper.oversample = oversampling; + } else { + throw new RangeError('Tone.WaveShaper: oversampling must be either \'none\', \'2x\', or \'4x\''); + } + } + }); + /** + * Clean up. + * @returns {Tone.WaveShaper} this + */ + Tone.WaveShaper.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._shaper.disconnect(); + this._shaper = null; + this._curve = null; + return this; + }; + return Tone.WaveShaper; + }); + Module(function (Tone) { + /** + * @class Tone.TimeBase is a flexible encoding of time + * which can be evaluated to and from a string. + * Parsing code modified from https://code.google.com/p/tapdigit/ + * Copyright 2011 2012 Ariya Hidayat, New BSD License + * @extends {Tone} + * @param {Time} val The time value as a number or string + * @param {String=} units Unit values + * @example + * Tone.TimeBase(4, "n") + * Tone.TimeBase(2, "t") + * Tone.TimeBase("2t").add("1m") + * Tone.TimeBase("2t + 1m"); + */ + Tone.TimeBase = function (val, units) { + //allows it to be constructed with or without 'new' + if (this instanceof Tone.TimeBase) { + /** + * Any expressions parsed from the Time + * @type {Array} + * @private + */ + this._expr = this._noOp; + if (val instanceof Tone.TimeBase) { + this.copy(val); + } else if (!this.isUndef(units) || this.isNumber(val)) { + //default units + units = this.defaultArg(units, this._defaultUnits); + var method = this._primaryExpressions[units].method; + this._expr = method.bind(this, val); + } else if (this.isString(val)) { + this.set(val); + } else if (this.isUndef(val)) { + //default expression + this._expr = this._defaultExpr(); + } + } else { + return new Tone.TimeBase(val, units); + } + }; + Tone.extend(Tone.TimeBase); + /** + * Repalce the current time value with the value + * given by the expression string. + * @param {String} exprString + * @return {Tone.TimeBase} this + */ + Tone.TimeBase.prototype.set = function (exprString) { + this._expr = this._parseExprString(exprString); + return this; + }; + /** + * Return a clone of the TimeBase object. + * @return {Tone.TimeBase} The new cloned Tone.TimeBase + */ + Tone.TimeBase.prototype.clone = function () { + var instance = new this.constructor(); + instance.copy(this); + return instance; + }; + /** + * Copies the value of time to this Time + * @param {Tone.TimeBase} time + * @return {TimeBase} + */ + Tone.TimeBase.prototype.copy = function (time) { + var val = time._expr(); + return this.set(val); + }; + /////////////////////////////////////////////////////////////////////////// + // ABSTRACT SYNTAX TREE PARSER + /////////////////////////////////////////////////////////////////////////// + /** + * All the primary expressions. + * @private + * @type {Object} + */ + Tone.TimeBase.prototype._primaryExpressions = { + 'n': { + regexp: /^(\d+)n/i, + method: function (value) { + value = parseInt(value); + if (value === 1) { + return this._beatsToUnits(this._timeSignature()); + } else { + return this._beatsToUnits(4 / value); + } + } + }, + 't': { + regexp: /^(\d+)t/i, + method: function (value) { + value = parseInt(value); + return this._beatsToUnits(8 / (parseInt(value) * 3)); + } + }, + 'm': { + regexp: /^(\d+)m/i, + method: function (value) { + return this._beatsToUnits(parseInt(value) * this._timeSignature()); + } + }, + 'i': { + regexp: /^(\d+)i/i, + method: function (value) { + return this._ticksToUnits(parseInt(value)); + } + }, + 'hz': { + regexp: /^(\d+(?:\.\d+)?)hz/i, + method: function (value) { + return this._frequencyToUnits(parseFloat(value)); + } + }, + 'tr': { + regexp: /^(\d+(?:\.\d+)?):(\d+(?:\.\d+)?):?(\d+(?:\.\d+)?)?/, + method: function (m, q, s) { + var total = 0; + if (m && m !== '0') { + total += this._beatsToUnits(this._timeSignature() * parseFloat(m)); + } + if (q && q !== '0') { + total += this._beatsToUnits(parseFloat(q)); + } + if (s && s !== '0') { + total += this._beatsToUnits(parseFloat(s) / 4); + } + return total; + } + }, + 's': { + regexp: /^(\d+(?:\.\d+)?s)/, + method: function (value) { + return this._secondsToUnits(parseFloat(value)); + } + }, + 'samples': { + regexp: /^(\d+)samples/, + method: function (value) { + return parseInt(value) / this.context.sampleRate; + } + }, + 'default': { + regexp: /^(\d+(?:\.\d+)?)/, + method: function (value) { + return this._primaryExpressions[this._defaultUnits].method.call(this, value); + } + } + }; + /** + * All the binary expressions that TimeBase can accept. + * @private + * @type {Object} + */ + Tone.TimeBase.prototype._binaryExpressions = { + '+': { + regexp: /^\+/, + precedence: 2, + method: function (lh, rh) { + return lh() + rh(); + } + }, + '-': { + regexp: /^\-/, + precedence: 2, + method: function (lh, rh) { + return lh() - rh(); + } + }, + '*': { + regexp: /^\*/, + precedence: 1, + method: function (lh, rh) { + return lh() * rh(); + } + }, + '/': { + regexp: /^\//, + precedence: 1, + method: function (lh, rh) { + return lh() / rh(); + } + } + }; + /** + * All the unary expressions. + * @private + * @type {Object} + */ + Tone.TimeBase.prototype._unaryExpressions = { + 'neg': { + regexp: /^\-/, + method: function (lh) { + return -lh(); + } + } + }; + /** + * Syntactic glue which holds expressions together + * @private + * @type {Object} + */ + Tone.TimeBase.prototype._syntaxGlue = { + '(': { regexp: /^\(/ }, + ')': { regexp: /^\)/ } + }; + /** + * tokenize the expression based on the Expressions object + * @param {string} expr + * @return {Object} returns two methods on the tokenized list, next and peek + * @private + */ + Tone.TimeBase.prototype._tokenize = function (expr) { + var position = -1; + var tokens = []; + while (expr.length > 0) { + expr = expr.trim(); + var token = getNextToken(expr, this); + tokens.push(token); + expr = expr.substr(token.value.length); + } + function getNextToken(expr, context) { + var expressions = [ + '_binaryExpressions', + '_unaryExpressions', + '_primaryExpressions', + '_syntaxGlue' + ]; + for (var i = 0; i < expressions.length; i++) { + var group = context[expressions[i]]; + for (var opName in group) { + var op = group[opName]; + var reg = op.regexp; + var match = expr.match(reg); + if (match !== null) { + return { + method: op.method, + precedence: op.precedence, + regexp: op.regexp, + value: match[0] + }; + } + } + } + throw new SyntaxError('Tone.TimeBase: Unexpected token ' + expr); + } + return { + next: function () { + return tokens[++position]; + }, + peek: function () { + return tokens[position + 1]; + } + }; + }; + /** + * Given a token, find the value within the groupName + * @param {Object} token + * @param {String} groupName + * @param {Number} precedence + * @private + */ + Tone.TimeBase.prototype._matchGroup = function (token, group, prec) { + var ret = false; + if (!this.isUndef(token)) { + for (var opName in group) { + var op = group[opName]; + if (op.regexp.test(token.value)) { + if (!this.isUndef(prec)) { + if (op.precedence === prec) { + return op; + } + } else { + return op; + } + } + } + } + return ret; + }; + /** + * Match a binary expression given the token and the precedence + * @param {Lexer} lexer + * @param {Number} precedence + * @private + */ + Tone.TimeBase.prototype._parseBinary = function (lexer, precedence) { + if (this.isUndef(precedence)) { + precedence = 2; + } + var expr; + if (precedence < 0) { + expr = this._parseUnary(lexer); + } else { + expr = this._parseBinary(lexer, precedence - 1); + } + var token = lexer.peek(); + while (token && this._matchGroup(token, this._binaryExpressions, precedence)) { + token = lexer.next(); + expr = token.method.bind(this, expr, this._parseBinary(lexer, precedence - 1)); + token = lexer.peek(); + } + return expr; + }; + /** + * Match a unary expression. + * @param {Lexer} lexer + * @private + */ + Tone.TimeBase.prototype._parseUnary = function (lexer) { + var token, expr; + token = lexer.peek(); + var op = this._matchGroup(token, this._unaryExpressions); + if (op) { + token = lexer.next(); + expr = this._parseUnary(lexer); + return op.method.bind(this, expr); + } + return this._parsePrimary(lexer); + }; + /** + * Match a primary expression (a value). + * @param {Lexer} lexer + * @private + */ + Tone.TimeBase.prototype._parsePrimary = function (lexer) { + var token, expr; + token = lexer.peek(); + if (this.isUndef(token)) { + throw new SyntaxError('Tone.TimeBase: Unexpected end of expression'); + } + if (this._matchGroup(token, this._primaryExpressions)) { + token = lexer.next(); + var matching = token.value.match(token.regexp); + return token.method.bind(this, matching[1], matching[2], matching[3]); + } + if (token && token.value === '(') { + lexer.next(); + expr = this._parseBinary(lexer); + token = lexer.next(); + if (!(token && token.value === ')')) { + throw new SyntaxError('Expected )'); + } + return expr; + } + throw new SyntaxError('Tone.TimeBase: Cannot process token ' + token.value); + }; + /** + * Recursively parse the string expression into a syntax tree. + * @param {string} expr + * @return {Function} the bound method to be evaluated later + * @private + */ + Tone.TimeBase.prototype._parseExprString = function (exprString) { + if (!this.isString(exprString)) { + exprString = exprString.toString(); + } + var lexer = this._tokenize(exprString); + var tree = this._parseBinary(lexer); + return tree; + }; + /////////////////////////////////////////////////////////////////////////// + // DEFAULTS + /////////////////////////////////////////////////////////////////////////// + /** + * The initial expression value + * @return {Number} The initial value 0 + * @private + */ + Tone.TimeBase.prototype._noOp = function () { + return 0; + }; + /** + * The default expression value if no arguments are given + * @private + */ + Tone.TimeBase.prototype._defaultExpr = function () { + return this._noOp; + }; + /** + * The default units if none are given. + * @private + */ + Tone.TimeBase.prototype._defaultUnits = 's'; + /////////////////////////////////////////////////////////////////////////// + // UNIT CONVERSIONS + /////////////////////////////////////////////////////////////////////////// + /** + * Returns the value of a frequency in the current units + * @param {Frequency} freq + * @return {Number} + * @private + */ + Tone.TimeBase.prototype._frequencyToUnits = function (freq) { + return 1 / freq; + }; + /** + * Return the value of the beats in the current units + * @param {Number} beats + * @return {Number} + * @private + */ + Tone.TimeBase.prototype._beatsToUnits = function (beats) { + return 60 / Tone.Transport.bpm.value * beats; + }; + /** + * Returns the value of a second in the current units + * @param {Seconds} seconds + * @return {Number} + * @private + */ + Tone.TimeBase.prototype._secondsToUnits = function (seconds) { + return seconds; + }; + /** + * Returns the value of a tick in the current time units + * @param {Ticks} ticks + * @return {Number} + * @private + */ + Tone.TimeBase.prototype._ticksToUnits = function (ticks) { + return ticks * (this._beatsToUnits(1) / Tone.Transport.PPQ); + }; + /** + * Return the time signature. + * @return {Number} + * @private + */ + Tone.TimeBase.prototype._timeSignature = function () { + return Tone.Transport.timeSignature; + }; + /////////////////////////////////////////////////////////////////////////// + // EXPRESSIONS + /////////////////////////////////////////////////////////////////////////// + /** + * Push an expression onto the expression list + * @param {Time} val + * @param {String} type + * @param {String} units + * @return {Tone.TimeBase} + * @private + */ + Tone.TimeBase.prototype._pushExpr = function (val, name, units) { + //create the expression + if (!(val instanceof Tone.TimeBase)) { + val = new this.constructor(val, units); + } + this._expr = this._binaryExpressions[name].method.bind(this, this._expr, val._expr); + return this; + }; + /** + * Add to the current value. + * @param {Time} val The value to add + * @param {String=} units Optional units to use with the value. + * @return {Tone.TimeBase} this + * @example + * Tone.TimeBase("2m").add("1m"); //"3m" + */ + Tone.TimeBase.prototype.add = function (val, units) { + return this._pushExpr(val, '+', units); + }; + /** + * Subtract the value from the current time. + * @param {Time} val The value to subtract + * @param {String=} units Optional units to use with the value. + * @return {Tone.TimeBase} this + * @example + * Tone.TimeBase("2m").sub("1m"); //"1m" + */ + Tone.TimeBase.prototype.sub = function (val, units) { + return this._pushExpr(val, '-', units); + }; + /** + * Multiply the current value by the given time. + * @param {Time} val The value to multiply + * @param {String=} units Optional units to use with the value. + * @return {Tone.TimeBase} this + * @example + * Tone.TimeBase("2m").mult("2"); //"4m" + */ + Tone.TimeBase.prototype.mult = function (val, units) { + return this._pushExpr(val, '*', units); + }; + /** + * Divide the current value by the given time. + * @param {Time} val The value to divide by + * @param {String=} units Optional units to use with the value. + * @return {Tone.TimeBase} this + * @example + * Tone.TimeBase("2m").div(2); //"1m" + */ + Tone.TimeBase.prototype.div = function (val, units) { + return this._pushExpr(val, '/', units); + }; + /** + * Evaluate the time value. Returns the time + * in seconds. + * @return {Seconds} + */ + Tone.TimeBase.prototype.eval = function () { + return this._expr(); + }; + /** + * Clean up + * @return {Tone.TimeBase} this + */ + Tone.TimeBase.prototype.dispose = function () { + this._expr = null; + }; + return Tone.TimeBase; + }); + Module(function (Tone) { + /** + * @class Tone.Time is a primitive type for encoding Time values. + * Eventually all time values are evaluated to seconds + * using the `eval` method. Tone.Time can be constructed + * with or without the `new` keyword. Tone.Time can be passed + * into the parameter of any method which takes time as an argument. + * @constructor + * @extends {Tone.TimeBase} + * @param {String|Number} val The time value. + * @param {String=} units The units of the value. + * @example + * var t = Tone.Time("4n");//encodes a quarter note + * t.mult(4); // multiply that value by 4 + * t.toNotation(); //returns "1m" + */ + Tone.Time = function (val, units) { + if (this instanceof Tone.Time) { + /** + * If the current clock time should + * be added to the output + * @type {Boolean} + * @private + */ + this._plusNow = false; + Tone.TimeBase.call(this, val, units); + } else { + return new Tone.Time(val, units); + } + }; + Tone.extend(Tone.Time, Tone.TimeBase); + //clone the expressions so that + //we can add more without modifying the original + Tone.Time.prototype._unaryExpressions = Object.create(Tone.TimeBase.prototype._unaryExpressions); + /* + * Adds an additional unary expression + * which quantizes values to the next subdivision + * @type {Object} + * @private + */ + Tone.Time.prototype._unaryExpressions.quantize = { + regexp: /^@/, + method: function (rh) { + return Tone.Transport.nextSubdivision(rh()); + } + }; + /* + * Adds an additional unary expression + * which adds the current clock time. + * @type {Object} + * @private + */ + Tone.Time.prototype._unaryExpressions.now = { + regexp: /^\+/, + method: function (lh) { + this._plusNow = true; + return lh(); + } + }; + /** + * Quantize the time by the given subdivision. Optionally add a + * percentage which will move the time value towards the ideal + * quantized value by that percentage. + * @param {Number|Time} val The subdivision to quantize to + * @param {NormalRange} [percent=1] Move the time value + * towards the quantized value by + * a percentage. + * @return {Tone.Time} this + * @example + * Tone.Time(21).quantize(2).eval() //returns 22 + * Tone.Time(0.6).quantize("4n", 0.5).eval() //returns 0.55 + */ + Tone.Time.prototype.quantize = function (subdiv, percent) { + percent = this.defaultArg(percent, 1); + this._expr = function (expr, subdivision, percent) { + expr = expr(); + subdivision = subdivision.toSeconds(); + var multiple = Math.round(expr / subdivision); + var ideal = multiple * subdivision; + var diff = ideal - expr; + return expr + diff * percent; + }.bind(this, this._expr, new this.constructor(subdiv), percent); + return this; + }; + /** + * Adds the clock time to the time expression at the + * moment of evaluation. + * @return {Tone.Time} this + */ + Tone.Time.prototype.addNow = function () { + this._plusNow = true; + return this; + }; + /** + * @override + * Override the default value return when no arguments are passed in. + * The default value is 'now' + * @private + */ + Tone.Time.prototype._defaultExpr = function () { + this._plusNow = true; + return this._noOp; + }; + /** + * Copies the value of time to this Time + * @param {Tone.Time} time + * @return {Time} + */ + Tone.Time.prototype.copy = function (time) { + Tone.TimeBase.prototype.copy.call(this, time); + this._plusNow = time._plusNow; + return this; + }; + //CONVERSIONS////////////////////////////////////////////////////////////// + /** + * Convert a Time to Notation. Values will be thresholded to the nearest 128th note. + * @return {Notation} + * @example + * //if the Transport is at 120bpm: + * Tone.Time(2).toNotation();//returns "1m" + */ + Tone.Time.prototype.toNotation = function () { + var time = this.toSeconds(); + var testNotations = [ + '1m', + '2n', + '4n', + '8n', + '16n', + '32n', + '64n', + '128n' + ]; + var retNotation = this._toNotationHelper(time, testNotations); + //try the same thing but with tripelets + var testTripletNotations = [ + '1m', + '2n', + '2t', + '4n', + '4t', + '8n', + '8t', + '16n', + '16t', + '32n', + '32t', + '64n', + '64t', + '128n' + ]; + var retTripletNotation = this._toNotationHelper(time, testTripletNotations); + //choose the simpler expression of the two + if (retTripletNotation.split('+').length < retNotation.split('+').length) { + return retTripletNotation; + } else { + return retNotation; + } + }; + /** + * Helper method for Tone.toNotation + * @param {Number} units + * @param {Array} testNotations + * @return {String} + * @private + */ + Tone.Time.prototype._toNotationHelper = function (units, testNotations) { + //the threshold is the last value in the array + var threshold = this._notationToUnits(testNotations[testNotations.length - 1]); + var retNotation = ''; + for (var i = 0; i < testNotations.length; i++) { + var notationTime = this._notationToUnits(testNotations[i]); + //account for floating point errors (i.e. round up if the value is 0.999999) + var multiple = units / notationTime; + var floatingPointError = 0.000001; + if (1 - multiple % 1 < floatingPointError) { + multiple += floatingPointError; + } + multiple = Math.floor(multiple); + if (multiple > 0) { + if (multiple === 1) { + retNotation += testNotations[i]; + } else { + retNotation += multiple.toString() + '*' + testNotations[i]; + } + units -= multiple * notationTime; + if (units < threshold) { + break; + } else { + retNotation += ' + '; + } + } + } + if (retNotation === '') { + retNotation = '0'; + } + return retNotation; + }; + /** + * Convert a notation value to the current units + * @param {Notation} notation + * @return {Number} + * @private + */ + Tone.Time.prototype._notationToUnits = function (notation) { + var primaryExprs = this._primaryExpressions; + var notationExprs = [ + primaryExprs.n, + primaryExprs.t, + primaryExprs.m + ]; + for (var i = 0; i < notationExprs.length; i++) { + var expr = notationExprs[i]; + var match = notation.match(expr.regexp); + if (match) { + return expr.method.call(this, match[1]); + } + } + }; + /** + * Return the time encoded as Bars:Beats:Sixteenths. + * @return {BarsBeatsSixteenths} + */ + Tone.Time.prototype.toBarsBeatsSixteenths = function () { + var quarterTime = this._beatsToUnits(1); + var quarters = this.toSeconds() / quarterTime; + var measures = Math.floor(quarters / this._timeSignature()); + var sixteenths = quarters % 1 * 4; + quarters = Math.floor(quarters) % this._timeSignature(); + sixteenths = sixteenths.toString(); + if (sixteenths.length > 3) { + sixteenths = parseFloat(sixteenths).toFixed(3); + } + var progress = [ + measures, + quarters, + sixteenths + ]; + return progress.join(':'); + }; + /** + * Return the time in ticks. + * @return {Ticks} + */ + Tone.Time.prototype.toTicks = function () { + var quarterTime = this._beatsToUnits(1); + var quarters = this.eval() / quarterTime; + return Math.floor(quarters * Tone.Transport.PPQ); + }; + /** + * Return the time in samples + * @return {Samples} + */ + Tone.Time.prototype.toSamples = function () { + return this.toSeconds() * this.context.sampleRate; + }; + /** + * Return the time as a frequency value + * @return {Frequency} + * @example + * Tone.Time(2).toFrequency(); //0.5 + */ + Tone.Time.prototype.toFrequency = function () { + return 1 / this.toSeconds(); + }; + /** + * Return the time in seconds. + * @return {Seconds} + */ + Tone.Time.prototype.toSeconds = function () { + return this.eval(); + }; + /** + * Return the time in milliseconds. + * @return {Milliseconds} + */ + Tone.Time.prototype.toMilliseconds = function () { + return this.toSeconds() * 1000; + }; + /** + * Return the time in seconds. + * @return {Seconds} + */ + Tone.Time.prototype.eval = function () { + var val = this._expr(); + return val + (this._plusNow ? this.now() : 0); + }; + return Tone.Time; + }); + Module(function (Tone) { + /** + * @class Tone.Frequency is a primitive type for encoding Frequency values. + * Eventually all time values are evaluated to hertz + * using the `eval` method. + * @constructor + * @extends {Tone.TimeBase} + * @param {String|Number} val The time value. + * @param {String=} units The units of the value. + * @example + * Tone.Frequency("C3").eval() // 261 + * Tone.Frequency(38, "midi").eval() // + * Tone.Frequency("C3").transpose(4).eval(); + */ + Tone.Frequency = function (val, units) { + if (this instanceof Tone.Frequency) { + Tone.TimeBase.call(this, val, units); + } else { + return new Tone.Frequency(val, units); + } + }; + Tone.extend(Tone.Frequency, Tone.TimeBase); + /////////////////////////////////////////////////////////////////////////// + // AUGMENT BASE EXPRESSIONS + /////////////////////////////////////////////////////////////////////////// + //clone the expressions so that + //we can add more without modifying the original + Tone.Frequency.prototype._primaryExpressions = Object.create(Tone.TimeBase.prototype._primaryExpressions); + /* + * midi type primary expression + * @type {Object} + * @private + */ + Tone.Frequency.prototype._primaryExpressions.midi = { + regexp: /^(\d+(?:\.\d+)?midi)/, + method: function (value) { + return this.midiToFrequency(value); + } + }; + /* + * note type primary expression + * @type {Object} + * @private + */ + Tone.Frequency.prototype._primaryExpressions.note = { + regexp: /^([a-g]{1}(?:b|#|x|bb)?)(-?[0-9]+)/i, + method: function (pitch, octave) { + var index = noteToScaleIndex[pitch.toLowerCase()]; + var noteNumber = index + (parseInt(octave) + 1) * 12; + return this.midiToFrequency(noteNumber); + } + }; + /* + * BeatsBarsSixteenths type primary expression + * @type {Object} + * @private + */ + Tone.Frequency.prototype._primaryExpressions.tr = { + regexp: /^(\d+(?:\.\d+)?):(\d+(?:\.\d+)?):?(\d+(?:\.\d+)?)?/, + method: function (m, q, s) { + var total = 1; + if (m && m !== '0') { + total *= this._beatsToUnits(this._timeSignature() * parseFloat(m)); + } + if (q && q !== '0') { + total *= this._beatsToUnits(parseFloat(q)); + } + if (s && s !== '0') { + total *= this._beatsToUnits(parseFloat(s) / 4); + } + return total; + } + }; + /////////////////////////////////////////////////////////////////////////// + // EXPRESSIONS + /////////////////////////////////////////////////////////////////////////// + /** + * Transposes the frequency by the given number of semitones. + * @param {Interval} interval + * @return {Tone.Frequency} this + * @example + * Tone.Frequency("A4").transpose(3); //"C5" + */ + Tone.Frequency.prototype.transpose = function (interval) { + this._expr = function (expr, interval) { + var val = expr(); + return val * this.intervalToFrequencyRatio(interval); + }.bind(this, this._expr, interval); + return this; + }; + /** + * Takes an array of semitone intervals and returns + * an array of frequencies transposed by those intervals. + * @param {Array} intervals + * @return {Tone.Frequency} this + * @example + * Tone.Frequency("A4").harmonize([0, 3, 7]); //["A4", "C5", "E5"] + */ + Tone.Frequency.prototype.harmonize = function (intervals) { + this._expr = function (expr, intervals) { + var val = expr(); + var ret = []; + for (var i = 0; i < intervals.length; i++) { + ret[i] = val * this.intervalToFrequencyRatio(intervals[i]); + } + return ret; + }.bind(this, this._expr, intervals); + return this; + }; + /////////////////////////////////////////////////////////////////////////// + // UNIT CONVERSIONS + /////////////////////////////////////////////////////////////////////////// + /** + * Return the value of the frequency as a MIDI note + * @return {MIDI} + * @example + * Tone.Frequency("C4").toMidi(); //60 + */ + Tone.Frequency.prototype.toMidi = function () { + return this.frequencyToMidi(this.eval()); + }; + /** + * Return the value of the frequency in Scientific Pitch Notation + * @return {Note} + * @example + * Tone.Frequency(69, "midi").toNote(); //"A4" + */ + Tone.Frequency.prototype.toNote = function () { + var freq = this.eval(); + var log = Math.log(freq / Tone.Frequency.A4) / Math.LN2; + var noteNumber = Math.round(12 * log) + 57; + var octave = Math.floor(noteNumber / 12); + if (octave < 0) { + noteNumber += -12 * octave; + } + var noteName = scaleIndexToNote[noteNumber % 12]; + return noteName + octave.toString(); + }; + /** + * Return the duration of one cycle in seconds. + * @return {Seconds} + */ + Tone.Frequency.prototype.toSeconds = function () { + return 1 / this.eval(); + }; + /** + * Return the value in Hertz + * @return {Frequency} + */ + Tone.Frequency.prototype.toFrequency = function () { + return this.eval(); + }; + /** + * Return the duration of one cycle in ticks + * @return {Ticks} + */ + Tone.Frequency.prototype.toTicks = function () { + var quarterTime = this._beatsToUnits(1); + var quarters = this.eval() / quarterTime; + return Math.floor(quarters * Tone.Transport.PPQ); + }; + /////////////////////////////////////////////////////////////////////////// + // UNIT CONVERSIONS HELPERS + /////////////////////////////////////////////////////////////////////////// + /** + * Returns the value of a frequency in the current units + * @param {Frequency} freq + * @return {Number} + * @private + */ + Tone.Frequency.prototype._frequencyToUnits = function (freq) { + return freq; + }; + /** + * Returns the value of a tick in the current time units + * @param {Ticks} ticks + * @return {Number} + * @private + */ + Tone.Frequency.prototype._ticksToUnits = function (ticks) { + return 1 / (ticks * 60 / (Tone.Transport.bpm.value * Tone.Transport.PPQ)); + }; + /** + * Return the value of the beats in the current units + * @param {Number} beats + * @return {Number} + * @private + */ + Tone.Frequency.prototype._beatsToUnits = function (beats) { + return 1 / Tone.TimeBase.prototype._beatsToUnits.call(this, beats); + }; + /** + * Returns the value of a second in the current units + * @param {Seconds} seconds + * @return {Number} + * @private + */ + Tone.Frequency.prototype._secondsToUnits = function (seconds) { + return 1 / seconds; + }; + /** + * The default units if none are given. + * @private + */ + Tone.Frequency.prototype._defaultUnits = 'hz'; + /////////////////////////////////////////////////////////////////////////// + // FREQUENCY CONVERSIONS + /////////////////////////////////////////////////////////////////////////// + /** + * Note to scale index + * @type {Object} + */ + var noteToScaleIndex = { + 'cbb': -2, + 'cb': -1, + 'c': 0, + 'c#': 1, + 'cx': 2, + 'dbb': 0, + 'db': 1, + 'd': 2, + 'd#': 3, + 'dx': 4, + 'ebb': 2, + 'eb': 3, + 'e': 4, + 'e#': 5, + 'ex': 6, + 'fbb': 3, + 'fb': 4, + 'f': 5, + 'f#': 6, + 'fx': 7, + 'gbb': 5, + 'gb': 6, + 'g': 7, + 'g#': 8, + 'gx': 9, + 'abb': 7, + 'ab': 8, + 'a': 9, + 'a#': 10, + 'ax': 11, + 'bbb': 9, + 'bb': 10, + 'b': 11, + 'b#': 12, + 'bx': 13 + }; + /** + * scale index to note (sharps) + * @type {Array} + */ + var scaleIndexToNote = [ + 'C', + 'C#', + 'D', + 'D#', + 'E', + 'F', + 'F#', + 'G', + 'G#', + 'A', + 'A#', + 'B' + ]; + /** + * The [concert pitch](https://en.wikipedia.org/wiki/Concert_pitch) + * A4's values in Hertz. + * @type {Frequency} + * @static + */ + Tone.Frequency.A4 = 440; + /** + * Convert a MIDI note to frequency value. + * @param {MIDI} midi The midi number to convert. + * @return {Frequency} the corresponding frequency value + * @example + * tone.midiToFrequency(69); // returns 440 + */ + Tone.Frequency.prototype.midiToFrequency = function (midi) { + return Tone.Frequency.A4 * Math.pow(2, (midi - 69) / 12); + }; + /** + * Convert a frequency value to a MIDI note. + * @param {Frequency} frequency The value to frequency value to convert. + * @returns {MIDI} + * @example + * tone.midiToFrequency(440); // returns 69 + */ + Tone.Frequency.prototype.frequencyToMidi = function (frequency) { + return 69 + 12 * Math.log(frequency / Tone.Frequency.A4) / Math.LN2; + }; + return Tone.Frequency; + }); + Module(function (Tone) { + /** + * @class Tone.TransportTime is a the time along the Transport's + * timeline. It is similar to Tone.Time, but instead of evaluating + * against the AudioContext's clock, it is evaluated against + * the Transport's position. See [TransportTime wiki](https://github.com/Tonejs/Tone.js/wiki/TransportTime). + * @constructor + * @param {Time} val The time value as a number or string + * @param {String=} units Unit values + * @extends {Tone.Time} + */ + Tone.TransportTime = function (val, units) { + if (this instanceof Tone.TransportTime) { + Tone.Time.call(this, val, units); + } else { + return new Tone.TransportTime(val, units); + } + }; + Tone.extend(Tone.TransportTime, Tone.Time); + //clone the expressions so that + //we can add more without modifying the original + Tone.TransportTime.prototype._unaryExpressions = Object.create(Tone.Time.prototype._unaryExpressions); + /** + * Adds an additional unary expression + * which quantizes values to the next subdivision + * @type {Object} + * @private + */ + Tone.TransportTime.prototype._unaryExpressions.quantize = { + regexp: /^@/, + method: function (rh) { + var subdivision = this._secondsToTicks(rh()); + var multiple = Math.ceil(Tone.Transport.ticks / subdivision); + return this._ticksToUnits(multiple * subdivision); + } + }; + /** + * Convert seconds into ticks + * @param {Seconds} seconds + * @return {Ticks} + * @private + */ + Tone.TransportTime.prototype._secondsToTicks = function (seconds) { + var quarterTime = this._beatsToUnits(1); + var quarters = seconds / quarterTime; + return Math.round(quarters * Tone.Transport.PPQ); + }; + /** + * Evaluate the time expression. Returns values in ticks + * @return {Ticks} + */ + Tone.TransportTime.prototype.eval = function () { + var val = this._secondsToTicks(this._expr()); + return val + (this._plusNow ? Tone.Transport.ticks : 0); + }; + /** + * Return the time in ticks. + * @return {Ticks} + */ + Tone.TransportTime.prototype.toTicks = function () { + return this.eval(); + }; + /** + * Return the time in seconds. + * @return {Seconds} + */ + Tone.TransportTime.prototype.toSeconds = function () { + var val = this._expr(); + return val + (this._plusNow ? Tone.Transport.seconds : 0); + }; + /** + * Return the time as a frequency value + * @return {Frequency} + */ + Tone.TransportTime.prototype.toFrequency = function () { + return 1 / this.toSeconds(); + }; + return Tone.TransportTime; + }); + Module(function (Tone) { + /////////////////////////////////////////////////////////////////////////// + // TYPES + /////////////////////////////////////////////////////////////////////////// + /** + * Units which a value can take on. + * @enum {String} + */ + Tone.Type = { + /** + * Default units + * @typedef {Default} + */ + Default: 'number', + /** + * Time can be described in a number of ways. Read more [Time](https://github.com/Tonejs/Tone.js/wiki/Time). + * + *
    + *
  • Numbers, which will be taken literally as the time (in seconds).
  • + *
  • Notation, ("4n", "8t") describes time in BPM and time signature relative values.
  • + *
  • TransportTime, ("4:3:2") will also provide tempo and time signature relative times + * in the form BARS:QUARTERS:SIXTEENTHS.
  • + *
  • Frequency, ("8hz") is converted to the length of the cycle in seconds.
  • + *
  • Now-Relative, ("+1") prefix any of the above with "+" and it will be interpreted as + * "the current time plus whatever expression follows".
  • + *
  • Expressions, ("3:0 + 2 - (1m / 7)") any of the above can also be combined + * into a mathematical expression which will be evaluated to compute the desired time.
  • + *
  • No Argument, for methods which accept time, no argument will be interpreted as + * "now" (i.e. the currentTime).
  • + *
+ * + * @typedef {Time} + */ + Time: 'time', + /** + * Frequency can be described similar to time, except ultimately the + * values are converted to frequency instead of seconds. A number + * is taken literally as the value in hertz. Additionally any of the + * Time encodings can be used. Note names in the form + * of NOTE OCTAVE (i.e. C4) are also accepted and converted to their + * frequency value. + * @typedef {Frequency} + */ + Frequency: 'frequency', + /** + * TransportTime describes a position along the Transport's timeline. It is + * similar to Time in that it uses all the same encodings, but TransportTime specifically + * pertains to the Transport's timeline, which is startable, stoppable, loopable, and seekable. + * [Read more](https://github.com/Tonejs/Tone.js/wiki/TransportTime) + * @typedef {TransportTime} + */ + TransportTime: 'transportTime', + /** + * Ticks are the basic subunit of the Transport. They are + * the smallest unit of time that the Transport supports. + * @typedef {Ticks} + */ + Ticks: 'ticks', + /** + * Normal values are within the range [0, 1]. + * @typedef {NormalRange} + */ + NormalRange: 'normalRange', + /** + * AudioRange values are between [-1, 1]. + * @typedef {AudioRange} + */ + AudioRange: 'audioRange', + /** + * Decibels are a logarithmic unit of measurement which is useful for volume + * because of the logarithmic way that we perceive loudness. 0 decibels + * means no change in volume. -10db is approximately half as loud and 10db + * is twice is loud. + * @typedef {Decibels} + */ + Decibels: 'db', + /** + * Half-step note increments, i.e. 12 is an octave above the root. and 1 is a half-step up. + * @typedef {Interval} + */ + Interval: 'interval', + /** + * Beats per minute. + * @typedef {BPM} + */ + BPM: 'bpm', + /** + * The value must be greater than or equal to 0. + * @typedef {Positive} + */ + Positive: 'positive', + /** + * A cent is a hundredth of a semitone. + * @typedef {Cents} + */ + Cents: 'cents', + /** + * Angle between 0 and 360. + * @typedef {Degrees} + */ + Degrees: 'degrees', + /** + * A number representing a midi note. + * @typedef {MIDI} + */ + MIDI: 'midi', + /** + * A colon-separated representation of time in the form of + * Bars:Beats:Sixteenths. + * @typedef {BarsBeatsSixteenths} + */ + BarsBeatsSixteenths: 'barsBeatsSixteenths', + /** + * Sampling is the reduction of a continuous signal to a discrete signal. + * Audio is typically sampled 44100 times per second. + * @typedef {Samples} + */ + Samples: 'samples', + /** + * Hertz are a frequency representation defined as one cycle per second. + * @typedef {Hertz} + */ + Hertz: 'hertz', + /** + * A frequency represented by a letter name, + * accidental and octave. This system is known as + * [Scientific Pitch Notation](https://en.wikipedia.org/wiki/Scientific_pitch_notation). + * @typedef {Note} + */ + Note: 'note', + /** + * One millisecond is a thousandth of a second. + * @typedef {Milliseconds} + */ + Milliseconds: 'milliseconds', + /** + * Seconds are the time unit of the AudioContext. In the end, + * all values need to be evaluated to seconds. + * @typedef {Seconds} + */ + Seconds: 'seconds', + /** + * A string representing a duration relative to a measure. + *
    + *
  • "4n" = quarter note
  • + *
  • "2m" = two measures
  • + *
  • "8t" = eighth-note triplet
  • + *
+ * @typedef {Notation} + */ + Notation: 'notation' + }; + /////////////////////////////////////////////////////////////////////////// + // AUGMENT TONE's PROTOTYPE + /////////////////////////////////////////////////////////////////////////// + /** + * Convert Time into seconds. + * + * Unlike the method which it overrides, this takes into account + * transporttime and musical notation. + * + * Time : 1.40 + * Notation: 4n|1m|2t + * Now Relative: +3n + * Math: 3n+16n or even complicated expressions ((3n*2)/6 + 1) + * + * @param {Time} time + * @return {Seconds} + */ + Tone.prototype.toSeconds = function (time) { + if (this.isNumber(time)) { + return time; + } else if (this.isUndef(time)) { + return this.now(); + } else if (this.isString(time)) { + return new Tone.Time(time).toSeconds(); + } else if (time instanceof Tone.TimeBase) { + return time.toSeconds(); + } + }; + /** + * Convert a frequency representation into a number. + * @param {Frequency} freq + * @return {Hertz} the frequency in hertz + */ + Tone.prototype.toFrequency = function (freq) { + if (this.isNumber(freq)) { + return freq; + } else if (this.isString(freq) || this.isUndef(freq)) { + return new Tone.Frequency(freq).eval(); + } else if (freq instanceof Tone.TimeBase) { + return freq.toFrequency(); + } + }; + /** + * Convert a time representation into ticks. + * @param {Time} time + * @return {Ticks} the time in ticks + */ + Tone.prototype.toTicks = function (time) { + if (this.isNumber(time) || this.isString(time)) { + return new Tone.TransportTime(time).toTicks(); + } else if (this.isUndef(time)) { + return Tone.Transport.ticks; + } else if (time instanceof Tone.TimeBase) { + return time.toTicks(); + } + }; + return Tone; + }); + Module(function (Tone) { + + /** + * @class Tone.Param wraps the native Web Audio's AudioParam to provide + * additional unit conversion functionality. It also + * serves as a base-class for classes which have a single, + * automatable parameter. + * @extends {Tone} + * @param {AudioParam} param The parameter to wrap. + * @param {Tone.Type} units The units of the audio param. + * @param {Boolean} convert If the param should be converted. + */ + Tone.Param = function () { + var options = this.optionsObject(arguments, [ + 'param', + 'units', + 'convert' + ], Tone.Param.defaults); + /** + * The native parameter to control + * @type {AudioParam} + * @private + */ + this._param = this.input = options.param; + /** + * The units of the parameter + * @type {Tone.Type} + */ + this.units = options.units; + /** + * If the value should be converted or not + * @type {Boolean} + */ + this.convert = options.convert; + /** + * True if the signal value is being overridden by + * a connected signal. + * @readOnly + * @type {boolean} + * @private + */ + this.overridden = false; + /** + * If there is an LFO, this is where it is held. + * @type {Tone.LFO} + * @private + */ + this._lfo = null; + if (this.isObject(options.lfo)) { + this.value = options.lfo; + } else if (!this.isUndef(options.value)) { + this.value = options.value; + } + }; + Tone.extend(Tone.Param); + /** + * Defaults + * @type {Object} + * @const + */ + Tone.Param.defaults = { + 'units': Tone.Type.Default, + 'convert': true, + 'param': undefined + }; + /** + * The current value of the parameter. + * @memberOf Tone.Param# + * @type {Number} + * @name value + */ + Object.defineProperty(Tone.Param.prototype, 'value', { + get: function () { + return this._toUnits(this._param.value); + }, + set: function (value) { + if (this.isObject(value)) { + //throw an error if the LFO needs to be included + if (this.isUndef(Tone.LFO)) { + throw new Error('Include \'Tone.LFO\' to use an LFO as a Param value.'); + } + //remove the old one + if (this._lfo) { + this._lfo.dispose(); + } + this._lfo = new Tone.LFO(value).start(); + this._lfo.connect(this.input); + } else { + var convertedVal = this._fromUnits(value); + this._param.cancelScheduledValues(0); + this._param.value = convertedVal; + } + } + }); + /** + * Convert the given value from the type specified by Tone.Param.units + * into the destination value (such as Gain or Frequency). + * @private + * @param {*} val the value to convert + * @return {number} the number which the value should be set to + */ + Tone.Param.prototype._fromUnits = function (val) { + if (this.convert || this.isUndef(this.convert)) { + switch (this.units) { + case Tone.Type.Time: + return this.toSeconds(val); + case Tone.Type.Frequency: + return this.toFrequency(val); + case Tone.Type.Decibels: + return this.dbToGain(val); + case Tone.Type.NormalRange: + return Math.min(Math.max(val, 0), 1); + case Tone.Type.AudioRange: + return Math.min(Math.max(val, -1), 1); + case Tone.Type.Positive: + return Math.max(val, 0); + default: + return val; + } + } else { + return val; + } + }; + /** + * Convert the parameters value into the units specified by Tone.Param.units. + * @private + * @param {number} val the value to convert + * @return {number} + */ + Tone.Param.prototype._toUnits = function (val) { + if (this.convert || this.isUndef(this.convert)) { + switch (this.units) { + case Tone.Type.Decibels: + return this.gainToDb(val); + default: + return val; + } + } else { + return val; + } + }; + /** + * the minimum output value + * @type {Number} + * @private + */ + Tone.Param.prototype._minOutput = 0.00001; + /** + * Schedules a parameter value change at the given time. + * @param {*} value The value to set the signal. + * @param {Time} time The time when the change should occur. + * @returns {Tone.Param} this + * @example + * //set the frequency to "G4" in exactly 1 second from now. + * freq.setValueAtTime("G4", "+1"); + */ + Tone.Param.prototype.setValueAtTime = function (value, time) { + value = this._fromUnits(value); + time = this.toSeconds(time); + if (time <= this.now() + this.blockTime) { + this._param.value = value; + } else { + this._param.setValueAtTime(value, time); + } + return this; + }; + /** + * Creates a schedule point with the current value at the current time. + * This is useful for creating an automation anchor point in order to + * schedule changes from the current value. + * + * @param {number=} now (Optionally) pass the now value in. + * @returns {Tone.Param} this + */ + Tone.Param.prototype.setRampPoint = function (now) { + now = this.defaultArg(now, this.now()); + var currentVal = this._param.value; + // exponentialRampToValueAt cannot ever ramp from or to 0 + // More info: https://bugzilla.mozilla.org/show_bug.cgi?id=1125600#c2 + if (currentVal === 0) { + currentVal = this._minOutput; + } + this._param.setValueAtTime(currentVal, now); + return this; + }; + /** + * Schedules a linear continuous change in parameter value from the + * previous scheduled parameter value to the given value. + * + * @param {number} value + * @param {Time} endTime + * @returns {Tone.Param} this + */ + Tone.Param.prototype.linearRampToValueAtTime = function (value, endTime) { + value = this._fromUnits(value); + this._param.linearRampToValueAtTime(value, this.toSeconds(endTime)); + return this; + }; + /** + * Schedules an exponential continuous change in parameter value from + * the previous scheduled parameter value to the given value. + * + * @param {number} value + * @param {Time} endTime + * @returns {Tone.Param} this + */ + Tone.Param.prototype.exponentialRampToValueAtTime = function (value, endTime) { + value = this._fromUnits(value); + value = Math.max(this._minOutput, value); + this._param.exponentialRampToValueAtTime(value, this.toSeconds(endTime)); + return this; + }; + /** + * Schedules an exponential continuous change in parameter value from + * the current time and current value to the given value over the + * duration of the rampTime. + * + * @param {number} value The value to ramp to. + * @param {Time} rampTime the time that it takes the + * value to ramp from it's current value + * @param {Time} [startTime=now] When the ramp should start. + * @returns {Tone.Param} this + * @example + * //exponentially ramp to the value 2 over 4 seconds. + * signal.exponentialRampToValue(2, 4); + */ + Tone.Param.prototype.exponentialRampToValue = function (value, rampTime, startTime) { + startTime = this.toSeconds(startTime); + this.setRampPoint(startTime); + this.exponentialRampToValueAtTime(value, startTime + this.toSeconds(rampTime)); + return this; + }; + /** + * Schedules an linear continuous change in parameter value from + * the current time and current value to the given value over the + * duration of the rampTime. + * + * @param {number} value The value to ramp to. + * @param {Time} rampTime the time that it takes the + * value to ramp from it's current value + * @param {Time} [startTime=now] When the ramp should start. + * @returns {Tone.Param} this + * @example + * //linearly ramp to the value 4 over 3 seconds. + * signal.linearRampToValue(4, 3); + */ + Tone.Param.prototype.linearRampToValue = function (value, rampTime, startTime) { + startTime = this.toSeconds(startTime); + this.setRampPoint(startTime); + this.linearRampToValueAtTime(value, startTime + this.toSeconds(rampTime)); + return this; + }; + /** + * Start exponentially approaching the target value at the given time with + * a rate having the given time constant. + * @param {number} value + * @param {Time} startTime + * @param {number} timeConstant + * @returns {Tone.Param} this + */ + Tone.Param.prototype.setTargetAtTime = function (value, startTime, timeConstant) { + value = this._fromUnits(value); + // The value will never be able to approach without timeConstant > 0. + // http://www.w3.org/TR/webaudio/#dfn-setTargetAtTime, where the equation + // is described. 0 results in a division by 0. + value = Math.max(this._minOutput, value); + timeConstant = Math.max(this._minOutput, timeConstant); + this._param.setTargetAtTime(value, this.toSeconds(startTime), timeConstant); + return this; + }; + /** + * Sets an array of arbitrary parameter values starting at the given time + * for the given duration. + * + * @param {Array} values + * @param {Time} startTime + * @param {Time} duration + * @returns {Tone.Param} this + */ + Tone.Param.prototype.setValueCurveAtTime = function (values, startTime, duration) { + for (var i = 0; i < values.length; i++) { + values[i] = this._fromUnits(values[i]); + } + this._param.setValueCurveAtTime(values, this.toSeconds(startTime), this.toSeconds(duration)); + return this; + }; + /** + * Cancels all scheduled parameter changes with times greater than or + * equal to startTime. + * + * @param {Time} startTime + * @returns {Tone.Param} this + */ + Tone.Param.prototype.cancelScheduledValues = function (startTime) { + this._param.cancelScheduledValues(this.toSeconds(startTime)); + return this; + }; + /** + * Ramps to the given value over the duration of the rampTime. + * Automatically selects the best ramp type (exponential or linear) + * depending on the `units` of the signal + * + * @param {number} value + * @param {Time} rampTime The time that it takes the + * value to ramp from it's current value + * @param {Time} [startTime=now] When the ramp should start. + * @returns {Tone.Param} this + * @example + * //ramp to the value either linearly or exponentially + * //depending on the "units" value of the signal + * signal.rampTo(0, 10); + * @example + * //schedule it to ramp starting at a specific time + * signal.rampTo(0, 10, 5) + */ + Tone.Param.prototype.rampTo = function (value, rampTime, startTime) { + rampTime = this.defaultArg(rampTime, 0); + if (this.units === Tone.Type.Frequency || this.units === Tone.Type.BPM) { + this.exponentialRampToValue(value, rampTime, startTime); + } else { + this.linearRampToValue(value, rampTime, startTime); + } + return this; + }; + /** + * The LFO created by the signal instance. If none + * was created, this is null. + * @type {Tone.LFO} + * @readOnly + * @memberOf Tone.Param# + * @name lfo + */ + Object.defineProperty(Tone.Param.prototype, 'lfo', { + get: function () { + return this._lfo; + } + }); + /** + * Clean up + * @returns {Tone.Param} this + */ + Tone.Param.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._param = null; + if (this._lfo) { + this._lfo.dispose(); + this._lfo = null; + } + return this; + }; + return Tone.Param; + }); + Module(function (Tone) { + + /** + * @class A thin wrapper around the Native Web Audio GainNode. + * The GainNode is a basic building block of the Web Audio + * API and is useful for routing audio and adjusting gains. + * @extends {Tone} + * @param {Number=} gain The initial gain of the GainNode + * @param {Tone.Type=} units The units of the gain parameter. + */ + Tone.Gain = function () { + var options = this.optionsObject(arguments, [ + 'gain', + 'units' + ], Tone.Gain.defaults); + /** + * The GainNode + * @type {GainNode} + * @private + */ + this.input = this.output = this._gainNode = this.context.createGain(); + /** + * The gain parameter of the gain node. + * @type {Tone.Param} + * @signal + */ + this.gain = new Tone.Param({ + 'param': this._gainNode.gain, + 'units': options.units, + 'value': options.gain, + 'convert': options.convert + }); + this._readOnly('gain'); + }; + Tone.extend(Tone.Gain); + /** + * The defaults + * @const + * @type {Object} + */ + Tone.Gain.defaults = { + 'gain': 1, + 'convert': true + }; + /** + * Clean up. + * @return {Tone.Gain} this + */ + Tone.Gain.prototype.dispose = function () { + Tone.Param.prototype.dispose.call(this); + this._gainNode.disconnect(); + this._gainNode = null; + this._writable('gain'); + this.gain.dispose(); + this.gain = null; + }; + //STATIC/////////////////////////////////////////////////////////////////// + /** + * Create input and outputs for this object. + * @param {Number} input The number of inputs + * @param {Number=} outputs The number of outputs + * @return {Tone} this + * @internal + */ + Tone.prototype.createInsOuts = function (inputs, outputs) { + if (inputs === 1) { + this.input = new Tone.Gain(); + } else if (inputs > 1) { + this.input = new Array(inputs); + } + if (outputs === 1) { + this.output = new Tone.Gain(); + } else if (outputs > 1) { + this.output = new Array(inputs); + } + }; + /////////////////////////////////////////////////////////////////////////// + return Tone.Gain; + }); + Module(function (Tone) { + + /** + * @class A signal is an audio-rate value. Tone.Signal is a core component of the library. + * Unlike a number, Signals can be scheduled with sample-level accuracy. Tone.Signal + * has all of the methods available to native Web Audio + * [AudioParam](http://webaudio.github.io/web-audio-api/#the-audioparam-interface) + * as well as additional conveniences. Read more about working with signals + * [here](https://github.com/Tonejs/Tone.js/wiki/Signals). + * + * @constructor + * @extends {Tone.Param} + * @param {Number|AudioParam} [value] Initial value of the signal. If an AudioParam + * is passed in, that parameter will be wrapped + * and controlled by the Signal. + * @param {string} [units=Number] unit The units the signal is in. + * @example + * var signal = new Tone.Signal(10); + */ + Tone.Signal = function () { + var options = this.optionsObject(arguments, [ + 'value', + 'units' + ], Tone.Signal.defaults); + /** + * The node where the constant signal value is scaled. + * @type {GainNode} + * @private + */ + this.output = this._gain = this.context.createGain(); + options.param = this._gain.gain; + Tone.Param.call(this, options); + /** + * The node where the value is set. + * @type {Tone.Param} + * @private + */ + this.input = this._param = this._gain.gain; + //connect the const output to the node output + Tone.Signal._constant.chain(this._gain); + }; + Tone.extend(Tone.Signal, Tone.Param); + /** + * The default values + * @type {Object} + * @static + * @const + */ + Tone.Signal.defaults = { + 'value': 0, + 'units': Tone.Type.Default, + 'convert': true + }; + /** + * When signals connect to other signals or AudioParams, + * they take over the output value of that signal or AudioParam. + * For all other nodes, the behavior is the same as a default connect. + * + * @override + * @param {AudioParam|AudioNode|Tone.Signal|Tone} node + * @param {number} [outputNumber=0] The output number to connect from. + * @param {number} [inputNumber=0] The input number to connect to. + * @returns {Tone.SignalBase} this + * @method + */ + Tone.Signal.prototype.connect = Tone.SignalBase.prototype.connect; + /** + * dispose and disconnect + * @returns {Tone.Signal} this + */ + Tone.Signal.prototype.dispose = function () { + Tone.Param.prototype.dispose.call(this); + this._param = null; + this._gain.disconnect(); + this._gain = null; + return this; + }; + /////////////////////////////////////////////////////////////////////////// + // STATIC + /////////////////////////////////////////////////////////////////////////// + /** + * Generates a constant output of 1. + * @static + * @private + * @const + * @type {AudioBufferSourceNode} + */ + Tone.Signal._constant = null; + /** + * initializer function + */ + Tone._initAudioContext(function (audioContext) { + var buffer = audioContext.createBuffer(1, 128, audioContext.sampleRate); + var arr = buffer.getChannelData(0); + for (var i = 0; i < arr.length; i++) { + arr[i] = 1; + } + Tone.Signal._constant = audioContext.createBufferSource(); + Tone.Signal._constant.channelCount = 1; + Tone.Signal._constant.channelCountMode = 'explicit'; + Tone.Signal._constant.buffer = buffer; + Tone.Signal._constant.loop = true; + Tone.Signal._constant.start(0); + Tone.Signal._constant.noGC(); + }); + return Tone.Signal; + }); + Module(function (Tone) { + + /** + * @class A Timeline class for scheduling and maintaining state + * along a timeline. All events must have a "time" property. + * Internally, events are stored in time order for fast + * retrieval. + * @extends {Tone} + * @param {Positive} [memory=Infinity] The number of previous events that are retained. + */ + Tone.Timeline = function () { + var options = this.optionsObject(arguments, ['memory'], Tone.Timeline.defaults); + /** + * The array of scheduled timeline events + * @type {Array} + * @private + */ + this._timeline = []; + /** + * An array of items to remove from the list. + * @type {Array} + * @private + */ + this._toRemove = []; + /** + * Flag if the tieline is mid iteration + * @private + * @type {Boolean} + */ + this._iterating = false; + /** + * The memory of the timeline, i.e. + * how many events in the past it will retain + * @type {Positive} + */ + this.memory = options.memory; + }; + Tone.extend(Tone.Timeline); + /** + * the default parameters + * @static + * @const + */ + Tone.Timeline.defaults = { 'memory': Infinity }; + /** + * The number of items in the timeline. + * @type {Number} + * @memberOf Tone.Timeline# + * @name length + * @readOnly + */ + Object.defineProperty(Tone.Timeline.prototype, 'length', { + get: function () { + return this._timeline.length; + } + }); + /** + * Insert an event object onto the timeline. Events must have a "time" attribute. + * @param {Object} event The event object to insert into the + * timeline. + * @returns {Tone.Timeline} this + */ + Tone.Timeline.prototype.add = function (event) { + //the event needs to have a time attribute + if (this.isUndef(event.time)) { + throw new Error('Tone.Timeline: events must have a time attribute'); + } + if (this._timeline.length) { + var index = this._search(event.time); + this._timeline.splice(index + 1, 0, event); + } else { + this._timeline.push(event); + } + //if the length is more than the memory, remove the previous ones + if (this.length > this.memory) { + var diff = this.length - this.memory; + this._timeline.splice(0, diff); + } + return this; + }; + /** + * Remove an event from the timeline. + * @param {Object} event The event object to remove from the list. + * @returns {Tone.Timeline} this + */ + Tone.Timeline.prototype.remove = function (event) { + if (this._iterating) { + this._toRemove.push(event); + } else { + var index = this._timeline.indexOf(event); + if (index !== -1) { + this._timeline.splice(index, 1); + } + } + return this; + }; + /** + * Get the nearest event whose time is less than or equal to the given time. + * @param {Number} time The time to query. + * @returns {Object} The event object set after that time. + */ + Tone.Timeline.prototype.get = function (time) { + var index = this._search(time); + if (index !== -1) { + return this._timeline[index]; + } else { + return null; + } + }; + /** + * Return the first event in the timeline without removing it + * @returns {Object} The first event object + */ + Tone.Timeline.prototype.peek = function () { + return this._timeline[0]; + }; + /** + * Return the first event in the timeline and remove it + * @returns {Object} The first event object + */ + Tone.Timeline.prototype.shift = function () { + return this._timeline.shift(); + }; + /** + * Get the event which is scheduled after the given time. + * @param {Number} time The time to query. + * @returns {Object} The event object after the given time + */ + Tone.Timeline.prototype.getAfter = function (time) { + var index = this._search(time); + if (index + 1 < this._timeline.length) { + return this._timeline[index + 1]; + } else { + return null; + } + }; + /** + * Get the event before the event at the given time. + * @param {Number} time The time to query. + * @returns {Object} The event object before the given time + */ + Tone.Timeline.prototype.getBefore = function (time) { + var len = this._timeline.length; + //if it's after the last item, return the last item + if (len > 0 && this._timeline[len - 1].time < time) { + return this._timeline[len - 1]; + } + var index = this._search(time); + if (index - 1 >= 0) { + return this._timeline[index - 1]; + } else { + return null; + } + }; + /** + * Cancel events after the given time + * @param {Number} time The time to query. + * @returns {Tone.Timeline} this + */ + Tone.Timeline.prototype.cancel = function (after) { + if (this._timeline.length > 1) { + var index = this._search(after); + if (index >= 0) { + if (this._timeline[index].time === after) { + //get the first item with that time + for (var i = index; i >= 0; i--) { + if (this._timeline[i].time === after) { + index = i; + } else { + break; + } + } + this._timeline = this._timeline.slice(0, index); + } else { + this._timeline = this._timeline.slice(0, index + 1); + } + } else { + this._timeline = []; + } + } else if (this._timeline.length === 1) { + //the first item's time + if (this._timeline[0].time >= after) { + this._timeline = []; + } + } + return this; + }; + /** + * Cancel events before or equal to the given time. + * @param {Number} time The time to cancel before. + * @returns {Tone.Timeline} this + */ + Tone.Timeline.prototype.cancelBefore = function (time) { + if (this._timeline.length) { + var index = this._search(time); + if (index >= 0) { + this._timeline = this._timeline.slice(index + 1); + } + } + return this; + }; + /** + * Does a binary serach on the timeline array and returns the + * nearest event index whose time is after or equal to the given time. + * If a time is searched before the first index in the timeline, -1 is returned. + * If the time is after the end, the index of the last item is returned. + * @param {Number} time + * @return {Number} the index in the timeline array + * @private + */ + Tone.Timeline.prototype._search = function (time) { + var beginning = 0; + var len = this._timeline.length; + var end = len; + if (len > 0 && this._timeline[len - 1].time <= time) { + return len - 1; + } + while (beginning < end) { + // calculate the midpoint for roughly equal partition + var midPoint = Math.floor(beginning + (end - beginning) / 2); + var event = this._timeline[midPoint]; + var nextEvent = this._timeline[midPoint + 1]; + if (event.time === time) { + //choose the last one that has the same time + for (var i = midPoint; i < this._timeline.length; i++) { + var testEvent = this._timeline[i]; + if (testEvent.time === time) { + midPoint = i; + } + } + return midPoint; + } else if (event.time < time && nextEvent.time > time) { + return midPoint; + } else if (event.time > time) { + //search lower + end = midPoint; + } else if (event.time < time) { + //search upper + beginning = midPoint + 1; + } + } + return -1; + }; + /** + * Internal iterator. Applies extra safety checks for + * removing items from the array. + * @param {Function} callback + * @param {Number=} lowerBound + * @param {Number=} upperBound + * @private + */ + Tone.Timeline.prototype._iterate = function (callback, lowerBound, upperBound) { + this._iterating = true; + lowerBound = this.defaultArg(lowerBound, 0); + upperBound = this.defaultArg(upperBound, this._timeline.length - 1); + for (var i = lowerBound; i <= upperBound; i++) { + callback(this._timeline[i]); + } + this._iterating = false; + if (this._toRemove.length > 0) { + for (var j = 0; j < this._toRemove.length; j++) { + var index = this._timeline.indexOf(this._toRemove[j]); + if (index !== -1) { + this._timeline.splice(index, 1); + } + } + this._toRemove = []; + } + }; + /** + * Iterate over everything in the array + * @param {Function} callback The callback to invoke with every item + * @returns {Tone.Timeline} this + */ + Tone.Timeline.prototype.forEach = function (callback) { + this._iterate(callback); + return this; + }; + /** + * Iterate over everything in the array at or before the given time. + * @param {Number} time The time to check if items are before + * @param {Function} callback The callback to invoke with every item + * @returns {Tone.Timeline} this + */ + Tone.Timeline.prototype.forEachBefore = function (time, callback) { + //iterate over the items in reverse so that removing an item doesn't break things + var upperBound = this._search(time); + if (upperBound !== -1) { + this._iterate(callback, 0, upperBound); + } + return this; + }; + /** + * Iterate over everything in the array after the given time. + * @param {Number} time The time to check if items are before + * @param {Function} callback The callback to invoke with every item + * @returns {Tone.Timeline} this + */ + Tone.Timeline.prototype.forEachAfter = function (time, callback) { + //iterate over the items in reverse so that removing an item doesn't break things + var lowerBound = this._search(time); + this._iterate(callback, lowerBound + 1); + return this; + }; + /** + * Iterate over everything in the array at or after the given time. Similar to + * forEachAfter, but includes the item(s) at the given time. + * @param {Number} time The time to check if items are before + * @param {Function} callback The callback to invoke with every item + * @returns {Tone.Timeline} this + */ + Tone.Timeline.prototype.forEachFrom = function (time, callback) { + //iterate over the items in reverse so that removing an item doesn't break things + var lowerBound = this._search(time); + //work backwards until the event time is less than time + while (lowerBound >= 0 && this._timeline[lowerBound].time >= time) { + lowerBound--; + } + this._iterate(callback, lowerBound + 1); + return this; + }; + /** + * Iterate over everything in the array at the given time + * @param {Number} time The time to check if items are before + * @param {Function} callback The callback to invoke with every item + * @returns {Tone.Timeline} this + */ + Tone.Timeline.prototype.forEachAtTime = function (time, callback) { + //iterate over the items in reverse so that removing an item doesn't break things + var upperBound = this._search(time); + if (upperBound !== -1) { + this._iterate(function (event) { + if (event.time === time) { + callback(event); + } + }, 0, upperBound); + } + return this; + }; + /** + * Clean up. + * @return {Tone.Timeline} this + */ + Tone.Timeline.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._timeline = null; + this._toRemove = null; + }; + return Tone.Timeline; + }); + Module(function (Tone) { + + /** + * @class A signal which adds the method getValueAtTime. + * Code and inspiration from https://github.com/jsantell/web-audio-automation-timeline + * @extends {Tone.Param} + * @param {Number=} value The initial value of the signal + * @param {String=} units The conversion units of the signal. + */ + Tone.TimelineSignal = function () { + var options = this.optionsObject(arguments, [ + 'value', + 'units' + ], Tone.Signal.defaults); + /** + * The scheduled events + * @type {Tone.Timeline} + * @private + */ + this._events = new Tone.Timeline(10); + //constructors + Tone.Signal.apply(this, options); + options.param = this._param; + Tone.Param.call(this, options); + /** + * The initial scheduled value + * @type {Number} + * @private + */ + this._initial = this._fromUnits(this._param.value); + }; + Tone.extend(Tone.TimelineSignal, Tone.Param); + /** + * The event types of a schedulable signal. + * @enum {String} + * @private + */ + Tone.TimelineSignal.Type = { + Linear: 'linear', + Exponential: 'exponential', + Target: 'target', + Curve: 'curve', + Set: 'set' + }; + /** + * The current value of the signal. + * @memberOf Tone.TimelineSignal# + * @type {Number} + * @name value + */ + Object.defineProperty(Tone.TimelineSignal.prototype, 'value', { + get: function () { + var now = this.now(); + var val = this.getValueAtTime(now); + return this._toUnits(val); + }, + set: function (value) { + var convertedVal = this._fromUnits(value); + this._initial = convertedVal; + this.cancelScheduledValues(); + this._param.value = convertedVal; + } + }); + /////////////////////////////////////////////////////////////////////////// + // SCHEDULING + /////////////////////////////////////////////////////////////////////////// + /** + * Schedules a parameter value change at the given time. + * @param {*} value The value to set the signal. + * @param {Time} time The time when the change should occur. + * @returns {Tone.TimelineSignal} this + * @example + * //set the frequency to "G4" in exactly 1 second from now. + * freq.setValueAtTime("G4", "+1"); + */ + Tone.TimelineSignal.prototype.setValueAtTime = function (value, startTime) { + value = this._fromUnits(value); + startTime = this.toSeconds(startTime); + this._events.add({ + 'type': Tone.TimelineSignal.Type.Set, + 'value': value, + 'time': startTime + }); + //invoke the original event + this._param.setValueAtTime(value, startTime); + return this; + }; + /** + * Schedules a linear continuous change in parameter value from the + * previous scheduled parameter value to the given value. + * + * @param {number} value + * @param {Time} endTime + * @returns {Tone.TimelineSignal} this + */ + Tone.TimelineSignal.prototype.linearRampToValueAtTime = function (value, endTime) { + value = this._fromUnits(value); + endTime = this.toSeconds(endTime); + this._events.add({ + 'type': Tone.TimelineSignal.Type.Linear, + 'value': value, + 'time': endTime + }); + this._param.linearRampToValueAtTime(value, endTime); + return this; + }; + /** + * Schedules an exponential continuous change in parameter value from + * the previous scheduled parameter value to the given value. + * + * @param {number} value + * @param {Time} endTime + * @returns {Tone.TimelineSignal} this + */ + Tone.TimelineSignal.prototype.exponentialRampToValueAtTime = function (value, endTime) { + //get the previous event and make sure it's not starting from 0 + endTime = this.toSeconds(endTime); + var beforeEvent = this._searchBefore(endTime); + if (beforeEvent && beforeEvent.value === 0) { + //reschedule that event + this.setValueAtTime(this._minOutput, beforeEvent.time); + } + value = this._fromUnits(value); + var setValue = Math.max(value, this._minOutput); + this._events.add({ + 'type': Tone.TimelineSignal.Type.Exponential, + 'value': setValue, + 'time': endTime + }); + //if the ramped to value is 0, make it go to the min output, and then set to 0. + if (value < this._minOutput) { + this._param.exponentialRampToValueAtTime(this._minOutput, endTime - this.sampleTime); + this.setValueAtTime(0, endTime); + } else { + this._param.exponentialRampToValueAtTime(value, endTime); + } + return this; + }; + /** + * Start exponentially approaching the target value at the given time with + * a rate having the given time constant. + * @param {number} value + * @param {Time} startTime + * @param {number} timeConstant + * @returns {Tone.TimelineSignal} this + */ + Tone.TimelineSignal.prototype.setTargetAtTime = function (value, startTime, timeConstant) { + value = this._fromUnits(value); + value = Math.max(this._minOutput, value); + timeConstant = Math.max(this._minOutput, timeConstant); + startTime = this.toSeconds(startTime); + this._events.add({ + 'type': Tone.TimelineSignal.Type.Target, + 'value': value, + 'time': startTime, + 'constant': timeConstant + }); + this._param.setTargetAtTime(value, startTime, timeConstant); + return this; + }; + /** + * Set an array of arbitrary values starting at the given time for the given duration. + * @param {Float32Array} values + * @param {Time} startTime + * @param {Time} duration + * @param {NormalRange} [scaling=1] If the values in the curve should be scaled by some value + * @returns {Tone.TimelineSignal} this + */ + Tone.TimelineSignal.prototype.setValueCurveAtTime = function (values, startTime, duration, scaling) { + scaling = this.defaultArg(scaling, 1); + //copy the array + var floats = new Array(values.length); + for (var i = 0; i < floats.length; i++) { + floats[i] = this._fromUnits(values[i]) * scaling; + } + startTime = this.toSeconds(startTime); + duration = this.toSeconds(duration); + this._events.add({ + 'type': Tone.TimelineSignal.Type.Curve, + 'value': floats, + 'time': startTime, + 'duration': duration + }); + //set the first value + this._param.setValueAtTime(floats[0], startTime); + //schedule a lienar ramp for each of the segments + for (var j = 1; j < floats.length; j++) { + var segmentTime = startTime + j / (floats.length - 1) * duration; + this._param.linearRampToValueAtTime(floats[j], segmentTime); + } + return this; + }; + /** + * Cancels all scheduled parameter changes with times greater than or + * equal to startTime. + * + * @param {Time} startTime + * @returns {Tone.TimelineSignal} this + */ + Tone.TimelineSignal.prototype.cancelScheduledValues = function (after) { + after = this.toSeconds(after); + this._events.cancel(after); + this._param.cancelScheduledValues(after); + return this; + }; + /** + * Sets the computed value at the given time. This provides + * a point from which a linear or exponential curve + * can be scheduled after. Will cancel events after + * the given time and shorten the currently scheduled + * linear or exponential ramp so that it ends at `time` . + * This is to avoid discontinuities and clicks in envelopes. + * @param {Time} time When to set the ramp point + * @returns {Tone.TimelineSignal} this + */ + Tone.TimelineSignal.prototype.setRampPoint = function (time) { + time = this.toSeconds(time); + //get the value at the given time + var val = this._toUnits(this.getValueAtTime(time)); + //if there is an event at the given time + //and that even is not a "set" + var before = this._searchBefore(time); + if (before && before.time === time) { + //remove everything after + this.cancelScheduledValues(time + this.sampleTime); + } else if (before && before.type === Tone.TimelineSignal.Type.Curve && before.time + before.duration > time) { + //if the curve is still playing + //cancel the curve + this.cancelScheduledValues(time); + this.linearRampToValueAtTime(val, time); + } else { + //reschedule the next event to end at the given time + var after = this._searchAfter(time); + if (after) { + //cancel the next event(s) + this.cancelScheduledValues(time); + if (after.type === Tone.TimelineSignal.Type.Linear) { + this.linearRampToValueAtTime(val, time); + } else if (after.type === Tone.TimelineSignal.Type.Exponential) { + this.exponentialRampToValueAtTime(val, time); + } + } + this.setValueAtTime(val, time); + } + return this; + }; + /** + * Do a linear ramp to the given value between the start and finish times. + * @param {Number} value The value to ramp to. + * @param {Time} start The beginning anchor point to do the linear ramp + * @param {Time} finish The ending anchor point by which the value of + * the signal will equal the given value. + * @returns {Tone.TimelineSignal} this + */ + Tone.TimelineSignal.prototype.linearRampToValueBetween = function (value, start, finish) { + this.setRampPoint(start); + this.linearRampToValueAtTime(value, finish); + return this; + }; + /** + * Do a exponential ramp to the given value between the start and finish times. + * @param {Number} value The value to ramp to. + * @param {Time} start The beginning anchor point to do the exponential ramp + * @param {Time} finish The ending anchor point by which the value of + * the signal will equal the given value. + * @returns {Tone.TimelineSignal} this + */ + Tone.TimelineSignal.prototype.exponentialRampToValueBetween = function (value, start, finish) { + this.setRampPoint(start); + this.exponentialRampToValueAtTime(value, finish); + return this; + }; + /////////////////////////////////////////////////////////////////////////// + // GETTING SCHEDULED VALUES + /////////////////////////////////////////////////////////////////////////// + /** + * Returns the value before or equal to the given time + * @param {Number} time The time to query + * @return {Object} The event at or before the given time. + * @private + */ + Tone.TimelineSignal.prototype._searchBefore = function (time) { + return this._events.get(time); + }; + /** + * The event after the given time + * @param {Number} time The time to query. + * @return {Object} The next event after the given time + * @private + */ + Tone.TimelineSignal.prototype._searchAfter = function (time) { + return this._events.getAfter(time); + }; + /** + * Get the scheduled value at the given time. This will + * return the unconverted (raw) value. + * @param {Number} time The time in seconds. + * @return {Number} The scheduled value at the given time. + */ + Tone.TimelineSignal.prototype.getValueAtTime = function (time) { + time = this.toSeconds(time); + var after = this._searchAfter(time); + var before = this._searchBefore(time); + var value = this._initial; + //if it was set by + if (before === null) { + value = this._initial; + } else if (before.type === Tone.TimelineSignal.Type.Target) { + var previous = this._events.getBefore(before.time); + var previouVal; + if (previous === null) { + previouVal = this._initial; + } else { + previouVal = previous.value; + } + value = this._exponentialApproach(before.time, previouVal, before.value, before.constant, time); + } else if (before.type === Tone.TimelineSignal.Type.Curve) { + value = this._curveInterpolate(before.time, before.value, before.duration, time); + } else if (after === null) { + value = before.value; + } else if (after.type === Tone.TimelineSignal.Type.Linear) { + value = this._linearInterpolate(before.time, before.value, after.time, after.value, time); + } else if (after.type === Tone.TimelineSignal.Type.Exponential) { + value = this._exponentialInterpolate(before.time, before.value, after.time, after.value, time); + } else { + value = before.value; + } + return value; + }; + /** + * When signals connect to other signals or AudioParams, + * they take over the output value of that signal or AudioParam. + * For all other nodes, the behavior is the same as a default connect. + * + * @override + * @param {AudioParam|AudioNode|Tone.Signal|Tone} node + * @param {number} [outputNumber=0] The output number to connect from. + * @param {number} [inputNumber=0] The input number to connect to. + * @returns {Tone.TimelineSignal} this + * @method + */ + Tone.TimelineSignal.prototype.connect = Tone.SignalBase.prototype.connect; + /////////////////////////////////////////////////////////////////////////// + // AUTOMATION CURVE CALCULATIONS + // MIT License, copyright (c) 2014 Jordan Santell + /////////////////////////////////////////////////////////////////////////// + /** + * Calculates the the value along the curve produced by setTargetAtTime + * @private + */ + Tone.TimelineSignal.prototype._exponentialApproach = function (t0, v0, v1, timeConstant, t) { + return v1 + (v0 - v1) * Math.exp(-(t - t0) / timeConstant); + }; + /** + * Calculates the the value along the curve produced by linearRampToValueAtTime + * @private + */ + Tone.TimelineSignal.prototype._linearInterpolate = function (t0, v0, t1, v1, t) { + return v0 + (v1 - v0) * ((t - t0) / (t1 - t0)); + }; + /** + * Calculates the the value along the curve produced by exponentialRampToValueAtTime + * @private + */ + Tone.TimelineSignal.prototype._exponentialInterpolate = function (t0, v0, t1, v1, t) { + v0 = Math.max(this._minOutput, v0); + return v0 * Math.pow(v1 / v0, (t - t0) / (t1 - t0)); + }; + /** + * Calculates the the value along the curve produced by setValueCurveAtTime + * @private + */ + Tone.TimelineSignal.prototype._curveInterpolate = function (start, curve, duration, time) { + var len = curve.length; + // If time is after duration, return the last curve value + if (time >= start + duration) { + return curve[len - 1]; + } else if (time <= start) { + return curve[0]; + } else { + var progress = (time - start) / duration; + var lowerIndex = Math.floor((len - 1) * progress); + var upperIndex = Math.ceil((len - 1) * progress); + var lowerVal = curve[lowerIndex]; + var upperVal = curve[upperIndex]; + if (upperIndex === lowerIndex) { + return lowerVal; + } else { + return this._linearInterpolate(lowerIndex, lowerVal, upperIndex, upperVal, progress * (len - 1)); + } + } + }; + /** + * Clean up. + * @return {Tone.TimelineSignal} this + */ + Tone.TimelineSignal.prototype.dispose = function () { + Tone.Signal.prototype.dispose.call(this); + Tone.Param.prototype.dispose.call(this); + this._events.dispose(); + this._events = null; + }; + return Tone.TimelineSignal; + }); + Module(function (Tone) { + + /** + * @class Pow applies an exponent to the incoming signal. The incoming signal + * must be AudioRange. + * + * @extends {Tone.SignalBase} + * @constructor + * @param {Positive} exp The exponent to apply to the incoming signal, must be at least 2. + * @example + * var pow = new Tone.Pow(2); + * var sig = new Tone.Signal(0.5).connect(pow); + * //output of pow is 0.25. + */ + Tone.Pow = function (exp) { + /** + * the exponent + * @private + * @type {number} + */ + this._exp = this.defaultArg(exp, 1); + /** + * @type {WaveShaperNode} + * @private + */ + this._expScaler = this.input = this.output = new Tone.WaveShaper(this._expFunc(this._exp), 8192); + }; + Tone.extend(Tone.Pow, Tone.SignalBase); + /** + * The value of the exponent. + * @memberOf Tone.Pow# + * @type {number} + * @name value + */ + Object.defineProperty(Tone.Pow.prototype, 'value', { + get: function () { + return this._exp; + }, + set: function (exp) { + this._exp = exp; + this._expScaler.setMap(this._expFunc(this._exp)); + } + }); + /** + * the function which maps the waveshaper + * @param {number} exp + * @return {function} + * @private + */ + Tone.Pow.prototype._expFunc = function (exp) { + return function (val) { + return Math.pow(Math.abs(val), exp); + }; + }; + /** + * Clean up. + * @returns {Tone.Pow} this + */ + Tone.Pow.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._expScaler.dispose(); + this._expScaler = null; + return this; + }; + return Tone.Pow; + }); + Module(function (Tone) { + + /** + * @class Tone.Envelope is an [ADSR](https://en.wikipedia.org/wiki/Synthesizer#ADSR_envelope) + * envelope generator. Tone.Envelope outputs a signal which + * can be connected to an AudioParam or Tone.Signal. + * + * + * @constructor + * @extends {Tone} + * @param {Time} [attack] The amount of time it takes for the envelope to go from + * 0 to it's maximum value. + * @param {Time} [decay] The period of time after the attack that it takes for the envelope + * to fall to the sustain value. + * @param {NormalRange} [sustain] The percent of the maximum value that the envelope rests at until + * the release is triggered. + * @param {Time} [release] The amount of time after the release is triggered it takes to reach 0. + * @example + * //an amplitude envelope + * var gainNode = Tone.context.createGain(); + * var env = new Tone.Envelope({ + * "attack" : 0.1, + * "decay" : 0.2, + * "sustain" : 1, + * "release" : 0.8, + * }); + * env.connect(gainNode.gain); + */ + Tone.Envelope = function () { + //get all of the defaults + var options = this.optionsObject(arguments, [ + 'attack', + 'decay', + 'sustain', + 'release' + ], Tone.Envelope.defaults); + /** + * When triggerAttack is called, the attack time is the amount of + * time it takes for the envelope to reach it's maximum value. + * @type {Time} + */ + this.attack = options.attack; + /** + * After the attack portion of the envelope, the value will fall + * over the duration of the decay time to it's sustain value. + * @type {Time} + */ + this.decay = options.decay; + /** + * The sustain value is the value + * which the envelope rests at after triggerAttack is + * called, but before triggerRelease is invoked. + * @type {NormalRange} + */ + this.sustain = options.sustain; + /** + * After triggerRelease is called, the envelope's + * value will fall to it's miminum value over the + * duration of the release time. + * @type {Time} + */ + this.release = options.release; + /** + * the next time the envelope is at standby + * @type {number} + * @private + */ + this._attackCurve = 'linear'; + /** + * the next time the envelope is at standby + * @type {number} + * @private + */ + this._releaseCurve = 'exponential'; + /** + * the signal + * @type {Tone.TimelineSignal} + * @private + */ + this._sig = this.output = new Tone.TimelineSignal(); + this._sig.setValueAtTime(0, 0); + //set the attackCurve initially + this.attackCurve = options.attackCurve; + this.releaseCurve = options.releaseCurve; + }; + Tone.extend(Tone.Envelope); + /** + * the default parameters + * @static + * @const + */ + Tone.Envelope.defaults = { + 'attack': 0.01, + 'decay': 0.1, + 'sustain': 0.5, + 'release': 1, + 'attackCurve': 'linear', + 'releaseCurve': 'exponential' + }; + /** + * Read the current value of the envelope. Useful for + * syncronizing visual output to the envelope. + * @memberOf Tone.Envelope# + * @type {Number} + * @name value + * @readOnly + */ + Object.defineProperty(Tone.Envelope.prototype, 'value', { + get: function () { + return this.getValueAtTime(this.now()); + } + }); + /** + * The shape of the attack. + * Can be any of these strings: + *
    + *
  • linear
  • + *
  • exponential
  • + *
  • sine
  • + *
  • cosine
  • + *
  • bounce
  • + *
  • ripple
  • + *
  • step
  • + *
+ * Can also be an array which describes the curve. Values + * in the array are evenly subdivided and linearly + * interpolated over the duration of the attack. + * @memberOf Tone.Envelope# + * @type {String|Array} + * @name attackCurve + * @example + * env.attackCurve = "linear"; + * @example + * //can also be an array + * env.attackCurve = [0, 0.2, 0.3, 0.4, 1] + */ + Object.defineProperty(Tone.Envelope.prototype, 'attackCurve', { + get: function () { + if (this.isString(this._attackCurve)) { + return this._attackCurve; + } else if (this.isArray(this._attackCurve)) { + //look up the name in the curves array + for (var type in Tone.Envelope.Type) { + if (Tone.Envelope.Type[type].In === this._attackCurve) { + return type; + } + } + //otherwise just return the array + return this._attackCurve; + } + }, + set: function (curve) { + //check if it's a valid type + if (Tone.Envelope.Type.hasOwnProperty(curve)) { + var curveDef = Tone.Envelope.Type[curve]; + if (this.isObject(curveDef)) { + this._attackCurve = curveDef.In; + } else { + this._attackCurve = curveDef; + } + } else if (this.isArray(curve)) { + this._attackCurve = curve; + } else { + throw new Error('Tone.Envelope: invalid curve: ' + curve); + } + } + }); + /** + * The shape of the release. See the attack curve types. + * @memberOf Tone.Envelope# + * @type {String|Array} + * @name releaseCurve + * @example + * env.releaseCurve = "linear"; + */ + Object.defineProperty(Tone.Envelope.prototype, 'releaseCurve', { + get: function () { + if (this.isString(this._releaseCurve)) { + return this._releaseCurve; + } else if (this.isArray(this._releaseCurve)) { + //look up the name in the curves array + for (var type in Tone.Envelope.Type) { + if (Tone.Envelope.Type[type].Out === this._releaseCurve) { + return type; + } + } + //otherwise just return the array + return this._releaseCurve; + } + }, + set: function (curve) { + //check if it's a valid type + if (Tone.Envelope.Type.hasOwnProperty(curve)) { + var curveDef = Tone.Envelope.Type[curve]; + if (this.isObject(curveDef)) { + this._releaseCurve = curveDef.Out; + } else { + this._releaseCurve = curveDef; + } + } else if (this.isArray(curve)) { + this._releaseCurve = curve; + } else { + throw new Error('Tone.Envelope: invalid curve: ' + curve); + } + } + }); + /** + * Trigger the attack/decay portion of the ADSR envelope. + * @param {Time} [time=now] When the attack should start. + * @param {NormalRange} [velocity=1] The velocity of the envelope scales the vales. + * number between 0-1 + * @returns {Tone.Envelope} this + * @example + * //trigger the attack 0.5 seconds from now with a velocity of 0.2 + * env.triggerAttack("+0.5", 0.2); + */ + Tone.Envelope.prototype.triggerAttack = function (time, velocity) { + time = this.toSeconds(time); + var originalAttack = this.toSeconds(this.attack); + var attack = originalAttack; + var decay = this.toSeconds(this.decay); + velocity = this.defaultArg(velocity, 1); + //check if it's not a complete attack + var currentValue = this.getValueAtTime(time); + if (currentValue > 0) { + //subtract the current value from the attack time + var attackRate = 1 / attack; + var remainingDistance = 1 - currentValue; + //the attack is now the remaining time + attack = remainingDistance / attackRate; + } + //attack + if (this._attackCurve === 'linear') { + this._sig.linearRampToValue(velocity, attack, time); + } else if (this._attackCurve === 'exponential') { + this._sig.exponentialRampToValue(velocity, attack, time); + } else if (attack > 0) { + this._sig.setRampPoint(time); + var curve = this._attackCurve; + //take only a portion of the curve + if (attack < originalAttack) { + var percentComplete = 1 - attack / originalAttack; + var sliceIndex = Math.floor(percentComplete * this._attackCurve.length); + curve = this._attackCurve.slice(sliceIndex); + //the first index is the current value + curve[0] = currentValue; + } + this._sig.setValueCurveAtTime(curve, time, attack, velocity); + } + //decay + this._sig.exponentialRampToValue(velocity * this.sustain, decay, attack + time); + return this; + }; + /** + * Triggers the release of the envelope. + * @param {Time} [time=now] When the release portion of the envelope should start. + * @returns {Tone.Envelope} this + * @example + * //trigger release immediately + * env.triggerRelease(); + */ + Tone.Envelope.prototype.triggerRelease = function (time) { + time = this.toSeconds(time); + var currentValue = this.getValueAtTime(time); + if (currentValue > 0) { + var release = this.toSeconds(this.release); + if (this._releaseCurve === 'linear') { + this._sig.linearRampToValue(0, release, time); + } else if (this._releaseCurve === 'exponential') { + this._sig.exponentialRampToValue(0, release, time); + } else { + var curve = this._releaseCurve; + if (this.isArray(curve)) { + this._sig.setRampPoint(time); + this._sig.setValueCurveAtTime(curve, time, release, currentValue); + } + } + } + return this; + }; + /** + * Get the scheduled value at the given time. This will + * return the unconverted (raw) value. + * @param {Number} time The time in seconds. + * @return {Number} The scheduled value at the given time. + */ + Tone.Envelope.prototype.getValueAtTime = function (time) { + return this._sig.getValueAtTime(time); + }; + /** + * triggerAttackRelease is shorthand for triggerAttack, then waiting + * some duration, then triggerRelease. + * @param {Time} duration The duration of the sustain. + * @param {Time} [time=now] When the attack should be triggered. + * @param {number} [velocity=1] The velocity of the envelope. + * @returns {Tone.Envelope} this + * @example + * //trigger the attack and then the release after 0.6 seconds. + * env.triggerAttackRelease(0.6); + */ + Tone.Envelope.prototype.triggerAttackRelease = function (duration, time, velocity) { + time = this.toSeconds(time); + this.triggerAttack(time, velocity); + this.triggerRelease(time + this.toSeconds(duration)); + return this; + }; + /** + * Cancels all scheduled envelope changes after the given time. + * @param {Time} after + * @returns {Tone.Envelope} this + */ + Tone.Envelope.prototype.cancel = function (after) { + this._sig.cancelScheduledValues(after); + return this; + }; + /** + * Borrows the connect method from Tone.Signal. + * @function + * @private + */ + Tone.Envelope.prototype.connect = Tone.Signal.prototype.connect; + /** + * Generate some complex envelope curves. + */ + (function _createCurves() { + var curveLen = 128; + var i, k; + //cosine curve + var cosineCurve = []; + for (i = 0; i < curveLen; i++) { + cosineCurve[i] = Math.sin(i / (curveLen - 1) * (Math.PI / 2)); + } + //ripple curve + var rippleCurve = []; + var rippleCurveFreq = 6.4; + for (i = 0; i < curveLen - 1; i++) { + k = i / (curveLen - 1); + var sineWave = Math.sin(k * (Math.PI * 2) * rippleCurveFreq - Math.PI / 2) + 1; + rippleCurve[i] = sineWave / 10 + k * 0.83; + } + rippleCurve[curveLen - 1] = 1; + //stairs curve + var stairsCurve = []; + var steps = 5; + for (i = 0; i < curveLen; i++) { + stairsCurve[i] = Math.ceil(i / (curveLen - 1) * steps) / steps; + } + //in-out easing curve + var sineCurve = []; + for (i = 0; i < curveLen; i++) { + k = i / (curveLen - 1); + sineCurve[i] = 0.5 * (1 - Math.cos(Math.PI * k)); + } + //a bounce curve + var bounceCurve = []; + for (i = 0; i < curveLen; i++) { + k = i / (curveLen - 1); + var freq = Math.pow(k, 3) * 4 + 0.2; + var val = Math.cos(freq * Math.PI * 2 * k); + bounceCurve[i] = Math.abs(val * (1 - k)); + } + /** + * Invert a value curve to make it work for the release + * @private + */ + function invertCurve(curve) { + var out = new Array(curve.length); + for (var j = 0; j < curve.length; j++) { + out[j] = 1 - curve[j]; + } + return out; + } + /** + * reverse the curve + * @private + */ + function reverseCurve(curve) { + return curve.slice(0).reverse(); + } + /** + * attack and release curve arrays + * @type {Object} + * @private + */ + Tone.Envelope.Type = { + 'linear': 'linear', + 'exponential': 'exponential', + 'bounce': { + In: invertCurve(bounceCurve), + Out: bounceCurve + }, + 'cosine': { + In: cosineCurve, + Out: reverseCurve(cosineCurve) + }, + 'step': { + In: stairsCurve, + Out: invertCurve(stairsCurve) + }, + 'ripple': { + In: rippleCurve, + Out: invertCurve(rippleCurve) + }, + 'sine': { + In: sineCurve, + Out: invertCurve(sineCurve) + } + }; + }()); + /** + * Disconnect and dispose. + * @returns {Tone.Envelope} this + */ + Tone.Envelope.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._sig.dispose(); + this._sig = null; + this._attackCurve = null; + this._releaseCurve = null; + return this; + }; + return Tone.Envelope; + }); + Module(function (Tone) { + + /** + * @class Tone.AmplitudeEnvelope is a Tone.Envelope connected to a gain node. + * Unlike Tone.Envelope, which outputs the envelope's value, Tone.AmplitudeEnvelope accepts + * an audio signal as the input and will apply the envelope to the amplitude + * of the signal. Read more about ADSR Envelopes on [Wikipedia](https://en.wikipedia.org/wiki/Synthesizer#ADSR_envelope). + * + * @constructor + * @extends {Tone.Envelope} + * @param {Time|Object} [attack] The amount of time it takes for the envelope to go from + * 0 to it's maximum value. + * @param {Time} [decay] The period of time after the attack that it takes for the envelope + * to fall to the sustain value. + * @param {NormalRange} [sustain] The percent of the maximum value that the envelope rests at until + * the release is triggered. + * @param {Time} [release] The amount of time after the release is triggered it takes to reach 0. + * @example + * var ampEnv = new Tone.AmplitudeEnvelope({ + * "attack": 0.1, + * "decay": 0.2, + * "sustain": 1.0, + * "release": 0.8 + * }).toMaster(); + * //create an oscillator and connect it + * var osc = new Tone.Oscillator().connect(ampEnv).start(); + * //trigger the envelopes attack and release "8t" apart + * ampEnv.triggerAttackRelease("8t"); + */ + Tone.AmplitudeEnvelope = function () { + Tone.Envelope.apply(this, arguments); + /** + * the input node + * @type {GainNode} + * @private + */ + this.input = this.output = new Tone.Gain(); + this._sig.connect(this.output.gain); + }; + Tone.extend(Tone.AmplitudeEnvelope, Tone.Envelope); + /** + * Clean up + * @return {Tone.AmplitudeEnvelope} this + */ + Tone.AmplitudeEnvelope.prototype.dispose = function () { + this.input.dispose(); + this.input = null; + Tone.Envelope.prototype.dispose.call(this); + return this; + }; + return Tone.AmplitudeEnvelope; + }); + Module(function (Tone) { + + /** + * @class Wrapper around the native Web Audio's + * [AnalyserNode](http://webaudio.github.io/web-audio-api/#idl-def-AnalyserNode). + * Extracts FFT or Waveform data from the incoming signal. + * @extends {Tone} + * @param {String=} type The return type of the analysis, either "fft", or "waveform". + * @param {Number=} size The size of the FFT. Value must be a power of + * two in the range 32 to 32768. + */ + Tone.Analyser = function () { + var options = this.optionsObject(arguments, [ + 'type', + 'size' + ], Tone.Analyser.defaults); + /** + * The analyser node. + * @private + * @type {AnalyserNode} + */ + this._analyser = this.input = this.output = this.context.createAnalyser(); + /** + * The analysis type + * @type {String} + * @private + */ + this._type = options.type; + /** + * The return type of the analysis + * @type {String} + * @private + */ + this._returnType = options.returnType; + /** + * The buffer that the FFT data is written to + * @type {TypedArray} + * @private + */ + this._buffer = null; + //set the values initially + this.size = options.size; + this.type = options.type; + this.returnType = options.returnType; + this.minDecibels = options.minDecibels; + this.maxDecibels = options.maxDecibels; + }; + Tone.extend(Tone.Analyser); + /** + * The default values. + * @type {Object} + * @const + */ + Tone.Analyser.defaults = { + 'size': 1024, + 'returnType': 'byte', + 'type': 'fft', + 'smoothing': 0.8, + 'maxDecibels': -30, + 'minDecibels': -100 + }; + /** + * Possible return types of Tone.Analyser.analyse() + * @enum {String} + */ + Tone.Analyser.Type = { + Waveform: 'waveform', + FFT: 'fft' + }; + /** + * Possible return types of Tone.Analyser.analyse(). + * byte values are between [0,255]. float values are between + * [-1, 1] when the type is set to "waveform" and between + * [minDecibels,maxDecibels] when the type is "fft". + * @enum {String} + */ + Tone.Analyser.ReturnType = { + Byte: 'byte', + Float: 'float' + }; + /** + * Run the analysis given the current settings and return the + * result as a TypedArray. + * @returns {TypedArray} + */ + Tone.Analyser.prototype.analyse = function () { + if (this._type === Tone.Analyser.Type.FFT) { + if (this._returnType === Tone.Analyser.ReturnType.Byte) { + this._analyser.getByteFrequencyData(this._buffer); + } else { + this._analyser.getFloatFrequencyData(this._buffer); + } + } else if (this._type === Tone.Analyser.Type.Waveform) { + if (this._returnType === Tone.Analyser.ReturnType.Byte) { + this._analyser.getByteTimeDomainData(this._buffer); + } else { + if (this.isFunction(AnalyserNode.prototype.getFloatTimeDomainData)) { + this._analyser.getFloatTimeDomainData(this._buffer); + } else { + var uint8 = new Uint8Array(this._buffer.length); + this._analyser.getByteTimeDomainData(uint8); + //referenced https://github.com/mohayonao/get-float-time-domain-data + // POLYFILL + for (var i = 0; i < uint8.length; i++) { + this._buffer[i] = (uint8[i] - 128) * 0.0078125; + } + } + } + } + return this._buffer; + }; + /** + * The size of analysis. This must be a power of two in the range 32 to 32768. + * @memberOf Tone.Analyser# + * @type {Number} + * @name size + */ + Object.defineProperty(Tone.Analyser.prototype, 'size', { + get: function () { + return this._analyser.frequencyBinCount; + }, + set: function (size) { + this._analyser.fftSize = size * 2; + this.type = this._type; + } + }); + /** + * The return type of Tone.Analyser.analyse(), either "byte" or "float". + * When the type is set to "byte" the range of values returned in the array + * are between 0-255. "float" values are between + * [-1, 1] when the type is set to "waveform" and between + * [minDecibels,maxDecibels] when the type is "fft". + * @memberOf Tone.Analyser# + * @type {String} + * @name type + */ + Object.defineProperty(Tone.Analyser.prototype, 'returnType', { + get: function () { + return this._returnType; + }, + set: function (type) { + if (type === Tone.Analyser.ReturnType.Byte) { + this._buffer = new Uint8Array(this._analyser.frequencyBinCount); + } else if (type === Tone.Analyser.ReturnType.Float) { + this._buffer = new Float32Array(this._analyser.frequencyBinCount); + } else { + throw new TypeError('Tone.Analayser: invalid return type: ' + type); + } + this._returnType = type; + } + }); + /** + * The analysis function returned by Tone.Analyser.analyse(), either "fft" or "waveform". + * @memberOf Tone.Analyser# + * @type {String} + * @name type + */ + Object.defineProperty(Tone.Analyser.prototype, 'type', { + get: function () { + return this._type; + }, + set: function (type) { + if (type !== Tone.Analyser.Type.Waveform && type !== Tone.Analyser.Type.FFT) { + throw new TypeError('Tone.Analyser: invalid type: ' + type); + } + this._type = type; + } + }); + /** + * 0 represents no time averaging with the last analysis frame. + * @memberOf Tone.Analyser# + * @type {NormalRange} + * @name smoothing + */ + Object.defineProperty(Tone.Analyser.prototype, 'smoothing', { + get: function () { + return this._analyser.smoothingTimeConstant; + }, + set: function (val) { + this._analyser.smoothingTimeConstant = val; + } + }); + /** + * The smallest decibel value which is analysed by the FFT. + * @memberOf Tone.Analyser# + * @type {Decibels} + * @name minDecibels + */ + Object.defineProperty(Tone.Analyser.prototype, 'minDecibels', { + get: function () { + return this._analyser.minDecibels; + }, + set: function (val) { + this._analyser.minDecibels = val; + } + }); + /** + * The largest decibel value which is analysed by the FFT. + * @memberOf Tone.Analyser# + * @type {Decibels} + * @name maxDecibels + */ + Object.defineProperty(Tone.Analyser.prototype, 'maxDecibels', { + get: function () { + return this._analyser.maxDecibels; + }, + set: function (val) { + this._analyser.maxDecibels = val; + } + }); + /** + * Clean up. + * @return {Tone.Analyser} this + */ + Tone.Analyser.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._analyser.disconnect(); + this._analyser = null; + this._buffer = null; + }; + return Tone.Analyser; + }); + Module(function (Tone) { + + /** + * @class Tone.Compressor is a thin wrapper around the Web Audio + * [DynamicsCompressorNode](http://webaudio.github.io/web-audio-api/#the-dynamicscompressornode-interface). + * Compression reduces the volume of loud sounds or amplifies quiet sounds + * by narrowing or "compressing" an audio signal's dynamic range. + * Read more on [Wikipedia](https://en.wikipedia.org/wiki/Dynamic_range_compression). + * + * @extends {Tone} + * @constructor + * @param {Decibels|Object} [threshold] The value above which the compression starts to be applied. + * @param {Positive} [ratio] The gain reduction ratio. + * @example + * var comp = new Tone.Compressor(-30, 3); + */ + Tone.Compressor = function () { + var options = this.optionsObject(arguments, [ + 'threshold', + 'ratio' + ], Tone.Compressor.defaults); + /** + * the compressor node + * @type {DynamicsCompressorNode} + * @private + */ + this._compressor = this.input = this.output = this.context.createDynamicsCompressor(); + /** + * the threshold vaue + * @type {Decibels} + * @signal + */ + this.threshold = new Tone.Param({ + 'param': this._compressor.threshold, + 'units': Tone.Type.Decibels, + 'convert': false + }); + /** + * The attack parameter + * @type {Time} + * @signal + */ + this.attack = new Tone.Param(this._compressor.attack, Tone.Type.Time); + /** + * The release parameter + * @type {Time} + * @signal + */ + this.release = new Tone.Param(this._compressor.release, Tone.Type.Time); + /** + * The knee parameter + * @type {Decibels} + * @signal + */ + this.knee = new Tone.Param({ + 'param': this._compressor.knee, + 'units': Tone.Type.Decibels, + 'convert': false + }); + /** + * The ratio value + * @type {Number} + * @signal + */ + this.ratio = new Tone.Param({ + 'param': this._compressor.ratio, + 'convert': false + }); + //set the defaults + this._readOnly([ + 'knee', + 'release', + 'attack', + 'ratio', + 'threshold' + ]); + this.set(options); + }; + Tone.extend(Tone.Compressor); + /** + * @static + * @const + * @type {Object} + */ + Tone.Compressor.defaults = { + 'ratio': 12, + 'threshold': -24, + 'release': 0.25, + 'attack': 0.003, + 'knee': 30 + }; + /** + * clean up + * @returns {Tone.Compressor} this + */ + Tone.Compressor.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._writable([ + 'knee', + 'release', + 'attack', + 'ratio', + 'threshold' + ]); + this._compressor.disconnect(); + this._compressor = null; + this.attack.dispose(); + this.attack = null; + this.release.dispose(); + this.release = null; + this.threshold.dispose(); + this.threshold = null; + this.ratio.dispose(); + this.ratio = null; + this.knee.dispose(); + this.knee = null; + return this; + }; + return Tone.Compressor; + }); + Module(function (Tone) { + + /** + * @class Add a signal and a number or two signals. When no value is + * passed into the constructor, Tone.Add will sum input[0] + * and input[1]. If a value is passed into the constructor, + * the it will be added to the input. + * + * @constructor + * @extends {Tone.Signal} + * @param {number=} value If no value is provided, Tone.Add will sum the first + * and second inputs. + * @example + * var signal = new Tone.Signal(2); + * var add = new Tone.Add(2); + * signal.connect(add); + * //the output of add equals 4 + * @example + * //if constructed with no arguments + * //it will add the first and second inputs + * var add = new Tone.Add(); + * var sig0 = new Tone.Signal(3).connect(add, 0, 0); + * var sig1 = new Tone.Signal(4).connect(add, 0, 1); + * //the output of add equals 7. + */ + Tone.Add = function (value) { + this.createInsOuts(2, 0); + /** + * the summing node + * @type {GainNode} + * @private + */ + this._sum = this.input[0] = this.input[1] = this.output = new Tone.Gain(); + /** + * @private + * @type {Tone.Signal} + */ + this._param = this.input[1] = new Tone.Signal(value); + this._param.connect(this._sum); + }; + Tone.extend(Tone.Add, Tone.Signal); + /** + * Clean up. + * @returns {Tone.Add} this + */ + Tone.Add.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._sum.dispose(); + this._sum = null; + this._param.dispose(); + this._param = null; + return this; + }; + return Tone.Add; + }); + Module(function (Tone) { + + /** + * @class Multiply two incoming signals. Or, if a number is given in the constructor, + * multiplies the incoming signal by that value. + * + * @constructor + * @extends {Tone.Signal} + * @param {number=} value Constant value to multiple. If no value is provided, + * it will return the product of the first and second inputs + * @example + * var mult = new Tone.Multiply(); + * var sigA = new Tone.Signal(3); + * var sigB = new Tone.Signal(4); + * sigA.connect(mult, 0, 0); + * sigB.connect(mult, 0, 1); + * //output of mult is 12. + * @example + * var mult = new Tone.Multiply(10); + * var sig = new Tone.Signal(2).connect(mult); + * //the output of mult is 20. + */ + Tone.Multiply = function (value) { + this.createInsOuts(2, 0); + /** + * the input node is the same as the output node + * it is also the GainNode which handles the scaling of incoming signal + * + * @type {GainNode} + * @private + */ + this._mult = this.input[0] = this.output = new Tone.Gain(); + /** + * the scaling parameter + * @type {AudioParam} + * @private + */ + this._param = this.input[1] = this.output.gain; + this._param.value = this.defaultArg(value, 0); + }; + Tone.extend(Tone.Multiply, Tone.Signal); + /** + * clean up + * @returns {Tone.Multiply} this + */ + Tone.Multiply.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._mult.dispose(); + this._mult = null; + this._param = null; + return this; + }; + return Tone.Multiply; + }); + Module(function (Tone) { + + /** + * @class Negate the incoming signal. i.e. an input signal of 10 will output -10 + * + * @constructor + * @extends {Tone.SignalBase} + * @example + * var neg = new Tone.Negate(); + * var sig = new Tone.Signal(-2).connect(neg); + * //output of neg is positive 2. + */ + Tone.Negate = function () { + /** + * negation is done by multiplying by -1 + * @type {Tone.Multiply} + * @private + */ + this._multiply = this.input = this.output = new Tone.Multiply(-1); + }; + Tone.extend(Tone.Negate, Tone.SignalBase); + /** + * clean up + * @returns {Tone.Negate} this + */ + Tone.Negate.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._multiply.dispose(); + this._multiply = null; + return this; + }; + return Tone.Negate; + }); + Module(function (Tone) { + + /** + * @class Subtract the signal connected to input[1] from the signal connected + * to input[0]. If an argument is provided in the constructor, the + * signals .value will be subtracted from the incoming signal. + * + * @extends {Tone.Signal} + * @constructor + * @param {number=} value The value to subtract from the incoming signal. If the value + * is omitted, it will subtract the second signal from the first. + * @example + * var sub = new Tone.Subtract(1); + * var sig = new Tone.Signal(4).connect(sub); + * //the output of sub is 3. + * @example + * var sub = new Tone.Subtract(); + * var sigA = new Tone.Signal(10); + * var sigB = new Tone.Signal(2.5); + * sigA.connect(sub, 0, 0); + * sigB.connect(sub, 0, 1); + * //output of sub is 7.5 + */ + Tone.Subtract = function (value) { + this.createInsOuts(2, 0); + /** + * the summing node + * @type {GainNode} + * @private + */ + this._sum = this.input[0] = this.output = new Tone.Gain(); + /** + * negate the input of the second input before connecting it + * to the summing node. + * @type {Tone.Negate} + * @private + */ + this._neg = new Tone.Negate(); + /** + * the node where the value is set + * @private + * @type {Tone.Signal} + */ + this._param = this.input[1] = new Tone.Signal(value); + this._param.chain(this._neg, this._sum); + }; + Tone.extend(Tone.Subtract, Tone.Signal); + /** + * Clean up. + * @returns {Tone.SignalBase} this + */ + Tone.Subtract.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._neg.dispose(); + this._neg = null; + this._sum.disconnect(); + this._sum = null; + this._param.dispose(); + this._param = null; + return this; + }; + return Tone.Subtract; + }); + Module(function (Tone) { + + /** + * @class GreaterThanZero outputs 1 when the input is strictly greater than zero + * + * @constructor + * @extends {Tone.SignalBase} + * @example + * var gt0 = new Tone.GreaterThanZero(); + * var sig = new Tone.Signal(0.01).connect(gt0); + * //the output of gt0 is 1. + * sig.value = 0; + * //the output of gt0 is 0. + */ + Tone.GreaterThanZero = function () { + /** + * @type {Tone.WaveShaper} + * @private + */ + this._thresh = this.output = new Tone.WaveShaper(function (val) { + if (val <= 0) { + return 0; + } else { + return 1; + } + }, 127); + /** + * scale the first thresholded signal by a large value. + * this will help with values which are very close to 0 + * @type {Tone.Multiply} + * @private + */ + this._scale = this.input = new Tone.Multiply(10000); + //connections + this._scale.connect(this._thresh); + }; + Tone.extend(Tone.GreaterThanZero, Tone.SignalBase); + /** + * dispose method + * @returns {Tone.GreaterThanZero} this + */ + Tone.GreaterThanZero.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._scale.dispose(); + this._scale = null; + this._thresh.dispose(); + this._thresh = null; + return this; + }; + return Tone.GreaterThanZero; + }); + Module(function (Tone) { + + /** + * @class Output 1 if the signal is greater than the value, otherwise outputs 0. + * can compare two signals or a signal and a number. + * + * @constructor + * @extends {Tone.Signal} + * @param {number} [value=0] the value to compare to the incoming signal + * @example + * var gt = new Tone.GreaterThan(2); + * var sig = new Tone.Signal(4).connect(gt); + * //output of gt is equal 1. + */ + Tone.GreaterThan = function (value) { + this.createInsOuts(2, 0); + /** + * subtract the amount from the incoming signal + * @type {Tone.Subtract} + * @private + */ + this._param = this.input[0] = new Tone.Subtract(value); + this.input[1] = this._param.input[1]; + /** + * compare that amount to zero + * @type {Tone.GreaterThanZero} + * @private + */ + this._gtz = this.output = new Tone.GreaterThanZero(); + //connect + this._param.connect(this._gtz); + }; + Tone.extend(Tone.GreaterThan, Tone.Signal); + /** + * dispose method + * @returns {Tone.GreaterThan} this + */ + Tone.GreaterThan.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._param.dispose(); + this._param = null; + this._gtz.dispose(); + this._gtz = null; + return this; + }; + return Tone.GreaterThan; + }); + Module(function (Tone) { + + /** + * @class Return the absolute value of an incoming signal. + * + * @constructor + * @extends {Tone.SignalBase} + * @example + * var signal = new Tone.Signal(-1); + * var abs = new Tone.Abs(); + * signal.connect(abs); + * //the output of abs is 1. + */ + Tone.Abs = function () { + /** + * @type {Tone.LessThan} + * @private + */ + this._abs = this.input = this.output = new Tone.WaveShaper(function (val) { + if (val === 0) { + return 0; + } else { + return Math.abs(val); + } + }, 127); + }; + Tone.extend(Tone.Abs, Tone.SignalBase); + /** + * dispose method + * @returns {Tone.Abs} this + */ + Tone.Abs.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._abs.dispose(); + this._abs = null; + return this; + }; + return Tone.Abs; + }); + Module(function (Tone) { + + /** + * @class Signal-rate modulo operator. Only works in AudioRange [-1, 1] and for modulus + * values in the NormalRange. + * + * @constructor + * @extends {Tone.SignalBase} + * @param {NormalRange} modulus The modulus to apply. + * @example + * var mod = new Tone.Modulo(0.2) + * var sig = new Tone.Signal(0.5).connect(mod); + * //mod outputs 0.1 + */ + Tone.Modulo = function (modulus) { + this.createInsOuts(1, 0); + /** + * A waveshaper gets the integer multiple of + * the input signal and the modulus. + * @private + * @type {Tone.WaveShaper} + */ + this._shaper = new Tone.WaveShaper(Math.pow(2, 16)); + /** + * the integer multiple is multiplied by the modulus + * @type {Tone.Multiply} + * @private + */ + this._multiply = new Tone.Multiply(); + /** + * and subtracted from the input signal + * @type {Tone.Subtract} + * @private + */ + this._subtract = this.output = new Tone.Subtract(); + /** + * the modulus signal + * @type {Tone.Signal} + * @private + */ + this._modSignal = new Tone.Signal(modulus); + //connections + this.input.fan(this._shaper, this._subtract); + this._modSignal.connect(this._multiply, 0, 0); + this._shaper.connect(this._multiply, 0, 1); + this._multiply.connect(this._subtract, 0, 1); + this._setWaveShaper(modulus); + }; + Tone.extend(Tone.Modulo, Tone.SignalBase); + /** + * @param {number} mod the modulus to apply + * @private + */ + Tone.Modulo.prototype._setWaveShaper = function (mod) { + this._shaper.setMap(function (val) { + var multiple = Math.floor((val + 0.0001) / mod); + return multiple; + }); + }; + /** + * The modulus value. + * @memberOf Tone.Modulo# + * @type {NormalRange} + * @name value + */ + Object.defineProperty(Tone.Modulo.prototype, 'value', { + get: function () { + return this._modSignal.value; + }, + set: function (mod) { + this._modSignal.value = mod; + this._setWaveShaper(mod); + } + }); + /** + * clean up + * @returns {Tone.Modulo} this + */ + Tone.Modulo.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._shaper.dispose(); + this._shaper = null; + this._multiply.dispose(); + this._multiply = null; + this._subtract.dispose(); + this._subtract = null; + this._modSignal.dispose(); + this._modSignal = null; + return this; + }; + return Tone.Modulo; + }); + Module(function (Tone) { + + /** + * @class AudioToGain converts an input in AudioRange [-1,1] to NormalRange [0,1]. + * See Tone.GainToAudio. + * + * @extends {Tone.SignalBase} + * @constructor + * @example + * var a2g = new Tone.AudioToGain(); + */ + Tone.AudioToGain = function () { + /** + * @type {WaveShaperNode} + * @private + */ + this._norm = this.input = this.output = new Tone.WaveShaper(function (x) { + return (x + 1) / 2; + }); + }; + Tone.extend(Tone.AudioToGain, Tone.SignalBase); + /** + * clean up + * @returns {Tone.AudioToGain} this + */ + Tone.AudioToGain.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._norm.dispose(); + this._norm = null; + return this; + }; + return Tone.AudioToGain; + }); + Module(function (Tone) { + + /** + * @class Evaluate an expression at audio rate.

+ * Parsing code modified from https://code.google.com/p/tapdigit/ + * Copyright 2011 2012 Ariya Hidayat, New BSD License + * + * @extends {Tone.SignalBase} + * @constructor + * @param {string} expr the expression to generate + * @example + * //adds the signals from input[0] and input[1]. + * var expr = new Tone.Expr("$0 + $1"); + */ + Tone.Expr = function () { + var expr = this._replacements(Array.prototype.slice.call(arguments)); + var inputCount = this._parseInputs(expr); + /** + * hold onto all of the nodes for disposal + * @type {Array} + * @private + */ + this._nodes = []; + /** + * The inputs. The length is determined by the expression. + * @type {Array} + */ + this.input = new Array(inputCount); + //create a gain for each input + for (var i = 0; i < inputCount; i++) { + this.input[i] = this.context.createGain(); + } + //parse the syntax tree + var tree = this._parseTree(expr); + //evaluate the results + var result; + try { + result = this._eval(tree); + } catch (e) { + this._disposeNodes(); + throw new Error('Tone.Expr: Could evaluate expression: ' + expr); + } + /** + * The output node is the result of the expression + * @type {Tone} + */ + this.output = result; + }; + Tone.extend(Tone.Expr, Tone.SignalBase); + //some helpers to cut down the amount of code + function applyBinary(Constructor, args, self) { + var op = new Constructor(); + self._eval(args[0]).connect(op, 0, 0); + self._eval(args[1]).connect(op, 0, 1); + return op; + } + function applyUnary(Constructor, args, self) { + var op = new Constructor(); + self._eval(args[0]).connect(op, 0, 0); + return op; + } + function getNumber(arg) { + return arg ? parseFloat(arg) : undefined; + } + function literalNumber(arg) { + return arg && arg.args ? parseFloat(arg.args) : undefined; + } + /* + * the Expressions that Tone.Expr can parse. + * + * each expression belongs to a group and contains a regexp + * for selecting the operator as well as that operators method + * + * @type {Object} + * @private + */ + Tone.Expr._Expressions = { + //values + 'value': { + 'signal': { + regexp: /^\d+\.\d+|^\d+/, + method: function (arg) { + var sig = new Tone.Signal(getNumber(arg)); + return sig; + } + }, + 'input': { + regexp: /^\$\d/, + method: function (arg, self) { + return self.input[getNumber(arg.substr(1))]; + } + } + }, + //syntactic glue + 'glue': { + '(': { regexp: /^\(/ }, + ')': { regexp: /^\)/ }, + ',': { regexp: /^,/ } + }, + //functions + 'func': { + 'abs': { + regexp: /^abs/, + method: applyUnary.bind(this, Tone.Abs) + }, + 'mod': { + regexp: /^mod/, + method: function (args, self) { + var modulus = literalNumber(args[1]); + var op = new Tone.Modulo(modulus); + self._eval(args[0]).connect(op); + return op; + } + }, + 'pow': { + regexp: /^pow/, + method: function (args, self) { + var exp = literalNumber(args[1]); + var op = new Tone.Pow(exp); + self._eval(args[0]).connect(op); + return op; + } + }, + 'a2g': { + regexp: /^a2g/, + method: function (args, self) { + var op = new Tone.AudioToGain(); + self._eval(args[0]).connect(op); + return op; + } + } + }, + //binary expressions + 'binary': { + '+': { + regexp: /^\+/, + precedence: 1, + method: applyBinary.bind(this, Tone.Add) + }, + '-': { + regexp: /^\-/, + precedence: 1, + method: function (args, self) { + //both unary and binary op + if (args.length === 1) { + return applyUnary(Tone.Negate, args, self); + } else { + return applyBinary(Tone.Subtract, args, self); + } + } + }, + '*': { + regexp: /^\*/, + precedence: 0, + method: applyBinary.bind(this, Tone.Multiply) + } + }, + //unary expressions + 'unary': { + '-': { + regexp: /^\-/, + method: applyUnary.bind(this, Tone.Negate) + }, + '!': { + regexp: /^\!/, + method: applyUnary.bind(this, Tone.NOT) + } + } + }; + /** + * @param {string} expr the expression string + * @return {number} the input count + * @private + */ + Tone.Expr.prototype._parseInputs = function (expr) { + var inputArray = expr.match(/\$\d/g); + var inputMax = 0; + if (inputArray !== null) { + for (var i = 0; i < inputArray.length; i++) { + var inputNum = parseInt(inputArray[i].substr(1)) + 1; + inputMax = Math.max(inputMax, inputNum); + } + } + return inputMax; + }; + /** + * @param {Array} args an array of arguments + * @return {string} the results of the replacements being replaced + * @private + */ + Tone.Expr.prototype._replacements = function (args) { + var expr = args.shift(); + for (var i = 0; i < args.length; i++) { + expr = expr.replace(/\%/i, args[i]); + } + return expr; + }; + /** + * tokenize the expression based on the Expressions object + * @param {string} expr + * @return {Object} returns two methods on the tokenized list, next and peek + * @private + */ + Tone.Expr.prototype._tokenize = function (expr) { + var position = -1; + var tokens = []; + while (expr.length > 0) { + expr = expr.trim(); + var token = getNextToken(expr); + tokens.push(token); + expr = expr.substr(token.value.length); + } + function getNextToken(expr) { + for (var type in Tone.Expr._Expressions) { + var group = Tone.Expr._Expressions[type]; + for (var opName in group) { + var op = group[opName]; + var reg = op.regexp; + var match = expr.match(reg); + if (match !== null) { + return { + type: type, + value: match[0], + method: op.method + }; + } + } + } + throw new SyntaxError('Tone.Expr: Unexpected token ' + expr); + } + return { + next: function () { + return tokens[++position]; + }, + peek: function () { + return tokens[position + 1]; + } + }; + }; + /** + * recursively parse the string expression into a syntax tree + * + * @param {string} expr + * @return {Object} + * @private + */ + Tone.Expr.prototype._parseTree = function (expr) { + var lexer = this._tokenize(expr); + var isUndef = this.isUndef.bind(this); + function matchSyntax(token, syn) { + return !isUndef(token) && token.type === 'glue' && token.value === syn; + } + function matchGroup(token, groupName, prec) { + var ret = false; + var group = Tone.Expr._Expressions[groupName]; + if (!isUndef(token)) { + for (var opName in group) { + var op = group[opName]; + if (op.regexp.test(token.value)) { + if (!isUndef(prec)) { + if (op.precedence === prec) { + return true; + } + } else { + return true; + } + } + } + } + return ret; + } + function parseExpression(precedence) { + if (isUndef(precedence)) { + precedence = 5; + } + var expr; + if (precedence < 0) { + expr = parseUnary(); + } else { + expr = parseExpression(precedence - 1); + } + var token = lexer.peek(); + while (matchGroup(token, 'binary', precedence)) { + token = lexer.next(); + expr = { + operator: token.value, + method: token.method, + args: [ + expr, + parseExpression(precedence - 1) + ] + }; + token = lexer.peek(); + } + return expr; + } + function parseUnary() { + var token, expr; + token = lexer.peek(); + if (matchGroup(token, 'unary')) { + token = lexer.next(); + expr = parseUnary(); + return { + operator: token.value, + method: token.method, + args: [expr] + }; + } + return parsePrimary(); + } + function parsePrimary() { + var token, expr; + token = lexer.peek(); + if (isUndef(token)) { + throw new SyntaxError('Tone.Expr: Unexpected termination of expression'); + } + if (token.type === 'func') { + token = lexer.next(); + return parseFunctionCall(token); + } + if (token.type === 'value') { + token = lexer.next(); + return { + method: token.method, + args: token.value + }; + } + if (matchSyntax(token, '(')) { + lexer.next(); + expr = parseExpression(); + token = lexer.next(); + if (!matchSyntax(token, ')')) { + throw new SyntaxError('Expected )'); + } + return expr; + } + throw new SyntaxError('Tone.Expr: Parse error, cannot process token ' + token.value); + } + function parseFunctionCall(func) { + var token, args = []; + token = lexer.next(); + if (!matchSyntax(token, '(')) { + throw new SyntaxError('Tone.Expr: Expected ( in a function call "' + func.value + '"'); + } + token = lexer.peek(); + if (!matchSyntax(token, ')')) { + args = parseArgumentList(); + } + token = lexer.next(); + if (!matchSyntax(token, ')')) { + throw new SyntaxError('Tone.Expr: Expected ) in a function call "' + func.value + '"'); + } + return { + method: func.method, + args: args, + name: name + }; + } + function parseArgumentList() { + var token, expr, args = []; + while (true) { + expr = parseExpression(); + if (isUndef(expr)) { + // TODO maybe throw exception? + break; + } + args.push(expr); + token = lexer.peek(); + if (!matchSyntax(token, ',')) { + break; + } + lexer.next(); + } + return args; + } + return parseExpression(); + }; + /** + * recursively evaluate the expression tree + * @param {Object} tree + * @return {AudioNode} the resulting audio node from the expression + * @private + */ + Tone.Expr.prototype._eval = function (tree) { + if (!this.isUndef(tree)) { + var node = tree.method(tree.args, this); + this._nodes.push(node); + return node; + } + }; + /** + * dispose all the nodes + * @private + */ + Tone.Expr.prototype._disposeNodes = function () { + for (var i = 0; i < this._nodes.length; i++) { + var node = this._nodes[i]; + if (this.isFunction(node.dispose)) { + node.dispose(); + } else if (this.isFunction(node.disconnect)) { + node.disconnect(); + } + node = null; + this._nodes[i] = null; + } + this._nodes = null; + }; + /** + * clean up + */ + Tone.Expr.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._disposeNodes(); + }; + return Tone.Expr; + }); + Module(function (Tone) { + + /** + * @class Convert an incoming signal between 0, 1 to an equal power gain scale. + * + * @extends {Tone.SignalBase} + * @constructor + * @example + * var eqPowGain = new Tone.EqualPowerGain(); + */ + Tone.EqualPowerGain = function () { + /** + * @type {Tone.WaveShaper} + * @private + */ + this._eqPower = this.input = this.output = new Tone.WaveShaper(function (val) { + if (Math.abs(val) < 0.001) { + //should output 0 when input is 0 + return 0; + } else { + return this.equalPowerScale(val); + } + }.bind(this), 4096); + }; + Tone.extend(Tone.EqualPowerGain, Tone.SignalBase); + /** + * clean up + * @returns {Tone.EqualPowerGain} this + */ + Tone.EqualPowerGain.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._eqPower.dispose(); + this._eqPower = null; + return this; + }; + return Tone.EqualPowerGain; + }); + Module(function (Tone) { + + /** + * @class Tone.Crossfade provides equal power fading between two inputs. + * More on crossfading technique [here](https://en.wikipedia.org/wiki/Fade_(audio_engineering)#Crossfading). + * + * @constructor + * @extends {Tone} + * @param {NormalRange} [initialFade=0.5] + * @example + * var crossFade = new Tone.CrossFade(0.5); + * //connect effect A to crossfade from + * //effect output 0 to crossfade input 0 + * effectA.connect(crossFade, 0, 0); + * //connect effect B to crossfade from + * //effect output 0 to crossfade input 1 + * effectB.connect(crossFade, 0, 1); + * crossFade.fade.value = 0; + * // ^ only effectA is output + * crossFade.fade.value = 1; + * // ^ only effectB is output + * crossFade.fade.value = 0.5; + * // ^ the two signals are mixed equally. + */ + Tone.CrossFade = function (initialFade) { + this.createInsOuts(2, 1); + /** + * Alias for input[0]. + * @type {Tone.Gain} + */ + this.a = this.input[0] = new Tone.Gain(); + /** + * Alias for input[1]. + * @type {Tone.Gain} + */ + this.b = this.input[1] = new Tone.Gain(); + /** + * The mix between the two inputs. A fade value of 0 + * will output 100% input[0] and + * a value of 1 will output 100% input[1]. + * @type {NormalRange} + * @signal + */ + this.fade = new Tone.Signal(this.defaultArg(initialFade, 0.5), Tone.Type.NormalRange); + /** + * equal power gain cross fade + * @private + * @type {Tone.EqualPowerGain} + */ + this._equalPowerA = new Tone.EqualPowerGain(); + /** + * equal power gain cross fade + * @private + * @type {Tone.EqualPowerGain} + */ + this._equalPowerB = new Tone.EqualPowerGain(); + /** + * invert the incoming signal + * @private + * @type {Tone} + */ + this._invert = new Tone.Expr('1 - $0'); + //connections + this.a.connect(this.output); + this.b.connect(this.output); + this.fade.chain(this._equalPowerB, this.b.gain); + this.fade.chain(this._invert, this._equalPowerA, this.a.gain); + this._readOnly('fade'); + }; + Tone.extend(Tone.CrossFade); + /** + * clean up + * @returns {Tone.CrossFade} this + */ + Tone.CrossFade.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._writable('fade'); + this._equalPowerA.dispose(); + this._equalPowerA = null; + this._equalPowerB.dispose(); + this._equalPowerB = null; + this.fade.dispose(); + this.fade = null; + this._invert.dispose(); + this._invert = null; + this.a.dispose(); + this.a = null; + this.b.dispose(); + this.b = null; + return this; + }; + return Tone.CrossFade; + }); + Module(function (Tone) { + + /** + * @class Tone.Filter is a filter which allows for all of the same native methods + * as the [BiquadFilterNode](http://webaudio.github.io/web-audio-api/#the-biquadfilternode-interface). + * Tone.Filter has the added ability to set the filter rolloff at -12 + * (default), -24 and -48. + * + * @constructor + * @extends {Tone} + * @param {Frequency|Object} [frequency] The cutoff frequency of the filter. + * @param {string=} type The type of filter. + * @param {number=} rolloff The drop in decibels per octave after the cutoff frequency. + * 3 choices: -12, -24, and -48 + * @example + * var filter = new Tone.Filter(200, "highpass"); + */ + Tone.Filter = function () { + this.createInsOuts(1, 1); + var options = this.optionsObject(arguments, [ + 'frequency', + 'type', + 'rolloff' + ], Tone.Filter.defaults); + /** + * the filter(s) + * @type {Array} + * @private + */ + this._filters = []; + /** + * The cutoff frequency of the filter. + * @type {Frequency} + * @signal + */ + this.frequency = new Tone.Signal(options.frequency, Tone.Type.Frequency); + /** + * The detune parameter + * @type {Cents} + * @signal + */ + this.detune = new Tone.Signal(0, Tone.Type.Cents); + /** + * The gain of the filter, only used in certain filter types + * @type {Number} + * @signal + */ + this.gain = new Tone.Signal({ + 'value': options.gain, + 'convert': false + }); + /** + * The Q or Quality of the filter + * @type {Positive} + * @signal + */ + this.Q = new Tone.Signal(options.Q); + /** + * the type of the filter + * @type {string} + * @private + */ + this._type = options.type; + /** + * the rolloff value of the filter + * @type {number} + * @private + */ + this._rolloff = options.rolloff; + //set the rolloff; + this.rolloff = options.rolloff; + this._readOnly([ + 'detune', + 'frequency', + 'gain', + 'Q' + ]); + }; + Tone.extend(Tone.Filter); + /** + * the default parameters + * + * @static + * @type {Object} + */ + Tone.Filter.defaults = { + 'type': 'lowpass', + 'frequency': 350, + 'rolloff': -12, + 'Q': 1, + 'gain': 0 + }; + /** + * The type of the filter. Types: "lowpass", "highpass", + * "bandpass", "lowshelf", "highshelf", "notch", "allpass", or "peaking". + * @memberOf Tone.Filter# + * @type {string} + * @name type + */ + Object.defineProperty(Tone.Filter.prototype, 'type', { + get: function () { + return this._type; + }, + set: function (type) { + var types = [ + 'lowpass', + 'highpass', + 'bandpass', + 'lowshelf', + 'highshelf', + 'notch', + 'allpass', + 'peaking' + ]; + if (types.indexOf(type) === -1) { + throw new TypeError('Tone.Filter: invalid type ' + type); + } + this._type = type; + for (var i = 0; i < this._filters.length; i++) { + this._filters[i].type = type; + } + } + }); + /** + * The rolloff of the filter which is the drop in db + * per octave. Implemented internally by cascading filters. + * Only accepts the values -12, -24, -48 and -96. + * @memberOf Tone.Filter# + * @type {number} + * @name rolloff + */ + Object.defineProperty(Tone.Filter.prototype, 'rolloff', { + get: function () { + return this._rolloff; + }, + set: function (rolloff) { + rolloff = parseInt(rolloff, 10); + var possibilities = [ + -12, + -24, + -48, + -96 + ]; + var cascadingCount = possibilities.indexOf(rolloff); + //check the rolloff is valid + if (cascadingCount === -1) { + throw new RangeError('Tone.Filter: rolloff can only be -12, -24, -48 or -96'); + } + cascadingCount += 1; + this._rolloff = rolloff; + //first disconnect the filters and throw them away + this.input.disconnect(); + for (var i = 0; i < this._filters.length; i++) { + this._filters[i].disconnect(); + this._filters[i] = null; + } + this._filters = new Array(cascadingCount); + for (var count = 0; count < cascadingCount; count++) { + var filter = this.context.createBiquadFilter(); + filter.type = this._type; + this.frequency.connect(filter.frequency); + this.detune.connect(filter.detune); + this.Q.connect(filter.Q); + this.gain.connect(filter.gain); + this._filters[count] = filter; + } + //connect them up + var connectionChain = [this.input].concat(this._filters).concat([this.output]); + this.connectSeries.apply(this, connectionChain); + } + }); + /** + * Clean up. + * @return {Tone.Filter} this + */ + Tone.Filter.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + for (var i = 0; i < this._filters.length; i++) { + this._filters[i].disconnect(); + this._filters[i] = null; + } + this._filters = null; + this._writable([ + 'detune', + 'frequency', + 'gain', + 'Q' + ]); + this.frequency.dispose(); + this.Q.dispose(); + this.frequency = null; + this.Q = null; + this.detune.dispose(); + this.detune = null; + this.gain.dispose(); + this.gain = null; + return this; + }; + return Tone.Filter; + }); + Module(function (Tone) { + + /** + * @class Split the incoming signal into three bands (low, mid, high) + * with two crossover frequency controls. + * + * @extends {Tone} + * @constructor + * @param {Frequency|Object} [lowFrequency] the low/mid crossover frequency + * @param {Frequency} [highFrequency] the mid/high crossover frequency + */ + Tone.MultibandSplit = function () { + var options = this.optionsObject(arguments, [ + 'lowFrequency', + 'highFrequency' + ], Tone.MultibandSplit.defaults); + /** + * the input + * @type {Tone.Gain} + * @private + */ + this.input = new Tone.Gain(); + /** + * the outputs + * @type {Array} + * @private + */ + this.output = new Array(3); + /** + * The low band. Alias for output[0] + * @type {Tone.Filter} + */ + this.low = this.output[0] = new Tone.Filter(0, 'lowpass'); + /** + * the lower filter of the mid band + * @type {Tone.Filter} + * @private + */ + this._lowMidFilter = new Tone.Filter(0, 'highpass'); + /** + * The mid band output. Alias for output[1] + * @type {Tone.Filter} + */ + this.mid = this.output[1] = new Tone.Filter(0, 'lowpass'); + /** + * The high band output. Alias for output[2] + * @type {Tone.Filter} + */ + this.high = this.output[2] = new Tone.Filter(0, 'highpass'); + /** + * The low/mid crossover frequency. + * @type {Frequency} + * @signal + */ + this.lowFrequency = new Tone.Signal(options.lowFrequency, Tone.Type.Frequency); + /** + * The mid/high crossover frequency. + * @type {Frequency} + * @signal + */ + this.highFrequency = new Tone.Signal(options.highFrequency, Tone.Type.Frequency); + /** + * The quality of all the filters + * @type {Number} + * @signal + */ + this.Q = new Tone.Signal(options.Q); + this.input.fan(this.low, this.high); + this.input.chain(this._lowMidFilter, this.mid); + //the frequency control signal + this.lowFrequency.connect(this.low.frequency); + this.lowFrequency.connect(this._lowMidFilter.frequency); + this.highFrequency.connect(this.mid.frequency); + this.highFrequency.connect(this.high.frequency); + //the Q value + this.Q.connect(this.low.Q); + this.Q.connect(this._lowMidFilter.Q); + this.Q.connect(this.mid.Q); + this.Q.connect(this.high.Q); + this._readOnly([ + 'high', + 'mid', + 'low', + 'highFrequency', + 'lowFrequency' + ]); + }; + Tone.extend(Tone.MultibandSplit); + /** + * @private + * @static + * @type {Object} + */ + Tone.MultibandSplit.defaults = { + 'lowFrequency': 400, + 'highFrequency': 2500, + 'Q': 1 + }; + /** + * Clean up. + * @returns {Tone.MultibandSplit} this + */ + Tone.MultibandSplit.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._writable([ + 'high', + 'mid', + 'low', + 'highFrequency', + 'lowFrequency' + ]); + this.low.dispose(); + this.low = null; + this._lowMidFilter.dispose(); + this._lowMidFilter = null; + this.mid.dispose(); + this.mid = null; + this.high.dispose(); + this.high = null; + this.lowFrequency.dispose(); + this.lowFrequency = null; + this.highFrequency.dispose(); + this.highFrequency = null; + this.Q.dispose(); + this.Q = null; + return this; + }; + return Tone.MultibandSplit; + }); + Module(function (Tone) { + + /** + * @class Tone.EQ3 is a three band EQ with control over low, mid, and high gain as + * well as the low and high crossover frequencies. + * + * @constructor + * @extends {Tone} + * + * @param {Decibels|Object} [lowLevel] The gain applied to the lows. + * @param {Decibels} [midLevel] The gain applied to the mid. + * @param {Decibels} [highLevel] The gain applied to the high. + * @example + * var eq = new Tone.EQ3(-10, 3, -20); + */ + Tone.EQ3 = function () { + var options = this.optionsObject(arguments, [ + 'low', + 'mid', + 'high' + ], Tone.EQ3.defaults); + /** + * the output node + * @type {GainNode} + * @private + */ + this.output = new Tone.Gain(); + /** + * the multiband split + * @type {Tone.MultibandSplit} + * @private + */ + this._multibandSplit = this.input = new Tone.MultibandSplit({ + 'lowFrequency': options.lowFrequency, + 'highFrequency': options.highFrequency + }); + /** + * The gain for the lower signals + * @type {Tone.Gain} + * @private + */ + this._lowGain = new Tone.Gain(options.low, Tone.Type.Decibels); + /** + * The gain for the mid signals + * @type {Tone.Gain} + * @private + */ + this._midGain = new Tone.Gain(options.mid, Tone.Type.Decibels); + /** + * The gain in decibels of the high part + * @type {Tone.Gain} + * @private + */ + this._highGain = new Tone.Gain(options.high, Tone.Type.Decibels); + /** + * The gain in decibels of the low part + * @type {Decibels} + * @signal + */ + this.low = this._lowGain.gain; + /** + * The gain in decibels of the mid part + * @type {Decibels} + * @signal + */ + this.mid = this._midGain.gain; + /** + * The gain in decibels of the high part + * @type {Decibels} + * @signal + */ + this.high = this._highGain.gain; + /** + * The Q value for all of the filters. + * @type {Positive} + * @signal + */ + this.Q = this._multibandSplit.Q; + /** + * The low/mid crossover frequency. + * @type {Frequency} + * @signal + */ + this.lowFrequency = this._multibandSplit.lowFrequency; + /** + * The mid/high crossover frequency. + * @type {Frequency} + * @signal + */ + this.highFrequency = this._multibandSplit.highFrequency; + //the frequency bands + this._multibandSplit.low.chain(this._lowGain, this.output); + this._multibandSplit.mid.chain(this._midGain, this.output); + this._multibandSplit.high.chain(this._highGain, this.output); + this._readOnly([ + 'low', + 'mid', + 'high', + 'lowFrequency', + 'highFrequency' + ]); + }; + Tone.extend(Tone.EQ3); + /** + * the default values + */ + Tone.EQ3.defaults = { + 'low': 0, + 'mid': 0, + 'high': 0, + 'lowFrequency': 400, + 'highFrequency': 2500 + }; + /** + * clean up + * @returns {Tone.EQ3} this + */ + Tone.EQ3.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._writable([ + 'low', + 'mid', + 'high', + 'lowFrequency', + 'highFrequency' + ]); + this._multibandSplit.dispose(); + this._multibandSplit = null; + this.lowFrequency = null; + this.highFrequency = null; + this._lowGain.dispose(); + this._lowGain = null; + this._midGain.dispose(); + this._midGain = null; + this._highGain.dispose(); + this._highGain = null; + this.low = null; + this.mid = null; + this.high = null; + this.Q = null; + return this; + }; + return Tone.EQ3; + }); + Module(function (Tone) { + + /** + * @class Performs a linear scaling on an input signal. + * Scales a NormalRange input to between + * outputMin and outputMax. + * + * @constructor + * @extends {Tone.SignalBase} + * @param {number} [outputMin=0] The output value when the input is 0. + * @param {number} [outputMax=1] The output value when the input is 1. + * @example + * var scale = new Tone.Scale(50, 100); + * var signal = new Tone.Signal(0.5).connect(scale); + * //the output of scale equals 75 + */ + Tone.Scale = function (outputMin, outputMax) { + /** + * @private + * @type {number} + */ + this._outputMin = this.defaultArg(outputMin, 0); + /** + * @private + * @type {number} + */ + this._outputMax = this.defaultArg(outputMax, 1); + /** + * @private + * @type {Tone.Multiply} + * @private + */ + this._scale = this.input = new Tone.Multiply(1); + /** + * @private + * @type {Tone.Add} + * @private + */ + this._add = this.output = new Tone.Add(0); + this._scale.connect(this._add); + this._setRange(); + }; + Tone.extend(Tone.Scale, Tone.SignalBase); + /** + * The minimum output value. This number is output when + * the value input value is 0. + * @memberOf Tone.Scale# + * @type {number} + * @name min + */ + Object.defineProperty(Tone.Scale.prototype, 'min', { + get: function () { + return this._outputMin; + }, + set: function (min) { + this._outputMin = min; + this._setRange(); + } + }); + /** + * The maximum output value. This number is output when + * the value input value is 1. + * @memberOf Tone.Scale# + * @type {number} + * @name max + */ + Object.defineProperty(Tone.Scale.prototype, 'max', { + get: function () { + return this._outputMax; + }, + set: function (max) { + this._outputMax = max; + this._setRange(); + } + }); + /** + * set the values + * @private + */ + Tone.Scale.prototype._setRange = function () { + this._add.value = this._outputMin; + this._scale.value = this._outputMax - this._outputMin; + }; + /** + * Clean up. + * @returns {Tone.Scale} this + */ + Tone.Scale.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._add.dispose(); + this._add = null; + this._scale.dispose(); + this._scale = null; + return this; + }; + return Tone.Scale; + }); + Module(function (Tone) { + /** + * @class Performs an exponential scaling on an input signal. + * Scales a NormalRange value [0,1] exponentially + * to the output range of outputMin to outputMax. + * + * @constructor + * @extends {Tone.SignalBase} + * @param {number} [outputMin=0] The output value when the input is 0. + * @param {number} [outputMax=1] The output value when the input is 1. + * @param {number} [exponent=2] The exponent which scales the incoming signal. + * @example + * var scaleExp = new Tone.ScaleExp(0, 100, 2); + * var signal = new Tone.Signal(0.5).connect(scaleExp); + */ + Tone.ScaleExp = function (outputMin, outputMax, exponent) { + /** + * scale the input to the output range + * @type {Tone.Scale} + * @private + */ + this._scale = this.output = new Tone.Scale(outputMin, outputMax); + /** + * @private + * @type {Tone.Pow} + * @private + */ + this._exp = this.input = new Tone.Pow(this.defaultArg(exponent, 2)); + this._exp.connect(this._scale); + }; + Tone.extend(Tone.ScaleExp, Tone.SignalBase); + /** + * Instead of interpolating linearly between the min and + * max values, setting the exponent will interpolate between + * the two values with an exponential curve. + * @memberOf Tone.ScaleExp# + * @type {number} + * @name exponent + */ + Object.defineProperty(Tone.ScaleExp.prototype, 'exponent', { + get: function () { + return this._exp.value; + }, + set: function (exp) { + this._exp.value = exp; + } + }); + /** + * The minimum output value. This number is output when + * the value input value is 0. + * @memberOf Tone.ScaleExp# + * @type {number} + * @name min + */ + Object.defineProperty(Tone.ScaleExp.prototype, 'min', { + get: function () { + return this._scale.min; + }, + set: function (min) { + this._scale.min = min; + } + }); + /** + * The maximum output value. This number is output when + * the value input value is 1. + * @memberOf Tone.ScaleExp# + * @type {number} + * @name max + */ + Object.defineProperty(Tone.ScaleExp.prototype, 'max', { + get: function () { + return this._scale.max; + }, + set: function (max) { + this._scale.max = max; + } + }); + /** + * Clean up. + * @returns {Tone.ScaleExp} this + */ + Tone.ScaleExp.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._scale.dispose(); + this._scale = null; + this._exp.dispose(); + this._exp = null; + return this; + }; + return Tone.ScaleExp; + }); + Module(function (Tone) { + + /** + * @class Wrapper around Web Audio's native [DelayNode](http://webaudio.github.io/web-audio-api/#the-delaynode-interface). + * @extends {Tone} + * @param {Time=} delayTime The delay applied to the incoming signal. + * @param {Time=} maxDelay The maximum delay time. + */ + Tone.Delay = function () { + var options = this.optionsObject(arguments, [ + 'delayTime', + 'maxDelay' + ], Tone.Delay.defaults); + /** + * The native delay node + * @type {DelayNode} + * @private + */ + this._delayNode = this.input = this.output = this.context.createDelay(this.toSeconds(options.maxDelay)); + /** + * The amount of time the incoming signal is + * delayed. + * @type {Tone.Param} + * @signal + */ + this.delayTime = new Tone.Param({ + 'param': this._delayNode.delayTime, + 'units': Tone.Type.Time, + 'value': options.delayTime + }); + this._readOnly('delayTime'); + }; + Tone.extend(Tone.Delay); + /** + * The defaults + * @const + * @type {Object} + */ + Tone.Delay.defaults = { + 'maxDelay': 1, + 'delayTime': 0 + }; + /** + * Clean up. + * @return {Tone.Delay} this + */ + Tone.Delay.prototype.dispose = function () { + Tone.Param.prototype.dispose.call(this); + this._delayNode.disconnect(); + this._delayNode = null; + this._writable('delayTime'); + this.delayTime = null; + return this; + }; + return Tone.Delay; + }); + Module(function (Tone) { + + /** + * @class Comb filters are basic building blocks for physical modeling. Read more + * about comb filters on [CCRMA's website](https://ccrma.stanford.edu/~jos/pasp/Feedback_Comb_Filters.html). + * + * @extends {Tone} + * @constructor + * @param {Time|Object} [delayTime] The delay time of the filter. + * @param {NormalRange=} resonance The amount of feedback the filter has. + */ + Tone.FeedbackCombFilter = function () { + var options = this.optionsObject(arguments, [ + 'delayTime', + 'resonance' + ], Tone.FeedbackCombFilter.defaults); + /** + * the delay node + * @type {DelayNode} + * @private + */ + this._delay = this.input = this.output = new Tone.Delay(options.delayTime); + /** + * The amount of delay of the comb filter. + * @type {Time} + * @signal + */ + this.delayTime = this._delay.delayTime; + /** + * the feedback node + * @type {GainNode} + * @private + */ + this._feedback = new Tone.Gain(options.resonance, Tone.Type.NormalRange); + /** + * The amount of feedback of the delayed signal. + * @type {NormalRange} + * @signal + */ + this.resonance = this._feedback.gain; + this._delay.chain(this._feedback, this._delay); + this._readOnly([ + 'resonance', + 'delayTime' + ]); + }; + Tone.extend(Tone.FeedbackCombFilter); + /** + * the default parameters + * @static + * @const + * @type {Object} + */ + Tone.FeedbackCombFilter.defaults = { + 'delayTime': 0.1, + 'resonance': 0.5 + }; + /** + * clean up + * @returns {Tone.FeedbackCombFilter} this + */ + Tone.FeedbackCombFilter.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._writable([ + 'resonance', + 'delayTime' + ]); + this._delay.dispose(); + this._delay = null; + this.delayTime = null; + this._feedback.dispose(); + this._feedback = null; + this.resonance = null; + return this; + }; + return Tone.FeedbackCombFilter; + }); + Module(function (Tone) { + + /** + * @class Tone.Follower is a crude envelope follower which will follow + * the amplitude of an incoming signal. + * Take care with small (< 0.02) attack or decay values + * as follower has some ripple which is exaggerated + * at these values. Read more about envelope followers (also known + * as envelope detectors) on [Wikipedia](https://en.wikipedia.org/wiki/Envelope_detector). + * + * @constructor + * @extends {Tone} + * @param {Time|Object} [attack] The rate at which the follower rises. + * @param {Time=} release The rate at which the folower falls. + * @example + * var follower = new Tone.Follower(0.2, 0.4); + */ + Tone.Follower = function () { + this.createInsOuts(1, 1); + var options = this.optionsObject(arguments, [ + 'attack', + 'release' + ], Tone.Follower.defaults); + /** + * @type {Tone.Abs} + * @private + */ + this._abs = new Tone.Abs(); + /** + * the lowpass filter which smooths the input + * @type {BiquadFilterNode} + * @private + */ + this._filter = this.context.createBiquadFilter(); + this._filter.type = 'lowpass'; + this._filter.frequency.value = 0; + this._filter.Q.value = -100; + /** + * @type {WaveShaperNode} + * @private + */ + this._frequencyValues = new Tone.WaveShaper(); + /** + * @type {Tone.Subtract} + * @private + */ + this._sub = new Tone.Subtract(); + /** + * @type {Tone.Delay} + * @private + */ + this._delay = new Tone.Delay(this.blockTime); + /** + * this keeps it far from 0, even for very small differences + * @type {Tone.Multiply} + * @private + */ + this._mult = new Tone.Multiply(10000); + /** + * @private + * @type {number} + */ + this._attack = options.attack; + /** + * @private + * @type {number} + */ + this._release = options.release; + //the smoothed signal to get the values + this.input.chain(this._abs, this._filter, this.output); + //the difference path + this._abs.connect(this._sub, 0, 1); + this._filter.chain(this._delay, this._sub); + //threshold the difference and use the thresh to set the frequency + this._sub.chain(this._mult, this._frequencyValues, this._filter.frequency); + //set the attack and release values in the table + this._setAttackRelease(this._attack, this._release); + }; + Tone.extend(Tone.Follower); + /** + * @static + * @type {Object} + */ + Tone.Follower.defaults = { + 'attack': 0.05, + 'release': 0.5 + }; + /** + * sets the attack and release times in the wave shaper + * @param {Time} attack + * @param {Time} release + * @private + */ + Tone.Follower.prototype._setAttackRelease = function (attack, release) { + var minTime = this.blockTime; + attack = Tone.Time(attack).toFrequency(); + release = Tone.Time(release).toFrequency(); + attack = Math.max(attack, minTime); + release = Math.max(release, minTime); + this._frequencyValues.setMap(function (val) { + if (val <= 0) { + return attack; + } else { + return release; + } + }); + }; + /** + * The attack time. + * @memberOf Tone.Follower# + * @type {Time} + * @name attack + */ + Object.defineProperty(Tone.Follower.prototype, 'attack', { + get: function () { + return this._attack; + }, + set: function (attack) { + this._attack = attack; + this._setAttackRelease(this._attack, this._release); + } + }); + /** + * The release time. + * @memberOf Tone.Follower# + * @type {Time} + * @name release + */ + Object.defineProperty(Tone.Follower.prototype, 'release', { + get: function () { + return this._release; + }, + set: function (release) { + this._release = release; + this._setAttackRelease(this._attack, this._release); + } + }); + /** + * Borrows the connect method from Signal so that the output can be used + * as a Tone.Signal control signal. + * @function + */ + Tone.Follower.prototype.connect = Tone.Signal.prototype.connect; + /** + * dispose + * @returns {Tone.Follower} this + */ + Tone.Follower.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._filter.disconnect(); + this._filter = null; + this._frequencyValues.disconnect(); + this._frequencyValues = null; + this._delay.dispose(); + this._delay = null; + this._sub.disconnect(); + this._sub = null; + this._abs.dispose(); + this._abs = null; + this._mult.dispose(); + this._mult = null; + this._curve = null; + return this; + }; + return Tone.Follower; + }); + Module(function (Tone) { + + /** + * @class Tone.ScaledEnvelop is an envelope which can be scaled + * to any range. It's useful for applying an envelope + * to a frequency or any other non-NormalRange signal + * parameter. + * + * @extends {Tone.Envelope} + * @constructor + * @param {Time|Object} [attack] the attack time in seconds + * @param {Time} [decay] the decay time in seconds + * @param {number} [sustain] a percentage (0-1) of the full amplitude + * @param {Time} [release] the release time in seconds + * @example + * var scaledEnv = new Tone.ScaledEnvelope({ + * "attack" : 0.2, + * "min" : 200, + * "max" : 2000 + * }); + * scaledEnv.connect(oscillator.frequency); + */ + Tone.ScaledEnvelope = function () { + //get all of the defaults + var options = this.optionsObject(arguments, [ + 'attack', + 'decay', + 'sustain', + 'release' + ], Tone.Envelope.defaults); + Tone.Envelope.call(this, options); + options = this.defaultArg(options, Tone.ScaledEnvelope.defaults); + /** + * scale the incoming signal by an exponent + * @type {Tone.Pow} + * @private + */ + this._exp = this.output = new Tone.Pow(options.exponent); + /** + * scale the signal to the desired range + * @type {Tone.Multiply} + * @private + */ + this._scale = this.output = new Tone.Scale(options.min, options.max); + this._sig.chain(this._exp, this._scale); + }; + Tone.extend(Tone.ScaledEnvelope, Tone.Envelope); + /** + * the default parameters + * @static + */ + Tone.ScaledEnvelope.defaults = { + 'min': 0, + 'max': 1, + 'exponent': 1 + }; + /** + * The envelope's min output value. This is the value which it + * starts at. + * @memberOf Tone.ScaledEnvelope# + * @type {number} + * @name min + */ + Object.defineProperty(Tone.ScaledEnvelope.prototype, 'min', { + get: function () { + return this._scale.min; + }, + set: function (min) { + this._scale.min = min; + } + }); + /** + * The envelope's max output value. In other words, the value + * at the peak of the attack portion of the envelope. + * @memberOf Tone.ScaledEnvelope# + * @type {number} + * @name max + */ + Object.defineProperty(Tone.ScaledEnvelope.prototype, 'max', { + get: function () { + return this._scale.max; + }, + set: function (max) { + this._scale.max = max; + } + }); + /** + * The envelope's exponent value. + * @memberOf Tone.ScaledEnvelope# + * @type {number} + * @name exponent + */ + Object.defineProperty(Tone.ScaledEnvelope.prototype, 'exponent', { + get: function () { + return this._exp.value; + }, + set: function (exp) { + this._exp.value = exp; + } + }); + /** + * clean up + * @returns {Tone.ScaledEnvelope} this + */ + Tone.ScaledEnvelope.prototype.dispose = function () { + Tone.Envelope.prototype.dispose.call(this); + this._scale.dispose(); + this._scale = null; + this._exp.dispose(); + this._exp = null; + return this; + }; + return Tone.ScaledEnvelope; + }); + Module(function (Tone) { + + /** + * @class Tone.FrequencyEnvelope is a Tone.ScaledEnvelope, but instead of `min` and `max` + * it's got a `baseFrequency` and `octaves` parameter. + * + * @extends {Tone.Envelope} + * @constructor + * @param {Time|Object} [attack] the attack time in seconds + * @param {Time} [decay] the decay time in seconds + * @param {number} [sustain] a percentage (0-1) of the full amplitude + * @param {Time} [release] the release time in seconds + * @example + * var env = new Tone.FrequencyEnvelope({ + * "attack" : 0.2, + * "baseFrequency" : "C2", + * "octaves" : 4 + * }); + * scaledEnv.connect(oscillator.frequency); + */ + Tone.FrequencyEnvelope = function () { + var options = this.optionsObject(arguments, [ + 'attack', + 'decay', + 'sustain', + 'release' + ], Tone.Envelope.defaults); + Tone.ScaledEnvelope.call(this, options); + options = this.defaultArg(options, Tone.FrequencyEnvelope.defaults); + /** + * Stores the octave value + * @type {Positive} + * @private + */ + this._octaves = options.octaves; + //setup + this.baseFrequency = options.baseFrequency; + this.octaves = options.octaves; + }; + Tone.extend(Tone.FrequencyEnvelope, Tone.Envelope); + /** + * the default parameters + * @static + */ + Tone.FrequencyEnvelope.defaults = { + 'baseFrequency': 200, + 'octaves': 4, + 'exponent': 2 + }; + /** + * The envelope's mininum output value. This is the value which it + * starts at. + * @memberOf Tone.FrequencyEnvelope# + * @type {Frequency} + * @name baseFrequency + */ + Object.defineProperty(Tone.FrequencyEnvelope.prototype, 'baseFrequency', { + get: function () { + return this._scale.min; + }, + set: function (min) { + this._scale.min = this.toFrequency(min); + //also update the octaves + this.octaves = this._octaves; + } + }); + /** + * The number of octaves above the baseFrequency that the + * envelope will scale to. + * @memberOf Tone.FrequencyEnvelope# + * @type {Positive} + * @name octaves + */ + Object.defineProperty(Tone.FrequencyEnvelope.prototype, 'octaves', { + get: function () { + return this._octaves; + }, + set: function (octaves) { + this._octaves = octaves; + this._scale.max = this.baseFrequency * Math.pow(2, octaves); + } + }); + /** + * The envelope's exponent value. + * @memberOf Tone.FrequencyEnvelope# + * @type {number} + * @name exponent + */ + Object.defineProperty(Tone.FrequencyEnvelope.prototype, 'exponent', { + get: function () { + return this._exp.value; + }, + set: function (exp) { + this._exp.value = exp; + } + }); + /** + * clean up + * @returns {Tone.FrequencyEnvelope} this + */ + Tone.FrequencyEnvelope.prototype.dispose = function () { + Tone.ScaledEnvelope.prototype.dispose.call(this); + return this; + }; + return Tone.FrequencyEnvelope; + }); + Module(function (Tone) { + + /** + * @class Tone.Gate only passes a signal through when the incoming + * signal exceeds a specified threshold. To do this, Gate uses + * a Tone.Follower to follow the amplitude of the incoming signal. + * A common implementation of this class is a [Noise Gate](https://en.wikipedia.org/wiki/Noise_gate). + * + * @constructor + * @extends {Tone} + * @param {Decibels|Object} [threshold] The threshold above which the gate will open. + * @param {Time=} attack The follower's attack time + * @param {Time=} release The follower's release time + * @example + * var gate = new Tone.Gate(-30, 0.2, 0.3).toMaster(); + * var mic = new Tone.UserMedia().connect(gate); + * //the gate will only pass through the incoming + * //signal when it's louder than -30db + */ + Tone.Gate = function () { + this.createInsOuts(1, 1); + var options = this.optionsObject(arguments, [ + 'threshold', + 'attack', + 'release' + ], Tone.Gate.defaults); + /** + * @type {Tone.Follower} + * @private + */ + this._follower = new Tone.Follower(options.attack, options.release); + /** + * @type {Tone.GreaterThan} + * @private + */ + this._gt = new Tone.GreaterThan(this.dbToGain(options.threshold)); + //the connections + this.input.connect(this.output); + //the control signal + this.input.chain(this._gt, this._follower, this.output.gain); + }; + Tone.extend(Tone.Gate); + /** + * @const + * @static + * @type {Object} + */ + Tone.Gate.defaults = { + 'attack': 0.1, + 'release': 0.1, + 'threshold': -40 + }; + /** + * The threshold of the gate in decibels + * @memberOf Tone.Gate# + * @type {Decibels} + * @name threshold + */ + Object.defineProperty(Tone.Gate.prototype, 'threshold', { + get: function () { + return this.gainToDb(this._gt.value); + }, + set: function (thresh) { + this._gt.value = this.dbToGain(thresh); + } + }); + /** + * The attack speed of the gate + * @memberOf Tone.Gate# + * @type {Time} + * @name attack + */ + Object.defineProperty(Tone.Gate.prototype, 'attack', { + get: function () { + return this._follower.attack; + }, + set: function (attackTime) { + this._follower.attack = attackTime; + } + }); + /** + * The release speed of the gate + * @memberOf Tone.Gate# + * @type {Time} + * @name release + */ + Object.defineProperty(Tone.Gate.prototype, 'release', { + get: function () { + return this._follower.release; + }, + set: function (releaseTime) { + this._follower.release = releaseTime; + } + }); + /** + * Clean up. + * @returns {Tone.Gate} this + */ + Tone.Gate.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._follower.dispose(); + this._gt.dispose(); + this._follower = null; + this._gt = null; + return this; + }; + return Tone.Gate; + }); + Module(function (Tone) { + + /** + * @class A Timeline State. Provides the methods: setStateAtTime("state", time) + * and getValueAtTime(time). + * + * @extends {Tone.Timeline} + * @param {String} initial The initial state of the TimelineState. + * Defaults to undefined + */ + Tone.TimelineState = function (initial) { + Tone.Timeline.call(this); + /** + * The initial state + * @private + * @type {String} + */ + this._initial = initial; + }; + Tone.extend(Tone.TimelineState, Tone.Timeline); + /** + * Returns the scheduled state scheduled before or at + * the given time. + * @param {Number} time The time to query. + * @return {String} The name of the state input in setStateAtTime. + */ + Tone.TimelineState.prototype.getValueAtTime = function (time) { + var event = this.get(time); + if (event !== null) { + return event.state; + } else { + return this._initial; + } + }; + /** + * Returns the scheduled state scheduled before or at + * the given time. + * @param {String} state The name of the state to set. + * @param {Number} time The time to query. + */ + Tone.TimelineState.prototype.setStateAtTime = function (state, time) { + this.add({ + 'state': state, + 'time': time + }); + }; + return Tone.TimelineState; + }); + Module(function (Tone) { + + /** + * @class Tone.Emitter gives classes which extend it + * the ability to listen for and emit events. + * Inspiration and reference from Jerome Etienne's [MicroEvent](https://github.com/jeromeetienne/microevent.js). + * MIT (c) 2011 Jerome Etienne. + * + * @extends {Tone} + */ + Tone.Emitter = function () { + /** + * Contains all of the events. + * @private + * @type {Object} + */ + this._events = {}; + }; + Tone.extend(Tone.Emitter); + /** + * Bind a callback to a specific event. + * @param {String} event The name of the event to listen for. + * @param {Function} callback The callback to invoke when the + * event is emitted + * @return {Tone.Emitter} this + */ + Tone.Emitter.prototype.on = function (event, callback) { + //split the event + var events = event.split(/\W+/); + for (var i = 0; i < events.length; i++) { + var eventName = events[i]; + if (!this._events.hasOwnProperty(eventName)) { + this._events[eventName] = []; + } + this._events[eventName].push(callback); + } + return this; + }; + /** + * Remove the event listener. + * @param {String} event The event to stop listening to. + * @param {Function=} callback The callback which was bound to + * the event with Tone.Emitter.on. + * If no callback is given, all callbacks + * events are removed. + * @return {Tone.Emitter} this + */ + Tone.Emitter.prototype.off = function (event, callback) { + var events = event.split(/\W+/); + for (var ev = 0; ev < events.length; ev++) { + event = events[ev]; + if (this._events.hasOwnProperty(event)) { + if (Tone.prototype.isUndef(callback)) { + this._events[event] = []; + } else { + var eventList = this._events[event]; + for (var i = 0; i < eventList.length; i++) { + if (eventList[i] === callback) { + eventList.splice(i, 1); + } + } + } + } + } + return this; + }; + /** + * Invoke all of the callbacks bound to the event + * with any arguments passed in. + * @param {String} event The name of the event. + * @param {*...} args The arguments to pass to the functions listening. + * @return {Tone.Emitter} this + */ + Tone.Emitter.prototype.emit = function (event) { + if (this._events) { + var args = Array.prototype.slice.call(arguments, 1); + if (this._events.hasOwnProperty(event)) { + var eventList = this._events[event]; + for (var i = 0, len = eventList.length; i < len; i++) { + eventList[i].apply(this, args); + } + } + } + return this; + }; + /** + * Add Emitter functions (on/off/emit) to the object + * @param {Object|Function} object The object or class to extend. + */ + Tone.Emitter.mixin = function (object) { + var functions = [ + 'on', + 'off', + 'emit' + ]; + object._events = {}; + for (var i = 0; i < functions.length; i++) { + var func = functions[i]; + var emitterFunc = Tone.Emitter.prototype[func]; + object[func] = emitterFunc; + } + }; + /** + * Clean up + * @return {Tone.Emitter} this + */ + Tone.Emitter.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._events = null; + return this; + }; + return Tone.Emitter; + }); + Module(function (Tone) { + + /** + * @class A sample accurate clock which provides a callback at the given rate. + * While the callback is not sample-accurate (it is still susceptible to + * loose JS timing), the time passed in as the argument to the callback + * is precise. For most applications, it is better to use Tone.Transport + * instead of the Clock by itself since you can synchronize multiple callbacks. + * + * @constructor + * @extends {Tone.Emitter} + * @param {function} callback The callback to be invoked with the time of the audio event + * @param {Frequency} frequency The rate of the callback + * @example + * //the callback will be invoked approximately once a second + * //and will print the time exactly once a second apart. + * var clock = new Tone.Clock(function(time){ + * console.log(time); + * }, 1); + */ + Tone.Clock = function () { + Tone.Emitter.call(this); + var options = this.optionsObject(arguments, [ + 'callback', + 'frequency' + ], Tone.Clock.defaults); + /** + * The callback function to invoke at the scheduled tick. + * @type {Function} + */ + this.callback = options.callback; + /** + * The next time the callback is scheduled. + * @type {Number} + * @private + */ + this._nextTick = 0; + /** + * The last state of the clock. + * @type {State} + * @private + */ + this._lastState = Tone.State.Stopped; + /** + * The rate the callback function should be invoked. + * @type {BPM} + * @signal + */ + this.frequency = new Tone.TimelineSignal(options.frequency, Tone.Type.Frequency); + this._readOnly('frequency'); + /** + * The number of times the callback was invoked. Starts counting at 0 + * and increments after the callback was invoked. + * @type {Ticks} + * @readOnly + */ + this.ticks = 0; + /** + * The state timeline + * @type {Tone.TimelineState} + * @private + */ + this._state = new Tone.TimelineState(Tone.State.Stopped); + /** + * The loop function bound to its context. + * This is necessary to remove the event in the end. + * @type {Function} + * @private + */ + this._boundLoop = this._loop.bind(this); + //bind a callback to the worker thread + Tone.Clock._worker.addEventListener('message', this._boundLoop); + }; + Tone.extend(Tone.Clock, Tone.Emitter); + /** + * The defaults + * @const + * @type {Object} + */ + Tone.Clock.defaults = { + 'callback': Tone.noOp, + 'frequency': 1, + 'lookAhead': 'auto' + }; + /** + * Returns the playback state of the source, either "started", "stopped" or "paused". + * @type {Tone.State} + * @readOnly + * @memberOf Tone.Clock# + * @name state + */ + Object.defineProperty(Tone.Clock.prototype, 'state', { + get: function () { + return this._state.getValueAtTime(this.now()); + } + }); + /** + * Start the clock at the given time. Optionally pass in an offset + * of where to start the tick counter from. + * @param {Time} time The time the clock should start + * @param {Ticks=} offset Where the tick counter starts counting from. + * @return {Tone.Clock} this + */ + Tone.Clock.prototype.start = function (time, offset) { + time = this.toSeconds(time); + if (this._state.getValueAtTime(time) !== Tone.State.Started) { + this._state.add({ + 'state': Tone.State.Started, + 'time': time, + 'offset': offset + }); + } + return this; + }; + /** + * Stop the clock. Stopping the clock resets the tick counter to 0. + * @param {Time} [time=now] The time when the clock should stop. + * @returns {Tone.Clock} this + * @example + * clock.stop(); + */ + Tone.Clock.prototype.stop = function (time) { + time = this.toSeconds(time); + this._state.cancel(time); + this._state.setStateAtTime(Tone.State.Stopped, time); + return this; + }; + /** + * Pause the clock. Pausing does not reset the tick counter. + * @param {Time} [time=now] The time when the clock should stop. + * @returns {Tone.Clock} this + */ + Tone.Clock.prototype.pause = function (time) { + time = this.toSeconds(time); + if (this._state.getValueAtTime(time) === Tone.State.Started) { + this._state.setStateAtTime(Tone.State.Paused, time); + } + return this; + }; + /** + * The scheduling loop. + * @param {Number} time The current page time starting from 0 + * when the page was loaded. + * @private + */ + Tone.Clock.prototype._loop = function () { + //get the frequency value to compute the value of the next loop + var now = this.now(); + //if it's started + var lookAhead = Tone.Clock.lookAhead; + var updateInterval = Tone.Clock.updateInterval; + var lagCompensation = Tone.Clock.lag * 2; + var loopInterval = now + lookAhead + updateInterval + lagCompensation; + while (loopInterval > this._nextTick && this._state) { + var currentState = this._state.getValueAtTime(this._nextTick); + if (currentState !== this._lastState) { + this._lastState = currentState; + var event = this._state.get(this._nextTick); + // emit an event + if (currentState === Tone.State.Started) { + //correct the time + this._nextTick = event.time; + if (!this.isUndef(event.offset)) { + this.ticks = event.offset; + } + this.emit('start', event.time, this.ticks); + } else if (currentState === Tone.State.Stopped) { + this.ticks = 0; + this.emit('stop', event.time); + } else if (currentState === Tone.State.Paused) { + this.emit('pause', event.time); + } + } + var tickTime = this._nextTick; + if (this.frequency) { + this._nextTick += 1 / this.frequency.getValueAtTime(this._nextTick); + if (currentState === Tone.State.Started) { + this.callback(tickTime); + this.ticks++; + } + } + } + }; + /** + * Returns the scheduled state at the given time. + * @param {Time} time The time to query. + * @return {String} The name of the state input in setStateAtTime. + * @example + * clock.start("+0.1"); + * clock.getStateAtTime("+0.1"); //returns "started" + */ + Tone.Clock.prototype.getStateAtTime = function (time) { + time = this.toSeconds(time); + return this._state.getValueAtTime(time); + }; + /** + * Clean up + * @returns {Tone.Clock} this + */ + Tone.Clock.prototype.dispose = function () { + Tone.Emitter.prototype.dispose.call(this); + Tone.Clock._worker.removeEventListener('message', this._boundLoop); + this._writable('frequency'); + this.frequency.dispose(); + this.frequency = null; + this._boundLoop = null; + this._nextTick = Infinity; + this.callback = null; + this._state.dispose(); + this._state = null; + }; + /////////////////////////////////////////////////////////////////////////// + // WORKER + /////////////////////////////////////////////////////////////////////////// + //URL Shim + window.URL = window.URL || window.webkitURL; + /** + * The minimum amount of time events are + * scheduled in advance. + * @private + * @type {Number} + */ + Tone.Clock._lookAhead = 0.1; + /** + * How often the worker ticks + * @type {Seconds} + * @private + */ + Tone.Clock._updateInterval = Tone.Clock._lookAhead / 3; + /** + * The script which runs in a web worker + * @type {Blob} + * @private + */ + var blob = new Blob([//the initial timeout time + 'var timeoutTime = ' + Tone.Clock._updateInterval * 1000 + ';' + //onmessage callback + 'self.onmessage = function(msg){' + '\ttimeoutTime = parseInt(msg.data);' + '};' + //the tick function which posts a message + //and schedules a new tick + 'function tick(){' + '\tsetTimeout(tick, timeoutTime);' + '\tself.postMessage(\'tick\');' + '}' + //call tick initially + 'tick();']); + /** + * Create a blob url from the Blob + * @type {URL} + * @private + */ + var blobUrl = URL.createObjectURL(blob); + /** + * The Worker which generates a regular callback + * @type {Worker} + * @private + * @static + */ + Tone.Clock._worker = new Worker(blobUrl); + /** + * @private + * @type {Number} + * The time of the last update + */ + var lastUpdate = -1; + /** + * The current computed update rate of the clock. + * @type {Number} + * @private + */ + var computedUpdateInterval = 0; + //listen for message events and update the global clock lookahead + Tone.Clock._worker.addEventListener('message', function () { + var now = Tone.now(); + if (lastUpdate !== -1) { + var diff = now - lastUpdate; + computedUpdateInterval = Math.max(diff, computedUpdateInterval * 0.97); + } + lastUpdate = now; + }); + /** + * This is the time that the clock is falling behind + * the scheduled update interval. The Clock automatically + * adjusts for the lag and schedules further in advance. + * @type {Number} + * @memberOf Tone.Clock + * @name lag + * @static + * @readOnly + */ + Object.defineProperty(Tone.Clock, 'lag', { + get: function () { + var diff = computedUpdateInterval - Tone.Clock._updateInterval; + diff = Math.max(diff, 0); + return diff; + } + }); + /** + * The amount of time in advance that events are scheduled. + * The lookAhead will adjust slightly in response to the + * measured update time to try to avoid clicks. + * @type {Number} + * @memberOf Tone.Clock + * @name lookAhead + * @static + */ + Object.defineProperty(Tone.Clock, 'lookAhead', { + get: function () { + return Tone.Clock._lookAhead; + }, + set: function (lA) { + Tone.Clock._lookAhead = lA; + } + }); + /** + * How often the Web Worker callback is invoked. + * This number corresponds to how responsive the scheduling + * can be. Clock.updateInterval + Clock.lookAhead gives you the + * total latency between scheduling an event and hearing it. + * @type {Number} + * @memberOf Tone.Clock + * @name updateInterval + * @static + */ + Object.defineProperty(Tone.Clock, 'updateInterval', { + get: function () { + return Tone.Clock._updateInterval; + }, + set: function (interval) { + Tone.Clock._updateInterval = Math.max(interval, 0.01); + Tone.Clock._worker.postMessage(interval * 1000); + } + }); + /** + * The latency hint + * @private + * @type {String|Number} + */ + var latencyHint = 'interactive'; + /** + * The type of playback, which affects tradeoffs between audio + * output latency and responsiveness. + * + * In addition to setting the value in seconds, the latencyHint also + * accepts the strings "interactive" (prioritizes low latency), + * "playback" (prioritizes sustained playback), "balanced" (balances + * latency and performance), and "fastest" (lowest latency, might glitch more often). + * @type {String|Seconds} + * @memberOf Tone.Clock# + * @name latencyHint + * @static + * @example + * //set the lookAhead to 0.3 seconds + * Tone.Clock.latencyHint = 0.3; + */ + Object.defineProperty(Tone.Clock, 'latencyHint', { + get: function () { + return latencyHint; + }, + set: function (hint) { + var lookAhead = hint; + latencyHint = hint; + if (Tone.prototype.isString(hint)) { + switch (hint) { + case 'interactive': + lookAhead = 0.1; + Tone.context.latencyHint = hint; + break; + case 'playback': + lookAhead = 0.8; + Tone.context.latencyHint = hint; + break; + case 'balanced': + lookAhead = 0.25; + Tone.context.latencyHint = hint; + break; + case 'fastest': + lookAhead = 0.01; + break; + } + } + Tone.Clock.lookAhead = lookAhead; + Tone.Clock.updateInterval = lookAhead / 3; + } + }); + Tone._initAudioContext(function () { + lastUpdate = -1; + computedUpdateInterval = 0; + }); + return Tone.Clock; + }); + Module(function (Tone) { + + /** + * @class Similar to Tone.Timeline, but all events represent + * intervals with both "time" and "duration" times. The + * events are placed in a tree structure optimized + * for querying an intersection point with the timeline + * events. Internally uses an [Interval Tree](https://en.wikipedia.org/wiki/Interval_tree) + * to represent the data. + * @extends {Tone} + */ + Tone.IntervalTimeline = function () { + /** + * The root node of the inteval tree + * @type {IntervalNode} + * @private + */ + this._root = null; + /** + * Keep track of the length of the timeline. + * @type {Number} + * @private + */ + this._length = 0; + }; + Tone.extend(Tone.IntervalTimeline); + /** + * The event to add to the timeline. All events must + * have a time and duration value + * @param {Object} event The event to add to the timeline + * @return {Tone.IntervalTimeline} this + */ + Tone.IntervalTimeline.prototype.add = function (event) { + if (this.isUndef(event.time) || this.isUndef(event.duration)) { + throw new Error('Tone.IntervalTimeline: events must have time and duration parameters'); + } + var node = new IntervalNode(event.time, event.time + event.duration, event); + if (this._root === null) { + this._root = node; + } else { + this._root.insert(node); + } + this._length++; + // Restructure tree to be balanced + while (node !== null) { + node.updateHeight(); + node.updateMax(); + this._rebalance(node); + node = node.parent; + } + return this; + }; + /** + * Remove an event from the timeline. + * @param {Object} event The event to remove from the timeline + * @return {Tone.IntervalTimeline} this + */ + Tone.IntervalTimeline.prototype.remove = function (event) { + if (this._root !== null) { + var results = []; + this._root.search(event.time, results); + for (var i = 0; i < results.length; i++) { + var node = results[i]; + if (node.event === event) { + this._removeNode(node); + this._length--; + break; + } + } + } + return this; + }; + /** + * The number of items in the timeline. + * @type {Number} + * @memberOf Tone.IntervalTimeline# + * @name length + * @readOnly + */ + Object.defineProperty(Tone.IntervalTimeline.prototype, 'length', { + get: function () { + return this._length; + } + }); + /** + * Remove events whose time time is after the given time + * @param {Number} time The time to query. + * @returns {Tone.IntervalTimeline} this + */ + Tone.IntervalTimeline.prototype.cancel = function (after) { + this.forEachAfter(after, function (event) { + this.remove(event); + }.bind(this)); + return this; + }; + /** + * Set the root node as the given node + * @param {IntervalNode} node + * @private + */ + Tone.IntervalTimeline.prototype._setRoot = function (node) { + this._root = node; + if (this._root !== null) { + this._root.parent = null; + } + }; + /** + * Replace the references to the node in the node's parent + * with the replacement node. + * @param {IntervalNode} node + * @param {IntervalNode} replacement + * @private + */ + Tone.IntervalTimeline.prototype._replaceNodeInParent = function (node, replacement) { + if (node.parent !== null) { + if (node.isLeftChild()) { + node.parent.left = replacement; + } else { + node.parent.right = replacement; + } + this._rebalance(node.parent); + } else { + this._setRoot(replacement); + } + }; + /** + * Remove the node from the tree and replace it with + * a successor which follows the schema. + * @param {IntervalNode} node + * @private + */ + Tone.IntervalTimeline.prototype._removeNode = function (node) { + if (node.left === null && node.right === null) { + this._replaceNodeInParent(node, null); + } else if (node.right === null) { + this._replaceNodeInParent(node, node.left); + } else if (node.left === null) { + this._replaceNodeInParent(node, node.right); + } else { + var balance = node.getBalance(); + var replacement, temp; + if (balance > 0) { + if (node.left.right === null) { + replacement = node.left; + replacement.right = node.right; + temp = replacement; + } else { + replacement = node.left.right; + while (replacement.right !== null) { + replacement = replacement.right; + } + replacement.parent.right = replacement.left; + temp = replacement.parent; + replacement.left = node.left; + replacement.right = node.right; + } + } else { + if (node.right.left === null) { + replacement = node.right; + replacement.left = node.left; + temp = replacement; + } else { + replacement = node.right.left; + while (replacement.left !== null) { + replacement = replacement.left; + } + replacement.parent = replacement.parent; + replacement.parent.left = replacement.right; + temp = replacement.parent; + replacement.left = node.left; + replacement.right = node.right; + } + } + if (node.parent !== null) { + if (node.isLeftChild()) { + node.parent.left = replacement; + } else { + node.parent.right = replacement; + } + } else { + this._setRoot(replacement); + } + // this._replaceNodeInParent(node, replacement); + this._rebalance(temp); + } + node.dispose(); + }; + /** + * Rotate the tree to the left + * @param {IntervalNode} node + * @private + */ + Tone.IntervalTimeline.prototype._rotateLeft = function (node) { + var parent = node.parent; + var isLeftChild = node.isLeftChild(); + // Make node.right the new root of this sub tree (instead of node) + var pivotNode = node.right; + node.right = pivotNode.left; + pivotNode.left = node; + if (parent !== null) { + if (isLeftChild) { + parent.left = pivotNode; + } else { + parent.right = pivotNode; + } + } else { + this._setRoot(pivotNode); + } + }; + /** + * Rotate the tree to the right + * @param {IntervalNode} node + * @private + */ + Tone.IntervalTimeline.prototype._rotateRight = function (node) { + var parent = node.parent; + var isLeftChild = node.isLeftChild(); + // Make node.left the new root of this sub tree (instead of node) + var pivotNode = node.left; + node.left = pivotNode.right; + pivotNode.right = node; + if (parent !== null) { + if (isLeftChild) { + parent.left = pivotNode; + } else { + parent.right = pivotNode; + } + } else { + this._setRoot(pivotNode); + } + }; + /** + * Balance the BST + * @param {IntervalNode} node + * @private + */ + Tone.IntervalTimeline.prototype._rebalance = function (node) { + var balance = node.getBalance(); + if (balance > 1) { + if (node.left.getBalance() < 0) { + this._rotateLeft(node.left); + } else { + this._rotateRight(node); + } + } else if (balance < -1) { + if (node.right.getBalance() > 0) { + this._rotateRight(node.right); + } else { + this._rotateLeft(node); + } + } + }; + /** + * Get an event whose time and duration span the give time. Will + * return the match whose "time" value is closest to the given time. + * @param {Object} event The event to add to the timeline + * @return {Object} The event which spans the desired time + */ + Tone.IntervalTimeline.prototype.get = function (time) { + if (this._root !== null) { + var results = []; + this._root.search(time, results); + if (results.length > 0) { + var max = results[0]; + for (var i = 1; i < results.length; i++) { + if (results[i].low > max.low) { + max = results[i]; + } + } + return max.event; + } + } + return null; + }; + /** + * Iterate over everything in the timeline. + * @param {Function} callback The callback to invoke with every item + * @returns {Tone.IntervalTimeline} this + */ + Tone.IntervalTimeline.prototype.forEach = function (callback) { + if (this._root !== null) { + var allNodes = []; + if (this._root !== null) { + this._root.traverse(function (node) { + allNodes.push(node); + }); + } + for (var i = 0; i < allNodes.length; i++) { + var ev = allNodes[i].event; + if (ev) { + callback(ev); + } + } + } + return this; + }; + /** + * Iterate over everything in the array in which the given time + * overlaps with the time and duration time of the event. + * @param {Number} time The time to check if items are overlapping + * @param {Function} callback The callback to invoke with every item + * @returns {Tone.IntervalTimeline} this + */ + Tone.IntervalTimeline.prototype.forEachAtTime = function (time, callback) { + if (this._root !== null) { + var results = []; + this._root.search(time, results); + for (var i = results.length - 1; i >= 0; i--) { + var ev = results[i].event; + if (ev) { + callback(ev); + } + } + } + return this; + }; + /** + * Iterate over everything in the array in which the time is greater + * than the given time. + * @param {Number} time The time to check if items are before + * @param {Function} callback The callback to invoke with every item + * @returns {Tone.IntervalTimeline} this + */ + Tone.IntervalTimeline.prototype.forEachAfter = function (time, callback) { + if (this._root !== null) { + var results = []; + this._root.searchAfter(time, results); + for (var i = results.length - 1; i >= 0; i--) { + var ev = results[i].event; + if (ev) { + callback(ev); + } + } + } + return this; + }; + /** + * Clean up + * @return {Tone.IntervalTimeline} this + */ + Tone.IntervalTimeline.prototype.dispose = function () { + var allNodes = []; + if (this._root !== null) { + this._root.traverse(function (node) { + allNodes.push(node); + }); + } + for (var i = 0; i < allNodes.length; i++) { + allNodes[i].dispose(); + } + allNodes = null; + this._root = null; + return this; + }; + /////////////////////////////////////////////////////////////////////////// + // INTERVAL NODE HELPER + /////////////////////////////////////////////////////////////////////////// + /** + * Represents a node in the binary search tree, with the addition + * of a "high" value which keeps track of the highest value of + * its children. + * References: + * https://brooknovak.wordpress.com/2013/12/07/augmented-interval-tree-in-c/ + * http://www.mif.vu.lt/~valdas/ALGORITMAI/LITERATURA/Cormen/Cormen.pdf + * @param {Number} low + * @param {Number} high + * @private + */ + var IntervalNode = function (low, high, event) { + //the event container + this.event = event; + //the low value + this.low = low; + //the high value + this.high = high; + //the high value for this and all child nodes + this.max = this.high; + //the nodes to the left + this._left = null; + //the nodes to the right + this._right = null; + //the parent node + this.parent = null; + //the number of child nodes + this.height = 0; + }; + /** + * Insert a node into the correct spot in the tree + * @param {IntervalNode} node + */ + IntervalNode.prototype.insert = function (node) { + if (node.low <= this.low) { + if (this.left === null) { + this.left = node; + } else { + this.left.insert(node); + } + } else { + if (this.right === null) { + this.right = node; + } else { + this.right.insert(node); + } + } + }; + /** + * Search the tree for nodes which overlap + * with the given point + * @param {Number} point The point to query + * @param {Array} results The array to put the results + */ + IntervalNode.prototype.search = function (point, results) { + // If p is to the right of the rightmost point of any interval + // in this node and all children, there won't be any matches. + if (point > this.max) { + return; + } + // Search left children + if (this.left !== null) { + this.left.search(point, results); + } + // Check this node + if (this.low <= point && this.high > point) { + results.push(this); + } + // If p is to the left of the time of this interval, + // then it can't be in any child to the right. + if (this.low > point) { + return; + } + // Search right children + if (this.right !== null) { + this.right.search(point, results); + } + }; + /** + * Search the tree for nodes which are less + * than the given point + * @param {Number} point The point to query + * @param {Array} results The array to put the results + */ + IntervalNode.prototype.searchAfter = function (point, results) { + // Check this node + if (this.low >= point) { + results.push(this); + if (this.left !== null) { + this.left.searchAfter(point, results); + } + } + // search the right side + if (this.right !== null) { + this.right.searchAfter(point, results); + } + }; + /** + * Invoke the callback on this element and both it's branches + * @param {Function} callback + */ + IntervalNode.prototype.traverse = function (callback) { + callback(this); + if (this.left !== null) { + this.left.traverse(callback); + } + if (this.right !== null) { + this.right.traverse(callback); + } + }; + /** + * Update the height of the node + */ + IntervalNode.prototype.updateHeight = function () { + if (this.left !== null && this.right !== null) { + this.height = Math.max(this.left.height, this.right.height) + 1; + } else if (this.right !== null) { + this.height = this.right.height + 1; + } else if (this.left !== null) { + this.height = this.left.height + 1; + } else { + this.height = 0; + } + }; + /** + * Update the height of the node + */ + IntervalNode.prototype.updateMax = function () { + this.max = this.high; + if (this.left !== null) { + this.max = Math.max(this.max, this.left.max); + } + if (this.right !== null) { + this.max = Math.max(this.max, this.right.max); + } + }; + /** + * The balance is how the leafs are distributed on the node + * @return {Number} Negative numbers are balanced to the right + */ + IntervalNode.prototype.getBalance = function () { + var balance = 0; + if (this.left !== null && this.right !== null) { + balance = this.left.height - this.right.height; + } else if (this.left !== null) { + balance = this.left.height + 1; + } else if (this.right !== null) { + balance = -(this.right.height + 1); + } + return balance; + }; + /** + * @returns {Boolean} true if this node is the left child + * of its parent + */ + IntervalNode.prototype.isLeftChild = function () { + return this.parent !== null && this.parent.left === this; + }; + /** + * get/set the left node + * @type {IntervalNode} + */ + Object.defineProperty(IntervalNode.prototype, 'left', { + get: function () { + return this._left; + }, + set: function (node) { + this._left = node; + if (node !== null) { + node.parent = this; + } + this.updateHeight(); + this.updateMax(); + } + }); + /** + * get/set the right node + * @type {IntervalNode} + */ + Object.defineProperty(IntervalNode.prototype, 'right', { + get: function () { + return this._right; + }, + set: function (node) { + this._right = node; + if (node !== null) { + node.parent = this; + } + this.updateHeight(); + this.updateMax(); + } + }); + /** + * null out references. + */ + IntervalNode.prototype.dispose = function () { + this.parent = null; + this._left = null; + this._right = null; + this.event = null; + }; + /////////////////////////////////////////////////////////////////////////// + // END INTERVAL NODE HELPER + /////////////////////////////////////////////////////////////////////////// + return Tone.IntervalTimeline; + }); + Module(function (Tone) { + + /** + * @class Transport for timing musical events. + * Supports tempo curves and time changes. Unlike browser-based timing (setInterval, requestAnimationFrame) + * Tone.Transport timing events pass in the exact time of the scheduled event + * in the argument of the callback function. Pass that time value to the object + * you're scheduling.

+ * A single transport is created for you when the library is initialized. + *

+ * The transport emits the events: "start", "stop", "pause", and "loop" which are + * called with the time of that event as the argument. + * + * @extends {Tone.Emitter} + * @singleton + * @example + * //repeated event every 8th note + * Tone.Transport.scheduleRepeat(function(time){ + * //do something with the time + * }, "8n"); + * @example + * //schedule an event on the 16th measure + * Tone.Transport.schedule(function(time){ + * //do something with the time + * }, "16:0:0"); + */ + Tone.Transport = function () { + Tone.Emitter.call(this); + /////////////////////////////////////////////////////////////////////// + // LOOPING + ////////////////////////////////////////////////////////////////////// + /** + * If the transport loops or not. + * @type {boolean} + */ + this.loop = false; + /** + * The loop start position in ticks + * @type {Ticks} + * @private + */ + this._loopStart = 0; + /** + * The loop end position in ticks + * @type {Ticks} + * @private + */ + this._loopEnd = 0; + /////////////////////////////////////////////////////////////////////// + // CLOCK/TEMPO + ////////////////////////////////////////////////////////////////////// + /** + * Pulses per quarter is the number of ticks per quarter note. + * @private + * @type {Number} + */ + this._ppq = TransportConstructor.defaults.PPQ; + /** + * watches the main oscillator for timing ticks + * initially starts at 120bpm + * @private + * @type {Tone.Clock} + */ + this._clock = new Tone.Clock({ + 'callback': this._processTick.bind(this), + 'frequency': 0 + }); + this._bindClockEvents(); + /** + * The Beats Per Minute of the Transport. + * @type {BPM} + * @signal + * @example + * Tone.Transport.bpm.value = 80; + * //ramp the bpm to 120 over 10 seconds + * Tone.Transport.bpm.rampTo(120, 10); + */ + this.bpm = this._clock.frequency; + this.bpm._toUnits = this._toUnits.bind(this); + this.bpm._fromUnits = this._fromUnits.bind(this); + this.bpm.units = Tone.Type.BPM; + this.bpm.value = TransportConstructor.defaults.bpm; + this._readOnly('bpm'); + /** + * The time signature, or more accurately the numerator + * of the time signature over a denominator of 4. + * @type {Number} + * @private + */ + this._timeSignature = TransportConstructor.defaults.timeSignature; + /////////////////////////////////////////////////////////////////////// + // TIMELINE EVENTS + ////////////////////////////////////////////////////////////////////// + /** + * All the events in an object to keep track by ID + * @type {Object} + * @private + */ + this._scheduledEvents = {}; + /** + * The event ID counter + * @type {Number} + * @private + */ + this._eventID = 0; + /** + * The scheduled events. + * @type {Tone.Timeline} + * @private + */ + this._timeline = new Tone.Timeline(); + /** + * Repeated events + * @type {Array} + * @private + */ + this._repeatedEvents = new Tone.IntervalTimeline(); + /** + * Events that occur once + * @type {Array} + * @private + */ + this._onceEvents = new Tone.Timeline(); + /** + * All of the synced Signals + * @private + * @type {Array} + */ + this._syncedSignals = []; + /////////////////////////////////////////////////////////////////////// + // SWING + ////////////////////////////////////////////////////////////////////// + /** + * The subdivision of the swing + * @type {Ticks} + * @private + */ + this._swingTicks = TransportConstructor.defaults.PPQ / 2; + //8n + /** + * The swing amount + * @type {NormalRange} + * @private + */ + this._swingAmount = 0; + }; + Tone.extend(Tone.Transport, Tone.Emitter); + /** + * the defaults + * @type {Object} + * @const + * @static + */ + Tone.Transport.defaults = { + 'bpm': 120, + 'swing': 0, + 'swingSubdivision': '8n', + 'timeSignature': 4, + 'loopStart': 0, + 'loopEnd': '4m', + 'PPQ': 192 + }; + /////////////////////////////////////////////////////////////////////////////// + // TICKS + /////////////////////////////////////////////////////////////////////////////// + /** + * called on every tick + * @param {number} tickTime clock relative tick time + * @private + */ + Tone.Transport.prototype._processTick = function (tickTime) { + var ticks = this._clock.ticks; + //handle swing + if (this._swingAmount > 0 && ticks % this._ppq !== 0 && //not on a downbeat + ticks % (this._swingTicks * 2) !== 0) { + //add some swing + var progress = ticks % (this._swingTicks * 2) / (this._swingTicks * 2); + var amount = Math.sin(progress * Math.PI) * this._swingAmount; + tickTime += Tone.Time(this._swingTicks * 2 / 3, 'i').eval() * amount; + } + //do the loop test + if (this.loop) { + if (ticks === this._loopEnd) { + this.emit('loopEnd', tickTime); + this._clock.ticks = this._loopStart; + ticks = this._loopStart; + this.emit('loopStart', tickTime, this.seconds); + this.emit('loop', tickTime); + } + } + //process the single occurrence events + this._onceEvents.forEachBefore(ticks, function (event) { + event.callback(tickTime); + //remove the event + delete this._scheduledEvents[event.id.toString()]; + }.bind(this)); + //and clear the single occurrence timeline + this._onceEvents.cancelBefore(ticks); + //fire the next tick events if their time has come + this._timeline.forEachAtTime(ticks, function (event) { + event.callback(tickTime); + }); + //process the repeated events + this._repeatedEvents.forEachAtTime(ticks, function (event) { + if ((ticks - event.time) % event.interval === 0) { + event.callback(tickTime); + } + }); + }; + /////////////////////////////////////////////////////////////////////////////// + // SCHEDULABLE EVENTS + /////////////////////////////////////////////////////////////////////////////// + /** + * Schedule an event along the timeline. + * @param {Function} callback The callback to be invoked at the time. + * @param {TransportTime} time The time to invoke the callback at. + * @return {Number} The id of the event which can be used for canceling the event. + * @example + * //trigger the callback when the Transport reaches the desired time + * Tone.Transport.schedule(function(time){ + * envelope.triggerAttack(time); + * }, "128i"); + */ + Tone.Transport.prototype.schedule = function (callback, time) { + var event = { + 'time': this.toTicks(time), + 'callback': callback + }; + var id = this._eventID++; + this._scheduledEvents[id.toString()] = { + 'event': event, + 'timeline': this._timeline + }; + this._timeline.add(event); + return id; + }; + /** + * Schedule a repeated event along the timeline. The event will fire + * at the `interval` starting at the `startTime` and for the specified + * `duration`. + * @param {Function} callback The callback to invoke. + * @param {Time} interval The duration between successive + * callbacks. + * @param {TimelinePosition=} startTime When along the timeline the events should + * start being invoked. + * @param {Time} [duration=Infinity] How long the event should repeat. + * @return {Number} The ID of the scheduled event. Use this to cancel + * the event. + * @example + * //a callback invoked every eighth note after the first measure + * Tone.Transport.scheduleRepeat(callback, "8n", "1m"); + */ + Tone.Transport.prototype.scheduleRepeat = function (callback, interval, startTime, duration) { + if (interval <= 0) { + throw new Error('Tone.Transport: repeat events must have an interval larger than 0'); + } + var event = { + 'time': this.toTicks(startTime), + 'duration': this.toTicks(this.defaultArg(duration, Infinity)), + 'interval': this.toTicks(interval), + 'callback': callback + }; + var id = this._eventID++; + this._scheduledEvents[id.toString()] = { + 'event': event, + 'timeline': this._repeatedEvents + }; + this._repeatedEvents.add(event); + return id; + }; + /** + * Schedule an event that will be removed after it is invoked. + * Note that if the given time is less than the current transport time, + * the event will be invoked immediately. + * @param {Function} callback The callback to invoke once. + * @param {TransportTime} time The time the callback should be invoked. + * @returns {Number} The ID of the scheduled event. + */ + Tone.Transport.prototype.scheduleOnce = function (callback, time) { + var id = this._eventID++; + var event = { + 'time': this.toTicks(time), + 'callback': callback, + 'id': id + }; + this._scheduledEvents[id.toString()] = { + 'event': event, + 'timeline': this._onceEvents + }; + this._onceEvents.add(event); + return id; + }; + /** + * Clear the passed in event id from the timeline + * @param {Number} eventId The id of the event. + * @returns {Tone.Transport} this + */ + Tone.Transport.prototype.clear = function (eventId) { + if (this._scheduledEvents.hasOwnProperty(eventId)) { + var item = this._scheduledEvents[eventId.toString()]; + item.timeline.remove(item.event); + delete this._scheduledEvents[eventId.toString()]; + } + return this; + }; + /** + * Remove scheduled events from the timeline after + * the given time. Repeated events will be removed + * if their startTime is after the given time + * @param {TransportTime} [after=0] Clear all events after + * this time. + * @returns {Tone.Transport} this + */ + Tone.Transport.prototype.cancel = function (after) { + after = this.defaultArg(after, 0); + after = this.toTicks(after); + this._timeline.cancel(after); + this._onceEvents.cancel(after); + this._repeatedEvents.cancel(after); + return this; + }; + /////////////////////////////////////////////////////////////////////////////// + // START/STOP/PAUSE + /////////////////////////////////////////////////////////////////////////////// + /** + * Bind start/stop/pause events from the clock and emit them. + */ + Tone.Transport.prototype._bindClockEvents = function () { + this._clock.on('start', function (time, offset) { + offset = Tone.Time(this._clock.ticks, 'i').toSeconds(); + this.emit('start', time, offset); + }.bind(this)); + this._clock.on('stop', function (time) { + this.emit('stop', time); + }.bind(this)); + this._clock.on('pause', function (time) { + this.emit('pause', time); + }.bind(this)); + }; + /** + * Returns the playback state of the source, either "started", "stopped", or "paused" + * @type {Tone.State} + * @readOnly + * @memberOf Tone.Transport# + * @name state + */ + Object.defineProperty(Tone.Transport.prototype, 'state', { + get: function () { + return this._clock.getStateAtTime(this.now()); + } + }); + /** + * Start the transport and all sources synced to the transport. + * @param {Time} [time=now] The time when the transport should start. + * @param {TransportTime=} offset The timeline offset to start the transport. + * @returns {Tone.Transport} this + * @example + * //start the transport in one second starting at beginning of the 5th measure. + * Tone.Transport.start("+1", "4:0:0"); + */ + Tone.Transport.prototype.start = function (time, offset) { + //start the clock + if (!this.isUndef(offset)) { + offset = this.toTicks(offset); + } + this._clock.start(time, offset); + return this; + }; + /** + * Stop the transport and all sources synced to the transport. + * @param {Time} [time=now] The time when the transport should stop. + * @returns {Tone.Transport} this + * @example + * Tone.Transport.stop(); + */ + Tone.Transport.prototype.stop = function (time) { + this._clock.stop(time); + return this; + }; + /** + * Pause the transport and all sources synced to the transport. + * @param {Time} [time=now] + * @returns {Tone.Transport} this + */ + Tone.Transport.prototype.pause = function (time) { + this._clock.pause(time); + return this; + }; + /////////////////////////////////////////////////////////////////////////////// + // SETTERS/GETTERS + /////////////////////////////////////////////////////////////////////////////// + /** + * The time signature as just the numerator over 4. + * For example 4/4 would be just 4 and 6/8 would be 3. + * @memberOf Tone.Transport# + * @type {Number|Array} + * @name timeSignature + * @example + * //common time + * Tone.Transport.timeSignature = 4; + * // 7/8 + * Tone.Transport.timeSignature = [7, 8]; + * //this will be reduced to a single number + * Tone.Transport.timeSignature; //returns 3.5 + */ + Object.defineProperty(Tone.Transport.prototype, 'timeSignature', { + get: function () { + return this._timeSignature; + }, + set: function (timeSig) { + if (this.isArray(timeSig)) { + timeSig = timeSig[0] / timeSig[1] * 4; + } + this._timeSignature = timeSig; + } + }); + /** + * When the Tone.Transport.loop = true, this is the starting position of the loop. + * @memberOf Tone.Transport# + * @type {TransportTime} + * @name loopStart + */ + Object.defineProperty(Tone.Transport.prototype, 'loopStart', { + get: function () { + return Tone.TransportTime(this._loopStart, 'i').toSeconds(); + }, + set: function (startPosition) { + this._loopStart = this.toTicks(startPosition); + } + }); + /** + * When the Tone.Transport.loop = true, this is the ending position of the loop. + * @memberOf Tone.Transport# + * @type {TransportTime} + * @name loopEnd + */ + Object.defineProperty(Tone.Transport.prototype, 'loopEnd', { + get: function () { + return Tone.TransportTime(this._loopEnd, 'i').toSeconds(); + }, + set: function (endPosition) { + this._loopEnd = this.toTicks(endPosition); + } + }); + /** + * Set the loop start and stop at the same time. + * @param {TransportTime} startPosition + * @param {TransportTime} endPosition + * @returns {Tone.Transport} this + * @example + * //loop over the first measure + * Tone.Transport.setLoopPoints(0, "1m"); + * Tone.Transport.loop = true; + */ + Tone.Transport.prototype.setLoopPoints = function (startPosition, endPosition) { + this.loopStart = startPosition; + this.loopEnd = endPosition; + return this; + }; + /** + * The swing value. Between 0-1 where 1 equal to + * the note + half the subdivision. + * @memberOf Tone.Transport# + * @type {NormalRange} + * @name swing + */ + Object.defineProperty(Tone.Transport.prototype, 'swing', { + get: function () { + return this._swingAmount; + }, + set: function (amount) { + //scale the values to a normal range + this._swingAmount = amount; + } + }); + /** + * Set the subdivision which the swing will be applied to. + * The default value is an 8th note. Value must be less + * than a quarter note. + * + * @memberOf Tone.Transport# + * @type {Time} + * @name swingSubdivision + */ + Object.defineProperty(Tone.Transport.prototype, 'swingSubdivision', { + get: function () { + return Tone.Time(this._swingTicks, 'i').toNotation(); + }, + set: function (subdivision) { + this._swingTicks = this.toTicks(subdivision); + } + }); + /** + * The Transport's position in Bars:Beats:Sixteenths. + * Setting the value will jump to that position right away. + * @memberOf Tone.Transport# + * @type {BarsBeatsSixteenths} + * @name position + */ + Object.defineProperty(Tone.Transport.prototype, 'position', { + get: function () { + return Tone.TransportTime(this.ticks, 'i').toBarsBeatsSixteenths(); + }, + set: function (progress) { + var ticks = this.toTicks(progress); + this.ticks = ticks; + } + }); + /** + * The Transport's position in seconds + * Setting the value will jump to that position right away. + * @memberOf Tone.Transport# + * @type {Seconds} + * @name seconds + */ + Object.defineProperty(Tone.Transport.prototype, 'seconds', { + get: function () { + return Tone.TransportTime(this.ticks, 'i').toSeconds(); + }, + set: function (progress) { + var ticks = this.toTicks(progress); + this.ticks = ticks; + } + }); + /** + * The Transport's loop position as a normalized value. Always + * returns 0 if the transport if loop is not true. + * @memberOf Tone.Transport# + * @name progress + * @type {NormalRange} + */ + Object.defineProperty(Tone.Transport.prototype, 'progress', { + get: function () { + if (this.loop) { + return (this.ticks - this._loopStart) / (this._loopEnd - this._loopStart); + } else { + return 0; + } + } + }); + /** + * The transports current tick position. + * + * @memberOf Tone.Transport# + * @type {Ticks} + * @name ticks + */ + Object.defineProperty(Tone.Transport.prototype, 'ticks', { + get: function () { + return this._clock.ticks; + }, + set: function (t) { + var now = this.now(); + //stop everything synced to the transport + if (this.state === Tone.State.Started) { + this.emit('stop', now); + this._clock.ticks = t; + //restart it with the new time + this.emit('start', now, this.seconds); + } else { + this._clock.ticks = t; + } + } + }); + /** + * Pulses Per Quarter note. This is the smallest resolution + * the Transport timing supports. This should be set once + * on initialization and not set again. Changing this value + * after other objects have been created can cause problems. + * + * @memberOf Tone.Transport# + * @type {Number} + * @name PPQ + */ + Object.defineProperty(Tone.Transport.prototype, 'PPQ', { + get: function () { + return this._ppq; + }, + set: function (ppq) { + var bpm = this.bpm.value; + this._ppq = ppq; + this.bpm.value = bpm; + } + }); + /** + * The hint to the type of playback. Affects tradeoffs between audio + * output latency and responsiveness. + * + * In addition to setting the value in seconds, the latencyHint also + * accepts the strings "interactive" (prioritizes low latency), + * "playback" (prioritizes sustained playback), "balanced" (balances + * latency and performance), and "fastest" (lowest latency, might glitch more often). + * @memberOf Tone.Transport# + * @type {Seconds|String} + * @name latencyHint + */ + Object.defineProperty(Tone.Transport.prototype, 'latencyHint', { + get: function () { + return Tone.Clock.latencyHint; + }, + set: function (hint) { + Tone.Clock.latencyHint = hint; + } + }); + /** + * Convert from BPM to frequency (factoring in PPQ) + * @param {BPM} bpm The BPM value to convert to frequency + * @return {Frequency} The BPM as a frequency with PPQ factored in. + * @private + */ + Tone.Transport.prototype._fromUnits = function (bpm) { + return 1 / (60 / bpm / this.PPQ); + }; + /** + * Convert from frequency (with PPQ) into BPM + * @param {Frequency} freq The clocks frequency to convert to BPM + * @return {BPM} The frequency value as BPM. + * @private + */ + Tone.Transport.prototype._toUnits = function (freq) { + return freq / this.PPQ * 60; + }; + /////////////////////////////////////////////////////////////////////////////// + // SYNCING + /////////////////////////////////////////////////////////////////////////////// + /** + * Returns the time aligned to the next subdivision + * of the Transport. If the Transport is not started, + * it will return 0. + * Note: this will not work precisely during tempo ramps. + * @param {Time} subdivision The subdivision to quantize to + * @return {Number} The context time of the next subdivision. + * @example + * Tone.Transport.start(); //the transport must be started + * Tone.Transport.nextSubdivision("4n"); + */ + Tone.Transport.prototype.nextSubdivision = function (subdivision) { + subdivision = this.toSeconds(subdivision); + //if the transport's not started, return 0 + var now; + if (this.state === Tone.State.Started) { + now = this._clock._nextTick; + } else { + return 0; + } + var transportPos = Tone.Time(this.ticks, 'i').eval(); + var remainingTime = subdivision - transportPos % subdivision; + if (remainingTime === 0) { + remainingTime = subdivision; + } + return now + remainingTime; + }; + /** + * Attaches the signal to the tempo control signal so that + * any changes in the tempo will change the signal in the same + * ratio. + * + * @param {Tone.Signal} signal + * @param {number=} ratio Optionally pass in the ratio between + * the two signals. Otherwise it will be computed + * based on their current values. + * @returns {Tone.Transport} this + */ + Tone.Transport.prototype.syncSignal = function (signal, ratio) { + if (!ratio) { + //get the sync ratio + if (signal._param.value !== 0) { + ratio = signal._param.value / this.bpm._param.value; + } else { + ratio = 0; + } + } + var ratioSignal = new Tone.Gain(ratio); + this.bpm.chain(ratioSignal, signal._param); + this._syncedSignals.push({ + 'ratio': ratioSignal, + 'signal': signal, + 'initial': signal._param.value + }); + signal._param.value = 0; + return this; + }; + /** + * Unsyncs a previously synced signal from the transport's control. + * See Tone.Transport.syncSignal. + * @param {Tone.Signal} signal + * @returns {Tone.Transport} this + */ + Tone.Transport.prototype.unsyncSignal = function (signal) { + for (var i = this._syncedSignals.length - 1; i >= 0; i--) { + var syncedSignal = this._syncedSignals[i]; + if (syncedSignal.signal === signal) { + syncedSignal.ratio.dispose(); + syncedSignal.signal._param.value = syncedSignal.initial; + this._syncedSignals.splice(i, 1); + } + } + return this; + }; + /** + * Clean up. + * @returns {Tone.Transport} this + * @private + */ + Tone.Transport.prototype.dispose = function () { + Tone.Emitter.prototype.dispose.call(this); + this._clock.dispose(); + this._clock = null; + this._writable('bpm'); + this.bpm = null; + this._timeline.dispose(); + this._timeline = null; + this._onceEvents.dispose(); + this._onceEvents = null; + this._repeatedEvents.dispose(); + this._repeatedEvents = null; + return this; + }; + /////////////////////////////////////////////////////////////////////////////// + // INITIALIZATION + /////////////////////////////////////////////////////////////////////////////// + var TransportConstructor = Tone.Transport; + Tone._initAudioContext(function () { + if (typeof Tone.Transport === 'function') { + //a single transport object + Tone.Transport = new Tone.Transport(); + } else { + //stop the clock + Tone.Transport.stop(); + //get the previous values + var prevSettings = Tone.Transport.get(); + //destory the old transport + Tone.Transport.dispose(); + //make new Transport insides + TransportConstructor.call(Tone.Transport); + //set the previous config + Tone.Transport.set(prevSettings); + } + }); + return Tone.Transport; + }); + Module(function (Tone) { + + /** + * @class Tone.Volume is a simple volume node, useful for creating a volume fader. + * + * @extends {Tone} + * @constructor + * @param {Decibels} [volume=0] the initial volume + * @example + * var vol = new Tone.Volume(-12); + * instrument.chain(vol, Tone.Master); + */ + Tone.Volume = function () { + var options = this.optionsObject(arguments, ['volume'], Tone.Volume.defaults); + /** + * the output node + * @type {GainNode} + * @private + */ + this.output = this.input = new Tone.Gain(options.volume, Tone.Type.Decibels); + /** + * The unmuted volume + * @type {Decibels} + * @private + */ + this._unmutedVolume = 0; + /** + * if the volume is muted + * @type {Boolean} + * @private + */ + this._muted = false; + /** + * The volume control in decibels. + * @type {Decibels} + * @signal + */ + this.volume = this.output.gain; + this._readOnly('volume'); + //set the mute initially + this.mute = options.mute; + }; + Tone.extend(Tone.Volume); + /** + * Defaults + * @type {Object} + * @const + * @static + */ + Tone.Volume.defaults = { + 'volume': 0, + 'mute': false + }; + /** + * Mute the output. + * @memberOf Tone.Volume# + * @type {boolean} + * @name mute + * @example + * //mute the output + * volume.mute = true; + */ + Object.defineProperty(Tone.Volume.prototype, 'mute', { + get: function () { + return this._muted; + }, + set: function (mute) { + if (!this._muted && mute) { + this._unmutedVolume = this.volume.value; + //maybe it should ramp here? + this.volume.value = -Infinity; + } else if (this._muted && !mute) { + this.volume.value = this._unmutedVolume; + } + this._muted = mute; + } + }); + /** + * clean up + * @returns {Tone.Volume} this + */ + Tone.Volume.prototype.dispose = function () { + this.input.dispose(); + Tone.prototype.dispose.call(this); + this._writable('volume'); + this.volume.dispose(); + this.volume = null; + return this; + }; + return Tone.Volume; + }); + Module(function (Tone) { + + /** + * @class A single master output which is connected to the + * AudioDestinationNode (aka your speakers). + * It provides useful conveniences such as the ability + * to set the volume and mute the entire application. + * It also gives you the ability to apply master effects to your application. + *

+ * Like Tone.Transport, A single Tone.Master is created + * on initialization and you do not need to explicitly construct one. + * + * @constructor + * @extends {Tone} + * @singleton + * @example + * //the audio will go from the oscillator to the speakers + * oscillator.connect(Tone.Master); + * //a convenience for connecting to the master output is also provided: + * oscillator.toMaster(); + * //the above two examples are equivalent. + */ + Tone.Master = function () { + this.createInsOuts(1, 1); + /** + * The private volume node + * @type {Tone.Volume} + * @private + */ + this._volume = this.output = new Tone.Volume(); + /** + * The volume of the master output. + * @type {Decibels} + * @signal + */ + this.volume = this._volume.volume; + this._readOnly('volume'); + //connections + this.input.chain(this.output, this.context.destination); + }; + Tone.extend(Tone.Master); + /** + * @type {Object} + * @const + */ + Tone.Master.defaults = { + 'volume': 0, + 'mute': false + }; + /** + * Mute the output. + * @memberOf Tone.Master# + * @type {boolean} + * @name mute + * @example + * //mute the output + * Tone.Master.mute = true; + */ + Object.defineProperty(Tone.Master.prototype, 'mute', { + get: function () { + return this._volume.mute; + }, + set: function (mute) { + this._volume.mute = mute; + } + }); + /** + * Add a master effects chain. NOTE: this will disconnect any nodes which were previously + * chained in the master effects chain. + * @param {AudioNode|Tone...} args All arguments will be connected in a row + * and the Master will be routed through it. + * @return {Tone.Master} this + * @example + * //some overall compression to keep the levels in check + * var masterCompressor = new Tone.Compressor({ + * "threshold" : -6, + * "ratio" : 3, + * "attack" : 0.5, + * "release" : 0.1 + * }); + * //give a little boost to the lows + * var lowBump = new Tone.Filter(200, "lowshelf"); + * //route everything through the filter + * //and compressor before going to the speakers + * Tone.Master.chain(lowBump, masterCompressor); + */ + Tone.Master.prototype.chain = function () { + this.input.disconnect(); + this.input.chain.apply(this.input, arguments); + arguments[arguments.length - 1].connect(this.output); + }; + /** + * Clean up + * @return {Tone.Master} this + */ + Tone.Master.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._writable('volume'); + this._volume.dispose(); + this._volume = null; + this.volume = null; + }; + /////////////////////////////////////////////////////////////////////////// + // AUGMENT TONE's PROTOTYPE + /////////////////////////////////////////////////////////////////////////// + /** + * Connect 'this' to the master output. Shorthand for this.connect(Tone.Master) + * @returns {Tone} this + * @example + * //connect an oscillator to the master output + * var osc = new Tone.Oscillator().toMaster(); + */ + Tone.prototype.toMaster = function () { + this.connect(Tone.Master); + return this; + }; + /** + * Also augment AudioNode's prototype to include toMaster + * as a convenience + * @returns {AudioNode} this + */ + AudioNode.prototype.toMaster = function () { + this.connect(Tone.Master); + return this; + }; + var MasterConstructor = Tone.Master; + /** + * initialize the module and listen for new audio contexts + */ + Tone._initAudioContext(function () { + //a single master output + if (!Tone.prototype.isUndef(Tone.Master)) { + Tone.Master = new MasterConstructor(); + } else { + MasterConstructor.prototype.dispose.call(Tone.Master); + MasterConstructor.call(Tone.Master); + } + }); + return Tone.Master; + }); + Module(function (Tone) { + + /** + * @class Base class for sources. Sources have start/stop methods + * and the ability to be synced to the + * start/stop of Tone.Transport. + * + * @constructor + * @extends {Tone} + * @example + * //Multiple state change events can be chained together, + * //but must be set in the correct order and with ascending times + * + * // OK + * state.start().stop("+0.2"); + * // AND + * state.start().stop("+0.2").start("+0.4").stop("+0.7") + * + * // BAD + * state.stop("+0.2").start(); + * // OR + * state.start("+0.3").stop("+0.2"); + * + */ + Tone.Source = function (options) { + // this.createInsOuts(0, 1); + options = this.defaultArg(options, Tone.Source.defaults); + /** + * The output volume node + * @type {Tone.Volume} + * @private + */ + this._volume = this.output = new Tone.Volume(options.volume); + /** + * The volume of the output in decibels. + * @type {Decibels} + * @signal + * @example + * source.volume.value = -6; + */ + this.volume = this._volume.volume; + this._readOnly('volume'); + /** + * Keep track of the scheduled state. + * @type {Tone.TimelineState} + * @private + */ + this._state = new Tone.TimelineState(Tone.State.Stopped); + this._state.memory = 10; + /** + * The synced `start` callback function from the transport + * @type {Function} + * @private + */ + this._synced = false; + /** + * Keep track of all of the scheduled event ids + * @type {Array} + * @private + */ + this._scheduled = []; + //make the output explicitly stereo + this._volume.output.output.channelCount = 2; + this._volume.output.output.channelCountMode = 'explicit'; + //mute initially + this.mute = options.mute; + }; + Tone.extend(Tone.Source); + /** + * The default parameters + * @static + * @const + * @type {Object} + */ + Tone.Source.defaults = { + 'volume': 0, + 'mute': false + }; + /** + * Returns the playback state of the source, either "started" or "stopped". + * @type {Tone.State} + * @readOnly + * @memberOf Tone.Source# + * @name state + */ + Object.defineProperty(Tone.Source.prototype, 'state', { + get: function () { + if (this._synced) { + if (Tone.Transport.state === Tone.State.Started) { + return this._state.getValueAtTime(Tone.Transport.seconds); + } else { + return Tone.State.Stopped; + } + } else { + return this._state.getValueAtTime(this.now()); + } + } + }); + /** + * Mute the output. + * @memberOf Tone.Source# + * @type {boolean} + * @name mute + * @example + * //mute the output + * source.mute = true; + */ + Object.defineProperty(Tone.Source.prototype, 'mute', { + get: function () { + return this._volume.mute; + }, + set: function (mute) { + this._volume.mute = mute; + } + }); + //overwrite these functions + Tone.Source.prototype._start = Tone.noOp; + Tone.Source.prototype._stop = Tone.noOp; + /** + * Start the source at the specified time. If no time is given, + * start the source now. + * @param {Time} [time=now] When the source should be started. + * @returns {Tone.Source} this + * @example + * source.start("+0.5"); //starts the source 0.5 seconds from now + */ + Tone.Source.prototype.start = function (time, offset, duration) { + if (this.isUndef(time) && this._synced) { + time = Tone.Transport.seconds; + } else { + time = this.toSeconds(time); + } + //if it's started, stop it and restart it + if (!this.retrigger && this._state.getValueAtTime(time) === Tone.State.Started) { + this.stop(time); + } + this._state.setStateAtTime(Tone.State.Started, time); + if (this._synced) { + // add the offset time to the event + var event = this._state.get(time); + event.offset = this.defaultArg(offset, 0); + event.duration = duration; + var sched = Tone.Transport.schedule(function (t) { + this._start(t, offset, duration); + }.bind(this), time); + this._scheduled.push(sched); + } else { + this._start.apply(this, arguments); + } + return this; + }; + /** + * Stop the source at the specified time. If no time is given, + * stop the source now. + * @param {Time} [time=now] When the source should be stopped. + * @returns {Tone.Source} this + * @example + * source.stop(); // stops the source immediately + */ + Tone.Source.prototype.stop = function (time) { + if (this.isUndef(time) && this._synced) { + time = Tone.Transport.seconds; + } else { + time = this.toSeconds(time); + } + this._state.cancel(time); + this._state.setStateAtTime(Tone.State.Stopped, time); + if (!this._synced) { + this._stop.apply(this, arguments); + } else { + var sched = Tone.Transport.schedule(this._stop.bind(this), time); + this._scheduled.push(sched); + } + return this; + }; + /** + * Sync the source to the Transport so that all subsequent + * calls to `start` and `stop` are synced to the TransportTime + * instead of the AudioContext time. + * + * @returns {Tone.Source} this + * @example + * //sync the source so that it plays between 0 and 0.3 on the Transport's timeline + * source.sync().start(0).stop(0.3); + * //start the transport. + * Tone.Transport.start(); + * + * @example + * //start the transport with an offset and the sync'ed sources + * //will start in the correct position + * source.sync().start(0.1); + * //the source will be invoked with an offset of 0.4 + * Tone.Transport.start("+0.5", 0.5); + */ + Tone.Source.prototype.sync = function () { + this._synced = true; + Tone.Transport.on('start loopStart', function (time, offset) { + if (offset > 0) { + // get the playback state at that time + var stateEvent = this._state.get(offset); + // listen for start events which may occur in the middle of the sync'ed time + if (stateEvent && stateEvent.state === Tone.State.Started && stateEvent.time !== offset) { + // get the offset + var startOffset = offset - this.toSeconds(stateEvent.time); + var duration; + if (stateEvent.duration) { + duration = this.toSeconds(stateEvent.duration) - startOffset; + } + this._start(time, this.toSeconds(stateEvent.offset) + startOffset, duration); + } + } + }.bind(this)); + Tone.Transport.on('stop pause loopEnd', function (time) { + if (this._state.getValueAtTime(Tone.Transport.seconds) === Tone.State.Started) { + this._stop(time); + } + }.bind(this)); + return this; + }; + /** + * Unsync the source to the Transport. See Tone.Source.sync + * @returns {Tone.Source} this + */ + Tone.Source.prototype.unsync = function () { + this._synced = false; + Tone.Transport.off('start stop pause loopEnd loopStart'); + // clear all of the scheduled ids + for (var i = 0; i < this._scheduled.length; i++) { + var id = this._scheduled[i]; + Tone.Transport.clear(id); + } + this._scheduled = []; + this._state.cancel(0); + return this; + }; + /** + * Clean up. + * @return {Tone.Source} this + */ + Tone.Source.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this.unsync(); + this._scheduled = null; + this._writable('volume'); + this._volume.dispose(); + this._volume = null; + this.volume = null; + this._state.dispose(); + this._state = null; + }; + return Tone.Source; + }); + Module(function (Tone) { + + /** + * @class Tone.Oscillator supports a number of features including + * phase rotation, multiple oscillator types (see Tone.Oscillator.type), + * and Transport syncing (see Tone.Oscillator.syncFrequency). + * + * @constructor + * @extends {Tone.Source} + * @param {Frequency} [frequency] Starting frequency + * @param {string} [type] The oscillator type. Read more about type below. + * @example + * //make and start a 440hz sine tone + * var osc = new Tone.Oscillator(440, "sine").toMaster().start(); + */ + Tone.Oscillator = function () { + var options = this.optionsObject(arguments, [ + 'frequency', + 'type' + ], Tone.Oscillator.defaults); + Tone.Source.call(this, options); + /** + * the main oscillator + * @type {OscillatorNode} + * @private + */ + this._oscillator = null; + /** + * The frequency control. + * @type {Frequency} + * @signal + */ + this.frequency = new Tone.Signal(options.frequency, Tone.Type.Frequency); + /** + * The detune control signal. + * @type {Cents} + * @signal + */ + this.detune = new Tone.Signal(options.detune, Tone.Type.Cents); + /** + * the periodic wave + * @type {PeriodicWave} + * @private + */ + this._wave = null; + /** + * The partials of the oscillator + * @type {Array} + * @private + */ + this._partials = this.defaultArg(options.partials, [1]); + /** + * the phase of the oscillator + * between 0 - 360 + * @type {number} + * @private + */ + this._phase = options.phase; + /** + * the type of the oscillator + * @type {string} + * @private + */ + this._type = null; + //setup + this.type = options.type; + this.phase = this._phase; + this._readOnly([ + 'frequency', + 'detune' + ]); + }; + Tone.extend(Tone.Oscillator, Tone.Source); + /** + * the default parameters + * @type {Object} + */ + Tone.Oscillator.defaults = { + 'type': 'sine', + 'frequency': 440, + 'detune': 0, + 'phase': 0, + 'partials': [] + }; + /** + * The Oscillator types + * @enum {String} + */ + Tone.Oscillator.Type = { + Sine: 'sine', + Triangle: 'triangle', + Sawtooth: 'sawtooth', + Square: 'square', + Custom: 'custom' + }; + /** + * start the oscillator + * @param {Time} [time=now] + * @private + */ + Tone.Oscillator.prototype._start = function (time) { + //new oscillator with previous values + this._oscillator = this.context.createOscillator(); + this._oscillator.setPeriodicWave(this._wave); + //connect the control signal to the oscillator frequency & detune + this._oscillator.connect(this.output); + this.frequency.connect(this._oscillator.frequency); + this.detune.connect(this._oscillator.detune); + //start the oscillator + this._oscillator.start(this.toSeconds(time)); + }; + /** + * stop the oscillator + * @private + * @param {Time} [time=now] (optional) timing parameter + * @returns {Tone.Oscillator} this + */ + Tone.Oscillator.prototype._stop = function (time) { + if (this._oscillator) { + this._oscillator.stop(this.toSeconds(time)); + this._oscillator = null; + } + return this; + }; + /** + * Sync the signal to the Transport's bpm. Any changes to the transports bpm, + * will also affect the oscillators frequency. + * @returns {Tone.Oscillator} this + * @example + * Tone.Transport.bpm.value = 120; + * osc.frequency.value = 440; + * //the ration between the bpm and the frequency will be maintained + * osc.syncFrequency(); + * Tone.Transport.bpm.value = 240; + * // the frequency of the oscillator is doubled to 880 + */ + Tone.Oscillator.prototype.syncFrequency = function () { + Tone.Transport.syncSignal(this.frequency); + return this; + }; + /** + * Unsync the oscillator's frequency from the Transport. + * See Tone.Oscillator.syncFrequency + * @returns {Tone.Oscillator} this + */ + Tone.Oscillator.prototype.unsyncFrequency = function () { + Tone.Transport.unsyncSignal(this.frequency); + return this; + }; + /** + * The type of the oscillator: either sine, square, triangle, or sawtooth. Also capable of + * setting the first x number of partials of the oscillator. For example: "sine4" would + * set be the first 4 partials of the sine wave and "triangle8" would set the first + * 8 partials of the triangle wave. + *

+ * Uses PeriodicWave internally even for native types so that it can set the phase. + * PeriodicWave equations are from the + * [Webkit Web Audio implementation](https://code.google.com/p/chromium/codesearch#chromium/src/third_party/WebKit/Source/modules/webaudio/PeriodicWave.cpp&sq=package:chromium). + * + * @memberOf Tone.Oscillator# + * @type {string} + * @name type + * @example + * //set it to a square wave + * osc.type = "square"; + * @example + * //set the first 6 partials of a sawtooth wave + * osc.type = "sawtooth6"; + */ + Object.defineProperty(Tone.Oscillator.prototype, 'type', { + get: function () { + return this._type; + }, + set: function (type) { + var coefs = this._getRealImaginary(type, this._phase); + var periodicWave = this.context.createPeriodicWave(coefs[0], coefs[1]); + this._wave = periodicWave; + if (this._oscillator !== null) { + this._oscillator.setPeriodicWave(this._wave); + } + this._type = type; + } + }); + /** + * Returns the real and imaginary components based + * on the oscillator type. + * @returns {Array} [real, imaginary] + * @private + */ + Tone.Oscillator.prototype._getRealImaginary = function (type, phase) { + var fftSize = 4096; + var periodicWaveSize = fftSize / 2; + var real = new Float32Array(periodicWaveSize); + var imag = new Float32Array(periodicWaveSize); + var partialCount = 1; + if (type === Tone.Oscillator.Type.Custom) { + partialCount = this._partials.length + 1; + periodicWaveSize = partialCount; + } else { + var partial = /^(sine|triangle|square|sawtooth)(\d+)$/.exec(type); + if (partial) { + partialCount = parseInt(partial[2]) + 1; + type = partial[1]; + partialCount = Math.max(partialCount, 2); + periodicWaveSize = partialCount; + } + } + for (var n = 1; n < periodicWaveSize; ++n) { + var piFactor = 2 / (n * Math.PI); + var b; + switch (type) { + case Tone.Oscillator.Type.Sine: + b = n <= partialCount ? 1 : 0; + break; + case Tone.Oscillator.Type.Square: + b = n & 1 ? 2 * piFactor : 0; + break; + case Tone.Oscillator.Type.Sawtooth: + b = piFactor * (n & 1 ? 1 : -1); + break; + case Tone.Oscillator.Type.Triangle: + if (n & 1) { + b = 2 * (piFactor * piFactor) * (n - 1 >> 1 & 1 ? -1 : 1); + } else { + b = 0; + } + break; + case Tone.Oscillator.Type.Custom: + b = this._partials[n - 1]; + break; + default: + throw new TypeError('Tone.Oscillator: invalid type: ' + type); + } + if (b !== 0) { + real[n] = -b * Math.sin(phase * n); + imag[n] = b * Math.cos(phase * n); + } else { + real[n] = 0; + imag[n] = 0; + } + } + return [ + real, + imag + ]; + }; + /** + * Compute the inverse FFT for a given phase. + * @param {Float32Array} real + * @param {Float32Array} imag + * @param {NormalRange} phase + * @return {AudioRange} + * @private + */ + Tone.Oscillator.prototype._inverseFFT = function (real, imag, phase) { + var sum = 0; + var len = real.length; + for (var i = 0; i < len; i++) { + sum += real[i] * Math.cos(i * phase) + imag[i] * Math.sin(i * phase); + } + return sum; + }; + /** + * Returns the initial value of the oscillator. + * @return {AudioRange} + * @private + */ + Tone.Oscillator.prototype._getInitialValue = function () { + var coefs = this._getRealImaginary(this._type, 0); + var real = coefs[0]; + var imag = coefs[1]; + var maxValue = 0; + var twoPi = Math.PI * 2; + //check for peaks in 8 places + for (var i = 0; i < 8; i++) { + maxValue = Math.max(this._inverseFFT(real, imag, i / 8 * twoPi), maxValue); + } + return -this._inverseFFT(real, imag, this._phase) / maxValue; + }; + /** + * The partials of the waveform. A partial represents + * the amplitude at a harmonic. The first harmonic is the + * fundamental frequency, the second is the octave and so on + * following the harmonic series. + * Setting this value will automatically set the type to "custom". + * The value is an empty array when the type is not "custom". + * @memberOf Tone.Oscillator# + * @type {Array} + * @name partials + * @example + * osc.partials = [1, 0.2, 0.01]; + */ + Object.defineProperty(Tone.Oscillator.prototype, 'partials', { + get: function () { + if (this._type !== Tone.Oscillator.Type.Custom) { + return []; + } else { + return this._partials; + } + }, + set: function (partials) { + this._partials = partials; + this.type = Tone.Oscillator.Type.Custom; + } + }); + /** + * The phase of the oscillator in degrees. + * @memberOf Tone.Oscillator# + * @type {Degrees} + * @name phase + * @example + * osc.phase = 180; //flips the phase of the oscillator + */ + Object.defineProperty(Tone.Oscillator.prototype, 'phase', { + get: function () { + return this._phase * (180 / Math.PI); + }, + set: function (phase) { + this._phase = phase * Math.PI / 180; + //reset the type + this.type = this._type; + } + }); + /** + * Dispose and disconnect. + * @return {Tone.Oscillator} this + */ + Tone.Oscillator.prototype.dispose = function () { + Tone.Source.prototype.dispose.call(this); + if (this._oscillator !== null) { + this._oscillator.disconnect(); + this._oscillator = null; + } + this._wave = null; + this._writable([ + 'frequency', + 'detune' + ]); + this.frequency.dispose(); + this.frequency = null; + this.detune.dispose(); + this.detune = null; + this._partials = null; + return this; + }; + return Tone.Oscillator; + }); + Module(function (Tone) { + /** + * @class Tone.Zero outputs 0's at audio-rate. The reason this has to be + * it's own class is that many browsers optimize out Tone.Signal + * with a value of 0 and will not process nodes further down the graph. + * @extends {Tone} + */ + Tone.Zero = function () { + /** + * The gain node + * @type {Tone.Gain} + * @private + */ + this._gain = this.input = this.output = new Tone.Gain(); + Tone.Zero._zeros.connect(this._gain); + }; + Tone.extend(Tone.Zero); + /** + * clean up + * @return {Tone.Zero} this + */ + Tone.Zero.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._gain.dispose(); + this._gain = null; + return this; + }; + /** + * Generates a constant output of 0. This is so + * the processing graph doesn't optimize out this + * segment of the graph. + * @static + * @private + * @const + * @type {AudioBufferSourceNode} + */ + Tone.Zero._zeros = null; + /** + * initializer function + */ + Tone._initAudioContext(function (audioContext) { + var buffer = audioContext.createBuffer(1, 128, audioContext.sampleRate); + var arr = buffer.getChannelData(0); + for (var i = 0; i < arr.length; i++) { + arr[i] = 0; + } + Tone.Zero._zeros = audioContext.createBufferSource(); + Tone.Zero._zeros.channelCount = 1; + Tone.Zero._zeros.channelCountMode = 'explicit'; + Tone.Zero._zeros.buffer = buffer; + Tone.Zero._zeros.loop = true; + Tone.Zero._zeros.start(0); + Tone.Zero._zeros.noGC(); + }); + return Tone.Zero; + }); + Module(function (Tone) { + + /** + * @class LFO stands for low frequency oscillator. Tone.LFO produces an output signal + * which can be attached to an AudioParam or Tone.Signal + * in order to modulate that parameter with an oscillator. The LFO can + * also be synced to the transport to start/stop and change when the tempo changes. + * + * @constructor + * @extends {Tone.Oscillator} + * @param {Frequency|Object} [frequency] The frequency of the oscillation. Typically, LFOs will be + * in the frequency range of 0.1 to 10 hertz. + * @param {number=} min The minimum output value of the LFO. + * @param {number=} max The maximum value of the LFO. + * @example + * var lfo = new Tone.LFO("4n", 400, 4000); + * lfo.connect(filter.frequency); + */ + Tone.LFO = function () { + var options = this.optionsObject(arguments, [ + 'frequency', + 'min', + 'max' + ], Tone.LFO.defaults); + /** + * The oscillator. + * @type {Tone.Oscillator} + * @private + */ + this._oscillator = new Tone.Oscillator({ + 'frequency': options.frequency, + 'type': options.type + }); + /** + * the lfo's frequency + * @type {Frequency} + * @signal + */ + this.frequency = this._oscillator.frequency; + /** + * The amplitude of the LFO, which controls the output range between + * the min and max output. For example if the min is -10 and the max + * is 10, setting the amplitude to 0.5 would make the LFO modulate + * between -5 and 5. + * @type {Number} + * @signal + */ + this.amplitude = this._oscillator.volume; + this.amplitude.units = Tone.Type.NormalRange; + this.amplitude.value = options.amplitude; + /** + * The signal which is output when the LFO is stopped + * @type {Tone.Signal} + * @private + */ + this._stoppedSignal = new Tone.Signal(0, Tone.Type.AudioRange); + /** + * Just outputs zeros. + * @type {Tone.Zero} + * @private + */ + this._zeros = new Tone.Zero(); + /** + * The value that the LFO outputs when it's stopped + * @type {AudioRange} + * @private + */ + this._stoppedValue = 0; + /** + * @type {Tone.AudioToGain} + * @private + */ + this._a2g = new Tone.AudioToGain(); + /** + * @type {Tone.Scale} + * @private + */ + this._scaler = this.output = new Tone.Scale(options.min, options.max); + /** + * the units of the LFO (used for converting) + * @type {Tone.Type} + * @private + */ + this._units = Tone.Type.Default; + this.units = options.units; + //connect it up + this._oscillator.chain(this._a2g, this._scaler); + this._zeros.connect(this._a2g); + this._stoppedSignal.connect(this._a2g); + this._readOnly([ + 'amplitude', + 'frequency' + ]); + this.phase = options.phase; + }; + Tone.extend(Tone.LFO, Tone.Oscillator); + /** + * the default parameters + * + * @static + * @const + * @type {Object} + */ + Tone.LFO.defaults = { + 'type': 'sine', + 'min': 0, + 'max': 1, + 'phase': 0, + 'frequency': '4n', + 'amplitude': 1, + 'units': Tone.Type.Default + }; + /** + * Start the LFO. + * @param {Time} [time=now] the time the LFO will start + * @returns {Tone.LFO} this + */ + Tone.LFO.prototype.start = function (time) { + time = this.toSeconds(time); + this._stoppedSignal.setValueAtTime(0, time); + this._oscillator.start(time); + return this; + }; + /** + * Stop the LFO. + * @param {Time} [time=now] the time the LFO will stop + * @returns {Tone.LFO} this + */ + Tone.LFO.prototype.stop = function (time) { + time = this.toSeconds(time); + this._stoppedSignal.setValueAtTime(this._stoppedValue, time); + this._oscillator.stop(time); + return this; + }; + /** + * Sync the start/stop/pause to the transport + * and the frequency to the bpm of the transport + * @returns {Tone.LFO} this + * @example + * lfo.frequency.value = "8n"; + * lfo.sync().start(0) + * //the rate of the LFO will always be an eighth note, + * //even as the tempo changes + */ + Tone.LFO.prototype.sync = function () { + this._oscillator.sync(); + this._oscillator.syncFrequency(); + return this; + }; + /** + * unsync the LFO from transport control + * @returns {Tone.LFO} this + */ + Tone.LFO.prototype.unsync = function () { + this._oscillator.unsync(); + this._oscillator.unsyncFrequency(); + return this; + }; + /** + * The miniumum output of the LFO. + * @memberOf Tone.LFO# + * @type {number} + * @name min + */ + Object.defineProperty(Tone.LFO.prototype, 'min', { + get: function () { + return this._toUnits(this._scaler.min); + }, + set: function (min) { + min = this._fromUnits(min); + this._scaler.min = min; + } + }); + /** + * The maximum output of the LFO. + * @memberOf Tone.LFO# + * @type {number} + * @name max + */ + Object.defineProperty(Tone.LFO.prototype, 'max', { + get: function () { + return this._toUnits(this._scaler.max); + }, + set: function (max) { + max = this._fromUnits(max); + this._scaler.max = max; + } + }); + /** + * The type of the oscillator: sine, square, sawtooth, triangle. + * @memberOf Tone.LFO# + * @type {string} + * @name type + */ + Object.defineProperty(Tone.LFO.prototype, 'type', { + get: function () { + return this._oscillator.type; + }, + set: function (type) { + this._oscillator.type = type; + this._stoppedValue = this._oscillator._getInitialValue(); + this._stoppedSignal.value = this._stoppedValue; + } + }); + /** + * The phase of the LFO. + * @memberOf Tone.LFO# + * @type {number} + * @name phase + */ + Object.defineProperty(Tone.LFO.prototype, 'phase', { + get: function () { + return this._oscillator.phase; + }, + set: function (phase) { + this._oscillator.phase = phase; + this._stoppedValue = this._oscillator._getInitialValue(); + this._stoppedSignal.value = this._stoppedValue; + } + }); + /** + * The output units of the LFO. + * @memberOf Tone.LFO# + * @type {Tone.Type} + * @name units + */ + Object.defineProperty(Tone.LFO.prototype, 'units', { + get: function () { + return this._units; + }, + set: function (val) { + var currentMin = this.min; + var currentMax = this.max; + //convert the min and the max + this._units = val; + this.min = currentMin; + this.max = currentMax; + } + }); + /** + * Mute the output. + * @memberOf Tone.LFO# + * @type {Boolean} + * @name mute + */ + Object.defineProperty(Tone.LFO.prototype, 'mute', { + get: function () { + return this._oscillator.mute; + }, + set: function (mute) { + this._oscillator.mute = mute; + } + }); + /** + * Returns the playback state of the source, either "started" or "stopped". + * @type {Tone.State} + * @readOnly + * @memberOf Tone.LFO# + * @name state + */ + Object.defineProperty(Tone.LFO.prototype, 'state', { + get: function () { + return this._oscillator.state; + } + }); + /** + * Connect the output of the LFO to an AudioParam, AudioNode, or Tone Node. + * Tone.LFO will automatically convert to the destination units of the + * will get the units from the connected node. + * @param {Tone | AudioParam | AudioNode} node + * @param {number} [outputNum=0] optionally which output to connect from + * @param {number} [inputNum=0] optionally which input to connect to + * @returns {Tone.LFO} this + * @private + */ + Tone.LFO.prototype.connect = function (node) { + if (node.constructor === Tone.Signal || node.constructor === Tone.Param || node.constructor === Tone.TimelineSignal) { + this.convert = node.convert; + this.units = node.units; + } + Tone.Signal.prototype.connect.apply(this, arguments); + return this; + }; + /** + * private method borrowed from Param converts + * units from their destination value + * @function + * @private + */ + Tone.LFO.prototype._fromUnits = Tone.Param.prototype._fromUnits; + /** + * private method borrowed from Param converts + * units to their destination value + * @function + * @private + */ + Tone.LFO.prototype._toUnits = Tone.Param.prototype._toUnits; + /** + * disconnect and dispose + * @returns {Tone.LFO} this + */ + Tone.LFO.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._writable([ + 'amplitude', + 'frequency' + ]); + this._oscillator.dispose(); + this._oscillator = null; + this._stoppedSignal.dispose(); + this._stoppedSignal = null; + this._zeros.dispose(); + this._zeros = null; + this._scaler.dispose(); + this._scaler = null; + this._a2g.dispose(); + this._a2g = null; + this.frequency = null; + this.amplitude = null; + return this; + }; + return Tone.LFO; + }); + Module(function (Tone) { + + /** + * @class Tone.Limiter will limit the loudness of an incoming signal. + * It is composed of a Tone.Compressor with a fast attack + * and release. Limiters are commonly used to safeguard against + * signal clipping. Unlike a compressor, limiters do not provide + * smooth gain reduction and almost completely prevent + * additional gain above the threshold. + * + * @extends {Tone} + * @constructor + * @param {number} threshold The theshold above which the limiting is applied. + * @example + * var limiter = new Tone.Limiter(-6); + */ + Tone.Limiter = function () { + var options = this.optionsObject(arguments, ['threshold'], Tone.Limiter.defaults); + /** + * the compressor + * @private + * @type {Tone.Compressor} + */ + this._compressor = this.input = this.output = new Tone.Compressor({ + 'attack': 0.001, + 'decay': 0.001, + 'threshold': options.threshold + }); + /** + * The threshold of of the limiter + * @type {Decibel} + * @signal + */ + this.threshold = this._compressor.threshold; + this._readOnly('threshold'); + }; + Tone.extend(Tone.Limiter); + /** + * The default value + * @type {Object} + * @const + * @static + */ + Tone.Limiter.defaults = { 'threshold': -12 }; + /** + * Clean up. + * @returns {Tone.Limiter} this + */ + Tone.Limiter.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._compressor.dispose(); + this._compressor = null; + this._writable('threshold'); + this.threshold = null; + return this; + }; + return Tone.Limiter; + }); + Module(function (Tone) { + + /** + * @class Tone.Lowpass is a lowpass feedback comb filter. It is similar to + * Tone.FeedbackCombFilter, but includes a lowpass filter. + * + * @extends {Tone} + * @constructor + * @param {Time|Object} [delayTime] The delay time of the comb filter + * @param {NormalRange=} resonance The resonance (feedback) of the comb filter + * @param {Frequency=} dampening The cutoff of the lowpass filter dampens the + * signal as it is fedback. + */ + Tone.LowpassCombFilter = function () { + this.createInsOuts(1, 1); + var options = this.optionsObject(arguments, [ + 'delayTime', + 'resonance', + 'dampening' + ], Tone.LowpassCombFilter.defaults); + /** + * the delay node + * @type {DelayNode} + * @private + */ + this._delay = this.input = new Tone.Delay(options.delayTime); + /** + * The delayTime of the comb filter. + * @type {Time} + * @signal + */ + this.delayTime = this._delay.delayTime; + /** + * the lowpass filter + * @type {BiquadFilterNode} + * @private + */ + this._lowpass = this.output = this.context.createBiquadFilter(); + this._lowpass.Q.value = -3.0102999566398125; + this._lowpass.type = 'lowpass'; + /** + * The dampening control of the feedback + * @type {Frequency} + * @signal + */ + this.dampening = new Tone.Param({ + 'param': this._lowpass.frequency, + 'units': Tone.Type.Frequency, + 'value': options.dampening + }); + /** + * the feedback gain + * @type {Tone.Gain} + * @private + */ + this._feedback = new Tone.Gain(options.resonance, Tone.Type.NormalRange); + /** + * The amount of feedback of the delayed signal. + * @type {NormalRange} + * @signal + */ + this.resonance = this._feedback.gain; + //connections + this._delay.chain(this._lowpass, this._feedback, this._delay); + this._readOnly([ + 'dampening', + 'resonance', + 'delayTime' + ]); + }; + Tone.extend(Tone.LowpassCombFilter); + /** + * the default parameters + * @static + * @const + * @type {Object} + */ + Tone.LowpassCombFilter.defaults = { + 'delayTime': 0.1, + 'resonance': 0.5, + 'dampening': 3000 + }; + /** + * Clean up. + * @returns {Tone.LowpassCombFilter} this + */ + Tone.LowpassCombFilter.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._writable([ + 'dampening', + 'resonance', + 'delayTime' + ]); + this.dampening.dispose(); + this.dampening = null; + this.resonance.dispose(); + this.resonance = null; + this._delay.dispose(); + this._delay = null; + this.delayTime = null; + this._lowpass.disconnect(); + this._lowpass = null; + this._feedback.disconnect(); + this._feedback = null; + return this; + }; + return Tone.LowpassCombFilter; + }); + Module(function (Tone) { + + /** + * @class Tone.Merge brings two signals into the left and right + * channels of a single stereo channel. + * + * @constructor + * @extends {Tone} + * @example + * var merge = new Tone.Merge().toMaster(); + * //routing a sine tone in the left channel + * //and noise in the right channel + * var osc = new Tone.Oscillator().connect(merge.left); + * var noise = new Tone.Noise().connect(merge.right); + * //starting our oscillators + * noise.start(); + * osc.start(); + */ + Tone.Merge = function () { + this.createInsOuts(2, 0); + /** + * The left input channel. + * Alias for input[0] + * @type {GainNode} + */ + this.left = this.input[0] = new Tone.Gain(); + /** + * The right input channel. + * Alias for input[1]. + * @type {GainNode} + */ + this.right = this.input[1] = new Tone.Gain(); + /** + * the merger node for the two channels + * @type {ChannelMergerNode} + * @private + */ + this._merger = this.output = this.context.createChannelMerger(2); + //connections + this.left.connect(this._merger, 0, 0); + this.right.connect(this._merger, 0, 1); + this.left.channelCount = 1; + this.right.channelCount = 1; + this.left.channelCountMode = 'explicit'; + this.right.channelCountMode = 'explicit'; + }; + Tone.extend(Tone.Merge); + /** + * Clean up. + * @returns {Tone.Merge} this + */ + Tone.Merge.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this.left.dispose(); + this.left = null; + this.right.dispose(); + this.right = null; + this._merger.disconnect(); + this._merger = null; + return this; + }; + return Tone.Merge; + }); + Module(function (Tone) { + + /** + * @class Tone.Meter gets the [RMS](https://en.wikipedia.org/wiki/Root_mean_square) + * of an input signal with some averaging applied. It can also get the raw + * value of the input signal. + * + * @constructor + * @extends {Tone} + * @param {String} type Either "level" or "signal". + * @param {Number} smoothing The amount of smoothing applied between frames. + * @example + * var meter = new Tone.Meter(); + * var mic = new Tone.UserMedia().start(); + * //connect mic to the meter + * mic.connect(meter); + * //the current level of the mic input + * var level = meter.value; + */ + Tone.Meter = function () { + var options = this.optionsObject(arguments, [ + 'type', + 'smoothing' + ], Tone.Meter.defaults); + /** + * The type of the meter, either "level" or "signal". + * A "level" meter will return the volume level (rms) of the + * input signal and a "signal" meter will return + * the signal value of the input. + * @type {String} + */ + this.type = options.type; + /** + * The analyser node which computes the levels. + * @private + * @type {Tone.Analyser} + */ + this.input = this.output = this._analyser = new Tone.Analyser('waveform', 512); + this._analyser.returnType = 'float'; + /** + * The amount of carryover between the current and last frame. + * Only applied meter for "level" type. + * @type {Number} + */ + this.smoothing = options.smoothing; + /** + * The last computed value + * @type {Number} + * @private + */ + this._lastValue = 0; + }; + Tone.extend(Tone.Meter); + /** + * @private + * @enum {String} + */ + Tone.Meter.Type = { + Level: 'level', + Signal: 'signal' + }; + /** + * The defaults + * @type {Object} + * @static + * @const + */ + Tone.Meter.defaults = { + 'smoothing': 0.8, + 'type': Tone.Meter.Type.Level + }; + /** + * The current value of the meter. A value of 1 is + * "unity". + * @memberOf Tone.Meter# + * @type {Number} + * @name value + * @readOnly + */ + Object.defineProperty(Tone.Meter.prototype, 'value', { + get: function () { + var signal = this._analyser.analyse(); + if (this.type === Tone.Meter.Type.Level) { + //rms + var sum = 0; + for (var i = 0; i < signal.length; i++) { + sum += Math.pow(signal[i], 2); + } + var rms = Math.sqrt(sum / signal.length); + //smooth it + rms = Math.max(rms, this._lastValue * this.smoothing); + this._lastValue = rms; + //scale it + var unity = 0.35; + var val = rms / unity; + //scale the output curve + return Math.sqrt(val); + } else { + return signal[0]; + } + } + }); + /** + * Clean up. + * @returns {Tone.Meter} this + */ + Tone.Meter.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._analyser.dispose(); + this._analyser = null; + return this; + }; + return Tone.Meter; + }); + Module(function (Tone) { + + /** + * @class Tone.Split splits an incoming signal into left and right channels. + * + * @constructor + * @extends {Tone} + * @example + * var split = new Tone.Split(); + * stereoSignal.connect(split); + */ + Tone.Split = function () { + this.createInsOuts(0, 2); + /** + * @type {ChannelSplitterNode} + * @private + */ + this._splitter = this.input = this.context.createChannelSplitter(2); + /** + * Left channel output. + * Alias for output[0] + * @type {Tone.Gain} + */ + this.left = this.output[0] = new Tone.Gain(); + /** + * Right channel output. + * Alias for output[1] + * @type {Tone.Gain} + */ + this.right = this.output[1] = new Tone.Gain(); + //connections + this._splitter.connect(this.left, 0, 0); + this._splitter.connect(this.right, 1, 0); + }; + Tone.extend(Tone.Split); + /** + * Clean up. + * @returns {Tone.Split} this + */ + Tone.Split.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._splitter.disconnect(); + this.left.dispose(); + this.left = null; + this.right.dispose(); + this.right = null; + this._splitter = null; + return this; + }; + return Tone.Split; + }); + Module(function (Tone) { + + /** + * @class Mid/Side processing separates the the 'mid' signal + * (which comes out of both the left and the right channel) + * and the 'side' (which only comes out of the the side channels).

+ * + * Mid = (Left+Right)/sqrt(2); // obtain mid-signal from left and right
+ * Side = (Left-Right)/sqrt(2); // obtain side-signal from left and righ
+ *
+ * + * @extends {Tone} + * @constructor + */ + Tone.MidSideSplit = function () { + this.createInsOuts(0, 2); + /** + * split the incoming signal into left and right channels + * @type {Tone.Split} + * @private + */ + this._split = this.input = new Tone.Split(); + /** + * The mid send. Connect to mid processing. Alias for + * output[0] + * @type {Tone.Expr} + */ + this.mid = this.output[0] = new Tone.Expr('($0 + $1) * $2'); + /** + * The side output. Connect to side processing. Alias for + * output[1] + * @type {Tone.Expr} + */ + this.side = this.output[1] = new Tone.Expr('($0 - $1) * $2'); + this._split.connect(this.mid, 0, 0); + this._split.connect(this.mid, 1, 1); + this._split.connect(this.side, 0, 0); + this._split.connect(this.side, 1, 1); + sqrtTwo.connect(this.mid, 0, 2); + sqrtTwo.connect(this.side, 0, 2); + }; + Tone.extend(Tone.MidSideSplit); + /** + * a constant signal equal to 1 / sqrt(2) + * @type {Number} + * @signal + * @private + * @static + */ + var sqrtTwo = null; + Tone._initAudioContext(function () { + sqrtTwo = new Tone.Signal(1 / Math.sqrt(2)); + }); + /** + * clean up + * @returns {Tone.MidSideSplit} this + */ + Tone.MidSideSplit.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this.mid.dispose(); + this.mid = null; + this.side.dispose(); + this.side = null; + this._split.dispose(); + this._split = null; + return this; + }; + return Tone.MidSideSplit; + }); + Module(function (Tone) { + + /** + * @class Mid/Side processing separates the the 'mid' signal + * (which comes out of both the left and the right channel) + * and the 'side' (which only comes out of the the side channels). + * MidSideMerge merges the mid and side signal after they've been seperated + * by Tone.MidSideSplit.

+ * + * Left = (Mid+Side)/sqrt(2); // obtain left signal from mid and side
+ * Right = (Mid-Side)/sqrt(2); // obtain right signal from mid and side
+ *
+ * + * @extends {Tone.StereoEffect} + * @constructor + */ + Tone.MidSideMerge = function () { + this.createInsOuts(2, 0); + /** + * The mid signal input. Alias for + * input[0] + * @type {Tone.Gain} + */ + this.mid = this.input[0] = new Tone.Gain(); + /** + * recombine the mid/side into Left + * @type {Tone.Expr} + * @private + */ + this._left = new Tone.Expr('($0 + $1) * $2'); + /** + * The side signal input. Alias for + * input[1] + * @type {Tone.Gain} + */ + this.side = this.input[1] = new Tone.Gain(); + /** + * recombine the mid/side into Right + * @type {Tone.Expr} + * @private + */ + this._right = new Tone.Expr('($0 - $1) * $2'); + /** + * Merge the left/right signal back into a stereo signal. + * @type {Tone.Merge} + * @private + */ + this._merge = this.output = new Tone.Merge(); + this.mid.connect(this._left, 0, 0); + this.side.connect(this._left, 0, 1); + this.mid.connect(this._right, 0, 0); + this.side.connect(this._right, 0, 1); + this._left.connect(this._merge, 0, 0); + this._right.connect(this._merge, 0, 1); + sqrtTwo.connect(this._left, 0, 2); + sqrtTwo.connect(this._right, 0, 2); + }; + Tone.extend(Tone.MidSideMerge); + /** + * A constant signal equal to 1 / sqrt(2). + * @type {Number} + * @signal + * @private + * @static + */ + var sqrtTwo = null; + Tone._initAudioContext(function () { + sqrtTwo = new Tone.Signal(1 / Math.sqrt(2)); + }); + /** + * clean up + * @returns {Tone.MidSideMerge} this + */ + Tone.MidSideMerge.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this.mid.dispose(); + this.mid = null; + this.side.dispose(); + this.side = null; + this._left.dispose(); + this._left = null; + this._right.dispose(); + this._right = null; + this._merge.dispose(); + this._merge = null; + return this; + }; + return Tone.MidSideMerge; + }); + Module(function (Tone) { + + /** + * @class Tone.MidSideCompressor applies two different compressors to the mid + * and side signal components. See Tone.MidSideSplit. + * + * @extends {Tone} + * @param {Object} options The options that are passed to the mid and side + * compressors. + * @constructor + */ + Tone.MidSideCompressor = function (options) { + options = this.defaultArg(options, Tone.MidSideCompressor.defaults); + /** + * the mid/side split + * @type {Tone.MidSideSplit} + * @private + */ + this._midSideSplit = this.input = new Tone.MidSideSplit(); + /** + * the mid/side recombination + * @type {Tone.MidSideMerge} + * @private + */ + this._midSideMerge = this.output = new Tone.MidSideMerge(); + /** + * The compressor applied to the mid signal + * @type {Tone.Compressor} + */ + this.mid = new Tone.Compressor(options.mid); + /** + * The compressor applied to the side signal + * @type {Tone.Compressor} + */ + this.side = new Tone.Compressor(options.side); + this._midSideSplit.mid.chain(this.mid, this._midSideMerge.mid); + this._midSideSplit.side.chain(this.side, this._midSideMerge.side); + this._readOnly([ + 'mid', + 'side' + ]); + }; + Tone.extend(Tone.MidSideCompressor); + /** + * @const + * @static + * @type {Object} + */ + Tone.MidSideCompressor.defaults = { + 'mid': { + 'ratio': 3, + 'threshold': -24, + 'release': 0.03, + 'attack': 0.02, + 'knee': 16 + }, + 'side': { + 'ratio': 6, + 'threshold': -30, + 'release': 0.25, + 'attack': 0.03, + 'knee': 10 + } + }; + /** + * Clean up. + * @returns {Tone.MidSideCompressor} this + */ + Tone.MidSideCompressor.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._writable([ + 'mid', + 'side' + ]); + this.mid.dispose(); + this.mid = null; + this.side.dispose(); + this.side = null; + this._midSideSplit.dispose(); + this._midSideSplit = null; + this._midSideMerge.dispose(); + this._midSideMerge = null; + return this; + }; + return Tone.MidSideCompressor; + }); + Module(function (Tone) { + + /** + * @class Tone.Mono coerces the incoming mono or stereo signal into a mono signal + * where both left and right channels have the same value. This can be useful + * for [stereo imaging](https://en.wikipedia.org/wiki/Stereo_imaging). + * + * @extends {Tone} + * @constructor + */ + Tone.Mono = function () { + this.createInsOuts(1, 0); + /** + * merge the signal + * @type {Tone.Merge} + * @private + */ + this._merge = this.output = new Tone.Merge(); + this.input.connect(this._merge, 0, 0); + this.input.connect(this._merge, 0, 1); + this.input.gain.value = this.dbToGain(-10); + }; + Tone.extend(Tone.Mono); + /** + * clean up + * @returns {Tone.Mono} this + */ + Tone.Mono.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._merge.dispose(); + this._merge = null; + return this; + }; + return Tone.Mono; + }); + Module(function (Tone) { + + /** + * @class A compressor with seperate controls over low/mid/high dynamics + * + * @extends {Tone} + * @constructor + * @param {Object} options The low/mid/high compressor settings. + * @example + * var multiband = new Tone.MultibandCompressor({ + * "lowFrequency" : 200, + * "highFrequency" : 1300 + * "low" : { + * "threshold" : -12 + * } + * }) + */ + Tone.MultibandCompressor = function (options) { + options = this.defaultArg(arguments, Tone.MultibandCompressor.defaults); + /** + * split the incoming signal into high/mid/low + * @type {Tone.MultibandSplit} + * @private + */ + this._splitter = this.input = new Tone.MultibandSplit({ + 'lowFrequency': options.lowFrequency, + 'highFrequency': options.highFrequency + }); + /** + * low/mid crossover frequency. + * @type {Frequency} + * @signal + */ + this.lowFrequency = this._splitter.lowFrequency; + /** + * mid/high crossover frequency. + * @type {Frequency} + * @signal + */ + this.highFrequency = this._splitter.highFrequency; + /** + * the output + * @type {Tone.Gain} + * @private + */ + this.output = new Tone.Gain(); + /** + * The compressor applied to the low frequencies. + * @type {Tone.Compressor} + */ + this.low = new Tone.Compressor(options.low); + /** + * The compressor applied to the mid frequencies. + * @type {Tone.Compressor} + */ + this.mid = new Tone.Compressor(options.mid); + /** + * The compressor applied to the high frequencies. + * @type {Tone.Compressor} + */ + this.high = new Tone.Compressor(options.high); + //connect the compressor + this._splitter.low.chain(this.low, this.output); + this._splitter.mid.chain(this.mid, this.output); + this._splitter.high.chain(this.high, this.output); + this._readOnly([ + 'high', + 'mid', + 'low', + 'highFrequency', + 'lowFrequency' + ]); + }; + Tone.extend(Tone.MultibandCompressor); + /** + * @const + * @static + * @type {Object} + */ + Tone.MultibandCompressor.defaults = { + 'low': Tone.Compressor.defaults, + 'mid': Tone.Compressor.defaults, + 'high': Tone.Compressor.defaults, + 'lowFrequency': 250, + 'highFrequency': 2000 + }; + /** + * clean up + * @returns {Tone.MultibandCompressor} this + */ + Tone.MultibandCompressor.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._splitter.dispose(); + this._writable([ + 'high', + 'mid', + 'low', + 'highFrequency', + 'lowFrequency' + ]); + this.low.dispose(); + this.mid.dispose(); + this.high.dispose(); + this._splitter = null; + this.low = null; + this.mid = null; + this.high = null; + this.lowFrequency = null; + this.highFrequency = null; + return this; + }; + return Tone.MultibandCompressor; + }); + Module(function (Tone) { + + /** + * @class Tone.Panner is an equal power Left/Right Panner and does not + * support 3D. Panner uses the StereoPannerNode when available. + * + * @constructor + * @extends {Tone} + * @param {NormalRange} [initialPan=0] The initail panner value (defaults to 0 = center) + * @example + * //pan the input signal hard right. + * var panner = new Tone.Panner(1); + */ + Tone.Panner = function (initialPan) { + if (this._hasStereoPanner) { + /** + * the panner node + * @type {StereoPannerNode} + * @private + */ + this._panner = this.input = this.output = this.context.createStereoPanner(); + /** + * The pan control. -1 = hard left, 1 = hard right. + * @type {NormalRange} + * @signal + */ + this.pan = this._panner.pan; + } else { + /** + * the dry/wet knob + * @type {Tone.CrossFade} + * @private + */ + this._crossFade = new Tone.CrossFade(); + /** + * @type {Tone.Merge} + * @private + */ + this._merger = this.output = new Tone.Merge(); + /** + * @type {Tone.Split} + * @private + */ + this._splitter = this.input = new Tone.Split(); + /** + * The pan control. -1 = hard left, 1 = hard right. + * @type {AudioRange} + * @signal + */ + this.pan = new Tone.Signal(0, Tone.Type.AudioRange); + /** + * always sends 0 + * @type {Tone.Zero} + * @private + */ + this._zero = new Tone.Zero(); + /** + * The analog to gain conversion + * @type {Tone.AudioToGain} + * @private + */ + this._a2g = new Tone.AudioToGain(); + //CONNECTIONS: + this._zero.connect(this._a2g); + this.pan.chain(this._a2g, this._crossFade.fade); + //left channel is a, right channel is b + this._splitter.connect(this._crossFade, 0, 0); + this._splitter.connect(this._crossFade, 1, 1); + //merge it back together + this._crossFade.a.connect(this._merger, 0, 0); + this._crossFade.b.connect(this._merger, 0, 1); + } + //initial value + this.pan.value = this.defaultArg(initialPan, 0); + this._readOnly('pan'); + }; + Tone.extend(Tone.Panner); + /** + * indicates if the panner is using the new StereoPannerNode internally + * @type {boolean} + * @private + */ + Tone.Panner.prototype._hasStereoPanner = Tone.prototype.isFunction(Tone.context.createStereoPanner); + /** + * Clean up. + * @returns {Tone.Panner} this + */ + Tone.Panner.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._writable('pan'); + if (this._hasStereoPanner) { + this._panner.disconnect(); + this._panner = null; + this.pan = null; + } else { + this._zero.dispose(); + this._zero = null; + this._crossFade.dispose(); + this._crossFade = null; + this._splitter.dispose(); + this._splitter = null; + this._merger.dispose(); + this._merger = null; + this.pan.dispose(); + this.pan = null; + this._a2g.dispose(); + this._a2g = null; + } + return this; + }; + return Tone.Panner; + }); + Module(function (Tone) { + + /** + * @class A spatialized panner node which supports equalpower or HRTF panning. + * Tries to normalize the API across various browsers. See Tone.Listener + * + * @constructor + * @extends {Tone} + * @param {Number} positionX The initial x position. + * @param {Number} positionY The initial y position. + * @param {Number} positionZ The initial z position. + */ + Tone.Panner3D = function () { + var options = this.optionsObject(arguments, [ + 'positionX', + 'positionY', + 'positionZ' + ], Tone.Panner3D.defaults); + /** + * The panner node + * @type {PannerNode} + * @private + */ + this._panner = this.input = this.output = this.context.createPanner(); + //set some values + this._panner.panningModel = options.panningModel; + this._panner.maxDistance = options.maxDistance; + this._panner.distanceModel = options.distanceModel; + this._panner.coneOuterGain = options.coneOuterGain; + this._panner.coneOuterAngle = options.coneOuterAngle; + this._panner.coneInnerAngle = options.coneInnerAngle; + this._panner.refDistance = options.refDistance; + this._panner.rolloffFactor = options.rolloffFactor; + /** + * Holds the current orientation + * @type {Array} + * @private + */ + this._orientation = [ + options.orientationX, + options.orientationY, + options.orientationZ + ]; + /** + * Holds the current position + * @type {Array} + * @private + */ + this._position = [ + options.positionX, + options.positionY, + options.positionZ + ]; + // set the default position/orientation + this.orientationX = options.orientationX; + this.orientationY = options.orientationY; + this.orientationZ = options.orientationZ; + this.positionX = options.positionX; + this.positionY = options.positionY; + this.positionZ = options.positionZ; + }; + Tone.extend(Tone.Panner3D); + /** + * the default parameters + * @static + * @const + * @type {Object} + * Defaults according to the specification + */ + Tone.Panner3D.defaults = { + 'positionX': 0, + 'positionY': 0, + 'positionZ': 0, + 'orientationX': 0, + 'orientationY': 0, + 'orientationZ': 0, + 'panningModel': 'equalpower', + 'maxDistance': 10000, + 'distanceModel': 'inverse', + 'coneOuterGain': 0, + 'coneOuterAngle': 360, + 'coneInnerAngle': 360, + 'refDistance': 1, + 'rolloffFactor': 1 + }; + /** + * The ramp time which is applied to the setTargetAtTime + * @type {Number} + * @private + */ + Tone.Panner3D.prototype._rampTimeConstant = 0.01; + /** + * Sets the position of the source in 3d space. + * @param {Number} x + * @param {Number} y + * @param {Number} z + * @return {Tone.Panner3D} this + */ + Tone.Panner3D.prototype.setPosition = function (x, y, z) { + if (this._panner.positionX) { + var now = this.now(); + this._panner.positionX.setTargetAtTime(x, now, this._rampTimeConstant); + this._panner.positionY.setTargetAtTime(y, now, this._rampTimeConstant); + this._panner.positionZ.setTargetAtTime(z, now, this._rampTimeConstant); + } else { + this._panner.setPosition(x, y, z); + } + this._position = Array.prototype.slice.call(arguments); + return this; + }; + /** + * Sets the orientation of the source in 3d space. + * @param {Number} x + * @param {Number} y + * @param {Number} z + * @return {Tone.Panner3D} this + */ + Tone.Panner3D.prototype.setOrientation = function (x, y, z) { + if (this._panner.orientationX) { + var now = this.now(); + this._panner.orientationX.setTargetAtTime(x, now, this._rampTimeConstant); + this._panner.orientationY.setTargetAtTime(y, now, this._rampTimeConstant); + this._panner.orientationZ.setTargetAtTime(z, now, this._rampTimeConstant); + } else { + this._panner.setOrientation(x, y, z); + } + this._orientation = Array.prototype.slice.call(arguments); + return this; + }; + /** + * The x position of the panner object. + * @type {Number} + * @memberOf Tone.Panner3D# + * @name positionX + */ + Object.defineProperty(Tone.Panner3D.prototype, 'positionX', { + set: function (pos) { + this._position[0] = pos; + this.setPosition.apply(this, this._position); + }, + get: function () { + return this._position[0]; + } + }); + /** + * The y position of the panner object. + * @type {Number} + * @memberOf Tone.Panner3D# + * @name positionY + */ + Object.defineProperty(Tone.Panner3D.prototype, 'positionY', { + set: function (pos) { + this._position[1] = pos; + this.setPosition.apply(this, this._position); + }, + get: function () { + return this._position[1]; + } + }); + /** + * The z position of the panner object. + * @type {Number} + * @memberOf Tone.Panner3D# + * @name positionZ + */ + Object.defineProperty(Tone.Panner3D.prototype, 'positionZ', { + set: function (pos) { + this._position[2] = pos; + this.setPosition.apply(this, this._position); + }, + get: function () { + return this._position[2]; + } + }); + /** + * The x orientation of the panner object. + * @type {Number} + * @memberOf Tone.Panner3D# + * @name orientationX + */ + Object.defineProperty(Tone.Panner3D.prototype, 'orientationX', { + set: function (pos) { + this._orientation[0] = pos; + this.setOrientation.apply(this, this._orientation); + }, + get: function () { + return this._orientation[0]; + } + }); + /** + * The y orientation of the panner object. + * @type {Number} + * @memberOf Tone.Panner3D# + * @name orientationY + */ + Object.defineProperty(Tone.Panner3D.prototype, 'orientationY', { + set: function (pos) { + this._orientation[1] = pos; + this.setOrientation.apply(this, this._orientation); + }, + get: function () { + return this._orientation[1]; + } + }); + /** + * The z orientation of the panner object. + * @type {Number} + * @memberOf Tone.Panner3D# + * @name orientationZ + */ + Object.defineProperty(Tone.Panner3D.prototype, 'orientationZ', { + set: function (pos) { + this._orientation[2] = pos; + this.setOrientation.apply(this, this._orientation); + }, + get: function () { + return this._orientation[2]; + } + }); + /** + * Proxy a property on the panner to an exposed public propery + * @param {String} prop + * @private + */ + Tone.Panner3D._aliasProperty = function (prop) { + Object.defineProperty(Tone.Panner3D.prototype, prop, { + set: function (val) { + this._panner[prop] = val; + }, + get: function () { + return this._panner[prop]; + } + }); + }; + /** + * The panning model. Either "equalpower" or "HRTF". + * @type {String} + * @memberOf Tone.Panner3D# + * @name panningModel + */ + Tone.Panner3D._aliasProperty('panningModel'); + /** + * A reference distance for reducing volume as source move further from the listener + * @type {Number} + * @memberOf Tone.Panner3D# + * @name refDistance + */ + Tone.Panner3D._aliasProperty('refDistance'); + /** + * Describes how quickly the volume is reduced as source moves away from listener. + * @type {Number} + * @memberOf Tone.Panner3D# + * @name rolloffFactor + */ + Tone.Panner3D._aliasProperty('rolloffFactor'); + /** + * The distance model used by, "linear", "inverse", or "exponential". + * @type {String} + * @memberOf Tone.Panner3D# + * @name distanceModel + */ + Tone.Panner3D._aliasProperty('distanceModel'); + /** + * The angle, in degrees, inside of which there will be no volume reduction + * @type {Degrees} + * @memberOf Tone.Panner3D# + * @name coneInnerAngle + */ + Tone.Panner3D._aliasProperty('coneInnerAngle'); + /** + * The angle, in degrees, outside of which the volume will be reduced + * to a constant value of coneOuterGain + * @type {Degrees} + * @memberOf Tone.Panner3D# + * @name coneOuterAngle + */ + Tone.Panner3D._aliasProperty('coneOuterAngle'); + /** + * The gain outside of the coneOuterAngle + * @type {Gain} + * @memberOf Tone.Panner3D# + * @name coneOuterGain + */ + Tone.Panner3D._aliasProperty('coneOuterGain'); + /** + * The maximum distance between source and listener, + * after which the volume will not be reduced any further. + * @type {Positive} + * @memberOf Tone.Panner3D# + * @name maxDistance + */ + Tone.Panner3D._aliasProperty('maxDistance'); + /** + * Clean up. + * @returns {Tone.Panner3D} this + */ + Tone.Panner3D.prototype.dispose = function () { + this._panner.disconnect(); + this._panner = null; + this._orientation = null; + this._position = null; + return this; + }; + return Tone.Panner3D; + }); + Module(function (Tone) { + + /** + * @class Tone.PanVol is a Tone.Panner and Tone.Volume in one. + * + * @extends {Tone} + * @constructor + * @param {AudioRange} pan the initial pan + * @param {number} volume The output volume. + * @example + * //pan the incoming signal left and drop the volume + * var panVol = new Tone.PanVol(0.25, -12); + */ + Tone.PanVol = function () { + var options = this.optionsObject(arguments, [ + 'pan', + 'volume' + ], Tone.PanVol.defaults); + /** + * The panning node + * @type {Tone.Panner} + * @private + */ + this._panner = this.input = new Tone.Panner(options.pan); + /** + * The L/R panning control. + * @type {AudioRange} + * @signal + */ + this.pan = this._panner.pan; + /** + * The volume node + * @type {Tone.Volume} + */ + this._volume = this.output = new Tone.Volume(options.volume); + /** + * The volume control in decibels. + * @type {Decibels} + * @signal + */ + this.volume = this._volume.volume; + //connections + this._panner.connect(this._volume); + this._readOnly([ + 'pan', + 'volume' + ]); + }; + Tone.extend(Tone.PanVol); + /** + * The defaults + * @type {Object} + * @const + * @static + */ + Tone.PanVol.defaults = { + 'pan': 0.5, + 'volume': 0 + }; + /** + * clean up + * @returns {Tone.PanVol} this + */ + Tone.PanVol.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._writable([ + 'pan', + 'volume' + ]); + this._panner.dispose(); + this._panner = null; + this.pan = null; + this._volume.dispose(); + this._volume = null; + this.volume = null; + return this; + }; + return Tone.PanVol; + }); + Module(function (Tone) { + + /** + * @class Tone.CtrlInterpolate will interpolate between given values based + * on the "index" property. Passing in an array or object literal + * will interpolate each of the parameters. Note (i.e. "C3") + * and Time (i.e. "4n + 2") can be interpolated. All other values are + * assumed to be numbers. + * @example + * var interp = new Tone.CtrlInterpolate([0, 2, 9, 4]); + * interp.index = 0.75; + * interp.value; //returns 1.5 + * + * @example + * var interp = new Tone.CtrlInterpolate([ + * [2, 4, 5], + * [9, 3, 2], + * ]); + * @param {Array} values The array of values to interpolate over + * @param {Positive} index The initial interpolation index. + * @extends {Tone} + */ + Tone.CtrlInterpolate = function () { + var options = this.optionsObject(arguments, [ + 'values', + 'index' + ], Tone.CtrlInterpolate.defaults); + /** + * The values to interpolate between + * @type {Array} + */ + this.values = options.values; + /** + * The interpolated index between values. For example: a value of 1.5 + * would interpolate equally between the value at index 1 + * and the value at index 2. + * @example + * interp.index = 0; + * interp.value; //returns the value at 0 + * interp.index = 0.5; + * interp.value; //returns the value between indices 0 and 1. + * @type {Positive} + */ + this.index = options.index; + }; + Tone.extend(Tone.CtrlInterpolate); + /** + * The defaults + * @const + * @type {Object} + */ + Tone.CtrlInterpolate.defaults = { + 'index': 0, + 'values': [] + }; + /** + * The current interpolated value based on the index + * @readOnly + * @memberOf Tone.CtrlInterpolate# + * @type {*} + * @name value + */ + Object.defineProperty(Tone.CtrlInterpolate.prototype, 'value', { + get: function () { + var index = this.index; + index = Math.min(index, this.values.length - 1); + var lowerPosition = Math.floor(index); + var lower = this.values[lowerPosition]; + var upper = this.values[Math.ceil(index)]; + return this._interpolate(index - lowerPosition, lower, upper); + } + }); + /** + * Internal interpolation routine + * @param {NormalRange} index The index between the lower and upper + * @param {*} lower + * @param {*} upper + * @return {*} The interpolated value + * @private + */ + Tone.CtrlInterpolate.prototype._interpolate = function (index, lower, upper) { + if (this.isArray(lower)) { + var retArray = []; + for (var i = 0; i < lower.length; i++) { + retArray[i] = this._interpolate(index, lower[i], upper[i]); + } + return retArray; + } else if (this.isObject(lower)) { + var retObj = {}; + for (var attr in lower) { + retObj[attr] = this._interpolate(index, lower[attr], upper[attr]); + } + return retObj; + } else { + lower = this._toNumber(lower); + upper = this._toNumber(upper); + return (1 - index) * lower + index * upper; + } + }; + /** + * Convert from the given type into a number + * @param {Number|String} value + * @return {Number} + * @private + */ + Tone.CtrlInterpolate.prototype._toNumber = function (val) { + if (this.isNumber(val)) { + return val; + } else { + //otherwise assume that it's Time... + return this.toSeconds(val); + } + }; + /** + * Clean up + * @return {Tone.CtrlInterpolate} this + */ + Tone.CtrlInterpolate.prototype.dispose = function () { + this.values = null; + }; + return Tone.CtrlInterpolate; + }); + Module(function (Tone) { + + /** + * @class Tone.CtrlMarkov represents a Markov Chain where each call + * to Tone.CtrlMarkov.next will move to the next state. If the next + * state choice is an array, the next state is chosen randomly with + * even probability for all of the choices. For a weighted probability + * of the next choices, pass in an object with "state" and "probability" attributes. + * The probabilities will be normalized and then chosen. If no next options + * are given for the current state, the state will stay there. + * @extends {Tone} + * @example + * var chain = new Tone.CtrlMarkov({ + * "beginning" : ["end", "middle"], + * "middle" : "end" + * }); + * chain.value = "beginning"; + * chain.next(); //returns "end" or "middle" with 50% probability + * + * @example + * var chain = new Tone.CtrlMarkov({ + * "beginning" : [{"value" : "end", "probability" : 0.8}, + * {"value" : "middle", "probability" : 0.2}], + * "middle" : "end" + * }); + * chain.value = "beginning"; + * chain.next(); //returns "end" with 80% probability or "middle" with 20%. + * @param {Object} values An object with the state names as the keys + * and the next state(s) as the values. + */ + Tone.CtrlMarkov = function (values, initial) { + /** + * The Markov values with states as the keys + * and next state(s) as the values. + * @type {Object} + */ + this.values = this.defaultArg(values, {}); + /** + * The current state of the Markov values. The next + * state will be evaluated and returned when Tone.CtrlMarkov.next + * is invoked. + * @type {String} + */ + this.value = this.defaultArg(initial, Object.keys(this.values)[0]); + }; + Tone.extend(Tone.CtrlMarkov); + /** + * Returns the next state of the Markov values. + * @return {String} + */ + Tone.CtrlMarkov.prototype.next = function () { + if (this.values.hasOwnProperty(this.value)) { + var next = this.values[this.value]; + if (this.isArray(next)) { + var distribution = this._getProbDistribution(next); + var rand = Math.random(); + var total = 0; + for (var i = 0; i < distribution.length; i++) { + var dist = distribution[i]; + if (rand > total && rand < total + dist) { + var chosen = next[i]; + if (this.isObject(chosen)) { + this.value = chosen.value; + } else { + this.value = chosen; + } + } + total += dist; + } + } else { + this.value = next; + } + } + return this.value; + }; + /** + * Choose randomly from an array weighted options in the form + * {"state" : string, "probability" : number} or an array of values + * @param {Array} options + * @return {Array} The randomly selected choice + * @private + */ + Tone.CtrlMarkov.prototype._getProbDistribution = function (options) { + var distribution = []; + var total = 0; + var needsNormalizing = false; + for (var i = 0; i < options.length; i++) { + var option = options[i]; + if (this.isObject(option)) { + needsNormalizing = true; + distribution[i] = option.probability; + } else { + distribution[i] = 1 / options.length; + } + total += distribution[i]; + } + if (needsNormalizing) { + //normalize the values + for (var j = 0; j < distribution.length; j++) { + distribution[j] = distribution[j] / total; + } + } + return distribution; + }; + /** + * Clean up + * @return {Tone.CtrlMarkov} this + */ + Tone.CtrlMarkov.prototype.dispose = function () { + this.values = null; + }; + return Tone.CtrlMarkov; + }); + Module(function (Tone) { + + /** + * @class Generate patterns from an array of values. + * Has a number of arpeggiation and randomized + * selection patterns. + *
    + *
  • "up" - cycles upward
  • + *
  • "down" - cycles downward
  • + *
  • "upDown" - up then and down
  • + *
  • "downUp" - cycles down then and up
  • + *
  • "alternateUp" - jump up two and down one
  • + *
  • "alternateDown" - jump down two and up one
  • + *
  • "random" - randomly select an index
  • + *
  • "randomWalk" - randomly moves one index away from the current position
  • + *
  • "randomOnce" - randomly select an index without repeating until all values have been chosen.
  • + *
+ * @param {Array} values An array of options to choose from. + * @param {Tone.CtrlPattern.Type=} type The name of the pattern. + * @extends {Tone} + */ + Tone.CtrlPattern = function () { + var options = this.optionsObject(arguments, [ + 'values', + 'type' + ], Tone.CtrlPattern.defaults); + /** + * The array of values to arpeggiate over + * @type {Array} + */ + this.values = options.values; + /** + * The current position in the values array + * @type {Number} + */ + this.index = 0; + /** + * The type placeholder + * @type {Tone.CtrlPattern.Type} + * @private + */ + this._type = null; + /** + * Shuffled values for the RandomOnce type + * @type {Array} + * @private + */ + this._shuffled = null; + /** + * The direction of the movement + * @type {String} + * @private + */ + this._direction = null; + this.type = options.type; + }; + Tone.extend(Tone.CtrlPattern); + /** + * The Control Patterns + * @type {Object} + * @static + */ + Tone.CtrlPattern.Type = { + Up: 'up', + Down: 'down', + UpDown: 'upDown', + DownUp: 'downUp', + AlternateUp: 'alternateUp', + AlternateDown: 'alternateDown', + Random: 'random', + RandomWalk: 'randomWalk', + RandomOnce: 'randomOnce' + }; + /** + * The default values. + * @type {Object} + */ + Tone.CtrlPattern.defaults = { + 'type': Tone.CtrlPattern.Type.Up, + 'values': [] + }; + /** + * The value at the current index of the pattern. + * @readOnly + * @memberOf Tone.CtrlPattern# + * @type {*} + * @name value + */ + Object.defineProperty(Tone.CtrlPattern.prototype, 'value', { + get: function () { + //some safeguards + if (this.values.length === 0) { + return; + } else if (this.values.length === 1) { + return this.values[0]; + } + this.index = Math.min(this.index, this.values.length - 1); + var val = this.values[this.index]; + if (this.type === Tone.CtrlPattern.Type.RandomOnce) { + if (this.values.length !== this._shuffled.length) { + this._shuffleValues(); + } + val = this.values[this._shuffled[this.index]]; + } + return val; + } + }); + /** + * The pattern used to select the next + * item from the values array + * @memberOf Tone.CtrlPattern# + * @type {Tone.CtrlPattern.Type} + * @name type + */ + Object.defineProperty(Tone.CtrlPattern.prototype, 'type', { + get: function () { + return this._type; + }, + set: function (type) { + this._type = type; + this._shuffled = null; + //the first index + if (this._type === Tone.CtrlPattern.Type.Up || this._type === Tone.CtrlPattern.Type.UpDown || this._type === Tone.CtrlPattern.Type.RandomOnce || this._type === Tone.CtrlPattern.Type.AlternateUp) { + this.index = 0; + } else if (this._type === Tone.CtrlPattern.Type.Down || this._type === Tone.CtrlPattern.Type.DownUp || this._type === Tone.CtrlPattern.Type.AlternateDown) { + this.index = this.values.length - 1; + } + //the direction + if (this._type === Tone.CtrlPattern.Type.UpDown || this._type === Tone.CtrlPattern.Type.AlternateUp) { + this._direction = Tone.CtrlPattern.Type.Up; + } else if (this._type === Tone.CtrlPattern.Type.DownUp || this._type === Tone.CtrlPattern.Type.AlternateDown) { + this._direction = Tone.CtrlPattern.Type.Down; + } + //randoms + if (this._type === Tone.CtrlPattern.Type.RandomOnce) { + this._shuffleValues(); + } else if (this._type === Tone.CtrlPattern.Random) { + this.index = Math.floor(Math.random() * this.values.length); + } + } + }); + /** + * Return the next value given the current position + * and pattern. + * @return {*} The next value + */ + Tone.CtrlPattern.prototype.next = function () { + var type = this.type; + //choose the next index + if (type === Tone.CtrlPattern.Type.Up) { + this.index++; + if (this.index >= this.values.length) { + this.index = 0; + } + } else if (type === Tone.CtrlPattern.Type.Down) { + this.index--; + if (this.index < 0) { + this.index = this.values.length - 1; + } + } else if (type === Tone.CtrlPattern.Type.UpDown || type === Tone.CtrlPattern.Type.DownUp) { + if (this._direction === Tone.CtrlPattern.Type.Up) { + this.index++; + } else { + this.index--; + } + if (this.index < 0) { + this.index = 1; + this._direction = Tone.CtrlPattern.Type.Up; + } else if (this.index >= this.values.length) { + this.index = this.values.length - 2; + this._direction = Tone.CtrlPattern.Type.Down; + } + } else if (type === Tone.CtrlPattern.Type.Random) { + this.index = Math.floor(Math.random() * this.values.length); + } else if (type === Tone.CtrlPattern.Type.RandomWalk) { + if (Math.random() < 0.5) { + this.index--; + this.index = Math.max(this.index, 0); + } else { + this.index++; + this.index = Math.min(this.index, this.values.length - 1); + } + } else if (type === Tone.CtrlPattern.Type.RandomOnce) { + this.index++; + if (this.index >= this.values.length) { + this.index = 0; + //reshuffle the values for next time + this._shuffleValues(); + } + } else if (type === Tone.CtrlPattern.Type.AlternateUp) { + if (this._direction === Tone.CtrlPattern.Type.Up) { + this.index += 2; + this._direction = Tone.CtrlPattern.Type.Down; + } else { + this.index -= 1; + this._direction = Tone.CtrlPattern.Type.Up; + } + if (this.index >= this.values.length) { + this.index = 0; + this._direction = Tone.CtrlPattern.Type.Up; + } + } else if (type === Tone.CtrlPattern.Type.AlternateDown) { + if (this._direction === Tone.CtrlPattern.Type.Up) { + this.index += 1; + this._direction = Tone.CtrlPattern.Type.Down; + } else { + this.index -= 2; + this._direction = Tone.CtrlPattern.Type.Up; + } + if (this.index < 0) { + this.index = this.values.length - 1; + this._direction = Tone.CtrlPattern.Type.Down; + } + } + return this.value; + }; + /** + * Shuffles the values and places the results into the _shuffled + * @private + */ + Tone.CtrlPattern.prototype._shuffleValues = function () { + var copy = []; + this._shuffled = []; + for (var i = 0; i < this.values.length; i++) { + copy[i] = i; + } + while (copy.length > 0) { + var randVal = copy.splice(Math.floor(copy.length * Math.random()), 1); + this._shuffled.push(randVal[0]); + } + }; + /** + * Clean up + * @returns {Tone.CtrlPattern} this + */ + Tone.CtrlPattern.prototype.dispose = function () { + this._shuffled = null; + this.values = null; + }; + return Tone.CtrlPattern; + }); + Module(function (Tone) { + + /** + * @class Choose a random value. + * @extends {Tone} + * @example + * var randomWalk = new Tone.CtrlRandom({ + * "min" : 0, + * "max" : 10, + * "integer" : true + * }); + * randomWalk.eval(); + * + * @param {Number|Time=} min The minimum return value. + * @param {Number|Time=} max The maximum return value. + */ + Tone.CtrlRandom = function () { + var options = this.optionsObject(arguments, [ + 'min', + 'max' + ], Tone.CtrlRandom.defaults); + /** + * The minimum return value + * @type {Number|Time} + */ + this.min = options.min; + /** + * The maximum return value + * @type {Number|Time} + */ + this.max = options.max; + /** + * If the return value should be an integer + * @type {Boolean} + */ + this.integer = options.integer; + }; + Tone.extend(Tone.CtrlRandom); + /** + * The defaults + * @const + * @type {Object} + */ + Tone.CtrlRandom.defaults = { + 'min': 0, + 'max': 1, + 'integer': false + }; + /** + * Return a random value between min and max. + * @readOnly + * @memberOf Tone.CtrlRandom# + * @type {*} + * @name value + */ + Object.defineProperty(Tone.CtrlRandom.prototype, 'value', { + get: function () { + var min = this.toSeconds(this.min); + var max = this.toSeconds(this.max); + var rand = Math.random(); + var val = rand * min + (1 - rand) * max; + if (this.integer) { + val = Math.floor(val); + } + return val; + } + }); + return Tone.CtrlRandom; + }); + Module(function (Tone) { + + /** + * @class Buffer loading and storage. Tone.Buffer is used internally by all + * classes that make requests for audio files such as Tone.Player, + * Tone.Sampler and Tone.Convolver. + *

+ * Aside from load callbacks from individual buffers, Tone.Buffer + * provides static methods which keep track of the loading progress + * of all of the buffers. These methods are Tone.Buffer.on("load" / "progress" / "error") + * + * @constructor + * @extends {Tone} + * @param {AudioBuffer|string} url The url to load, or the audio buffer to set. + * @param {Function=} onload A callback which is invoked after the buffer is loaded. + * It's recommended to use Tone.Buffer.onload instead + * since it will give you a callback when ALL buffers are loaded. + * @param {Function=} onerror The callback to invoke if there is an error + * @example + * var buffer = new Tone.Buffer("path/to/sound.mp3", function(){ + * //the buffer is now available. + * var buff = buffer.get(); + * }); + */ + Tone.Buffer = function () { + var options = this.optionsObject(arguments, [ + 'url', + 'onload', + 'onerror' + ], Tone.Buffer.defaults); + /** + * stores the loaded AudioBuffer + * @type {AudioBuffer} + * @private + */ + this._buffer = null; + /** + * indicates if the buffer should be reversed or not + * @type {Boolean} + * @private + */ + this._reversed = options.reverse; + /** + * The XHR + * @type {XMLHttpRequest} + * @private + */ + this._xhr = null; + if (options.url instanceof AudioBuffer || options.url instanceof Tone.Buffer) { + this.set(options.url); + // invoke the onload callback + if (options.onload) { + options.onload(this); + } + } else if (this.isString(options.url)) { + this.load(options.url, options.onload, options.onerror); + } + }; + Tone.extend(Tone.Buffer); + /** + * the default parameters + * @type {Object} + */ + Tone.Buffer.defaults = { + 'url': undefined, + 'reverse': false + }; + /** + * Pass in an AudioBuffer or Tone.Buffer to set the value + * of this buffer. + * @param {AudioBuffer|Tone.Buffer} buffer the buffer + * @returns {Tone.Buffer} this + */ + Tone.Buffer.prototype.set = function (buffer) { + if (buffer instanceof Tone.Buffer) { + this._buffer = buffer.get(); + } else { + this._buffer = buffer; + } + return this; + }; + /** + * @return {AudioBuffer} The audio buffer stored in the object. + */ + Tone.Buffer.prototype.get = function () { + return this._buffer; + }; + /** + * Makes an xhr reqest for the selected url then decodes + * the file as an audio buffer. Invokes + * the callback once the audio buffer loads. + * @param {String} url The url of the buffer to load. + * filetype support depends on the + * browser. + * @returns {Promise} returns a Promise which resolves with the Tone.Buffer + */ + Tone.Buffer.prototype.load = function (url, onload, onerror) { + var promise = new Promise(function (load, error) { + this._xhr = Tone.Buffer.load(url, //success + function (buff) { + this._xhr = null; + this.set(buff); + load(this); + if (onload) { + onload(this); + } + }.bind(this), //error + function (err) { + this._xhr = null; + error(err); + if (onerror) { + onerror(err); + } + }.bind(this)); + }.bind(this)); + return promise; + }; + /** + * dispose and disconnect + * @returns {Tone.Buffer} this + */ + Tone.Buffer.prototype.dispose = function () { + Tone.Emitter.prototype.dispose.call(this); + this._buffer = null; + if (this._xhr) { + Tone.Buffer._currentDownloads--; + this._xhr.abort(); + this._xhr = null; + } + return this; + }; + /** + * If the buffer is loaded or not + * @memberOf Tone.Buffer# + * @type {Boolean} + * @name loaded + * @readOnly + */ + Object.defineProperty(Tone.Buffer.prototype, 'loaded', { + get: function () { + return this.length > 0; + } + }); + /** + * The duration of the buffer. + * @memberOf Tone.Buffer# + * @type {Number} + * @name duration + * @readOnly + */ + Object.defineProperty(Tone.Buffer.prototype, 'duration', { + get: function () { + if (this._buffer) { + return this._buffer.duration; + } else { + return 0; + } + } + }); + /** + * The length of the buffer in samples + * @memberOf Tone.Buffer# + * @type {Number} + * @name length + * @readOnly + */ + Object.defineProperty(Tone.Buffer.prototype, 'length', { + get: function () { + if (this._buffer) { + return this._buffer.length; + } else { + return 0; + } + } + }); + /** + * The number of discrete audio channels. Returns 0 if no buffer + * is loaded. + * @memberOf Tone.Buffer# + * @type {Number} + * @name numberOfChannels + * @readOnly + */ + Object.defineProperty(Tone.Buffer.prototype, 'numberOfChannels', { + get: function () { + if (this._buffer) { + return this._buffer.numberOfChannels; + } else { + return 0; + } + } + }); + /** + * Set the audio buffer from the array + * @param {Float32Array} array The array to fill the audio buffer + * @param {Number} [channels=1] The number of channels contained in the array. + * If the channel is more than 1, the input array + * is expected to be a multidimensional array + * with dimensions equal to the number of channels. + * @return {Tone.Buffer} this + */ + Tone.Buffer.prototype.fromArray = function (array) { + var isMultidimensional = array[0].length > 0; + var channels = isMultidimensional ? array.length : 1; + var len = isMultidimensional ? array[0].length : array.length; + var buffer = this.context.createBuffer(channels, len, this.context.sampleRate); + if (!isMultidimensional && channels === 1) { + array = [array]; + } + for (var c = 0; c < channels; c++) { + if (this.isFunction(buffer.copyToChannel)) { + buffer.copyToChannel(array[c], c); + } else { + var channel = buffer.getChannelData(c); + var channelArray = array[c]; + for (var i = 0; i < channelArray.length; i++) { + channel[i] = channelArray[i]; + } + } + } + this._buffer = buffer; + return this; + }; + /** + * Get the buffer as an array. Single channel buffers will return a 1-dimensional + * Float32Array, and multichannel buffers will return multidimensional arrays. + * @param {Number=} channel Optionally only copy a single channel from the array. + * @return {Array} + */ + Tone.Buffer.prototype.toArray = function (channel) { + if (this.isNumber(channel)) { + return this._buffer.getChannelData(channel); + } else { + var ret = []; + for (var c = 0; c < this.numberOfChannels; c++) { + ret[c] = new Float32Array(this.length); + if (this.isFunction(this._buffer.copyFromChannel)) { + this._buffer.copyFromChannel(ret[c], c); + } else { + var channelData = this._buffer.getChannelData(c); + var retArray = ret[c]; + for (var i = 0; i < channelData.length; i++) { + retArray[i] = channelData[i]; + } + } + } + if (ret.length === 1) { + return ret[0]; + } else { + return ret; + } + } + }; + /** + * Cut a subsection of the array and return a buffer of the + * subsection. Does not modify the original buffer + * @param {Time} start The time to start the slice + * @param {Time=} end The end time to slice. If none is given + * will default to the end of the buffer + * @return {Tone.Buffer} this + */ + Tone.Buffer.prototype.slice = function (start, end) { + end = this.defaultArg(end, this.duration); + var startSamples = Math.floor(this.context.sampleRate * this.toSeconds(start)); + var endSamples = Math.floor(this.context.sampleRate * this.toSeconds(end)); + var replacement = []; + for (var i = 0; i < this.numberOfChannels; i++) { + replacement[i] = this.toArray(i).slice(startSamples, endSamples); + } + var retBuffer = new Tone.Buffer().fromArray(replacement); + return retBuffer; + }; + /** + * Reverse the buffer. + * @private + * @return {Tone.Buffer} this + */ + Tone.Buffer.prototype._reverse = function () { + if (this.loaded) { + for (var i = 0; i < this._buffer.numberOfChannels; i++) { + Array.prototype.reverse.call(this._buffer.getChannelData(i)); + } + } + return this; + }; + /** + * Reverse the buffer. + * @memberOf Tone.Buffer# + * @type {Boolean} + * @name reverse + */ + Object.defineProperty(Tone.Buffer.prototype, 'reverse', { + get: function () { + return this._reversed; + }, + set: function (rev) { + if (this._reversed !== rev) { + this._reversed = rev; + this._reverse(); + } + } + }); + /////////////////////////////////////////////////////////////////////////// + // STATIC METHODS + /////////////////////////////////////////////////////////////////////////// + //statically inherits Emitter methods + Tone.Emitter.mixin(Tone.Buffer); + /** + * the static queue for all of the xhr requests + * @type {Array} + * @private + */ + Tone.Buffer._downloadQueue = []; + /** + * the total number of downloads + * @type {Number} + * @private + */ + Tone.Buffer._currentDownloads = 0; + /** + * A path which is prefixed before every url. + * @type {String} + * @static + */ + Tone.Buffer.baseUrl = ''; + /** + * Loads a url using XMLHttpRequest. + * @param {String} url + * @param {Function} onload + * @param {Function} onerror + * @param {Function} onprogress + * @return {XMLHttpRequest} + */ + Tone.Buffer.load = function (url, onload, onerror) { + //default + onload = onload || Tone.noOp; + function onError(e) { + if (onerror) { + onerror(e); + } else { + throw new Error(e); + } + } + function onProgress() { + //calculate the progress + var totalProgress = 0; + for (var i = 0; i < Tone.Buffer._downloadQueue.length; i++) { + totalProgress += Tone.Buffer._downloadQueue[i].progress; + } + Tone.Buffer.emit('progress', totalProgress / Tone.Buffer._downloadQueue.length); + } + var request = new XMLHttpRequest(); + request.open('GET', Tone.Buffer.baseUrl + url, true); + request.responseType = 'arraybuffer'; + //start out as 0 + request.progress = 0; + Tone.Buffer._currentDownloads++; + Tone.Buffer._downloadQueue.push(request); + request.addEventListener('load', function () { + if (request.status === 200) { + Tone.context.decodeAudioData(request.response, function (buff) { + request.progress = 1; + onProgress(); + onload(buff); + Tone.Buffer._currentDownloads--; + if (Tone.Buffer._currentDownloads === 0) { + // clear the downloads + Tone.Buffer._downloadQueue = []; + //emit the event at the end + Tone.Buffer.emit('load'); + } + }, function () { + onError('Tone.Buffer: could not decode audio data: ' + url); + }); + } else { + onError('Tone.Buffer: could not locate file: ' + url); + } + }); + request.addEventListener('error', onError); + request.addEventListener('progress', function (event) { + if (event.lengthComputable) { + //only go to 95%, the last 5% is when the audio is decoded + request.progress = event.loaded / event.total * 0.95; + onProgress(); + } + }); + request.send(); + return request; + }; + /** + * Stop all of the downloads in progress + * @return {Tone.Buffer} + */ + Tone.Buffer.stopDownloads = function () { + Tone.Buffer._downloadQueue.forEach(function (request) { + request.abort(); + }); + Tone.Buffer._currentDownloads = 0; + return Tone.Buffer; + }; + /** + * Checks a url's extension to see if the current browser can play that file type. + * @param {String} url The url/extension to test + * @return {Boolean} If the file extension can be played + * @static + * @example + * Tone.Buffer.supportsType("wav"); //returns true + * Tone.Buffer.supportsType("path/to/file.wav"); //returns true + */ + Tone.Buffer.supportsType = function (url) { + var extension = url.split('.'); + extension = extension[extension.length - 1]; + var response = document.createElement('audio').canPlayType('audio/' + extension); + return response !== ''; + }; + return Tone.Buffer; + }); + Module(function (Tone) { + /** + * @class A data structure for holding multiple buffers. + * + * @param {Object|Array} urls An object literal or array + * of urls to load. + * @param {Function=} callback The callback to invoke when + * the buffers are loaded. + * @extends {Tone} + * @example + * //load a whole bank of piano samples + * var pianoSamples = new Tone.Buffers({ + * "C4" : "path/to/C4.mp3" + * "C#4" : "path/to/C#4.mp3" + * "D4" : "path/to/D4.mp3" + * "D#4" : "path/to/D#4.mp3" + * ... + * }, function(){ + * //play one of the samples when they all load + * player.buffer = pianoSamples.get("C4"); + * player.start(); + * }); + * + */ + Tone.Buffers = function (urls, onload, baseUrl) { + /** + * All of the buffers + * @type {Object} + * @private + */ + this._buffers = {}; + /** + * A path which is prefixed before every url. + * @type {String} + */ + this.baseUrl = this.defaultArg(baseUrl, ''); + urls = this._flattenUrls(urls); + this._loadingCount = 0; + //add each one + for (var key in urls) { + this._loadingCount++; + this.add(key, urls[key], this._bufferLoaded.bind(this, onload)); + } + }; + Tone.extend(Tone.Buffers); + /** + * True if the buffers object has a buffer by that name. + * @param {String|Number} name The key or index of the + * buffer. + * @return {Boolean} + */ + Tone.Buffers.prototype.has = function (name) { + return this._buffers.hasOwnProperty(name); + }; + /** + * Get a buffer by name. If an array was loaded, + * then use the array index. + * @param {String|Number} name The key or index of the + * buffer. + * @return {Tone.Buffer} + */ + Tone.Buffers.prototype.get = function (name) { + if (this.has(name)) { + return this._buffers[name]; + } else { + throw new Error('Tone.Buffers: no buffer named ' + name); + } + }; + /** + * A buffer was loaded. decrement the counter. + * @param {Function} callback + * @private + */ + Tone.Buffers.prototype._bufferLoaded = function (callback) { + this._loadingCount--; + if (this._loadingCount === 0 && callback) { + callback(this); + } + }; + /** + * If the buffers are loaded or not + * @memberOf Tone.Buffers# + * @type {Boolean} + * @name loaded + * @readOnly + */ + Object.defineProperty(Tone.Buffers.prototype, 'loaded', { + get: function () { + var isLoaded = true; + for (var buffName in this._buffers) { + var buff = this.get(buffName); + isLoaded = isLoaded && buff.loaded; + } + return isLoaded; + } + }); + /** + * Add a buffer by name and url to the Buffers + * @param {String} name A unique name to give + * the buffer + * @param {String|Tone.Buffer|Audiobuffer} url Either the url of the bufer, + * or a buffer which will be added + * with the given name. + * @param {Function=} callback The callback to invoke + * when the url is loaded. + */ + Tone.Buffers.prototype.add = function (name, url, callback) { + callback = this.defaultArg(callback, Tone.noOp); + if (url instanceof Tone.Buffer) { + this._buffers[name] = url; + callback(this); + } else if (url instanceof AudioBuffer) { + this._buffers[name] = new Tone.Buffer(url); + callback(this); + } else if (this.isString(url)) { + this._buffers[name] = new Tone.Buffer(this.baseUrl + url, callback); + } + return this; + }; + /** + * Flatten an object into a single depth object. + * thanks to https://gist.github.com/penguinboy/762197 + * @param {Object} ob + * @return {Object} + * @private + */ + Tone.Buffers.prototype._flattenUrls = function (ob) { + var toReturn = {}; + for (var i in ob) { + if (!ob.hasOwnProperty(i)) + continue; + if (this.isObject(ob[i])) { + var flatObject = this._flattenUrls(ob[i]); + for (var x in flatObject) { + if (!flatObject.hasOwnProperty(x)) + continue; + toReturn[i + '.' + x] = flatObject[x]; + } + } else { + toReturn[i] = ob[i]; + } + } + return toReturn; + }; + /** + * Clean up. + * @return {Tone.Buffers} this + */ + Tone.Buffers.prototype.dispose = function () { + for (var name in this._buffers) { + this._buffers[name].dispose(); + } + this._buffers = null; + return this; + }; + return Tone.Buffers; + }); + Module(function (Tone) { + + /** + * buses are another way of routing audio + * + * augments Tone.prototype to include send and recieve + */ + /** + * All of the routes + * + * @type {Object} + * @static + * @private + */ + var Buses = {}; + /** + * Send this signal to the channel name. + * @param {string} channelName A named channel to send the signal to. + * @param {Decibels} amount The amount of the source to send to the bus. + * @return {GainNode} The gain node which connects this node to the desired channel. + * Can be used to adjust the levels of the send. + * @example + * source.send("reverb", -12); + */ + Tone.prototype.send = function (channelName, amount) { + if (!Buses.hasOwnProperty(channelName)) { + Buses[channelName] = this.context.createGain(); + } + amount = this.defaultArg(amount, 0); + var sendKnob = new Tone.Gain(amount, Tone.Type.Decibels); + this.output.chain(sendKnob, Buses[channelName]); + return sendKnob; + }; + /** + * Recieve the input from the desired channelName to the input + * + * @param {string} channelName A named channel to send the signal to. + * @param {AudioNode} [input] If no input is selected, the + * input of the current node is + * chosen. + * @returns {Tone} this + * @example + * reverbEffect.receive("reverb"); + */ + Tone.prototype.receive = function (channelName, input) { + if (!Buses.hasOwnProperty(channelName)) { + Buses[channelName] = this.context.createGain(); + } + if (this.isUndef(input)) { + input = this.input; + } + Buses[channelName].connect(input); + return this; + }; + //remove all the send/receives when a new audio context is passed in + Tone._initAudioContext(function () { + Buses = {}; + }); + return Tone; + }); + Module(function (Tone) { + + /** + * @class Tone.Draw is useful for synchronizing visuals and audio events. + * Callbacks from Tone.Transport or any of the Tone.Event classes + * always happen _before_ the scheduled time and are not synchronized + * to the animation frame so they are not good for triggering tightly + * synchronized visuals and sound. Tone.Draw makes it easy to schedule + * callbacks using the AudioContext time and uses requestAnimationFrame. + * + * @singleton + * @extends {Tone} + * @example + * Tone.Transport.schedule(function(time){ + * //use the time argument to schedule a callback with Tone.Draw + * Tone.Draw.schedule(function(){ + * //do drawing or DOM manipulation here + * }, time) + * }, "+0.5") + */ + Tone.Draw = function () { + /** + * All of the events. + * @type {Tone.Timeline} + * @private + */ + this._events = new Tone.Timeline(); + /** + * The duration after which events are not invoked. + * @type {Number} + * @default 0.25 + */ + this.expiration = 0.25; + /** + * The amount of time before the scheduled time + * that the callback can be invoked. Default is + * half the time of an animation frame (0.008 seconds). + * @type {Number} + * @default 0.008 + */ + this.anticipation = 0.008; + /** + * The draw loop + * @type {Function} + * @private + */ + this._boundDrawLoop = this._drawLoop.bind(this); + //start the loop + this._drawLoop(); + }; + Tone.extend(Tone.Draw); + /** + * Schedule a function at the given time to be invoked + * on the nearest animation frame. + * @param {Function} callback Callback is invoked at the given time. + * @param {Time} time The time relative to the AudioContext time + * to invoke the callback. + * @return {Tone.Draw} this + */ + Tone.Draw.prototype.schedule = function (callback, time) { + this._events.add({ + callback: callback, + time: this.toSeconds(time) + }); + return this; + }; + /** + * Cancel events scheduled after the given time + * @param {Time=} after Time after which scheduled events will + * be removed from the scheduling timeline. + * @return {Tone.Draw} this + */ + Tone.Draw.prototype.cancel = function (after) { + this._events.cancel(this.toSeconds(after)); + return this; + }; + /** + * The draw loop + * @private + */ + Tone.Draw.prototype._drawLoop = function () { + requestAnimationFrame(this._boundDrawLoop); + var now = Tone.now(); + while (this._events.length && this._events.peek().time - this.anticipation <= now) { + var event = this._events.shift(); + if (now - event.time <= this.expiration) { + event.callback(); + } + } + }; + //make a singleton + Tone.Draw = new Tone.Draw(); + return Tone.Draw; + }); + Module(function (Tone) { + + /** + * @class Both Tone.Panner3D and Tone.Listener have a position in 3D space + * using a right-handed cartesian coordinate system. + * The units used in the coordinate system are not defined; + * these coordinates are independent/invariant of any particular + * units such as meters or feet. Tone.Panner3D objects have an forward + * vector representing the direction the sound is projecting. Additionally, + * they have a sound cone representing how directional the sound is. + * For example, the sound could be omnidirectional, in which case it would + * be heard anywhere regardless of its forward, or it can be more directional + * and heard only if it is facing the listener. Tone.Listener objects + * (representing a person's ears) have an forward and up vector + * representing in which direction the person is facing. Because both the + * source stream and the listener can be moving, they both have a velocity + * vector representing both the speed and direction of movement. Taken together, + * these two velocities can be used to generate a doppler shift effect which changes the pitch. + *

+ * Note: the position of the Listener will have no effect on nodes not connected to a Tone.Panner3D + * + * @constructor + * @extends {Tone} + * @singleton + * @param {Number} positionX The initial x position. + * @param {Number} positionY The initial y position. + * @param {Number} positionZ The initial z position. + */ + Tone.Listener = function () { + var options = this.optionsObject(arguments, [ + 'positionX', + 'positionY', + 'positionZ' + ], ListenerConstructor.defaults); + /** + * The listener node + * @type {AudioListener} + * @private + */ + this._listener = this.context.listener; + /** + * Holds the current forward orientation + * @type {Array} + * @private + */ + this._orientation = [ + options.forwardX, + options.forwardY, + options.forwardZ, + options.upX, + options.upY, + options.upZ + ]; + /** + * Holds the current position + * @type {Array} + * @private + */ + this._position = [ + options.positionX, + options.positionY, + options.positionZ + ]; + // set the default position/forward + this.forwardX = options.forwardX; + this.forwardY = options.forwardY; + this.forwardZ = options.forwardZ; + this.upX = options.upX; + this.upY = options.upY; + this.upZ = options.upZ; + this.positionX = options.positionX; + this.positionY = options.positionY; + this.positionZ = options.positionZ; + }; + Tone.extend(Tone.Listener); + /** + * the default parameters + * @static + * @const + * @type {Object} + * Defaults according to the specification + */ + Tone.Listener.defaults = { + 'positionX': 0, + 'positionY': 0, + 'positionZ': 0, + 'forwardX': 0, + 'forwardY': 0, + 'forwardZ': 1, + 'upX': 0, + 'upY': 1, + 'upZ': 0 + }; + /** + * The ramp time which is applied to the setTargetAtTime + * @type {Number} + * @private + */ + Tone.Listener.prototype._rampTimeConstant = 0.01; + /** + * Sets the position of the listener in 3d space. + * @param {Number} x + * @param {Number} y + * @param {Number} z + * @return {Tone.Listener} this + */ + Tone.Listener.prototype.setPosition = function (x, y, z) { + if (this._listener.positionX) { + var now = this.now(); + this._listener.positionX.setTargetAtTime(x, now, this._rampTimeConstant); + this._listener.positionY.setTargetAtTime(y, now, this._rampTimeConstant); + this._listener.positionZ.setTargetAtTime(z, now, this._rampTimeConstant); + } else { + this._listener.setPosition(x, y, z); + } + this._position = Array.prototype.slice.call(arguments); + return this; + }; + /** + * Sets the orientation of the listener using two vectors, the forward + * vector (which direction the listener is facing) and the up vector + * (which the up direction of the listener). An up vector + * of 0, 0, 1 is equivalent to the listener standing up in the Z direction. + * @param {Number} x + * @param {Number} y + * @param {Number} z + * @param {Number} upX + * @param {Number} upY + * @param {Number} upZ + * @return {Tone.Listener} this + */ + Tone.Listener.prototype.setOrientation = function (x, y, z, upX, upY, upZ) { + if (this._listener.forwardX) { + var now = this.now(); + this._listener.forwardX.setTargetAtTime(x, now, this._rampTimeConstant); + this._listener.forwardY.setTargetAtTime(y, now, this._rampTimeConstant); + this._listener.forwardZ.setTargetAtTime(z, now, this._rampTimeConstant); + this._listener.upX.setTargetAtTime(upX, now, this._rampTimeConstant); + this._listener.upY.setTargetAtTime(upY, now, this._rampTimeConstant); + this._listener.upZ.setTargetAtTime(upZ, now, this._rampTimeConstant); + } else { + this._listener.setOrientation(x, y, z, upX, upY, upZ); + } + this._orientation = Array.prototype.slice.call(arguments); + return this; + }; + /** + * The x position of the panner object. + * @type {Number} + * @memberOf Tone.Listener# + * @name positionX + */ + Object.defineProperty(Tone.Listener.prototype, 'positionX', { + set: function (pos) { + this._position[0] = pos; + this.setPosition.apply(this, this._position); + }, + get: function () { + return this._position[0]; + } + }); + /** + * The y position of the panner object. + * @type {Number} + * @memberOf Tone.Listener# + * @name positionY + */ + Object.defineProperty(Tone.Listener.prototype, 'positionY', { + set: function (pos) { + this._position[1] = pos; + this.setPosition.apply(this, this._position); + }, + get: function () { + return this._position[1]; + } + }); + /** + * The z position of the panner object. + * @type {Number} + * @memberOf Tone.Listener# + * @name positionZ + */ + Object.defineProperty(Tone.Listener.prototype, 'positionZ', { + set: function (pos) { + this._position[2] = pos; + this.setPosition.apply(this, this._position); + }, + get: function () { + return this._position[2]; + } + }); + /** + * The x coordinate of the listeners front direction. i.e. + * which way they are facing. + * @type {Number} + * @memberOf Tone.Listener# + * @name forwardX + */ + Object.defineProperty(Tone.Listener.prototype, 'forwardX', { + set: function (pos) { + this._orientation[0] = pos; + this.setOrientation.apply(this, this._orientation); + }, + get: function () { + return this._orientation[0]; + } + }); + /** + * The y coordinate of the listeners front direction. i.e. + * which way they are facing. + * @type {Number} + * @memberOf Tone.Listener# + * @name forwardY + */ + Object.defineProperty(Tone.Listener.prototype, 'forwardY', { + set: function (pos) { + this._orientation[1] = pos; + this.setOrientation.apply(this, this._orientation); + }, + get: function () { + return this._orientation[1]; + } + }); + /** + * The z coordinate of the listeners front direction. i.e. + * which way they are facing. + * @type {Number} + * @memberOf Tone.Listener# + * @name forwardZ + */ + Object.defineProperty(Tone.Listener.prototype, 'forwardZ', { + set: function (pos) { + this._orientation[2] = pos; + this.setOrientation.apply(this, this._orientation); + }, + get: function () { + return this._orientation[2]; + } + }); + /** + * The x coordinate of the listener's up direction. i.e. + * the direction the listener is standing in. + * @type {Number} + * @memberOf Tone.Listener# + * @name upX + */ + Object.defineProperty(Tone.Listener.prototype, 'upX', { + set: function (pos) { + this._orientation[3] = pos; + this.setOrientation.apply(this, this._orientation); + }, + get: function () { + return this._orientation[3]; + } + }); + /** + * The y coordinate of the listener's up direction. i.e. + * the direction the listener is standing in. + * @type {Number} + * @memberOf Tone.Listener# + * @name upY + */ + Object.defineProperty(Tone.Listener.prototype, 'upY', { + set: function (pos) { + this._orientation[4] = pos; + this.setOrientation.apply(this, this._orientation); + }, + get: function () { + return this._orientation[4]; + } + }); + /** + * The z coordinate of the listener's up direction. i.e. + * the direction the listener is standing in. + * @type {Number} + * @memberOf Tone.Listener# + * @name upZ + */ + Object.defineProperty(Tone.Listener.prototype, 'upZ', { + set: function (pos) { + this._orientation[5] = pos; + this.setOrientation.apply(this, this._orientation); + }, + get: function () { + return this._orientation[5]; + } + }); + /** + * Clean up. + * @returns {Tone.Listener} this + */ + Tone.Listener.prototype.dispose = function () { + this._listener.disconnect(); + this._listener = null; + this._orientation = null; + this._position = null; + return this; + }; + //SINGLETON SETUP + var ListenerConstructor = Tone.Listener; + Tone._initAudioContext(function () { + if (typeof Tone.Listener === 'function') { + //a single listener object + Tone.Listener = new Tone.Listener(); + } else { + //make new Listener insides + ListenerConstructor.call(Tone.Listener); + } + }); + //END SINGLETON SETUP + return Tone.Listener; + }); + Module(function (Tone) { + + /** + * @class Tone.Effect is the base class for effects. Connect the effect between + * the effectSend and effectReturn GainNodes, then control the amount of + * effect which goes to the output using the wet control. + * + * @constructor + * @extends {Tone} + * @param {NormalRange|Object} [wet] The starting wet value. + */ + Tone.Effect = function () { + this.createInsOuts(1, 1); + //get all of the defaults + var options = this.optionsObject(arguments, ['wet'], Tone.Effect.defaults); + /** + * the drywet knob to control the amount of effect + * @type {Tone.CrossFade} + * @private + */ + this._dryWet = new Tone.CrossFade(options.wet); + /** + * The wet control is how much of the effected + * will pass through to the output. 1 = 100% effected + * signal, 0 = 100% dry signal. + * @type {NormalRange} + * @signal + */ + this.wet = this._dryWet.fade; + /** + * connect the effectSend to the input of hte effect + * @type {Tone.Gain} + * @private + */ + this.effectSend = new Tone.Gain(); + /** + * connect the output of the effect to the effectReturn + * @type {Tone.Gain} + * @private + */ + this.effectReturn = new Tone.Gain(); + //connections + this.input.connect(this._dryWet.a); + this.input.connect(this.effectSend); + this.effectReturn.connect(this._dryWet.b); + this._dryWet.connect(this.output); + this._readOnly(['wet']); + }; + Tone.extend(Tone.Effect); + /** + * @static + * @type {Object} + */ + Tone.Effect.defaults = { 'wet': 1 }; + /** + * chains the effect in between the effectSend and effectReturn + * @param {Tone} effect + * @private + * @returns {Tone.Effect} this + */ + Tone.Effect.prototype.connectEffect = function (effect) { + this.effectSend.chain(effect, this.effectReturn); + return this; + }; + /** + * Clean up. + * @returns {Tone.Effect} this + */ + Tone.Effect.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._dryWet.dispose(); + this._dryWet = null; + this.effectSend.dispose(); + this.effectSend = null; + this.effectReturn.dispose(); + this.effectReturn = null; + this._writable(['wet']); + this.wet = null; + return this; + }; + return Tone.Effect; + }); + Module(function (Tone) { + + /** + * @class Tone.AutoFilter is a Tone.Filter with a Tone.LFO connected to the filter cutoff frequency. + * Setting the LFO rate and depth allows for control over the filter modulation rate + * and depth. + * + * @constructor + * @extends {Tone.Effect} + * @param {Time|Object} [frequency] The rate of the LFO. + * @param {Frequency=} baseFrequency The lower value of the LFOs oscillation + * @param {Frequency=} octaves The number of octaves above the baseFrequency + * @example + * //create an autofilter and start it's LFO + * var autoFilter = new Tone.AutoFilter("4n").toMaster().start(); + * //route an oscillator through the filter and start it + * var oscillator = new Tone.Oscillator().connect(autoFilter).start(); + */ + Tone.AutoFilter = function () { + var options = this.optionsObject(arguments, [ + 'frequency', + 'baseFrequency', + 'octaves' + ], Tone.AutoFilter.defaults); + Tone.Effect.call(this, options); + /** + * the lfo which drives the filter cutoff + * @type {Tone.LFO} + * @private + */ + this._lfo = new Tone.LFO({ + 'frequency': options.frequency, + 'amplitude': options.depth + }); + /** + * The range of the filter modulating between the min and max frequency. + * 0 = no modulation. 1 = full modulation. + * @type {NormalRange} + * @signal + */ + this.depth = this._lfo.amplitude; + /** + * How fast the filter modulates between min and max. + * @type {Frequency} + * @signal + */ + this.frequency = this._lfo.frequency; + /** + * The filter node + * @type {Tone.Filter} + */ + this.filter = new Tone.Filter(options.filter); + /** + * The octaves placeholder + * @type {Positive} + * @private + */ + this._octaves = 0; + //connections + this.connectEffect(this.filter); + this._lfo.connect(this.filter.frequency); + this.type = options.type; + this._readOnly([ + 'frequency', + 'depth' + ]); + this.octaves = options.octaves; + this.baseFrequency = options.baseFrequency; + }; + //extend Effect + Tone.extend(Tone.AutoFilter, Tone.Effect); + /** + * defaults + * @static + * @type {Object} + */ + Tone.AutoFilter.defaults = { + 'frequency': 1, + 'type': 'sine', + 'depth': 1, + 'baseFrequency': 200, + 'octaves': 2.6, + 'filter': { + 'type': 'lowpass', + 'rolloff': -12, + 'Q': 1 + } + }; + /** + * Start the effect. + * @param {Time} [time=now] When the LFO will start. + * @returns {Tone.AutoFilter} this + */ + Tone.AutoFilter.prototype.start = function (time) { + this._lfo.start(time); + return this; + }; + /** + * Stop the effect. + * @param {Time} [time=now] When the LFO will stop. + * @returns {Tone.AutoFilter} this + */ + Tone.AutoFilter.prototype.stop = function (time) { + this._lfo.stop(time); + return this; + }; + /** + * Sync the filter to the transport. + * @param {Time} [delay=0] Delay time before starting the effect after the + * Transport has started. + * @returns {Tone.AutoFilter} this + */ + Tone.AutoFilter.prototype.sync = function (delay) { + this._lfo.sync(delay); + return this; + }; + /** + * Unsync the filter from the transport. + * @returns {Tone.AutoFilter} this + */ + Tone.AutoFilter.prototype.unsync = function () { + this._lfo.unsync(); + return this; + }; + /** + * Type of oscillator attached to the AutoFilter. + * Possible values: "sine", "square", "triangle", "sawtooth". + * @memberOf Tone.AutoFilter# + * @type {string} + * @name type + */ + Object.defineProperty(Tone.AutoFilter.prototype, 'type', { + get: function () { + return this._lfo.type; + }, + set: function (type) { + this._lfo.type = type; + } + }); + /** + * The minimum value of the filter's cutoff frequency. + * @memberOf Tone.AutoFilter# + * @type {Frequency} + * @name min + */ + Object.defineProperty(Tone.AutoFilter.prototype, 'baseFrequency', { + get: function () { + return this._lfo.min; + }, + set: function (freq) { + this._lfo.min = this.toFrequency(freq); + //and set the max + this.octaves = this._octaves; + } + }); + /** + * The maximum value of the filter's cutoff frequency. + * @memberOf Tone.AutoFilter# + * @type {Positive} + * @name octaves + */ + Object.defineProperty(Tone.AutoFilter.prototype, 'octaves', { + get: function () { + return this._octaves; + }, + set: function (oct) { + this._octaves = oct; + this._lfo.max = this.baseFrequency * Math.pow(2, oct); + } + }); + /** + * Clean up. + * @returns {Tone.AutoFilter} this + */ + Tone.AutoFilter.prototype.dispose = function () { + Tone.Effect.prototype.dispose.call(this); + this._lfo.dispose(); + this._lfo = null; + this.filter.dispose(); + this.filter = null; + this._writable([ + 'frequency', + 'depth' + ]); + this.frequency = null; + this.depth = null; + return this; + }; + return Tone.AutoFilter; + }); + Module(function (Tone) { + + /** + * @class Tone.AutoPanner is a Tone.Panner with an LFO connected to the pan amount. + * More on using autopanners [here](https://www.ableton.com/en/blog/autopan-chopper-effect-and-more-liveschool/). + * + * @constructor + * @extends {Tone.Effect} + * @param {Frequency|Object} [frequency] Rate of left-right oscillation. + * @example + * //create an autopanner and start it's LFO + * var autoPanner = new Tone.AutoPanner("4n").toMaster().start(); + * //route an oscillator through the panner and start it + * var oscillator = new Tone.Oscillator().connect(autoPanner).start(); + */ + Tone.AutoPanner = function () { + var options = this.optionsObject(arguments, ['frequency'], Tone.AutoPanner.defaults); + Tone.Effect.call(this, options); + /** + * the lfo which drives the panning + * @type {Tone.LFO} + * @private + */ + this._lfo = new Tone.LFO({ + 'frequency': options.frequency, + 'amplitude': options.depth, + 'min': -1, + 'max': 1 + }); + /** + * The amount of panning between left and right. + * 0 = always center. 1 = full range between left and right. + * @type {NormalRange} + * @signal + */ + this.depth = this._lfo.amplitude; + /** + * the panner node which does the panning + * @type {Tone.Panner} + * @private + */ + this._panner = new Tone.Panner(); + /** + * How fast the panner modulates between left and right. + * @type {Frequency} + * @signal + */ + this.frequency = this._lfo.frequency; + //connections + this.connectEffect(this._panner); + this._lfo.connect(this._panner.pan); + this.type = options.type; + this._readOnly([ + 'depth', + 'frequency' + ]); + }; + //extend Effect + Tone.extend(Tone.AutoPanner, Tone.Effect); + /** + * defaults + * @static + * @type {Object} + */ + Tone.AutoPanner.defaults = { + 'frequency': 1, + 'type': 'sine', + 'depth': 1 + }; + /** + * Start the effect. + * @param {Time} [time=now] When the LFO will start. + * @returns {Tone.AutoPanner} this + */ + Tone.AutoPanner.prototype.start = function (time) { + this._lfo.start(time); + return this; + }; + /** + * Stop the effect. + * @param {Time} [time=now] When the LFO will stop. + * @returns {Tone.AutoPanner} this + */ + Tone.AutoPanner.prototype.stop = function (time) { + this._lfo.stop(time); + return this; + }; + /** + * Sync the panner to the transport. + * @param {Time} [delay=0] Delay time before starting the effect after the + * Transport has started. + * @returns {Tone.AutoPanner} this + */ + Tone.AutoPanner.prototype.sync = function (delay) { + this._lfo.sync(delay); + return this; + }; + /** + * Unsync the panner from the transport + * @returns {Tone.AutoPanner} this + */ + Tone.AutoPanner.prototype.unsync = function () { + this._lfo.unsync(); + return this; + }; + /** + * Type of oscillator attached to the AutoFilter. + * Possible values: "sine", "square", "triangle", "sawtooth". + * @memberOf Tone.AutoFilter# + * @type {string} + * @name type + */ + Object.defineProperty(Tone.AutoPanner.prototype, 'type', { + get: function () { + return this._lfo.type; + }, + set: function (type) { + this._lfo.type = type; + } + }); + /** + * clean up + * @returns {Tone.AutoPanner} this + */ + Tone.AutoPanner.prototype.dispose = function () { + Tone.Effect.prototype.dispose.call(this); + this._lfo.dispose(); + this._lfo = null; + this._panner.dispose(); + this._panner = null; + this._writable([ + 'depth', + 'frequency' + ]); + this.frequency = null; + this.depth = null; + return this; + }; + return Tone.AutoPanner; + }); + Module(function (Tone) { + + /** + * @class Tone.AutoWah connects a Tone.Follower to a bandpass filter (Tone.Filter). + * The frequency of the filter is adjusted proportionally to the + * incoming signal's amplitude. Inspiration from [Tuna.js](https://github.com/Dinahmoe/tuna). + * + * @constructor + * @extends {Tone.Effect} + * @param {Frequency|Object} [baseFrequency] The frequency the filter is set + * to at the low point of the wah + * @param {Positive} [octaves] The number of octaves above the baseFrequency + * the filter will sweep to when fully open + * @param {Decibels} [sensitivity] The decibel threshold sensitivity for + * the incoming signal. Normal range of -40 to 0. + * @example + * var autoWah = new Tone.AutoWah(50, 6, -30).toMaster(); + * //initialize the synth and connect to autowah + * var synth = new Synth.connect(autoWah); + * //Q value influences the effect of the wah - default is 2 + * autoWah.Q.value = 6; + * //more audible on higher notes + * synth.triggerAttackRelease("C4", "8n") + */ + Tone.AutoWah = function () { + var options = this.optionsObject(arguments, [ + 'baseFrequency', + 'octaves', + 'sensitivity' + ], Tone.AutoWah.defaults); + Tone.Effect.call(this, options); + /** + * The envelope follower. Set the attack/release + * timing to adjust how the envelope is followed. + * @type {Tone.Follower} + * @private + */ + this.follower = new Tone.Follower(options.follower); + /** + * scales the follower value to the frequency domain + * @type {Tone} + * @private + */ + this._sweepRange = new Tone.ScaleExp(0, 1, 0.5); + /** + * @type {number} + * @private + */ + this._baseFrequency = options.baseFrequency; + /** + * @type {number} + * @private + */ + this._octaves = options.octaves; + /** + * the input gain to adjust the sensitivity + * @type {Tone.Gain} + * @private + */ + this._inputBoost = new Tone.Gain(); + /** + * @type {BiquadFilterNode} + * @private + */ + this._bandpass = new Tone.Filter({ + 'rolloff': -48, + 'frequency': 0, + 'Q': options.Q + }); + /** + * @type {Tone.Filter} + * @private + */ + this._peaking = new Tone.Filter(0, 'peaking'); + this._peaking.gain.value = options.gain; + /** + * The gain of the filter. + * @type {Number} + * @signal + */ + this.gain = this._peaking.gain; + /** + * The quality of the filter. + * @type {Positive} + * @signal + */ + this.Q = this._bandpass.Q; + //the control signal path + this.effectSend.chain(this._inputBoost, this.follower, this._sweepRange); + this._sweepRange.connect(this._bandpass.frequency); + this._sweepRange.connect(this._peaking.frequency); + //the filtered path + this.effectSend.chain(this._bandpass, this._peaking, this.effectReturn); + //set the initial value + this._setSweepRange(); + this.sensitivity = options.sensitivity; + this._readOnly([ + 'gain', + 'Q' + ]); + }; + Tone.extend(Tone.AutoWah, Tone.Effect); + /** + * @static + * @type {Object} + */ + Tone.AutoWah.defaults = { + 'baseFrequency': 100, + 'octaves': 6, + 'sensitivity': 0, + 'Q': 2, + 'gain': 2, + 'follower': { + 'attack': 0.3, + 'release': 0.5 + } + }; + /** + * The number of octaves that the filter will sweep above the + * baseFrequency. + * @memberOf Tone.AutoWah# + * @type {Number} + * @name octaves + */ + Object.defineProperty(Tone.AutoWah.prototype, 'octaves', { + get: function () { + return this._octaves; + }, + set: function (octaves) { + this._octaves = octaves; + this._setSweepRange(); + } + }); + /** + * The base frequency from which the sweep will start from. + * @memberOf Tone.AutoWah# + * @type {Frequency} + * @name baseFrequency + */ + Object.defineProperty(Tone.AutoWah.prototype, 'baseFrequency', { + get: function () { + return this._baseFrequency; + }, + set: function (baseFreq) { + this._baseFrequency = baseFreq; + this._setSweepRange(); + } + }); + /** + * The sensitivity to control how responsive to the input signal the filter is. + * @memberOf Tone.AutoWah# + * @type {Decibels} + * @name sensitivity + */ + Object.defineProperty(Tone.AutoWah.prototype, 'sensitivity', { + get: function () { + return this.gainToDb(1 / this._inputBoost.gain.value); + }, + set: function (sensitivy) { + this._inputBoost.gain.value = 1 / this.dbToGain(sensitivy); + } + }); + /** + * sets the sweep range of the scaler + * @private + */ + Tone.AutoWah.prototype._setSweepRange = function () { + this._sweepRange.min = this._baseFrequency; + this._sweepRange.max = Math.min(this._baseFrequency * Math.pow(2, this._octaves), this.context.sampleRate / 2); + }; + /** + * Clean up. + * @returns {Tone.AutoWah} this + */ + Tone.AutoWah.prototype.dispose = function () { + Tone.Effect.prototype.dispose.call(this); + this.follower.dispose(); + this.follower = null; + this._sweepRange.dispose(); + this._sweepRange = null; + this._bandpass.dispose(); + this._bandpass = null; + this._peaking.dispose(); + this._peaking = null; + this._inputBoost.dispose(); + this._inputBoost = null; + this._writable([ + 'gain', + 'Q' + ]); + this.gain = null; + this.Q = null; + return this; + }; + return Tone.AutoWah; + }); + Module(function (Tone) { + + /** + * @class Tone.Bitcrusher downsamples the incoming signal to a different bitdepth. + * Lowering the bitdepth of the signal creates distortion. Read more about Bitcrushing + * on [Wikipedia](https://en.wikipedia.org/wiki/Bitcrusher). + * + * @constructor + * @extends {Tone.Effect} + * @param {Number} bits The number of bits to downsample the signal. Nominal range + * of 1 to 8. + * @example + * //initialize crusher and route a synth through it + * var crusher = new Tone.BitCrusher(4).toMaster(); + * var synth = new Tone.MonoSynth().connect(crusher); + */ + Tone.BitCrusher = function () { + var options = this.optionsObject(arguments, ['bits'], Tone.BitCrusher.defaults); + Tone.Effect.call(this, options); + var invStepSize = 1 / Math.pow(2, options.bits - 1); + /** + * Subtract the input signal and the modulus of the input signal + * @type {Tone.Subtract} + * @private + */ + this._subtract = new Tone.Subtract(); + /** + * The mod function + * @type {Tone.Modulo} + * @private + */ + this._modulo = new Tone.Modulo(invStepSize); + /** + * keeps track of the bits + * @type {number} + * @private + */ + this._bits = options.bits; + //connect it up + this.effectSend.fan(this._subtract, this._modulo); + this._modulo.connect(this._subtract, 0, 1); + this._subtract.connect(this.effectReturn); + }; + Tone.extend(Tone.BitCrusher, Tone.Effect); + /** + * the default values + * @static + * @type {Object} + */ + Tone.BitCrusher.defaults = { 'bits': 4 }; + /** + * The bit depth of the effect. Nominal range of 1-8. + * @memberOf Tone.BitCrusher# + * @type {number} + * @name bits + */ + Object.defineProperty(Tone.BitCrusher.prototype, 'bits', { + get: function () { + return this._bits; + }, + set: function (bits) { + this._bits = bits; + var invStepSize = 1 / Math.pow(2, bits - 1); + this._modulo.value = invStepSize; + } + }); + /** + * Clean up. + * @returns {Tone.BitCrusher} this + */ + Tone.BitCrusher.prototype.dispose = function () { + Tone.Effect.prototype.dispose.call(this); + this._subtract.dispose(); + this._subtract = null; + this._modulo.dispose(); + this._modulo = null; + return this; + }; + return Tone.BitCrusher; + }); + Module(function (Tone) { + + /** + * @class Tone.ChebyShev is a Chebyshev waveshaper, an effect which is good + * for making different types of distortion sounds. + * Note that odd orders sound very different from even ones, + * and order = 1 is no change. + * Read more at [music.columbia.edu](http://music.columbia.edu/cmc/musicandcomputers/chapter4/04_06.php). + * + * @extends {Tone.Effect} + * @constructor + * @param {Positive|Object} [order] The order of the chebyshev polynomial. Normal range between 1-100. + * @example + * //create a new cheby + * var cheby = new Tone.Chebyshev(50); + * //create a monosynth connected to our cheby + * synth = new Tone.MonoSynth().connect(cheby); + */ + Tone.Chebyshev = function () { + var options = this.optionsObject(arguments, ['order'], Tone.Chebyshev.defaults); + Tone.Effect.call(this, options); + /** + * @type {WaveShaperNode} + * @private + */ + this._shaper = new Tone.WaveShaper(4096); + /** + * holds onto the order of the filter + * @type {number} + * @private + */ + this._order = options.order; + this.connectEffect(this._shaper); + this.order = options.order; + this.oversample = options.oversample; + }; + Tone.extend(Tone.Chebyshev, Tone.Effect); + /** + * @static + * @const + * @type {Object} + */ + Tone.Chebyshev.defaults = { + 'order': 1, + 'oversample': 'none' + }; + /** + * get the coefficient for that degree + * @param {number} x the x value + * @param {number} degree + * @param {Object} memo memoize the computed value. + * this speeds up computation greatly. + * @return {number} the coefficient + * @private + */ + Tone.Chebyshev.prototype._getCoefficient = function (x, degree, memo) { + if (memo.hasOwnProperty(degree)) { + return memo[degree]; + } else if (degree === 0) { + memo[degree] = 0; + } else if (degree === 1) { + memo[degree] = x; + } else { + memo[degree] = 2 * x * this._getCoefficient(x, degree - 1, memo) - this._getCoefficient(x, degree - 2, memo); + } + return memo[degree]; + }; + /** + * The order of the Chebyshev polynomial which creates + * the equation which is applied to the incoming + * signal through a Tone.WaveShaper. The equations + * are in the form:
+ * order 2: 2x^2 + 1
+ * order 3: 4x^3 + 3x
+ * @memberOf Tone.Chebyshev# + * @type {Positive} + * @name order + */ + Object.defineProperty(Tone.Chebyshev.prototype, 'order', { + get: function () { + return this._order; + }, + set: function (order) { + this._order = order; + var curve = new Array(4096); + var len = curve.length; + for (var i = 0; i < len; ++i) { + var x = i * 2 / len - 1; + if (x === 0) { + //should output 0 when input is 0 + curve[i] = 0; + } else { + curve[i] = this._getCoefficient(x, order, {}); + } + } + this._shaper.curve = curve; + } + }); + /** + * The oversampling of the effect. Can either be "none", "2x" or "4x". + * @memberOf Tone.Chebyshev# + * @type {string} + * @name oversample + */ + Object.defineProperty(Tone.Chebyshev.prototype, 'oversample', { + get: function () { + return this._shaper.oversample; + }, + set: function (oversampling) { + this._shaper.oversample = oversampling; + } + }); + /** + * Clean up. + * @returns {Tone.Chebyshev} this + */ + Tone.Chebyshev.prototype.dispose = function () { + Tone.Effect.prototype.dispose.call(this); + this._shaper.dispose(); + this._shaper = null; + return this; + }; + return Tone.Chebyshev; + }); + Module(function (Tone) { + + /** + * @class Base class for Stereo effects. Provides effectSendL/R and effectReturnL/R. + * + * @constructor + * @extends {Tone.Effect} + */ + Tone.StereoEffect = function () { + this.createInsOuts(1, 1); + //get the defaults + var options = this.optionsObject(arguments, ['wet'], Tone.Effect.defaults); + /** + * the drywet knob to control the amount of effect + * @type {Tone.CrossFade} + * @private + */ + this._dryWet = new Tone.CrossFade(options.wet); + /** + * The wet control, i.e. how much of the effected + * will pass through to the output. + * @type {NormalRange} + * @signal + */ + this.wet = this._dryWet.fade; + /** + * then split it + * @type {Tone.Split} + * @private + */ + this._split = new Tone.Split(); + /** + * the effects send LEFT + * @type {GainNode} + * @private + */ + this.effectSendL = this._split.left; + /** + * the effects send RIGHT + * @type {GainNode} + * @private + */ + this.effectSendR = this._split.right; + /** + * the stereo effect merger + * @type {Tone.Merge} + * @private + */ + this._merge = new Tone.Merge(); + /** + * the effect return LEFT + * @type {GainNode} + * @private + */ + this.effectReturnL = this._merge.left; + /** + * the effect return RIGHT + * @type {GainNode} + * @private + */ + this.effectReturnR = this._merge.right; + //connections + this.input.connect(this._split); + //dry wet connections + this.input.connect(this._dryWet, 0, 0); + this._merge.connect(this._dryWet, 0, 1); + this._dryWet.connect(this.output); + this._readOnly(['wet']); + }; + Tone.extend(Tone.StereoEffect, Tone.Effect); + /** + * Clean up. + * @returns {Tone.StereoEffect} this + */ + Tone.StereoEffect.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._dryWet.dispose(); + this._dryWet = null; + this._split.dispose(); + this._split = null; + this._merge.dispose(); + this._merge = null; + this.effectSendL = null; + this.effectSendR = null; + this.effectReturnL = null; + this.effectReturnR = null; + this._writable(['wet']); + this.wet = null; + return this; + }; + return Tone.StereoEffect; + }); + Module(function (Tone) { + + /** + * @class Tone.FeedbackEffect provides a loop between an + * audio source and its own output. This is a base-class + * for feedback effects. + * + * @constructor + * @extends {Tone.Effect} + * @param {NormalRange|Object} [feedback] The initial feedback value. + */ + Tone.FeedbackEffect = function () { + var options = this.optionsObject(arguments, ['feedback']); + options = this.defaultArg(options, Tone.FeedbackEffect.defaults); + Tone.Effect.call(this, options); + /** + * the gain which controls the feedback + * @type {Tone.Gain} + * @private + */ + this._feedbackGain = new Tone.Gain(options.feedback, Tone.Type.NormalRange); + /** + * The amount of signal which is fed back into the effect input. + * @type {NormalRange} + * @signal + */ + this.feedback = this._feedbackGain.gain; + //the feedback loop + this.effectReturn.chain(this._feedbackGain, this.effectSend); + this._readOnly(['feedback']); + }; + Tone.extend(Tone.FeedbackEffect, Tone.Effect); + /** + * @static + * @type {Object} + */ + Tone.FeedbackEffect.defaults = { 'feedback': 0.125 }; + /** + * Clean up. + * @returns {Tone.FeedbackEffect} this + */ + Tone.FeedbackEffect.prototype.dispose = function () { + Tone.Effect.prototype.dispose.call(this); + this._writable(['feedback']); + this._feedbackGain.dispose(); + this._feedbackGain = null; + this.feedback = null; + return this; + }; + return Tone.FeedbackEffect; + }); + Module(function (Tone) { + + /** + * @class Just like a stereo feedback effect, but the feedback is routed from left to right + * and right to left instead of on the same channel. + * + * @constructor + * @extends {Tone.FeedbackEffect} + */ + Tone.StereoXFeedbackEffect = function () { + var options = this.optionsObject(arguments, ['feedback'], Tone.FeedbackEffect.defaults); + Tone.StereoEffect.call(this, options); + /** + * The amount of feedback from the output + * back into the input of the effect (routed + * across left and right channels). + * @type {NormalRange} + * @signal + */ + this.feedback = new Tone.Signal(options.feedback, Tone.Type.NormalRange); + /** + * the left side feeback + * @type {Tone.Gain} + * @private + */ + this._feedbackLR = new Tone.Gain(); + /** + * the right side feeback + * @type {Tone.Gain} + * @private + */ + this._feedbackRL = new Tone.Gain(); + //connect it up + this.effectReturnL.chain(this._feedbackLR, this.effectSendR); + this.effectReturnR.chain(this._feedbackRL, this.effectSendL); + this.feedback.fan(this._feedbackLR.gain, this._feedbackRL.gain); + this._readOnly(['feedback']); + }; + Tone.extend(Tone.StereoXFeedbackEffect, Tone.FeedbackEffect); + /** + * clean up + * @returns {Tone.StereoXFeedbackEffect} this + */ + Tone.StereoXFeedbackEffect.prototype.dispose = function () { + Tone.StereoEffect.prototype.dispose.call(this); + this._writable(['feedback']); + this.feedback.dispose(); + this.feedback = null; + this._feedbackLR.dispose(); + this._feedbackLR = null; + this._feedbackRL.dispose(); + this._feedbackRL = null; + return this; + }; + return Tone.StereoXFeedbackEffect; + }); + Module(function (Tone) { + + /** + * @class Tone.Chorus is a stereo chorus effect with feedback composed of + * a left and right delay with a Tone.LFO applied to the delayTime of each channel. + * Inspiration from [Tuna.js](https://github.com/Dinahmoe/tuna/blob/master/tuna.js). + * Read more on the chorus effect on [SoundOnSound](http://www.soundonsound.com/sos/jun04/articles/synthsecrets.htm). + * + * @constructor + * @extends {Tone.StereoXFeedbackEffect} + * @param {Frequency|Object} [frequency] The frequency of the LFO. + * @param {Milliseconds} [delayTime] The delay of the chorus effect in ms. + * @param {NormalRange} [depth] The depth of the chorus. + * @example + * var chorus = new Tone.Chorus(4, 2.5, 0.5); + * var synth = new Tone.PolySynth(4, Tone.MonoSynth).connect(chorus); + * synth.triggerAttackRelease(["C3","E3","G3"], "8n"); + */ + Tone.Chorus = function () { + var options = this.optionsObject(arguments, [ + 'frequency', + 'delayTime', + 'depth' + ], Tone.Chorus.defaults); + Tone.StereoXFeedbackEffect.call(this, options); + /** + * the depth of the chorus + * @type {number} + * @private + */ + this._depth = options.depth; + /** + * the delayTime + * @type {number} + * @private + */ + this._delayTime = options.delayTime / 1000; + /** + * the lfo which controls the delayTime + * @type {Tone.LFO} + * @private + */ + this._lfoL = new Tone.LFO({ + 'frequency': options.frequency, + 'min': 0, + 'max': 1 + }); + /** + * another LFO for the right side with a 180 degree phase diff + * @type {Tone.LFO} + * @private + */ + this._lfoR = new Tone.LFO({ + 'frequency': options.frequency, + 'min': 0, + 'max': 1, + 'phase': 180 + }); + /** + * delay for left + * @type {Tone.Delay} + * @private + */ + this._delayNodeL = new Tone.Delay(); + /** + * delay for right + * @type {Tone.Delay} + * @private + */ + this._delayNodeR = new Tone.Delay(); + /** + * The frequency of the LFO which modulates the delayTime. + * @type {Frequency} + * @signal + */ + this.frequency = this._lfoL.frequency; + //connections + this.effectSendL.chain(this._delayNodeL, this.effectReturnL); + this.effectSendR.chain(this._delayNodeR, this.effectReturnR); + //and pass through to make the detune apparent + this.effectSendL.connect(this.effectReturnL); + this.effectSendR.connect(this.effectReturnR); + //lfo setup + this._lfoL.connect(this._delayNodeL.delayTime); + this._lfoR.connect(this._delayNodeR.delayTime); + //start the lfo + this._lfoL.start(); + this._lfoR.start(); + //have one LFO frequency control the other + this._lfoL.frequency.connect(this._lfoR.frequency); + //set the initial values + this.depth = this._depth; + this.frequency.value = options.frequency; + this.type = options.type; + this._readOnly(['frequency']); + this.spread = options.spread; + }; + Tone.extend(Tone.Chorus, Tone.StereoXFeedbackEffect); + /** + * @static + * @type {Object} + */ + Tone.Chorus.defaults = { + 'frequency': 1.5, + 'delayTime': 3.5, + 'depth': 0.7, + 'feedback': 0.1, + 'type': 'sine', + 'spread': 180 + }; + /** + * The depth of the effect. A depth of 1 makes the delayTime + * modulate between 0 and 2*delayTime (centered around the delayTime). + * @memberOf Tone.Chorus# + * @type {NormalRange} + * @name depth + */ + Object.defineProperty(Tone.Chorus.prototype, 'depth', { + get: function () { + return this._depth; + }, + set: function (depth) { + this._depth = depth; + var deviation = this._delayTime * depth; + this._lfoL.min = Math.max(this._delayTime - deviation, 0); + this._lfoL.max = this._delayTime + deviation; + this._lfoR.min = Math.max(this._delayTime - deviation, 0); + this._lfoR.max = this._delayTime + deviation; + } + }); + /** + * The delayTime in milliseconds of the chorus. A larger delayTime + * will give a more pronounced effect. Nominal range a delayTime + * is between 2 and 20ms. + * @memberOf Tone.Chorus# + * @type {Milliseconds} + * @name delayTime + */ + Object.defineProperty(Tone.Chorus.prototype, 'delayTime', { + get: function () { + return this._delayTime * 1000; + }, + set: function (delayTime) { + this._delayTime = delayTime / 1000; + this.depth = this._depth; + } + }); + /** + * The oscillator type of the LFO. + * @memberOf Tone.Chorus# + * @type {string} + * @name type + */ + Object.defineProperty(Tone.Chorus.prototype, 'type', { + get: function () { + return this._lfoL.type; + }, + set: function (type) { + this._lfoL.type = type; + this._lfoR.type = type; + } + }); + /** + * Amount of stereo spread. When set to 0, both LFO's will be panned centrally. + * When set to 180, LFO's will be panned hard left and right respectively. + * @memberOf Tone.Chorus# + * @type {Degrees} + * @name spread + */ + Object.defineProperty(Tone.Chorus.prototype, 'spread', { + get: function () { + return this._lfoR.phase - this._lfoL.phase; //180 + }, + set: function (spread) { + this._lfoL.phase = 90 - spread / 2; + this._lfoR.phase = spread / 2 + 90; + } + }); + /** + * Clean up. + * @returns {Tone.Chorus} this + */ + Tone.Chorus.prototype.dispose = function () { + Tone.StereoXFeedbackEffect.prototype.dispose.call(this); + this._lfoL.dispose(); + this._lfoL = null; + this._lfoR.dispose(); + this._lfoR = null; + this._delayNodeL.dispose(); + this._delayNodeL = null; + this._delayNodeR.dispose(); + this._delayNodeR = null; + this._writable('frequency'); + this.frequency = null; + return this; + }; + return Tone.Chorus; + }); + Module(function (Tone) { + + /** + * @class Tone.Convolver is a wrapper around the Native Web Audio + * [ConvolverNode](http://webaudio.github.io/web-audio-api/#the-convolvernode-interface). + * Convolution is useful for reverb and filter emulation. Read more about convolution reverb on + * [Wikipedia](https://en.wikipedia.org/wiki/Convolution_reverb). + * + * @constructor + * @extends {Tone.Effect} + * @param {string|Tone.Buffer|Object} [url] The URL of the impulse response or the Tone.Buffer + * contianing the impulse response. + * @param {Function} onload The callback to invoke when the url is loaded. + * @example + * //initializing the convolver with an impulse response + * var convolver = new Tone.Convolver("./path/to/ir.wav").toMaster(); + */ + Tone.Convolver = function () { + var options = this.optionsObject(arguments, [ + 'url', + 'onload' + ], Tone.Convolver.defaults); + Tone.Effect.call(this, options); + /** + * convolver node + * @type {ConvolverNode} + * @private + */ + this._convolver = this.context.createConvolver(); + /** + * the convolution buffer + * @type {Tone.Buffer} + * @private + */ + this._buffer = new Tone.Buffer(); + if (this.isString(options.url)) { + this._buffer.load(options.url, function (buffer) { + this.buffer = buffer; + options.onload(); + }.bind(this)); + } else if (options.url) { + this.buffer = options.url; + options.onload(); + } + this.connectEffect(this._convolver); + }; + Tone.extend(Tone.Convolver, Tone.Effect); + /** + * @static + * @const + * @type {Object} + */ + Tone.Convolver.defaults = { 'onload': Tone.noOp }; + /** + * The convolver's buffer + * @memberOf Tone.Convolver# + * @type {AudioBuffer} + * @name buffer + */ + Object.defineProperty(Tone.Convolver.prototype, 'buffer', { + get: function () { + return this._buffer.get(); + }, + set: function (buffer) { + this._buffer.set(buffer); + this._convolver.buffer = this._buffer.get(); + } + }); + /** + * Load an impulse response url as an audio buffer. + * Decodes the audio asynchronously and invokes + * the callback once the audio buffer loads. + * @param {string} url The url of the buffer to load. + * filetype support depends on the + * browser. + * @param {function=} callback + * @returns {Promise} + */ + Tone.Convolver.prototype.load = function (url, callback) { + return this._buffer.load(url, function (buff) { + this.buffer = buff; + if (callback) { + callback(); + } + }.bind(this)); + }; + /** + * Clean up. + * @returns {Tone.Convolver} this + */ + Tone.Convolver.prototype.dispose = function () { + Tone.Effect.prototype.dispose.call(this); + this._convolver.disconnect(); + this._convolver = null; + this._buffer.dispose(); + this._buffer = null; + return this; + }; + return Tone.Convolver; + }); + Module(function (Tone) { + + /** + * @class Tone.Distortion is a simple distortion effect using Tone.WaveShaper. + * Algorithm from [a stackoverflow answer](http://stackoverflow.com/a/22313408). + * + * @extends {Tone.Effect} + * @constructor + * @param {Number|Object} [distortion] The amount of distortion (nominal range of 0-1) + * @example + * var dist = new Tone.Distortion(0.8).toMaster(); + * var fm = new Tone.SimpleFM().connect(dist); + * //this sounds good on bass notes + * fm.triggerAttackRelease("A1", "8n"); + */ + Tone.Distortion = function () { + var options = this.optionsObject(arguments, ['distortion'], Tone.Distortion.defaults); + Tone.Effect.call(this, options); + /** + * @type {Tone.WaveShaper} + * @private + */ + this._shaper = new Tone.WaveShaper(4096); + /** + * holds the distortion amount + * @type {number} + * @private + */ + this._distortion = options.distortion; + this.connectEffect(this._shaper); + this.distortion = options.distortion; + this.oversample = options.oversample; + }; + Tone.extend(Tone.Distortion, Tone.Effect); + /** + * @static + * @const + * @type {Object} + */ + Tone.Distortion.defaults = { + 'distortion': 0.4, + 'oversample': 'none' + }; + /** + * The amount of distortion. + * @memberOf Tone.Distortion# + * @type {NormalRange} + * @name distortion + */ + Object.defineProperty(Tone.Distortion.prototype, 'distortion', { + get: function () { + return this._distortion; + }, + set: function (amount) { + this._distortion = amount; + var k = amount * 100; + var deg = Math.PI / 180; + this._shaper.setMap(function (x) { + if (Math.abs(x) < 0.001) { + //should output 0 when input is 0 + return 0; + } else { + return (3 + k) * x * 20 * deg / (Math.PI + k * Math.abs(x)); + } + }); + } + }); + /** + * The oversampling of the effect. Can either be "none", "2x" or "4x". + * @memberOf Tone.Distortion# + * @type {string} + * @name oversample + */ + Object.defineProperty(Tone.Distortion.prototype, 'oversample', { + get: function () { + return this._shaper.oversample; + }, + set: function (oversampling) { + this._shaper.oversample = oversampling; + } + }); + /** + * Clean up. + * @returns {Tone.Distortion} this + */ + Tone.Distortion.prototype.dispose = function () { + Tone.Effect.prototype.dispose.call(this); + this._shaper.dispose(); + this._shaper = null; + return this; + }; + return Tone.Distortion; + }); + Module(function (Tone) { + + /** + * @class Tone.FeedbackDelay is a DelayNode in which part of output + * signal is fed back into the delay. + * + * @constructor + * @extends {Tone.FeedbackEffect} + * @param {Time|Object} [delayTime] The delay applied to the incoming signal. + * @param {NormalRange=} feedback The amount of the effected signal which + * is fed back through the delay. + * @example + * var feedbackDelay = new Tone.FeedbackDelay("8n", 0.5).toMaster(); + * var tom = new Tone.DrumSynth({ + * "octaves" : 4, + * "pitchDecay" : 0.1 + * }).connect(feedbackDelay); + * tom.triggerAttackRelease("A2","32n"); + */ + Tone.FeedbackDelay = function () { + var options = this.optionsObject(arguments, [ + 'delayTime', + 'feedback' + ], Tone.FeedbackDelay.defaults); + Tone.FeedbackEffect.call(this, options); + /** + * the delay node + * @type {Tone.Delay} + * @private + */ + this._delayNode = new Tone.Delay(options.delayTime); + /** + * The delayTime of the DelayNode. + * @type {Time} + * @signal + */ + this.delayTime = this._delayNode.delayTime; + // connect it up + this.connectEffect(this._delayNode); + this._readOnly(['delayTime']); + }; + Tone.extend(Tone.FeedbackDelay, Tone.FeedbackEffect); + /** + * The default values. + * @const + * @static + * @type {Object} + */ + Tone.FeedbackDelay.defaults = { 'delayTime': 0.25 }; + /** + * clean up + * @returns {Tone.FeedbackDelay} this + */ + Tone.FeedbackDelay.prototype.dispose = function () { + Tone.FeedbackEffect.prototype.dispose.call(this); + this._delayNode.dispose(); + this._delayNode = null; + this._writable(['delayTime']); + this.delayTime = null; + return this; + }; + return Tone.FeedbackDelay; + }); + Module(function (Tone) { + + /** + * an array of comb filter delay values from Freeverb implementation + * @static + * @private + * @type {Array} + */ + var combFilterTunings = [ + 1557 / 44100, + 1617 / 44100, + 1491 / 44100, + 1422 / 44100, + 1277 / 44100, + 1356 / 44100, + 1188 / 44100, + 1116 / 44100 + ]; + /** + * an array of allpass filter frequency values from Freeverb implementation + * @private + * @static + * @type {Array} + */ + var allpassFilterFrequencies = [ + 225, + 556, + 441, + 341 + ]; + /** + * @class Tone.Freeverb is a reverb based on [Freeverb](https://ccrma.stanford.edu/~jos/pasp/Freeverb.html). + * Read more on reverb on [SoundOnSound](http://www.soundonsound.com/sos/may00/articles/reverb.htm). + * + * @extends {Tone.Effect} + * @constructor + * @param {NormalRange|Object} [roomSize] Correlated to the decay time. + * @param {Frequency} [dampening] The cutoff frequency of a lowpass filter as part + * of the reverb. + * @example + * var freeverb = new Tone.Freeverb().toMaster(); + * freeverb.dampening.value = 1000; + * //routing synth through the reverb + * var synth = new Tone.AMSynth().connect(freeverb); + */ + Tone.Freeverb = function () { + var options = this.optionsObject(arguments, [ + 'roomSize', + 'dampening' + ], Tone.Freeverb.defaults); + Tone.StereoEffect.call(this, options); + /** + * The roomSize value between. A larger roomSize + * will result in a longer decay. + * @type {NormalRange} + * @signal + */ + this.roomSize = new Tone.Signal(options.roomSize, Tone.Type.NormalRange); + /** + * The amount of dampening of the reverberant signal. + * @type {Frequency} + * @signal + */ + this.dampening = new Tone.Signal(options.dampening, Tone.Type.Frequency); + /** + * the comb filters + * @type {Array} + * @private + */ + this._combFilters = []; + /** + * the allpass filters on the left + * @type {Array} + * @private + */ + this._allpassFiltersL = []; + /** + * the allpass filters on the right + * @type {Array} + * @private + */ + this._allpassFiltersR = []; + //make the allpass filters on teh right + for (var l = 0; l < allpassFilterFrequencies.length; l++) { + var allpassL = this.context.createBiquadFilter(); + allpassL.type = 'allpass'; + allpassL.frequency.value = allpassFilterFrequencies[l]; + this._allpassFiltersL.push(allpassL); + } + //make the allpass filters on the left + for (var r = 0; r < allpassFilterFrequencies.length; r++) { + var allpassR = this.context.createBiquadFilter(); + allpassR.type = 'allpass'; + allpassR.frequency.value = allpassFilterFrequencies[r]; + this._allpassFiltersR.push(allpassR); + } + //make the comb filters + for (var c = 0; c < combFilterTunings.length; c++) { + var lfpf = new Tone.LowpassCombFilter(combFilterTunings[c]); + if (c < combFilterTunings.length / 2) { + this.effectSendL.chain(lfpf, this._allpassFiltersL[0]); + } else { + this.effectSendR.chain(lfpf, this._allpassFiltersR[0]); + } + this.roomSize.connect(lfpf.resonance); + this.dampening.connect(lfpf.dampening); + this._combFilters.push(lfpf); + } + //chain the allpass filters togetehr + this.connectSeries.apply(this, this._allpassFiltersL); + this.connectSeries.apply(this, this._allpassFiltersR); + this._allpassFiltersL[this._allpassFiltersL.length - 1].connect(this.effectReturnL); + this._allpassFiltersR[this._allpassFiltersR.length - 1].connect(this.effectReturnR); + this._readOnly([ + 'roomSize', + 'dampening' + ]); + }; + Tone.extend(Tone.Freeverb, Tone.StereoEffect); + /** + * @static + * @type {Object} + */ + Tone.Freeverb.defaults = { + 'roomSize': 0.7, + 'dampening': 3000 + }; + /** + * Clean up. + * @returns {Tone.Freeverb} this + */ + Tone.Freeverb.prototype.dispose = function () { + Tone.StereoEffect.prototype.dispose.call(this); + for (var al = 0; al < this._allpassFiltersL.length; al++) { + this._allpassFiltersL[al].disconnect(); + this._allpassFiltersL[al] = null; + } + this._allpassFiltersL = null; + for (var ar = 0; ar < this._allpassFiltersR.length; ar++) { + this._allpassFiltersR[ar].disconnect(); + this._allpassFiltersR[ar] = null; + } + this._allpassFiltersR = null; + for (var cf = 0; cf < this._combFilters.length; cf++) { + this._combFilters[cf].dispose(); + this._combFilters[cf] = null; + } + this._combFilters = null; + this._writable([ + 'roomSize', + 'dampening' + ]); + this.roomSize.dispose(); + this.roomSize = null; + this.dampening.dispose(); + this.dampening = null; + return this; + }; + return Tone.Freeverb; + }); + Module(function (Tone) { + + /** + * an array of the comb filter delay time values + * @private + * @static + * @type {Array} + */ + var combFilterDelayTimes = [ + 1687 / 25000, + 1601 / 25000, + 2053 / 25000, + 2251 / 25000 + ]; + /** + * the resonances of each of the comb filters + * @private + * @static + * @type {Array} + */ + var combFilterResonances = [ + 0.773, + 0.802, + 0.753, + 0.733 + ]; + /** + * the allpass filter frequencies + * @private + * @static + * @type {Array} + */ + var allpassFilterFreqs = [ + 347, + 113, + 37 + ]; + /** + * @class Tone.JCReverb is a simple [Schroeder Reverberator](https://ccrma.stanford.edu/~jos/pasp/Schroeder_Reverberators.html) + * tuned by John Chowning in 1970. + * It is made up of three allpass filters and four Tone.FeedbackCombFilter. + * + * + * @extends {Tone.Effect} + * @constructor + * @param {NormalRange|Object} [roomSize] Coorelates to the decay time. + * @example + * var reverb = new Tone.JCReverb(0.4).connect(Tone.Master); + * var delay = new Tone.FeedbackDelay(0.5); + * //connecting the synth to reverb through delay + * var synth = new Tone.DuoSynth().chain(delay, reverb); + * synth.triggerAttackRelease("A4","8n"); + */ + Tone.JCReverb = function () { + var options = this.optionsObject(arguments, ['roomSize'], Tone.JCReverb.defaults); + Tone.StereoEffect.call(this, options); + /** + * room size control values between [0,1] + * @type {NormalRange} + * @signal + */ + this.roomSize = new Tone.Signal(options.roomSize, Tone.Type.NormalRange); + /** + * scale the room size + * @type {Tone.Scale} + * @private + */ + this._scaleRoomSize = new Tone.Scale(-0.733, 0.197); + /** + * a series of allpass filters + * @type {Array} + * @private + */ + this._allpassFilters = []; + /** + * parallel feedback comb filters + * @type {Array} + * @private + */ + this._feedbackCombFilters = []; + //make the allpass filters + for (var af = 0; af < allpassFilterFreqs.length; af++) { + var allpass = this.context.createBiquadFilter(); + allpass.type = 'allpass'; + allpass.frequency.value = allpassFilterFreqs[af]; + this._allpassFilters.push(allpass); + } + //and the comb filters + for (var cf = 0; cf < combFilterDelayTimes.length; cf++) { + var fbcf = new Tone.FeedbackCombFilter(combFilterDelayTimes[cf], 0.1); + this._scaleRoomSize.connect(fbcf.resonance); + fbcf.resonance.value = combFilterResonances[cf]; + this._allpassFilters[this._allpassFilters.length - 1].connect(fbcf); + if (cf < combFilterDelayTimes.length / 2) { + fbcf.connect(this.effectReturnL); + } else { + fbcf.connect(this.effectReturnR); + } + this._feedbackCombFilters.push(fbcf); + } + //chain the allpass filters together + this.roomSize.connect(this._scaleRoomSize); + this.connectSeries.apply(this, this._allpassFilters); + this.effectSendL.connect(this._allpassFilters[0]); + this.effectSendR.connect(this._allpassFilters[0]); + this._readOnly(['roomSize']); + }; + Tone.extend(Tone.JCReverb, Tone.StereoEffect); + /** + * the default values + * @static + * @const + * @type {Object} + */ + Tone.JCReverb.defaults = { 'roomSize': 0.5 }; + /** + * Clean up. + * @returns {Tone.JCReverb} this + */ + Tone.JCReverb.prototype.dispose = function () { + Tone.StereoEffect.prototype.dispose.call(this); + for (var apf = 0; apf < this._allpassFilters.length; apf++) { + this._allpassFilters[apf].disconnect(); + this._allpassFilters[apf] = null; + } + this._allpassFilters = null; + for (var fbcf = 0; fbcf < this._feedbackCombFilters.length; fbcf++) { + this._feedbackCombFilters[fbcf].dispose(); + this._feedbackCombFilters[fbcf] = null; + } + this._feedbackCombFilters = null; + this._writable(['roomSize']); + this.roomSize.dispose(); + this.roomSize = null; + this._scaleRoomSize.dispose(); + this._scaleRoomSize = null; + return this; + }; + return Tone.JCReverb; + }); + Module(function (Tone) { + + /** + * @class Mid/Side processing separates the the 'mid' signal + * (which comes out of both the left and the right channel) + * and the 'side' (which only comes out of the the side channels) + * and effects them separately before being recombined. + * Applies a Mid/Side seperation and recombination. + * Algorithm found in [kvraudio forums](http://www.kvraudio.com/forum/viewtopic.php?t=212587). + *

+ * This is a base-class for Mid/Side Effects. + * + * @extends {Tone.Effect} + * @constructor + */ + Tone.MidSideEffect = function () { + Tone.Effect.apply(this, arguments); + /** + * The mid/side split + * @type {Tone.MidSideSplit} + * @private + */ + this._midSideSplit = new Tone.MidSideSplit(); + /** + * The mid/side merge + * @type {Tone.MidSideMerge} + * @private + */ + this._midSideMerge = new Tone.MidSideMerge(); + /** + * The mid send. Connect to mid processing + * @type {Tone.Expr} + * @private + */ + this.midSend = this._midSideSplit.mid; + /** + * The side send. Connect to side processing + * @type {Tone.Expr} + * @private + */ + this.sideSend = this._midSideSplit.side; + /** + * The mid return connection + * @type {GainNode} + * @private + */ + this.midReturn = this._midSideMerge.mid; + /** + * The side return connection + * @type {GainNode} + * @private + */ + this.sideReturn = this._midSideMerge.side; + //the connections + this.effectSend.connect(this._midSideSplit); + this._midSideMerge.connect(this.effectReturn); + }; + Tone.extend(Tone.MidSideEffect, Tone.Effect); + /** + * Clean up. + * @returns {Tone.MidSideEffect} this + */ + Tone.MidSideEffect.prototype.dispose = function () { + Tone.Effect.prototype.dispose.call(this); + this._midSideSplit.dispose(); + this._midSideSplit = null; + this._midSideMerge.dispose(); + this._midSideMerge = null; + this.midSend = null; + this.sideSend = null; + this.midReturn = null; + this.sideReturn = null; + return this; + }; + return Tone.MidSideEffect; + }); + Module(function (Tone) { + + /** + * @class Tone.Phaser is a phaser effect. Phasers work by changing the phase + * of different frequency components of an incoming signal. Read more on + * [Wikipedia](https://en.wikipedia.org/wiki/Phaser_(effect)). + * Inspiration for this phaser comes from [Tuna.js](https://github.com/Dinahmoe/tuna/). + * + * @extends {Tone.StereoEffect} + * @constructor + * @param {Frequency|Object} [frequency] The speed of the phasing. + * @param {number} [octaves] The octaves of the effect. + * @param {Frequency} [baseFrequency] The base frequency of the filters. + * @example + * var phaser = new Tone.Phaser({ + * "frequency" : 15, + * "octaves" : 5, + * "baseFrequency" : 1000 + * }).toMaster(); + * var synth = new Tone.FMSynth().connect(phaser); + * synth.triggerAttackRelease("E3", "2n"); + */ + Tone.Phaser = function () { + //set the defaults + var options = this.optionsObject(arguments, [ + 'frequency', + 'octaves', + 'baseFrequency' + ], Tone.Phaser.defaults); + Tone.StereoEffect.call(this, options); + /** + * the lfo which controls the frequency on the left side + * @type {Tone.LFO} + * @private + */ + this._lfoL = new Tone.LFO(options.frequency, 0, 1); + /** + * the lfo which controls the frequency on the right side + * @type {Tone.LFO} + * @private + */ + this._lfoR = new Tone.LFO(options.frequency, 0, 1); + this._lfoR.phase = 180; + /** + * the base modulation frequency + * @type {number} + * @private + */ + this._baseFrequency = options.baseFrequency; + /** + * the octaves of the phasing + * @type {number} + * @private + */ + this._octaves = options.octaves; + /** + * The quality factor of the filters + * @type {Positive} + * @signal + */ + this.Q = new Tone.Signal(options.Q, Tone.Type.Positive); + /** + * the array of filters for the left side + * @type {Array} + * @private + */ + this._filtersL = this._makeFilters(options.stages, this._lfoL, this.Q); + /** + * the array of filters for the left side + * @type {Array} + * @private + */ + this._filtersR = this._makeFilters(options.stages, this._lfoR, this.Q); + /** + * the frequency of the effect + * @type {Tone.Signal} + */ + this.frequency = this._lfoL.frequency; + this.frequency.value = options.frequency; + //connect them up + this.effectSendL.connect(this._filtersL[0]); + this.effectSendR.connect(this._filtersR[0]); + this._filtersL[options.stages - 1].connect(this.effectReturnL); + this._filtersR[options.stages - 1].connect(this.effectReturnR); + //control the frequency with one LFO + this._lfoL.frequency.connect(this._lfoR.frequency); + //set the options + this.baseFrequency = options.baseFrequency; + this.octaves = options.octaves; + //start the lfo + this._lfoL.start(); + this._lfoR.start(); + this._readOnly([ + 'frequency', + 'Q' + ]); + }; + Tone.extend(Tone.Phaser, Tone.StereoEffect); + /** + * defaults + * @static + * @type {object} + */ + Tone.Phaser.defaults = { + 'frequency': 0.5, + 'octaves': 3, + 'stages': 10, + 'Q': 10, + 'baseFrequency': 350 + }; + /** + * @param {number} stages + * @returns {Array} the number of filters all connected together + * @private + */ + Tone.Phaser.prototype._makeFilters = function (stages, connectToFreq, Q) { + var filters = new Array(stages); + //make all the filters + for (var i = 0; i < stages; i++) { + var filter = this.context.createBiquadFilter(); + filter.type = 'allpass'; + Q.connect(filter.Q); + connectToFreq.connect(filter.frequency); + filters[i] = filter; + } + this.connectSeries.apply(this, filters); + return filters; + }; + /** + * The number of octaves the phase goes above + * the baseFrequency + * @memberOf Tone.Phaser# + * @type {Positive} + * @name octaves + */ + Object.defineProperty(Tone.Phaser.prototype, 'octaves', { + get: function () { + return this._octaves; + }, + set: function (octaves) { + this._octaves = octaves; + var max = this._baseFrequency * Math.pow(2, octaves); + this._lfoL.max = max; + this._lfoR.max = max; + } + }); + /** + * The the base frequency of the filters. + * @memberOf Tone.Phaser# + * @type {number} + * @name baseFrequency + */ + Object.defineProperty(Tone.Phaser.prototype, 'baseFrequency', { + get: function () { + return this._baseFrequency; + }, + set: function (freq) { + this._baseFrequency = freq; + this._lfoL.min = freq; + this._lfoR.min = freq; + this.octaves = this._octaves; + } + }); + /** + * clean up + * @returns {Tone.Phaser} this + */ + Tone.Phaser.prototype.dispose = function () { + Tone.StereoEffect.prototype.dispose.call(this); + this._writable([ + 'frequency', + 'Q' + ]); + this.Q.dispose(); + this.Q = null; + this._lfoL.dispose(); + this._lfoL = null; + this._lfoR.dispose(); + this._lfoR = null; + for (var i = 0; i < this._filtersL.length; i++) { + this._filtersL[i].disconnect(); + this._filtersL[i] = null; + } + this._filtersL = null; + for (var j = 0; j < this._filtersR.length; j++) { + this._filtersR[j].disconnect(); + this._filtersR[j] = null; + } + this._filtersR = null; + this.frequency = null; + return this; + }; + return Tone.Phaser; + }); + Module(function (Tone) { + + /** + * @class Tone.PingPongDelay is a feedback delay effect where the echo is heard + * first in one channel and next in the opposite channel. In a stereo + * system these are the right and left channels. + * PingPongDelay in more simplified terms is two Tone.FeedbackDelays + * with independent delay values. Each delay is routed to one channel + * (left or right), and the channel triggered second will always + * trigger at the same interval after the first. + * + * @constructor + * @extends {Tone.StereoXFeedbackEffect} + * @param {Time|Object} [delayTime] The delayTime between consecutive echos. + * @param {NormalRange=} feedback The amount of the effected signal which + * is fed back through the delay. + * @example + * var pingPong = new Tone.PingPongDelay("4n", 0.2).toMaster(); + * var drum = new Tone.DrumSynth().connect(pingPong); + * drum.triggerAttackRelease("C4", "32n"); + */ + Tone.PingPongDelay = function () { + var options = this.optionsObject(arguments, [ + 'delayTime', + 'feedback' + ], Tone.PingPongDelay.defaults); + Tone.StereoXFeedbackEffect.call(this, options); + /** + * the delay node on the left side + * @type {Tone.Delay} + * @private + */ + this._leftDelay = new Tone.Delay(0, options.maxDelayTime); + /** + * the delay node on the right side + * @type {Tone.Delay} + * @private + */ + this._rightDelay = new Tone.Delay(0, options.maxDelayTime); + /** + * the predelay on the right side + * @type {Tone.Delay} + * @private + */ + this._rightPreDelay = new Tone.Delay(0, options.maxDelayTime); + /** + * the delay time signal + * @type {Time} + * @signal + */ + this.delayTime = new Tone.Signal(options.delayTime, Tone.Type.Time); + //connect it up + this.effectSendL.chain(this._leftDelay, this.effectReturnL); + this.effectSendR.chain(this._rightPreDelay, this._rightDelay, this.effectReturnR); + this.delayTime.fan(this._leftDelay.delayTime, this._rightDelay.delayTime, this._rightPreDelay.delayTime); + //rearranged the feedback to be after the rightPreDelay + this._feedbackLR.disconnect(); + this._feedbackLR.connect(this._rightDelay); + this._readOnly(['delayTime']); + }; + Tone.extend(Tone.PingPongDelay, Tone.StereoXFeedbackEffect); + /** + * @static + * @type {Object} + */ + Tone.PingPongDelay.defaults = { + 'delayTime': 0.25, + 'maxDelayTime': 1 + }; + /** + * Clean up. + * @returns {Tone.PingPongDelay} this + */ + Tone.PingPongDelay.prototype.dispose = function () { + Tone.StereoXFeedbackEffect.prototype.dispose.call(this); + this._leftDelay.dispose(); + this._leftDelay = null; + this._rightDelay.dispose(); + this._rightDelay = null; + this._rightPreDelay.dispose(); + this._rightPreDelay = null; + this._writable(['delayTime']); + this.delayTime.dispose(); + this.delayTime = null; + return this; + }; + return Tone.PingPongDelay; + }); + Module(function (Tone) { + + /** + * @class Tone.PitchShift does near-realtime pitch shifting to the incoming signal. + * The effect is achieved by speeding up or slowing down the delayTime + * of a DelayNode using a sawtooth wave. + * Algorithm found in [this pdf](http://dsp-book.narod.ru/soundproc.pdf). + * Additional reference by [Miller Pucket](http://msp.ucsd.edu/techniques/v0.11/book-html/node115.html). + * + * @extends {Tone.FeedbackEffect} + * @param {Interval=} pitch The interval to transpose the incoming signal by. + */ + Tone.PitchShift = function () { + var options = this.optionsObject(arguments, ['pitch'], Tone.PitchShift.defaults); + Tone.FeedbackEffect.call(this, options); + /** + * The pitch signal + * @type {Tone.Signal} + * @private + */ + this._frequency = new Tone.Signal(0); + /** + * Uses two DelayNodes to cover up the jump in + * the sawtooth wave. + * @type {DelayNode} + * @private + */ + this._delayA = new Tone.Delay(0, 1); + /** + * The first LFO. + * @type {Tone.LFO} + * @private + */ + this._lfoA = new Tone.LFO({ + 'min': 0, + 'max': 0.1, + 'type': 'sawtooth' + }).connect(this._delayA.delayTime); + /** + * The second DelayNode + * @type {DelayNode} + * @private + */ + this._delayB = new Tone.Delay(0, 1); + /** + * The first LFO. + * @type {Tone.LFO} + * @private + */ + this._lfoB = new Tone.LFO({ + 'min': 0, + 'max': 0.1, + 'type': 'sawtooth', + 'phase': 180 + }).connect(this._delayB.delayTime); + /** + * Crossfade quickly between the two delay lines + * to cover up the jump in the sawtooth wave + * @type {Tone.CrossFade} + * @private + */ + this._crossFade = new Tone.CrossFade(); + /** + * LFO which alternates between the two + * delay lines to cover up the disparity in the + * sawtooth wave. + * @type {Tone.LFO} + * @private + */ + this._crossFadeLFO = new Tone.LFO({ + 'min': 0, + 'max': 1, + 'type': 'triangle', + 'phase': 90 + }).connect(this._crossFade.fade); + /** + * The delay node + * @type {Tone.Delay} + * @private + */ + this._feedbackDelay = new Tone.Delay(options.delayTime); + /** + * The amount of delay on the input signal + * @type {Time} + * @signal + */ + this.delayTime = this._feedbackDelay.delayTime; + this._readOnly('delayTime'); + /** + * Hold the current pitch + * @type {Number} + * @private + */ + this._pitch = options.pitch; + /** + * Hold the current windowSize + * @type {Number} + * @private + */ + this._windowSize = options.windowSize; + //connect the two delay lines up + this._delayA.connect(this._crossFade.a); + this._delayB.connect(this._crossFade.b); + //connect the frequency + this._frequency.fan(this._lfoA.frequency, this._lfoB.frequency, this._crossFadeLFO.frequency); + //route the input + this.effectSend.fan(this._delayA, this._delayB); + this._crossFade.chain(this._feedbackDelay, this.effectReturn); + //start the LFOs at the same time + var now = this.now(); + this._lfoA.start(now); + this._lfoB.start(now); + this._crossFadeLFO.start(now); + //set the initial value + this.windowSize = this._windowSize; + }; + Tone.extend(Tone.PitchShift, Tone.FeedbackEffect); + /** + * default values + * @static + * @type {Object} + * @const + */ + Tone.PitchShift.defaults = { + 'pitch': 0, + 'windowSize': 0.1, + 'delayTime': 0, + 'feedback': 0 + }; + /** + * Repitch the incoming signal by some interval (measured + * in semi-tones). + * @memberOf Tone.PitchShift# + * @type {Interval} + * @name pitch + * @example + * pitchShift.pitch = -12; //down one octave + * pitchShift.pitch = 7; //up a fifth + */ + Object.defineProperty(Tone.PitchShift.prototype, 'pitch', { + get: function () { + return this._pitch; + }, + set: function (interval) { + this._pitch = interval; + var factor = 0; + if (interval < 0) { + this._lfoA.min = 0; + this._lfoA.max = this._windowSize; + this._lfoB.min = 0; + this._lfoB.max = this._windowSize; + factor = this.intervalToFrequencyRatio(interval - 1) + 1; + } else { + this._lfoA.min = this._windowSize; + this._lfoA.max = 0; + this._lfoB.min = this._windowSize; + this._lfoB.max = 0; + factor = this.intervalToFrequencyRatio(interval) - 1; + } + this._frequency.value = factor * (1.2 / this._windowSize); + } + }); + /** + * The window size corresponds roughly to the sample length in a looping sampler. + * Smaller values are desirable for a less noticeable delay time of the pitch shifted + * signal, but larger values will result in smoother pitch shifting for larger intervals. + * A nominal range of 0.03 to 0.1 is recommended. + * @memberOf Tone.PitchShift# + * @type {Time} + * @name windowSize + * @example + * pitchShift.windowSize = 0.1; + */ + Object.defineProperty(Tone.PitchShift.prototype, 'windowSize', { + get: function () { + return this._windowSize; + }, + set: function (size) { + this._windowSize = this.toSeconds(size); + this.pitch = this._pitch; + } + }); + /** + * Clean up. + * @return {Tone.PitchShift} this + */ + Tone.PitchShift.prototype.dispose = function () { + Tone.FeedbackEffect.prototype.dispose.call(this); + this._frequency.dispose(); + this._frequency = null; + this._delayA.disconnect(); + this._delayA = null; + this._delayB.disconnect(); + this._delayB = null; + this._lfoA.dispose(); + this._lfoA = null; + this._lfoB.dispose(); + this._lfoB = null; + this._crossFade.dispose(); + this._crossFade = null; + this._crossFadeLFO.dispose(); + this._crossFadeLFO = null; + this._writable('delayTime'); + this._feedbackDelay.dispose(); + this._feedbackDelay = null; + this.delayTime = null; + return this; + }; + return Tone.PitchShift; + }); + Module(function (Tone) { + + /** + * @class Base class for stereo feedback effects where the effectReturn + * is fed back into the same channel. + * + * @constructor + * @extends {Tone.FeedbackEffect} + */ + Tone.StereoFeedbackEffect = function () { + var options = this.optionsObject(arguments, ['feedback'], Tone.FeedbackEffect.defaults); + Tone.StereoEffect.call(this, options); + /** + * controls the amount of feedback + * @type {NormalRange} + * @signal + */ + this.feedback = new Tone.Signal(options.feedback, Tone.Type.NormalRange); + /** + * the left side feeback + * @type {Tone.Gain} + * @private + */ + this._feedbackL = new Tone.Gain(); + /** + * the right side feeback + * @type {Tone.Gain} + * @private + */ + this._feedbackR = new Tone.Gain(); + //connect it up + this.effectReturnL.chain(this._feedbackL, this.effectSendL); + this.effectReturnR.chain(this._feedbackR, this.effectSendR); + this.feedback.fan(this._feedbackL.gain, this._feedbackR.gain); + this._readOnly(['feedback']); + }; + Tone.extend(Tone.StereoFeedbackEffect, Tone.FeedbackEffect); + /** + * clean up + * @returns {Tone.StereoFeedbackEffect} this + */ + Tone.StereoFeedbackEffect.prototype.dispose = function () { + Tone.StereoEffect.prototype.dispose.call(this); + this._writable(['feedback']); + this.feedback.dispose(); + this.feedback = null; + this._feedbackL.dispose(); + this._feedbackL = null; + this._feedbackR.dispose(); + this._feedbackR = null; + return this; + }; + return Tone.StereoFeedbackEffect; + }); + Module(function (Tone) { + + /** + * @class Applies a width factor to the mid/side seperation. + * 0 is all mid and 1 is all side. + * Algorithm found in [kvraudio forums](http://www.kvraudio.com/forum/viewtopic.php?t=212587). + *

+ * + * Mid *= 2*(1-width)
+ * Side *= 2*width + *
+ * + * @extends {Tone.MidSideEffect} + * @constructor + * @param {NormalRange|Object} [width] The stereo width. A width of 0 is mono and 1 is stereo. 0.5 is no change. + */ + Tone.StereoWidener = function () { + var options = this.optionsObject(arguments, ['width'], Tone.StereoWidener.defaults); + Tone.MidSideEffect.call(this, options); + /** + * The width control. 0 = 100% mid. 1 = 100% side. 0.5 = no change. + * @type {NormalRange} + * @signal + */ + this.width = new Tone.Signal(options.width, Tone.Type.NormalRange); + /** + * Mid multiplier + * @type {Tone.Expr} + * @private + */ + this._midMult = new Tone.Expr('$0 * ($1 * (1 - $2))'); + /** + * Side multiplier + * @type {Tone.Expr} + * @private + */ + this._sideMult = new Tone.Expr('$0 * ($1 * $2)'); + /** + * constant output of 2 + * @type {Tone} + * @private + */ + this._two = new Tone.Signal(2); + //the mid chain + this._two.connect(this._midMult, 0, 1); + this.width.connect(this._midMult, 0, 2); + //the side chain + this._two.connect(this._sideMult, 0, 1); + this.width.connect(this._sideMult, 0, 2); + //connect it to the effect send/return + this.midSend.chain(this._midMult, this.midReturn); + this.sideSend.chain(this._sideMult, this.sideReturn); + this._readOnly(['width']); + }; + Tone.extend(Tone.StereoWidener, Tone.MidSideEffect); + /** + * the default values + * @static + * @type {Object} + */ + Tone.StereoWidener.defaults = { 'width': 0.5 }; + /** + * Clean up. + * @returns {Tone.StereoWidener} this + */ + Tone.StereoWidener.prototype.dispose = function () { + Tone.MidSideEffect.prototype.dispose.call(this); + this._writable(['width']); + this.width.dispose(); + this.width = null; + this._midMult.dispose(); + this._midMult = null; + this._sideMult.dispose(); + this._sideMult = null; + this._two.dispose(); + this._two = null; + return this; + }; + return Tone.StereoWidener; + }); + Module(function (Tone) { + + /** + * @class Tone.Tremolo modulates the amplitude of an incoming signal using a Tone.LFO. + * The type, frequency, and depth of the LFO is controllable. + * + * @extends {Tone.StereoEffect} + * @constructor + * @param {Frequency} [frequency] The rate of the effect. + * @param {NormalRange} [depth] The depth of the effect. + * @example + * //create a tremolo and start it's LFO + * var tremolo = new Tone.Tremolo(9, 0.75).toMaster().start(); + * //route an oscillator through the tremolo and start it + * var oscillator = new Tone.Oscillator().connect(tremolo).start(); + */ + Tone.Tremolo = function () { + var options = this.optionsObject(arguments, [ + 'frequency', + 'depth' + ], Tone.Tremolo.defaults); + Tone.StereoEffect.call(this, options); + /** + * The tremelo LFO in the left channel + * @type {Tone.LFO} + * @private + */ + this._lfoL = new Tone.LFO({ + 'phase': options.spread, + 'min': 1, + 'max': 0 + }); + /** + * The tremelo LFO in the left channel + * @type {Tone.LFO} + * @private + */ + this._lfoR = new Tone.LFO({ + 'phase': options.spread, + 'min': 1, + 'max': 0 + }); + /** + * Where the gain is multiplied + * @type {Tone.Gain} + * @private + */ + this._amplitudeL = new Tone.Gain(); + /** + * Where the gain is multiplied + * @type {Tone.Gain} + * @private + */ + this._amplitudeR = new Tone.Gain(); + /** + * The frequency of the tremolo. + * @type {Frequency} + * @signal + */ + this.frequency = new Tone.Signal(options.frequency, Tone.Type.Frequency); + /** + * The depth of the effect. A depth of 0, has no effect + * on the amplitude, and a depth of 1 makes the amplitude + * modulate fully between 0 and 1. + * @type {NormalRange} + * @signal + */ + this.depth = new Tone.Signal(options.depth, Tone.Type.NormalRange); + this._readOnly([ + 'frequency', + 'depth' + ]); + this.effectSendL.chain(this._amplitudeL, this.effectReturnL); + this.effectSendR.chain(this._amplitudeR, this.effectReturnR); + this._lfoL.connect(this._amplitudeL.gain); + this._lfoR.connect(this._amplitudeR.gain); + this.frequency.fan(this._lfoL.frequency, this._lfoR.frequency); + this.depth.fan(this._lfoR.amplitude, this._lfoL.amplitude); + this.type = options.type; + this.spread = options.spread; + }; + Tone.extend(Tone.Tremolo, Tone.StereoEffect); + /** + * @static + * @const + * @type {Object} + */ + Tone.Tremolo.defaults = { + 'frequency': 10, + 'type': 'sine', + 'depth': 0.5, + 'spread': 180 + }; + /** + * Start the tremolo. + * @param {Time} [time=now] When the tremolo begins. + * @returns {Tone.Tremolo} this + */ + Tone.Tremolo.prototype.start = function (time) { + this._lfoL.start(time); + this._lfoR.start(time); + return this; + }; + /** + * Stop the tremolo. + * @param {Time} [time=now] When the tremolo stops. + * @returns {Tone.Tremolo} this + */ + Tone.Tremolo.prototype.stop = function (time) { + this._lfoL.stop(time); + this._lfoR.stop(time); + return this; + }; + /** + * Sync the effect to the transport. + * @param {Time} [delay=0] Delay time before starting the effect after the + * Transport has started. + * @returns {Tone.AutoFilter} this + */ + Tone.Tremolo.prototype.sync = function (delay) { + this._lfoL.sync(delay); + this._lfoR.sync(delay); + return this; + }; + /** + * Unsync the filter from the transport + * @returns {Tone.Tremolo} this + */ + Tone.Tremolo.prototype.unsync = function () { + this._lfoL.unsync(); + this._lfoR.unsync(); + return this; + }; + /** + * The Tremolo's oscillator type. + * @memberOf Tone.Tremolo# + * @type {string} + * @name type + */ + Object.defineProperty(Tone.Tremolo.prototype, 'type', { + get: function () { + return this._lfoL.type; + }, + set: function (type) { + this._lfoL.type = type; + this._lfoR.type = type; + } + }); + /** + * Amount of stereo spread. When set to 0, both LFO's will be panned centrally. + * When set to 180, LFO's will be panned hard left and right respectively. + * @memberOf Tone.Tremolo# + * @type {Degrees} + * @name spread + */ + Object.defineProperty(Tone.Tremolo.prototype, 'spread', { + get: function () { + return this._lfoR.phase - this._lfoL.phase; //180 + }, + set: function (spread) { + this._lfoL.phase = 90 - spread / 2; + this._lfoR.phase = spread / 2 + 90; + } + }); + /** + * clean up + * @returns {Tone.Tremolo} this + */ + Tone.Tremolo.prototype.dispose = function () { + Tone.StereoEffect.prototype.dispose.call(this); + this._writable([ + 'frequency', + 'depth' + ]); + this._lfoL.dispose(); + this._lfoL = null; + this._lfoR.dispose(); + this._lfoR = null; + this._amplitudeL.dispose(); + this._amplitudeL = null; + this._amplitudeR.dispose(); + this._amplitudeR = null; + this.frequency = null; + this.depth = null; + return this; + }; + return Tone.Tremolo; + }); + Module(function (Tone) { + + /** + * @class A Vibrato effect composed of a Tone.Delay and a Tone.LFO. The LFO + * modulates the delayTime of the delay, causing the pitch to rise + * and fall. + * @extends {Tone.Effect} + * @param {Frequency} frequency The frequency of the vibrato. + * @param {NormalRange} depth The amount the pitch is modulated. + */ + Tone.Vibrato = function () { + var options = this.optionsObject(arguments, [ + 'frequency', + 'depth' + ], Tone.Vibrato.defaults); + Tone.Effect.call(this, options); + /** + * The delay node used for the vibrato effect + * @type {Tone.Delay} + * @private + */ + this._delayNode = new Tone.Delay(0, options.maxDelay); + /** + * The LFO used to control the vibrato + * @type {Tone.LFO} + * @private + */ + this._lfo = new Tone.LFO({ + 'type': options.type, + 'min': 0, + 'max': options.maxDelay, + 'frequency': options.frequency, + 'phase': -90 //offse the phase so the resting position is in the center + }).start().connect(this._delayNode.delayTime); + /** + * The frequency of the vibrato + * @type {Frequency} + * @signal + */ + this.frequency = this._lfo.frequency; + /** + * The depth of the vibrato. + * @type {NormalRange} + * @signal + */ + this.depth = this._lfo.amplitude; + this.depth.value = options.depth; + this._readOnly([ + 'frequency', + 'depth' + ]); + this.effectSend.chain(this._delayNode, this.effectReturn); + }; + Tone.extend(Tone.Vibrato, Tone.Effect); + /** + * The defaults + * @type {Object} + * @const + */ + Tone.Vibrato.defaults = { + 'maxDelay': 0.005, + 'frequency': 5, + 'depth': 0.1, + 'type': 'sine' + }; + /** + * Type of oscillator attached to the Vibrato. + * @memberOf Tone.Vibrato# + * @type {string} + * @name type + */ + Object.defineProperty(Tone.Vibrato.prototype, 'type', { + get: function () { + return this._lfo.type; + }, + set: function (type) { + this._lfo.type = type; + } + }); + /** + * Clean up. + * @returns {Tone.Vibrato} this + */ + Tone.Vibrato.prototype.dispose = function () { + Tone.Effect.prototype.dispose.call(this); + this._delayNode.dispose(); + this._delayNode = null; + this._lfo.dispose(); + this._lfo = null; + this._writable([ + 'frequency', + 'depth' + ]); + this.frequency = null; + this.depth = null; + }; + return Tone.Vibrato; + }); + Module(function (Tone) { + + /** + * @class Tone.Event abstracts away Tone.Transport.schedule and provides a schedulable + * callback for a single or repeatable events along the timeline. + * + * @extends {Tone} + * @param {function} callback The callback to invoke at the time. + * @param {*} value The value or values which should be passed to + * the callback function on invocation. + * @example + * var chord = new Tone.Event(function(time, chord){ + * //the chord as well as the exact time of the event + * //are passed in as arguments to the callback function + * }, ["D4", "E4", "F4"]); + * //start the chord at the beginning of the transport timeline + * chord.start(); + * //loop it every measure for 8 measures + * chord.loop = 8; + * chord.loopEnd = "1m"; + */ + Tone.Event = function () { + var options = this.optionsObject(arguments, [ + 'callback', + 'value' + ], Tone.Event.defaults); + /** + * Loop value + * @type {Boolean|Positive} + * @private + */ + this._loop = options.loop; + /** + * The callback to invoke. + * @type {Function} + */ + this.callback = options.callback; + /** + * The value which is passed to the + * callback function. + * @type {*} + * @private + */ + this.value = options.value; + /** + * When the note is scheduled to start. + * @type {Number} + * @private + */ + this._loopStart = this.toTicks(options.loopStart); + /** + * When the note is scheduled to start. + * @type {Number} + * @private + */ + this._loopEnd = this.toTicks(options.loopEnd); + /** + * Tracks the scheduled events + * @type {Tone.TimelineState} + * @private + */ + this._state = new Tone.TimelineState(Tone.State.Stopped); + /** + * The playback speed of the note. A speed of 1 + * is no change. + * @private + * @type {Positive} + */ + this._playbackRate = 1; + /** + * A delay time from when the event is scheduled to start + * @type {Ticks} + * @private + */ + this._startOffset = 0; + /** + * The probability that the callback will be invoked + * at the scheduled time. + * @type {NormalRange} + * @example + * //the callback will be invoked 50% of the time + * event.probability = 0.5; + */ + this.probability = options.probability; + /** + * If set to true, will apply small (+/-0.02 seconds) random variation + * to the callback time. If the value is given as a time, it will randomize + * by that amount. + * @example + * event.humanize = true; + * @type {Boolean|Time} + */ + this.humanize = options.humanize; + /** + * If mute is true, the callback won't be + * invoked. + * @type {Boolean} + */ + this.mute = options.mute; + //set the initial values + this.playbackRate = options.playbackRate; + }; + Tone.extend(Tone.Event); + /** + * The default values + * @type {Object} + * @const + */ + Tone.Event.defaults = { + 'callback': Tone.noOp, + 'loop': false, + 'loopEnd': '1m', + 'loopStart': 0, + 'playbackRate': 1, + 'value': null, + 'probability': 1, + 'mute': false, + 'humanize': false + }; + /** + * Reschedule all of the events along the timeline + * with the updated values. + * @param {Time} after Only reschedules events after the given time. + * @return {Tone.Event} this + * @private + */ + Tone.Event.prototype._rescheduleEvents = function (after) { + //if no argument is given, schedules all of the events + after = this.defaultArg(after, -1); + this._state.forEachFrom(after, function (event) { + var duration; + if (event.state === Tone.State.Started) { + if (!this.isUndef(event.id)) { + Tone.Transport.clear(event.id); + } + var startTick = event.time + Math.round(this.startOffset / this._playbackRate); + if (this._loop) { + duration = Infinity; + if (this.isNumber(this._loop)) { + duration = this._loop * this._getLoopDuration(); + } + var nextEvent = this._state.getAfter(startTick); + if (nextEvent !== null) { + duration = Math.min(duration, nextEvent.time - startTick); + } + if (duration !== Infinity) { + //schedule a stop since it's finite duration + this._state.setStateAtTime(Tone.State.Stopped, startTick + duration + 1); + duration = Tone.Time(duration, 'i'); + } + var interval = Tone.Time(this._getLoopDuration(), 'i'); + event.id = Tone.Transport.scheduleRepeat(this._tick.bind(this), interval, Tone.TransportTime(startTick, 'i'), duration); + } else { + event.id = Tone.Transport.schedule(this._tick.bind(this), startTick + 'i'); + } + } + }.bind(this)); + return this; + }; + /** + * Returns the playback state of the note, either "started" or "stopped". + * @type {String} + * @readOnly + * @memberOf Tone.Event# + * @name state + */ + Object.defineProperty(Tone.Event.prototype, 'state', { + get: function () { + return this._state.getValueAtTime(Tone.Transport.ticks); + } + }); + /** + * The start from the scheduled start time + * @type {Ticks} + * @memberOf Tone.Event# + * @name startOffset + * @private + */ + Object.defineProperty(Tone.Event.prototype, 'startOffset', { + get: function () { + return this._startOffset; + }, + set: function (offset) { + this._startOffset = offset; + } + }); + /** + * Start the note at the given time. + * @param {TimelinePosition} time When the note should start. + * @return {Tone.Event} this + */ + Tone.Event.prototype.start = function (time) { + time = this.toTicks(time); + if (this._state.getValueAtTime(time) === Tone.State.Stopped) { + this._state.add({ + 'state': Tone.State.Started, + 'time': time, + 'id': undefined + }); + this._rescheduleEvents(time); + } + return this; + }; + /** + * Stop the Event at the given time. + * @param {TimelinePosition} time When the note should stop. + * @return {Tone.Event} this + */ + Tone.Event.prototype.stop = function (time) { + this.cancel(time); + time = this.toTicks(time); + if (this._state.getValueAtTime(time) === Tone.State.Started) { + this._state.setStateAtTime(Tone.State.Stopped, time); + var previousEvent = this._state.getBefore(time); + var reschedulTime = time; + if (previousEvent !== null) { + reschedulTime = previousEvent.time; + } + this._rescheduleEvents(reschedulTime); + } + return this; + }; + /** + * Cancel all scheduled events greater than or equal to the given time + * @param {TimelinePosition} [time=0] The time after which events will be cancel. + * @return {Tone.Event} this + */ + Tone.Event.prototype.cancel = function (time) { + time = this.defaultArg(time, -Infinity); + time = this.toTicks(time); + this._state.forEachFrom(time, function (event) { + Tone.Transport.clear(event.id); + }); + this._state.cancel(time); + return this; + }; + /** + * The callback function invoker. Also + * checks if the Event is done playing + * @param {Number} time The time of the event in seconds + * @private + */ + Tone.Event.prototype._tick = function (time) { + if (!this.mute && this._state.getValueAtTime(Tone.Transport.ticks) === Tone.State.Started) { + if (this.probability < 1 && Math.random() > this.probability) { + return; + } + if (this.humanize) { + var variation = 0.02; + if (!this.isBoolean(this.humanize)) { + variation = this.toSeconds(this.humanize); + } + time += (Math.random() * 2 - 1) * variation; + } + this.callback(time, this.value); + } + }; + /** + * Get the duration of the loop. + * @return {Ticks} + * @private + */ + Tone.Event.prototype._getLoopDuration = function () { + return Math.round((this._loopEnd - this._loopStart) / this._playbackRate); + }; + /** + * If the note should loop or not + * between Tone.Event.loopStart and + * Tone.Event.loopEnd. An integer + * value corresponds to the number of + * loops the Event does after it starts. + * @memberOf Tone.Event# + * @type {Boolean|Positive} + * @name loop + */ + Object.defineProperty(Tone.Event.prototype, 'loop', { + get: function () { + return this._loop; + }, + set: function (loop) { + this._loop = loop; + this._rescheduleEvents(); + } + }); + /** + * The playback rate of the note. Defaults to 1. + * @memberOf Tone.Event# + * @type {Positive} + * @name playbackRate + * @example + * note.loop = true; + * //repeat the note twice as fast + * note.playbackRate = 2; + */ + Object.defineProperty(Tone.Event.prototype, 'playbackRate', { + get: function () { + return this._playbackRate; + }, + set: function (rate) { + this._playbackRate = rate; + this._rescheduleEvents(); + } + }); + /** + * The loopEnd point is the time the event will loop + * if Tone.Event.loop is true. + * @memberOf Tone.Event# + * @type {TransportTime} + * @name loopEnd + */ + Object.defineProperty(Tone.Event.prototype, 'loopEnd', { + get: function () { + return Tone.TransportTime(this._loopEnd, 'i').toNotation(); + }, + set: function (loopEnd) { + this._loopEnd = this.toTicks(loopEnd); + if (this._loop) { + this._rescheduleEvents(); + } + } + }); + /** + * The time when the loop should start. + * @memberOf Tone.Event# + * @type {TransportTime} + * @name loopStart + */ + Object.defineProperty(Tone.Event.prototype, 'loopStart', { + get: function () { + return Tone.TransportTime(this._loopStart, 'i').toNotation(); + }, + set: function (loopStart) { + this._loopStart = this.toTicks(loopStart); + if (this._loop) { + this._rescheduleEvents(); + } + } + }); + /** + * The current progress of the loop interval. + * Returns 0 if the event is not started yet or + * it is not set to loop. + * @memberOf Tone.Event# + * @type {NormalRange} + * @name progress + * @readOnly + */ + Object.defineProperty(Tone.Event.prototype, 'progress', { + get: function () { + if (this._loop) { + var ticks = Tone.Transport.ticks; + var lastEvent = this._state.get(ticks); + if (lastEvent !== null && lastEvent.state === Tone.State.Started) { + var loopDuration = this._getLoopDuration(); + var progress = (ticks - lastEvent.time) % loopDuration; + return progress / loopDuration; + } else { + return 0; + } + } else { + return 0; + } + } + }); + /** + * Clean up + * @return {Tone.Event} this + */ + Tone.Event.prototype.dispose = function () { + this.cancel(); + this._state.dispose(); + this._state = null; + this.callback = null; + this.value = null; + }; + return Tone.Event; + }); + Module(function (Tone) { + /** + * @class Tone.Loop creates a looped callback at the + * specified interval. The callback can be + * started, stopped and scheduled along + * the Transport's timeline. + * @example + * var loop = new Tone.Loop(function(time){ + * //triggered every eighth note. + * console.log(time); + * }, "8n").start(0); + * Tone.Transport.start(); + * @extends {Tone} + * @param {Function} callback The callback to invoke with the event. + * @param {Time} interval The time between successive callback calls. + */ + Tone.Loop = function () { + var options = this.optionsObject(arguments, [ + 'callback', + 'interval' + ], Tone.Loop.defaults); + /** + * The event which produces the callbacks + */ + this._event = new Tone.Event({ + 'callback': this._tick.bind(this), + 'loop': true, + 'loopEnd': options.interval, + 'playbackRate': options.playbackRate, + 'probability': options.probability + }); + /** + * The callback to invoke with the next event in the pattern + * @type {Function} + */ + this.callback = options.callback; + //set the iterations + this.iterations = options.iterations; + }; + Tone.extend(Tone.Loop); + /** + * The defaults + * @const + * @type {Object} + */ + Tone.Loop.defaults = { + 'interval': '4n', + 'callback': Tone.noOp, + 'playbackRate': 1, + 'iterations': Infinity, + 'probability': true, + 'mute': false + }; + /** + * Start the loop at the specified time along the Transport's + * timeline. + * @param {TimelinePosition=} time When to start the Loop. + * @return {Tone.Loop} this + */ + Tone.Loop.prototype.start = function (time) { + this._event.start(time); + return this; + }; + /** + * Stop the loop at the given time. + * @param {TimelinePosition=} time When to stop the Arpeggio + * @return {Tone.Loop} this + */ + Tone.Loop.prototype.stop = function (time) { + this._event.stop(time); + return this; + }; + /** + * Cancel all scheduled events greater than or equal to the given time + * @param {TimelinePosition} [time=0] The time after which events will be cancel. + * @return {Tone.Loop} this + */ + Tone.Loop.prototype.cancel = function (time) { + this._event.cancel(time); + return this; + }; + /** + * Internal function called when the notes should be called + * @param {Number} time The time the event occurs + * @private + */ + Tone.Loop.prototype._tick = function (time) { + this.callback(time); + }; + /** + * The state of the Loop, either started or stopped. + * @memberOf Tone.Loop# + * @type {String} + * @name state + * @readOnly + */ + Object.defineProperty(Tone.Loop.prototype, 'state', { + get: function () { + return this._event.state; + } + }); + /** + * The progress of the loop as a value between 0-1. 0, when + * the loop is stopped or done iterating. + * @memberOf Tone.Loop# + * @type {NormalRange} + * @name progress + * @readOnly + */ + Object.defineProperty(Tone.Loop.prototype, 'progress', { + get: function () { + return this._event.progress; + } + }); + /** + * The time between successive callbacks. + * @example + * loop.interval = "8n"; //loop every 8n + * @memberOf Tone.Loop# + * @type {Time} + * @name interval + */ + Object.defineProperty(Tone.Loop.prototype, 'interval', { + get: function () { + return this._event.loopEnd; + }, + set: function (interval) { + this._event.loopEnd = interval; + } + }); + /** + * The playback rate of the loop. The normal playback rate is 1 (no change). + * A `playbackRate` of 2 would be twice as fast. + * @memberOf Tone.Loop# + * @type {Time} + * @name playbackRate + */ + Object.defineProperty(Tone.Loop.prototype, 'playbackRate', { + get: function () { + return this._event.playbackRate; + }, + set: function (rate) { + this._event.playbackRate = rate; + } + }); + /** + * Random variation +/-0.01s to the scheduled time. + * Or give it a time value which it will randomize by. + * @type {Boolean|Time} + * @memberOf Tone.Loop# + * @name humanize + */ + Object.defineProperty(Tone.Loop.prototype, 'humanize', { + get: function () { + return this._event.humanize; + }, + set: function (variation) { + this._event.humanize = variation; + } + }); + /** + * The probably of the callback being invoked. + * @memberOf Tone.Loop# + * @type {NormalRange} + * @name probability + */ + Object.defineProperty(Tone.Loop.prototype, 'probability', { + get: function () { + return this._event.probability; + }, + set: function (prob) { + this._event.probability = prob; + } + }); + /** + * Muting the Loop means that no callbacks are invoked. + * @memberOf Tone.Loop# + * @type {Boolean} + * @name mute + */ + Object.defineProperty(Tone.Loop.prototype, 'mute', { + get: function () { + return this._event.mute; + }, + set: function (mute) { + this._event.mute = mute; + } + }); + /** + * The number of iterations of the loop. The default + * value is Infinity (loop forever). + * @memberOf Tone.Loop# + * @type {Positive} + * @name iterations + */ + Object.defineProperty(Tone.Loop.prototype, 'iterations', { + get: function () { + if (this._event.loop === true) { + return Infinity; + } else { + return this._event.loop; + } + return this._pattern.index; + }, + set: function (iters) { + if (iters === Infinity) { + this._event.loop = true; + } else { + this._event.loop = iters; + } + } + }); + /** + * Clean up + * @return {Tone.Loop} this + */ + Tone.Loop.prototype.dispose = function () { + this._event.dispose(); + this._event = null; + this.callback = null; + }; + return Tone.Loop; + }); + Module(function (Tone) { + + /** + * @class Tone.Part is a collection Tone.Events which can be + * started/stoped and looped as a single unit. + * + * @extends {Tone.Event} + * @param {Function} callback The callback to invoke on each event + * @param {Array} events the array of events + * @example + * var part = new Tone.Part(function(time, note){ + * //the notes given as the second element in the array + * //will be passed in as the second argument + * synth.triggerAttackRelease(note, "8n", time); + * }, [[0, "C2"], ["0:2", "C3"], ["0:3:2", "G2"]]); + * @example + * //use an array of objects as long as the object has a "time" attribute + * var part = new Tone.Part(function(time, value){ + * //the value is an object which contains both the note and the velocity + * synth.triggerAttackRelease(value.note, "8n", time, value.velocity); + * }, [{"time" : 0, "note" : "C3", "velocity": 0.9}, + * {"time" : "0:2", "note" : "C4", "velocity": 0.5} + * ]).start(0); + */ + Tone.Part = function () { + var options = this.optionsObject(arguments, [ + 'callback', + 'events' + ], Tone.Part.defaults); + /** + * If the part is looping or not + * @type {Boolean|Positive} + * @private + */ + this._loop = options.loop; + /** + * When the note is scheduled to start. + * @type {Ticks} + * @private + */ + this._loopStart = this.toTicks(options.loopStart); + /** + * When the note is scheduled to start. + * @type {Ticks} + * @private + */ + this._loopEnd = this.toTicks(options.loopEnd); + /** + * The playback rate of the part + * @type {Positive} + * @private + */ + this._playbackRate = options.playbackRate; + /** + * private holder of probability value + * @type {NormalRange} + * @private + */ + this._probability = options.probability; + /** + * the amount of variation from the + * given time. + * @type {Boolean|Time} + * @private + */ + this._humanize = options.humanize; + /** + * The start offset + * @type {Ticks} + * @private + */ + this._startOffset = 0; + /** + * Keeps track of the current state + * @type {Tone.TimelineState} + * @private + */ + this._state = new Tone.TimelineState(Tone.State.Stopped); + /** + * An array of Objects. + * @type {Array} + * @private + */ + this._events = []; + /** + * The callback to invoke at all the scheduled events. + * @type {Function} + */ + this.callback = options.callback; + /** + * If mute is true, the callback won't be + * invoked. + * @type {Boolean} + */ + this.mute = options.mute; + //add the events + var events = this.defaultArg(options.events, []); + if (!this.isUndef(options.events)) { + for (var i = 0; i < events.length; i++) { + if (Array.isArray(events[i])) { + this.add(events[i][0], events[i][1]); + } else { + this.add(events[i]); + } + } + } + }; + Tone.extend(Tone.Part, Tone.Event); + /** + * The default values + * @type {Object} + * @const + */ + Tone.Part.defaults = { + 'callback': Tone.noOp, + 'loop': false, + 'loopEnd': '1m', + 'loopStart': 0, + 'playbackRate': 1, + 'probability': 1, + 'humanize': false, + 'mute': false + }; + /** + * Start the part at the given time. + * @param {TransportTime} time When to start the part. + * @param {Time=} offset The offset from the start of the part + * to begin playing at. + * @return {Tone.Part} this + */ + Tone.Part.prototype.start = function (time, offset) { + var ticks = this.toTicks(time); + if (this._state.getValueAtTime(ticks) !== Tone.State.Started) { + if (this._loop) { + offset = this.defaultArg(offset, this._loopStart); + } else { + offset = this.defaultArg(offset, 0); + } + offset = this.toTicks(offset); + this._state.add({ + 'state': Tone.State.Started, + 'time': ticks, + 'offset': offset + }); + this._forEach(function (event) { + this._startNote(event, ticks, offset); + }); + } + return this; + }; + /** + * Start the event in the given event at the correct time given + * the ticks and offset and looping. + * @param {Tone.Event} event + * @param {Ticks} ticks + * @param {Ticks} offset + * @private + */ + Tone.Part.prototype._startNote = function (event, ticks, offset) { + ticks -= offset; + if (this._loop) { + if (event.startOffset >= this._loopStart && event.startOffset < this._loopEnd) { + if (event.startOffset < offset) { + //start it on the next loop + ticks += this._getLoopDuration(); + } + event.start(Tone.TransportTime(ticks, 'i')); + } else if (event.startOffset < this._loopStart && event.startOffset >= offset) { + event.loop = false; + event.start(Tone.TransportTime(ticks, 'i')); + } + } else { + if (event.startOffset >= offset) { + event.start(Tone.TransportTime(ticks, 'i')); + } + } + }; + /** + * The start from the scheduled start time + * @type {Ticks} + * @memberOf Tone.Part# + * @name startOffset + * @private + */ + Object.defineProperty(Tone.Part.prototype, 'startOffset', { + get: function () { + return this._startOffset; + }, + set: function (offset) { + this._startOffset = offset; + this._forEach(function (event) { + event.startOffset += this._startOffset; + }); + } + }); + /** + * Stop the part at the given time. + * @param {TimelinePosition} time When to stop the part. + * @return {Tone.Part} this + */ + Tone.Part.prototype.stop = function (time) { + var ticks = this.toTicks(time); + this._state.cancel(ticks); + this._state.setStateAtTime(Tone.State.Stopped, ticks); + this._forEach(function (event) { + event.stop(time); + }); + return this; + }; + /** + * Get/Set an Event's value at the given time. + * If a value is passed in and no event exists at + * the given time, one will be created with that value. + * If two events are at the same time, the first one will + * be returned. + * @example + * part.at("1m"); //returns the part at the first measure + * + * part.at("2m", "C2"); //set the value at "2m" to C2. + * //if an event didn't exist at that time, it will be created. + * @param {TransportTime} time The time of the event to get or set. + * @param {*=} value If a value is passed in, the value of the + * event at the given time will be set to it. + * @return {Tone.Event} the event at the time + */ + Tone.Part.prototype.at = function (time, value) { + time = Tone.TransportTime(time); + var tickTime = Tone.Time(1, 'i').toSeconds(); + for (var i = 0; i < this._events.length; i++) { + var event = this._events[i]; + if (Math.abs(time.toTicks() - event.startOffset) < tickTime) { + if (!this.isUndef(value)) { + event.value = value; + } + return event; + } + } + //if there was no event at that time, create one + if (!this.isUndef(value)) { + this.add(time, value); + //return the new event + return this._events[this._events.length - 1]; + } else { + return null; + } + }; + /** + * Add a an event to the part. + * @param {Time} time The time the note should start. + * If an object is passed in, it should + * have a 'time' attribute and the rest + * of the object will be used as the 'value'. + * @param {Tone.Event|*} value + * @returns {Tone.Part} this + * @example + * part.add("1m", "C#+11"); + */ + Tone.Part.prototype.add = function (time, value) { + //extract the parameters + if (time.hasOwnProperty('time')) { + value = time; + time = value.time; + } + time = this.toTicks(time); + var event; + if (value instanceof Tone.Event) { + event = value; + event.callback = this._tick.bind(this); + } else { + event = new Tone.Event({ + 'callback': this._tick.bind(this), + 'value': value + }); + } + //the start offset + event.startOffset = time; + //initialize the values + event.set({ + 'loopEnd': this.loopEnd, + 'loopStart': this.loopStart, + 'loop': this.loop, + 'humanize': this.humanize, + 'playbackRate': this.playbackRate, + 'probability': this.probability + }); + this._events.push(event); + //start the note if it should be played right now + this._restartEvent(event); + return this; + }; + /** + * Restart the given event + * @param {Tone.Event} event + * @private + */ + Tone.Part.prototype._restartEvent = function (event) { + this._state.forEach(function (stateEvent) { + if (stateEvent.state === Tone.State.Started) { + this._startNote(event, stateEvent.time, stateEvent.offset); + } else { + //stop the note + event.stop(Tone.TransportTime(stateEvent.time, 'i')); + } + }.bind(this)); + }; + /** + * Remove an event from the part. Will recursively iterate + * into nested parts to find the event. + * @param {Time} time The time of the event + * @param {*} value Optionally select only a specific event value + * @return {Tone.Part} this + */ + Tone.Part.prototype.remove = function (time, value) { + //extract the parameters + if (time.hasOwnProperty('time')) { + value = time; + time = value.time; + } + time = this.toTicks(time); + for (var i = this._events.length - 1; i >= 0; i--) { + var event = this._events[i]; + if (event instanceof Tone.Part) { + event.remove(time, value); + } else { + if (event.startOffset === time) { + if (this.isUndef(value) || !this.isUndef(value) && event.value === value) { + this._events.splice(i, 1); + event.dispose(); + } + } + } + } + return this; + }; + /** + * Remove all of the notes from the group. + * @return {Tone.Part} this + */ + Tone.Part.prototype.removeAll = function () { + this._forEach(function (event) { + event.dispose(); + }); + this._events = []; + return this; + }; + /** + * Cancel scheduled state change events: i.e. "start" and "stop". + * @param {TimelinePosition} after The time after which to cancel the scheduled events. + * @return {Tone.Part} this + */ + Tone.Part.prototype.cancel = function (after) { + after = this.toTicks(after); + this._forEach(function (event) { + event.cancel(after); + }); + this._state.cancel(after); + return this; + }; + /** + * Iterate over all of the events + * @param {Function} callback + * @param {Object} ctx The context + * @private + */ + Tone.Part.prototype._forEach = function (callback, ctx) { + ctx = this.defaultArg(ctx, this); + for (var i = this._events.length - 1; i >= 0; i--) { + var e = this._events[i]; + if (e instanceof Tone.Part) { + e._forEach(callback, ctx); + } else { + callback.call(ctx, e); + } + } + return this; + }; + /** + * Set the attribute of all of the events + * @param {String} attr the attribute to set + * @param {*} value The value to set it to + * @private + */ + Tone.Part.prototype._setAll = function (attr, value) { + this._forEach(function (event) { + event[attr] = value; + }); + }; + /** + * Internal tick method + * @param {Number} time The time of the event in seconds + * @private + */ + Tone.Part.prototype._tick = function (time, value) { + if (!this.mute) { + this.callback(time, value); + } + }; + /** + * Determine if the event should be currently looping + * given the loop boundries of this Part. + * @param {Tone.Event} event The event to test + * @private + */ + Tone.Part.prototype._testLoopBoundries = function (event) { + if (event.startOffset < this._loopStart || event.startOffset >= this._loopEnd) { + event.cancel(0); + } else { + //reschedule it if it's stopped + if (event.state === Tone.State.Stopped) { + this._restartEvent(event); + } + } + }; + /** + * The probability of the notes being triggered. + * @memberOf Tone.Part# + * @type {NormalRange} + * @name probability + */ + Object.defineProperty(Tone.Part.prototype, 'probability', { + get: function () { + return this._probability; + }, + set: function (prob) { + this._probability = prob; + this._setAll('probability', prob); + } + }); + /** + * If set to true, will apply small random variation + * to the callback time. If the value is given as a time, it will randomize + * by that amount. + * @example + * event.humanize = true; + * @type {Boolean|Time} + * @name humanize + */ + Object.defineProperty(Tone.Part.prototype, 'humanize', { + get: function () { + return this._humanize; + }, + set: function (variation) { + this._humanize = variation; + this._setAll('humanize', variation); + } + }); + /** + * If the part should loop or not + * between Tone.Part.loopStart and + * Tone.Part.loopEnd. An integer + * value corresponds to the number of + * loops the Part does after it starts. + * @memberOf Tone.Part# + * @type {Boolean|Positive} + * @name loop + * @example + * //loop the part 8 times + * part.loop = 8; + */ + Object.defineProperty(Tone.Part.prototype, 'loop', { + get: function () { + return this._loop; + }, + set: function (loop) { + this._loop = loop; + this._forEach(function (event) { + event._loopStart = this._loopStart; + event._loopEnd = this._loopEnd; + event.loop = loop; + this._testLoopBoundries(event); + }); + } + }); + /** + * The loopEnd point determines when it will + * loop if Tone.Part.loop is true. + * @memberOf Tone.Part# + * @type {TransportTime} + * @name loopEnd + */ + Object.defineProperty(Tone.Part.prototype, 'loopEnd', { + get: function () { + return Tone.TransportTime(this._loopEnd, 'i').toNotation(); + }, + set: function (loopEnd) { + this._loopEnd = this.toTicks(loopEnd); + if (this._loop) { + this._forEach(function (event) { + event.loopEnd = loopEnd; + this._testLoopBoundries(event); + }); + } + } + }); + /** + * The loopStart point determines when it will + * loop if Tone.Part.loop is true. + * @memberOf Tone.Part# + * @type {TransportTime} + * @name loopStart + */ + Object.defineProperty(Tone.Part.prototype, 'loopStart', { + get: function () { + return Tone.TransportTime(this._loopStart, 'i').toNotation(); + }, + set: function (loopStart) { + this._loopStart = this.toTicks(loopStart); + if (this._loop) { + this._forEach(function (event) { + event.loopStart = this.loopStart; + this._testLoopBoundries(event); + }); + } + } + }); + /** + * The playback rate of the part + * @memberOf Tone.Part# + * @type {Positive} + * @name playbackRate + */ + Object.defineProperty(Tone.Part.prototype, 'playbackRate', { + get: function () { + return this._playbackRate; + }, + set: function (rate) { + this._playbackRate = rate; + this._setAll('playbackRate', rate); + } + }); + /** + * The number of scheduled notes in the part. + * @memberOf Tone.Part# + * @type {Positive} + * @name length + * @readOnly + */ + Object.defineProperty(Tone.Part.prototype, 'length', { + get: function () { + return this._events.length; + } + }); + /** + * Clean up + * @return {Tone.Part} this + */ + Tone.Part.prototype.dispose = function () { + this.removeAll(); + this._state.dispose(); + this._state = null; + this.callback = null; + this._events = null; + return this; + }; + return Tone.Part; + }); + Module(function (Tone) { + /** + * @class Tone.Pattern arpeggiates between the given notes + * in a number of patterns. See Tone.CtrlPattern for + * a full list of patterns. + * @example + * var pattern = new Tone.Pattern(function(time, note){ + * //the order of the notes passed in depends on the pattern + * }, ["C2", "D4", "E5", "A6"], "upDown"); + * @extends {Tone.Loop} + * @param {Function} callback The callback to invoke with the + * event. + * @param {Array} values The values to arpeggiate over. + */ + Tone.Pattern = function () { + var options = this.optionsObject(arguments, [ + 'callback', + 'values', + 'pattern' + ], Tone.Pattern.defaults); + Tone.Loop.call(this, options); + /** + * The pattern manager + * @type {Tone.CtrlPattern} + * @private + */ + this._pattern = new Tone.CtrlPattern({ + 'values': options.values, + 'type': options.pattern, + 'index': options.index + }); + }; + Tone.extend(Tone.Pattern, Tone.Loop); + /** + * The defaults + * @const + * @type {Object} + */ + Tone.Pattern.defaults = { + 'pattern': Tone.CtrlPattern.Type.Up, + 'values': [] + }; + /** + * Internal function called when the notes should be called + * @param {Number} time The time the event occurs + * @private + */ + Tone.Pattern.prototype._tick = function (time) { + this.callback(time, this._pattern.value); + this._pattern.next(); + }; + /** + * The current index in the values array. + * @memberOf Tone.Pattern# + * @type {Positive} + * @name index + */ + Object.defineProperty(Tone.Pattern.prototype, 'index', { + get: function () { + return this._pattern.index; + }, + set: function (i) { + this._pattern.index = i; + } + }); + /** + * The array of events. + * @memberOf Tone.Pattern# + * @type {Array} + * @name values + */ + Object.defineProperty(Tone.Pattern.prototype, 'values', { + get: function () { + return this._pattern.values; + }, + set: function (vals) { + this._pattern.values = vals; + } + }); + /** + * The current value of the pattern. + * @memberOf Tone.Pattern# + * @type {*} + * @name value + * @readOnly + */ + Object.defineProperty(Tone.Pattern.prototype, 'value', { + get: function () { + return this._pattern.value; + } + }); + /** + * The pattern type. See Tone.CtrlPattern for the full list of patterns. + * @memberOf Tone.Pattern# + * @type {String} + * @name pattern + */ + Object.defineProperty(Tone.Pattern.prototype, 'pattern', { + get: function () { + return this._pattern.type; + }, + set: function (pattern) { + this._pattern.type = pattern; + } + }); + /** + * Clean up + * @return {Tone.Pattern} this + */ + Tone.Pattern.prototype.dispose = function () { + Tone.Loop.prototype.dispose.call(this); + this._pattern.dispose(); + this._pattern = null; + }; + return Tone.Pattern; + }); + Module(function (Tone) { + + /** + * @class A sequence is an alternate notation of a part. Instead + * of passing in an array of [time, event] pairs, pass + * in an array of events which will be spaced at the + * given subdivision. Sub-arrays will subdivide that beat + * by the number of items are in the array. + * Sequence notation inspiration from [Tidal](http://yaxu.org/tidal/) + * @param {Function} callback The callback to invoke with every note + * @param {Array} events The sequence + * @param {Time} subdivision The subdivision between which events are placed. + * @extends {Tone.Part} + * @example + * var seq = new Tone.Sequence(function(time, note){ + * console.log(note); + * //straight quater notes + * }, ["C4", "E4", "G4", "A4"], "4n"); + * @example + * var seq = new Tone.Sequence(function(time, note){ + * console.log(note); + * //subdivisions are given as subarrays + * }, ["C4", ["E4", "D4", "E4"], "G4", ["A4", "G4"]]); + */ + Tone.Sequence = function () { + var options = this.optionsObject(arguments, [ + 'callback', + 'events', + 'subdivision' + ], Tone.Sequence.defaults); + //remove the events + var events = options.events; + delete options.events; + Tone.Part.call(this, options); + /** + * The subdivison of each note + * @type {Ticks} + * @private + */ + this._subdivision = this.toTicks(options.subdivision); + //if no time was passed in, the loop end is the end of the cycle + if (this.isUndef(options.loopEnd) && !this.isUndef(events)) { + this._loopEnd = events.length * this._subdivision; + } + //defaults to looping + this._loop = true; + //add all of the events + if (!this.isUndef(events)) { + for (var i = 0; i < events.length; i++) { + this.add(i, events[i]); + } + } + }; + Tone.extend(Tone.Sequence, Tone.Part); + /** + * The default values. + * @type {Object} + */ + Tone.Sequence.defaults = { 'subdivision': '4n' }; + /** + * The subdivision of the sequence. This can only be + * set in the constructor. The subdivision is the + * interval between successive steps. + * @type {Time} + * @memberOf Tone.Sequence# + * @name subdivision + * @readOnly + */ + Object.defineProperty(Tone.Sequence.prototype, 'subdivision', { + get: function () { + return Tone.Time(this._subdivision, 'i').toNotation(); + } + }); + /** + * Get/Set an index of the sequence. If the index contains a subarray, + * a Tone.Sequence representing that sub-array will be returned. + * @example + * var sequence = new Tone.Sequence(playNote, ["E4", "C4", "F#4", ["A4", "Bb3"]]) + * sequence.at(0)// => returns "E4" + * //set a value + * sequence.at(0, "G3"); + * //get a nested sequence + * sequence.at(3).at(1)// => returns "Bb3" + * @param {Positive} index The index to get or set + * @param {*} value Optionally pass in the value to set at the given index. + */ + Tone.Sequence.prototype.at = function (index, value) { + //if the value is an array, + if (this.isArray(value)) { + //remove the current event at that index + this.remove(index); + } + //call the parent's method + return Tone.Part.prototype.at.call(this, this._indexTime(index), value); + }; + /** + * Add an event at an index, if there's already something + * at that index, overwrite it. If `value` is an array, + * it will be parsed as a subsequence. + * @param {Number} index The index to add the event to + * @param {*} value The value to add at that index + * @returns {Tone.Sequence} this + */ + Tone.Sequence.prototype.add = function (index, value) { + if (value === null) { + return this; + } + if (this.isArray(value)) { + //make a subsequence and add that to the sequence + var subSubdivision = Math.round(this._subdivision / value.length); + value = new Tone.Sequence(this._tick.bind(this), value, Tone.Time(subSubdivision, 'i')); + } + Tone.Part.prototype.add.call(this, this._indexTime(index), value); + return this; + }; + /** + * Remove a value from the sequence by index + * @param {Number} index The index of the event to remove + * @returns {Tone.Sequence} this + */ + Tone.Sequence.prototype.remove = function (index, value) { + Tone.Part.prototype.remove.call(this, this._indexTime(index), value); + return this; + }; + /** + * Get the time of the index given the Sequence's subdivision + * @param {Number} index + * @return {Time} The time of that index + * @private + */ + Tone.Sequence.prototype._indexTime = function (index) { + if (index instanceof Tone.TransportTime) { + return index; + } else { + return Tone.TransportTime(index * this._subdivision + this.startOffset, 'i'); + } + }; + /** + * Clean up. + * @return {Tone.Sequence} this + */ + Tone.Sequence.prototype.dispose = function () { + Tone.Part.prototype.dispose.call(this); + return this; + }; + return Tone.Sequence; + }); + Module(function (Tone) { + + /** + * @class Tone.PulseOscillator is a pulse oscillator with control over pulse width, + * also known as the duty cycle. At 50% duty cycle (width = 0.5) the wave is + * a square and only odd-numbered harmonics are present. At all other widths + * even-numbered harmonics are present. Read more + * [here](https://wigglewave.wordpress.com/2014/08/16/pulse-waveforms-and-harmonics/). + * + * @constructor + * @extends {Tone.Oscillator} + * @param {Frequency} [frequency] The frequency of the oscillator + * @param {NormalRange} [width] The width of the pulse + * @example + * var pulse = new Tone.PulseOscillator("E5", 0.4).toMaster().start(); + */ + Tone.PulseOscillator = function () { + var options = this.optionsObject(arguments, [ + 'frequency', + 'width' + ], Tone.Oscillator.defaults); + Tone.Source.call(this, options); + /** + * The width of the pulse. + * @type {NormalRange} + * @signal + */ + this.width = new Tone.Signal(options.width, Tone.Type.NormalRange); + /** + * gate the width amount + * @type {Tone.Gain} + * @private + */ + this._widthGate = new Tone.Gain(); + /** + * the sawtooth oscillator + * @type {Tone.Oscillator} + * @private + */ + this._sawtooth = new Tone.Oscillator({ + frequency: options.frequency, + detune: options.detune, + type: 'sawtooth', + phase: options.phase + }); + /** + * The frequency control. + * @type {Frequency} + * @signal + */ + this.frequency = this._sawtooth.frequency; + /** + * The detune in cents. + * @type {Cents} + * @signal + */ + this.detune = this._sawtooth.detune; + /** + * Threshold the signal to turn it into a square + * @type {Tone.WaveShaper} + * @private + */ + this._thresh = new Tone.WaveShaper(function (val) { + if (val < 0) { + return -1; + } else { + return 1; + } + }); + //connections + this._sawtooth.chain(this._thresh, this.output); + this.width.chain(this._widthGate, this._thresh); + this._readOnly([ + 'width', + 'frequency', + 'detune' + ]); + }; + Tone.extend(Tone.PulseOscillator, Tone.Oscillator); + /** + * The default parameters. + * @static + * @const + * @type {Object} + */ + Tone.PulseOscillator.defaults = { + 'frequency': 440, + 'detune': 0, + 'phase': 0, + 'width': 0.2 + }; + /** + * start the oscillator + * @param {Time} time + * @private + */ + Tone.PulseOscillator.prototype._start = function (time) { + time = this.toSeconds(time); + this._sawtooth.start(time); + this._widthGate.gain.setValueAtTime(1, time); + }; + /** + * stop the oscillator + * @param {Time} time + * @private + */ + Tone.PulseOscillator.prototype._stop = function (time) { + time = this.toSeconds(time); + this._sawtooth.stop(time); + //the width is still connected to the output. + //that needs to be stopped also + this._widthGate.gain.setValueAtTime(0, time); + }; + /** + * The phase of the oscillator in degrees. + * @memberOf Tone.PulseOscillator# + * @type {Degrees} + * @name phase + */ + Object.defineProperty(Tone.PulseOscillator.prototype, 'phase', { + get: function () { + return this._sawtooth.phase; + }, + set: function (phase) { + this._sawtooth.phase = phase; + } + }); + /** + * The type of the oscillator. Always returns "pulse". + * @readOnly + * @memberOf Tone.PulseOscillator# + * @type {string} + * @name type + */ + Object.defineProperty(Tone.PulseOscillator.prototype, 'type', { + get: function () { + return 'pulse'; + } + }); + /** + * The partials of the waveform. Cannot set partials for this waveform type + * @memberOf Tone.PulseOscillator# + * @type {Array} + * @name partials + * @private + */ + Object.defineProperty(Tone.PulseOscillator.prototype, 'partials', { + get: function () { + return []; + } + }); + /** + * Clean up method. + * @return {Tone.PulseOscillator} this + */ + Tone.PulseOscillator.prototype.dispose = function () { + Tone.Source.prototype.dispose.call(this); + this._sawtooth.dispose(); + this._sawtooth = null; + this._writable([ + 'width', + 'frequency', + 'detune' + ]); + this.width.dispose(); + this.width = null; + this._widthGate.dispose(); + this._widthGate = null; + this._thresh.dispose(); + this._thresh = null; + this.frequency = null; + this.detune = null; + return this; + }; + return Tone.PulseOscillator; + }); + Module(function (Tone) { + + /** + * @class Tone.PWMOscillator modulates the width of a Tone.PulseOscillator + * at the modulationFrequency. This has the effect of continuously + * changing the timbre of the oscillator by altering the harmonics + * generated. + * + * @extends {Tone.Oscillator} + * @constructor + * @param {Frequency} frequency The starting frequency of the oscillator. + * @param {Frequency} modulationFrequency The modulation frequency of the width of the pulse. + * @example + * var pwm = new Tone.PWMOscillator("Ab3", 0.3).toMaster().start(); + */ + Tone.PWMOscillator = function () { + var options = this.optionsObject(arguments, [ + 'frequency', + 'modulationFrequency' + ], Tone.PWMOscillator.defaults); + Tone.Source.call(this, options); + /** + * the pulse oscillator + * @type {Tone.PulseOscillator} + * @private + */ + this._pulse = new Tone.PulseOscillator(options.modulationFrequency); + //change the pulse oscillator type + this._pulse._sawtooth.type = 'sine'; + /** + * the modulator + * @type {Tone.Oscillator} + * @private + */ + this._modulator = new Tone.Oscillator({ + 'frequency': options.frequency, + 'detune': options.detune, + 'phase': options.phase + }); + /** + * Scale the oscillator so it doesn't go silent + * at the extreme values. + * @type {Tone.Multiply} + * @private + */ + this._scale = new Tone.Multiply(2); + /** + * The frequency control. + * @type {Frequency} + * @signal + */ + this.frequency = this._modulator.frequency; + /** + * The detune of the oscillator. + * @type {Cents} + * @signal + */ + this.detune = this._modulator.detune; + /** + * The modulation rate of the oscillator. + * @type {Frequency} + * @signal + */ + this.modulationFrequency = this._pulse.frequency; + //connections + this._modulator.chain(this._scale, this._pulse.width); + this._pulse.connect(this.output); + this._readOnly([ + 'modulationFrequency', + 'frequency', + 'detune' + ]); + }; + Tone.extend(Tone.PWMOscillator, Tone.Oscillator); + /** + * default values + * @static + * @type {Object} + * @const + */ + Tone.PWMOscillator.defaults = { + 'frequency': 440, + 'detune': 0, + 'phase': 0, + 'modulationFrequency': 0.4 + }; + /** + * start the oscillator + * @param {Time} [time=now] + * @private + */ + Tone.PWMOscillator.prototype._start = function (time) { + time = this.toSeconds(time); + this._modulator.start(time); + this._pulse.start(time); + }; + /** + * stop the oscillator + * @param {Time} time (optional) timing parameter + * @private + */ + Tone.PWMOscillator.prototype._stop = function (time) { + time = this.toSeconds(time); + this._modulator.stop(time); + this._pulse.stop(time); + }; + /** + * The type of the oscillator. Always returns "pwm". + * @readOnly + * @memberOf Tone.PWMOscillator# + * @type {string} + * @name type + */ + Object.defineProperty(Tone.PWMOscillator.prototype, 'type', { + get: function () { + return 'pwm'; + } + }); + /** + * The partials of the waveform. Cannot set partials for this waveform type + * @memberOf Tone.PWMOscillator# + * @type {Array} + * @name partials + * @private + */ + Object.defineProperty(Tone.PWMOscillator.prototype, 'partials', { + get: function () { + return []; + } + }); + /** + * The phase of the oscillator in degrees. + * @memberOf Tone.PWMOscillator# + * @type {number} + * @name phase + */ + Object.defineProperty(Tone.PWMOscillator.prototype, 'phase', { + get: function () { + return this._modulator.phase; + }, + set: function (phase) { + this._modulator.phase = phase; + } + }); + /** + * Clean up. + * @return {Tone.PWMOscillator} this + */ + Tone.PWMOscillator.prototype.dispose = function () { + Tone.Source.prototype.dispose.call(this); + this._pulse.dispose(); + this._pulse = null; + this._scale.dispose(); + this._scale = null; + this._modulator.dispose(); + this._modulator = null; + this._writable([ + 'modulationFrequency', + 'frequency', + 'detune' + ]); + this.frequency = null; + this.detune = null; + this.modulationFrequency = null; + return this; + }; + return Tone.PWMOscillator; + }); + Module(function (Tone) { + + /** + * @class Tone.FMOscillator + * + * @extends {Tone.Oscillator} + * @constructor + * @param {Frequency} frequency The starting frequency of the oscillator. + * @param {String} type The type of the carrier oscillator. + * @param {String} modulationType The type of the modulator oscillator. + * @example + * //a sine oscillator frequency-modulated by a square wave + * var fmOsc = new Tone.FMOscillator("Ab3", "sine", "square").toMaster().start(); + */ + Tone.FMOscillator = function () { + var options = this.optionsObject(arguments, [ + 'frequency', + 'type', + 'modulationType' + ], Tone.FMOscillator.defaults); + Tone.Source.call(this, options); + /** + * The carrier oscillator + * @type {Tone.Oscillator} + * @private + */ + this._carrier = new Tone.Oscillator(options.frequency, options.type); + /** + * The oscillator's frequency + * @type {Frequency} + * @signal + */ + this.frequency = new Tone.Signal(options.frequency, Tone.Type.Frequency); + /** + * The detune control signal. + * @type {Cents} + * @signal + */ + this.detune = this._carrier.detune; + this.detune.value = options.detune; + /** + * The modulation index which is in essence the depth or amount of the modulation. In other terms it is the + * ratio of the frequency of the modulating signal (mf) to the amplitude of the + * modulating signal (ma) -- as in ma/mf. + * @type {Positive} + * @signal + */ + this.modulationIndex = new Tone.Multiply(options.modulationIndex); + this.modulationIndex.units = Tone.Type.Positive; + /** + * The modulating oscillator + * @type {Tone.Oscillator} + * @private + */ + this._modulator = new Tone.Oscillator(options.frequency, options.modulationType); + /** + * Harmonicity is the frequency ratio between the carrier and the modulator oscillators. + * A harmonicity of 1 gives both oscillators the same frequency. + * Harmonicity = 2 means a change of an octave. + * @type {Positive} + * @signal + * @example + * //pitch the modulator an octave below carrier + * synth.harmonicity.value = 0.5; + */ + this.harmonicity = new Tone.Multiply(options.harmonicity); + this.harmonicity.units = Tone.Type.Positive; + /** + * the node where the modulation happens + * @type {Tone.Gain} + * @private + */ + this._modulationNode = new Tone.Gain(0); + //connections + this.frequency.connect(this._carrier.frequency); + this.frequency.chain(this.harmonicity, this._modulator.frequency); + this.frequency.chain(this.modulationIndex, this._modulationNode); + this._modulator.connect(this._modulationNode.gain); + this._modulationNode.connect(this._carrier.frequency); + this._carrier.connect(this.output); + this.detune.connect(this._modulator.detune); + this.phase = options.phase; + this._readOnly([ + 'modulationIndex', + 'frequency', + 'detune', + 'harmonicity' + ]); + }; + Tone.extend(Tone.FMOscillator, Tone.Oscillator); + /** + * default values + * @static + * @type {Object} + * @const + */ + Tone.FMOscillator.defaults = { + 'frequency': 440, + 'detune': 0, + 'phase': 0, + 'modulationIndex': 2, + 'modulationType': 'square', + 'harmonicity': 1 + }; + /** + * start the oscillator + * @param {Time} [time=now] + * @private + */ + Tone.FMOscillator.prototype._start = function (time) { + time = this.toSeconds(time); + this._modulator.start(time); + this._carrier.start(time); + }; + /** + * stop the oscillator + * @param {Time} time (optional) timing parameter + * @private + */ + Tone.FMOscillator.prototype._stop = function (time) { + time = this.toSeconds(time); + this._modulator.stop(time); + this._carrier.stop(time); + }; + /** + * The type of the carrier oscillator + * @memberOf Tone.FMOscillator# + * @type {string} + * @name type + */ + Object.defineProperty(Tone.FMOscillator.prototype, 'type', { + get: function () { + return this._carrier.type; + }, + set: function (type) { + this._carrier.type = type; + } + }); + /** + * The type of the modulator oscillator + * @memberOf Tone.FMOscillator# + * @type {String} + * @name modulationType + */ + Object.defineProperty(Tone.FMOscillator.prototype, 'modulationType', { + get: function () { + return this._modulator.type; + }, + set: function (type) { + this._modulator.type = type; + } + }); + /** + * The phase of the oscillator in degrees. + * @memberOf Tone.FMOscillator# + * @type {number} + * @name phase + */ + Object.defineProperty(Tone.FMOscillator.prototype, 'phase', { + get: function () { + return this._carrier.phase; + }, + set: function (phase) { + this._carrier.phase = phase; + this._modulator.phase = phase; + } + }); + /** + * The partials of the carrier waveform. A partial represents + * the amplitude at a harmonic. The first harmonic is the + * fundamental frequency, the second is the octave and so on + * following the harmonic series. + * Setting this value will automatically set the type to "custom". + * The value is an empty array when the type is not "custom". + * @memberOf Tone.FMOscillator# + * @type {Array} + * @name partials + * @example + * osc.partials = [1, 0.2, 0.01]; + */ + Object.defineProperty(Tone.FMOscillator.prototype, 'partials', { + get: function () { + return this._carrier.partials; + }, + set: function (partials) { + this._carrier.partials = partials; + } + }); + /** + * Clean up. + * @return {Tone.FMOscillator} this + */ + Tone.FMOscillator.prototype.dispose = function () { + Tone.Source.prototype.dispose.call(this); + this._writable([ + 'modulationIndex', + 'frequency', + 'detune', + 'harmonicity' + ]); + this.frequency.dispose(); + this.frequency = null; + this.detune = null; + this.harmonicity.dispose(); + this.harmonicity = null; + this._carrier.dispose(); + this._carrier = null; + this._modulator.dispose(); + this._modulator = null; + this._modulationNode.dispose(); + this._modulationNode = null; + this.modulationIndex.dispose(); + this.modulationIndex = null; + return this; + }; + return Tone.FMOscillator; + }); + Module(function (Tone) { + + /** + * @class Tone.AMOscillator + * + * @extends {Tone.Oscillator} + * @constructor + * @param {Frequency} frequency The starting frequency of the oscillator. + * @param {String} type The type of the carrier oscillator. + * @param {String} modulationType The type of the modulator oscillator. + * @example + * //a sine oscillator frequency-modulated by a square wave + * var fmOsc = new Tone.AMOscillator("Ab3", "sine", "square").toMaster().start(); + */ + Tone.AMOscillator = function () { + var options = this.optionsObject(arguments, [ + 'frequency', + 'type', + 'modulationType' + ], Tone.AMOscillator.defaults); + Tone.Source.call(this, options); + /** + * The carrier oscillator + * @type {Tone.Oscillator} + * @private + */ + this._carrier = new Tone.Oscillator(options.frequency, options.type); + /** + * The oscillator's frequency + * @type {Frequency} + * @signal + */ + this.frequency = this._carrier.frequency; + /** + * The detune control signal. + * @type {Cents} + * @signal + */ + this.detune = this._carrier.detune; + this.detune.value = options.detune; + /** + * The modulating oscillator + * @type {Tone.Oscillator} + * @private + */ + this._modulator = new Tone.Oscillator(options.frequency, options.modulationType); + /** + * convert the -1,1 output to 0,1 + * @type {Tone.AudioToGain} + * @private + */ + this._modulationScale = new Tone.AudioToGain(); + /** + * Harmonicity is the frequency ratio between the carrier and the modulator oscillators. + * A harmonicity of 1 gives both oscillators the same frequency. + * Harmonicity = 2 means a change of an octave. + * @type {Positive} + * @signal + * @example + * //pitch the modulator an octave below carrier + * synth.harmonicity.value = 0.5; + */ + this.harmonicity = new Tone.Multiply(options.harmonicity); + this.harmonicity.units = Tone.Type.Positive; + /** + * the node where the modulation happens + * @type {Tone.Gain} + * @private + */ + this._modulationNode = new Tone.Gain(0); + //connections + this.frequency.chain(this.harmonicity, this._modulator.frequency); + this.detune.connect(this._modulator.detune); + this._modulator.chain(this._modulationScale, this._modulationNode.gain); + this._carrier.chain(this._modulationNode, this.output); + this.phase = options.phase; + this._readOnly([ + 'frequency', + 'detune', + 'harmonicity' + ]); + }; + Tone.extend(Tone.AMOscillator, Tone.Oscillator); + /** + * default values + * @static + * @type {Object} + * @const + */ + Tone.AMOscillator.defaults = { + 'frequency': 440, + 'detune': 0, + 'phase': 0, + 'modulationType': 'square', + 'harmonicity': 1 + }; + /** + * start the oscillator + * @param {Time} [time=now] + * @private + */ + Tone.AMOscillator.prototype._start = function (time) { + time = this.toSeconds(time); + this._modulator.start(time); + this._carrier.start(time); + }; + /** + * stop the oscillator + * @param {Time} time (optional) timing parameter + * @private + */ + Tone.AMOscillator.prototype._stop = function (time) { + time = this.toSeconds(time); + this._modulator.stop(time); + this._carrier.stop(time); + }; + /** + * The type of the carrier oscillator + * @memberOf Tone.AMOscillator# + * @type {string} + * @name type + */ + Object.defineProperty(Tone.AMOscillator.prototype, 'type', { + get: function () { + return this._carrier.type; + }, + set: function (type) { + this._carrier.type = type; + } + }); + /** + * The type of the modulator oscillator + * @memberOf Tone.AMOscillator# + * @type {string} + * @name modulationType + */ + Object.defineProperty(Tone.AMOscillator.prototype, 'modulationType', { + get: function () { + return this._modulator.type; + }, + set: function (type) { + this._modulator.type = type; + } + }); + /** + * The phase of the oscillator in degrees. + * @memberOf Tone.AMOscillator# + * @type {number} + * @name phase + */ + Object.defineProperty(Tone.AMOscillator.prototype, 'phase', { + get: function () { + return this._carrier.phase; + }, + set: function (phase) { + this._carrier.phase = phase; + this._modulator.phase = phase; + } + }); + /** + * The partials of the carrier waveform. A partial represents + * the amplitude at a harmonic. The first harmonic is the + * fundamental frequency, the second is the octave and so on + * following the harmonic series. + * Setting this value will automatically set the type to "custom". + * The value is an empty array when the type is not "custom". + * @memberOf Tone.AMOscillator# + * @type {Array} + * @name partials + * @example + * osc.partials = [1, 0.2, 0.01]; + */ + Object.defineProperty(Tone.AMOscillator.prototype, 'partials', { + get: function () { + return this._carrier.partials; + }, + set: function (partials) { + this._carrier.partials = partials; + } + }); + /** + * Clean up. + * @return {Tone.AMOscillator} this + */ + Tone.AMOscillator.prototype.dispose = function () { + Tone.Source.prototype.dispose.call(this); + this._writable([ + 'frequency', + 'detune', + 'harmonicity' + ]); + this.frequency = null; + this.detune = null; + this.harmonicity.dispose(); + this.harmonicity = null; + this._carrier.dispose(); + this._carrier = null; + this._modulator.dispose(); + this._modulator = null; + this._modulationNode.dispose(); + this._modulationNode = null; + this._modulationScale.dispose(); + this._modulationScale = null; + return this; + }; + return Tone.AMOscillator; + }); + Module(function (Tone) { + + /** + * @class Tone.FatOscillator + * + * @extends {Tone.Oscillator} + * @constructor + * @param {Frequency} frequency The starting frequency of the oscillator. + * @param {String} type The type of the carrier oscillator. + * @param {String} modulationType The type of the modulator oscillator. + * @example + * //a sine oscillator frequency-modulated by a square wave + * var fmOsc = new Tone.FatOscillator("Ab3", "sine", "square").toMaster().start(); + */ + Tone.FatOscillator = function () { + var options = this.optionsObject(arguments, [ + 'frequency', + 'type', + 'spread' + ], Tone.FatOscillator.defaults); + Tone.Source.call(this, options); + /** + * The oscillator's frequency + * @type {Frequency} + * @signal + */ + this.frequency = new Tone.Signal(options.frequency, Tone.Type.Frequency); + /** + * The detune control signal. + * @type {Cents} + * @signal + */ + this.detune = new Tone.Signal(options.detune, Tone.Type.Cents); + /** + * The array of oscillators + * @type {Array} + * @private + */ + this._oscillators = []; + /** + * The total spread of the oscillators + * @type {Cents} + * @private + */ + this._spread = options.spread; + /** + * The type of the oscillator + * @type {String} + * @private + */ + this._type = options.type; + /** + * The phase of the oscillators + * @type {Degrees} + * @private + */ + this._phase = options.phase; + /** + * The partials array + * @type {Array} + * @private + */ + this._partials = this.defaultArg(options.partials, []); + //set the count initially + this.count = options.count; + this._readOnly([ + 'frequency', + 'detune' + ]); + }; + Tone.extend(Tone.FatOscillator, Tone.Oscillator); + /** + * default values + * @static + * @type {Object} + * @const + */ + Tone.FatOscillator.defaults = { + 'frequency': 440, + 'detune': 0, + 'phase': 0, + 'spread': 20, + 'count': 3, + 'type': 'sawtooth' + }; + /** + * start the oscillator + * @param {Time} [time=now] + * @private + */ + Tone.FatOscillator.prototype._start = function (time) { + time = this.toSeconds(time); + this._forEach(function (osc) { + osc.start(time); + }); + }; + /** + * stop the oscillator + * @param {Time} time (optional) timing parameter + * @private + */ + Tone.FatOscillator.prototype._stop = function (time) { + time = this.toSeconds(time); + this._forEach(function (osc) { + osc.stop(time); + }); + }; + /** + * Iterate over all of the oscillators + * @param {Function} iterator The iterator function + * @private + */ + Tone.FatOscillator.prototype._forEach = function (iterator) { + for (var i = 0; i < this._oscillators.length; i++) { + iterator.call(this, this._oscillators[i], i); + } + }; + /** + * The type of the carrier oscillator + * @memberOf Tone.FatOscillator# + * @type {string} + * @name type + */ + Object.defineProperty(Tone.FatOscillator.prototype, 'type', { + get: function () { + return this._type; + }, + set: function (type) { + this._type = type; + this._forEach(function (osc) { + osc.type = type; + }); + } + }); + /** + * The detune spread between the oscillators. If "count" is + * set to 3 oscillators and the "spread" is set to 40, + * the three oscillators would be detuned like this: [-20, 0, 20] + * for a total detune spread of 40 cents. + * @memberOf Tone.FatOscillator# + * @type {Cents} + * @name spread + */ + Object.defineProperty(Tone.FatOscillator.prototype, 'spread', { + get: function () { + return this._spread; + }, + set: function (spread) { + this._spread = spread; + if (this._oscillators.length > 1) { + var start = -spread / 2; + var step = spread / (this._oscillators.length - 1); + this._forEach(function (osc, i) { + osc.detune.value = start + step * i; + }); + } + } + }); + /** + * The number of detuned oscillators + * @memberOf Tone.FatOscillator# + * @type {Number} + * @name count + */ + Object.defineProperty(Tone.FatOscillator.prototype, 'count', { + get: function () { + return this._oscillators.length; + }, + set: function (count) { + count = Math.max(count, 1); + if (this._oscillators.length !== count) { + // var partials = this.partials; + // var type = this.type; + //dispose the previous oscillators + this._forEach(function (osc) { + osc.dispose(); + }); + this._oscillators = []; + for (var i = 0; i < count; i++) { + var osc = new Tone.Oscillator(); + if (this.type === Tone.Oscillator.Type.Custom) { + osc.partials = this._partials; + } else { + osc.type = this._type; + } + osc.phase = this._phase; + osc.volume.value = -6 - count; + this.frequency.connect(osc.frequency); + this.detune.connect(osc.detune); + osc.connect(this.output); + this._oscillators[i] = osc; + } + //set the spread + this.spread = this._spread; + if (this.state === Tone.State.Started) { + this._forEach(function (osc) { + osc.start(); + }); + } + } + } + }); + /** + * The phase of the oscillator in degrees. + * @memberOf Tone.FatOscillator# + * @type {Number} + * @name phase + */ + Object.defineProperty(Tone.FatOscillator.prototype, 'phase', { + get: function () { + return this._phase; + }, + set: function (phase) { + this._phase = phase; + this._forEach(function (osc) { + osc.phase = phase; + }); + } + }); + /** + * The partials of the carrier waveform. A partial represents + * the amplitude at a harmonic. The first harmonic is the + * fundamental frequency, the second is the octave and so on + * following the harmonic series. + * Setting this value will automatically set the type to "custom". + * The value is an empty array when the type is not "custom". + * @memberOf Tone.FatOscillator# + * @type {Array} + * @name partials + * @example + * osc.partials = [1, 0.2, 0.01]; + */ + Object.defineProperty(Tone.FatOscillator.prototype, 'partials', { + get: function () { + return this._partials; + }, + set: function (partials) { + this._partials = partials; + this._type = Tone.Oscillator.Type.Custom; + this._forEach(function (osc) { + osc.partials = partials; + }); + } + }); + /** + * Clean up. + * @return {Tone.FatOscillator} this + */ + Tone.FatOscillator.prototype.dispose = function () { + Tone.Source.prototype.dispose.call(this); + this._writable([ + 'frequency', + 'detune' + ]); + this.frequency.dispose(); + this.frequency = null; + this.detune.dispose(); + this.detune = null; + this._forEach(function (osc) { + osc.dispose(); + }); + this._oscillators = null; + this._partials = null; + return this; + }; + return Tone.FatOscillator; + }); + Module(function (Tone) { + + /** + * @class Tone.OmniOscillator aggregates Tone.Oscillator, Tone.PulseOscillator, + * Tone.PWMOscillator, Tone.FMOscillator, Tone.AMOscillator, and Tone.FatOscillator + * into one class. The oscillator class can be changed by setting the `type`. + * `omniOsc.type = "pwm"` will set it to the Tone.PWMOscillator. Prefixing + * any of the basic types ("sine", "square4", etc.) with "fm", "am", or "fat" + * will use the FMOscillator, AMOscillator or FatOscillator respectively. + * For example: `omniOsc.type = "fatsawtooth"` will create set the oscillator + * to a FatOscillator of type "sawtooth". + * + * @extends {Tone.Oscillator} + * @constructor + * @param {Frequency} frequency The initial frequency of the oscillator. + * @param {String} type The type of the oscillator. + * @example + * var omniOsc = new Tone.OmniOscillator("C#4", "pwm"); + */ + Tone.OmniOscillator = function () { + var options = this.optionsObject(arguments, [ + 'frequency', + 'type' + ], Tone.OmniOscillator.defaults); + Tone.Source.call(this, options); + /** + * The frequency control. + * @type {Frequency} + * @signal + */ + this.frequency = new Tone.Signal(options.frequency, Tone.Type.Frequency); + /** + * The detune control + * @type {Cents} + * @signal + */ + this.detune = new Tone.Signal(options.detune, Tone.Type.Cents); + /** + * the type of the oscillator source + * @type {String} + * @private + */ + this._sourceType = undefined; + /** + * the oscillator + * @type {Tone.Oscillator} + * @private + */ + this._oscillator = null; + //set the oscillator + this.type = options.type; + this._readOnly([ + 'frequency', + 'detune' + ]); + //set the options + this.set(options); + }; + Tone.extend(Tone.OmniOscillator, Tone.Oscillator); + /** + * default values + * @static + * @type {Object} + * @const + */ + Tone.OmniOscillator.defaults = { + 'frequency': 440, + 'detune': 0, + 'type': 'sine', + 'phase': 0 + }; + /** + * @enum {String} + * @private + */ + var OmniOscType = { + Pulse: 'PulseOscillator', + PWM: 'PWMOscillator', + Osc: 'Oscillator', + FM: 'FMOscillator', + AM: 'AMOscillator', + Fat: 'FatOscillator' + }; + /** + * start the oscillator + * @param {Time} [time=now] the time to start the oscillator + * @private + */ + Tone.OmniOscillator.prototype._start = function (time) { + this._oscillator.start(time); + }; + /** + * start the oscillator + * @param {Time} [time=now] the time to start the oscillator + * @private + */ + Tone.OmniOscillator.prototype._stop = function (time) { + this._oscillator.stop(time); + }; + /** + * The type of the oscillator. Can be any of the basic types: sine, square, triangle, sawtooth. Or + * prefix the basic types with "fm", "am", or "fat" to use the FMOscillator, AMOscillator or FatOscillator + * types. The oscillator could also be set to "pwm" or "pulse". All of the parameters of the + * oscillator's class are accessible when the oscillator is set to that type, but throws an error + * when it's not. + * + * @memberOf Tone.OmniOscillator# + * @type {String} + * @name type + * @example + * omniOsc.type = "pwm"; + * //modulationFrequency is parameter which is available + * //only when the type is "pwm". + * omniOsc.modulationFrequency.value = 0.5; + * @example + * //an square wave frequency modulated by a sawtooth + * omniOsc.type = "fmsquare"; + * omniOsc.modulationType = "sawtooth"; + */ + Object.defineProperty(Tone.OmniOscillator.prototype, 'type', { + get: function () { + var prefix = ''; + if (this._sourceType === OmniOscType.FM) { + prefix = 'fm'; + } else if (this._sourceType === OmniOscType.AM) { + prefix = 'am'; + } else if (this._sourceType === OmniOscType.Fat) { + prefix = 'fat'; + } + return prefix + this._oscillator.type; + }, + set: function (type) { + if (type.substr(0, 2) === 'fm') { + this._createNewOscillator(OmniOscType.FM); + this._oscillator.type = type.substr(2); + } else if (type.substr(0, 2) === 'am') { + this._createNewOscillator(OmniOscType.AM); + this._oscillator.type = type.substr(2); + } else if (type.substr(0, 3) === 'fat') { + this._createNewOscillator(OmniOscType.Fat); + this._oscillator.type = type.substr(3); + } else if (type === 'pwm') { + this._createNewOscillator(OmniOscType.PWM); + } else if (type === 'pulse') { + this._createNewOscillator(OmniOscType.Pulse); + } else { + this._createNewOscillator(OmniOscType.Osc); + this._oscillator.type = type; + } + } + }); + /** + * The partials of the waveform. A partial represents + * the amplitude at a harmonic. The first harmonic is the + * fundamental frequency, the second is the octave and so on + * following the harmonic series. + * Setting this value will automatically set the type to "custom". + * The value is an empty array when the type is not "custom". + * This is not available on "pwm" and "pulse" oscillator types. + * @memberOf Tone.OmniOscillator# + * @type {Array} + * @name partials + * @example + * osc.partials = [1, 0.2, 0.01]; + */ + Object.defineProperty(Tone.OmniOscillator.prototype, 'partials', { + get: function () { + return this._oscillator.partials; + }, + set: function (partials) { + this._oscillator.partials = partials; + } + }); + /** + * Set a member/attribute of the oscillator. + * @param {Object|String} params + * @param {number=} value + * @param {Time=} rampTime + * @returns {Tone.OmniOscillator} this + */ + Tone.OmniOscillator.prototype.set = function (params, value) { + //make sure the type is set first + if (params === 'type') { + this.type = value; + } else if (this.isObject(params) && params.hasOwnProperty('type')) { + this.type = params.type; + } + //then set the rest + Tone.prototype.set.apply(this, arguments); + return this; + }; + /** + * connect the oscillator to the frequency and detune signals + * @private + */ + Tone.OmniOscillator.prototype._createNewOscillator = function (oscType) { + if (oscType !== this._sourceType) { + this._sourceType = oscType; + var OscillatorConstructor = Tone[oscType]; + //short delay to avoid clicks on the change + var now = this.now() + this.blockTime; + if (this._oscillator !== null) { + var oldOsc = this._oscillator; + oldOsc.stop(now); + //dispose the old one + setTimeout(function () { + oldOsc.dispose(); + oldOsc = null; + }, this.blockTime * 1000); + } + this._oscillator = new OscillatorConstructor(); + this.frequency.connect(this._oscillator.frequency); + this.detune.connect(this._oscillator.detune); + this._oscillator.connect(this.output); + if (this.state === Tone.State.Started) { + this._oscillator.start(now); + } + } + }; + /** + * The phase of the oscillator in degrees. + * @memberOf Tone.OmniOscillator# + * @type {Degrees} + * @name phase + */ + Object.defineProperty(Tone.OmniOscillator.prototype, 'phase', { + get: function () { + return this._oscillator.phase; + }, + set: function (phase) { + this._oscillator.phase = phase; + } + }); + /** + * The width of the oscillator (only if the oscillator is set to "pulse") + * @memberOf Tone.OmniOscillator# + * @type {NormalRange} + * @signal + * @name width + * @example + * var omniOsc = new Tone.OmniOscillator(440, "pulse"); + * //can access the width attribute only if type === "pulse" + * omniOsc.width.value = 0.2; + */ + Object.defineProperty(Tone.OmniOscillator.prototype, 'width', { + get: function () { + if (this._sourceType === OmniOscType.Pulse) { + return this._oscillator.width; + } + } + }); + /** + * The number of detuned oscillators + * @memberOf Tone.OmniOscillator# + * @type {Number} + * @name count + */ + Object.defineProperty(Tone.OmniOscillator.prototype, 'count', { + get: function () { + if (this._sourceType === OmniOscType.Fat) { + return this._oscillator.count; + } + }, + set: function (count) { + if (this._sourceType === OmniOscType.Fat) { + this._oscillator.count = count; + } + } + }); + /** + * The detune spread between the oscillators. If "count" is + * set to 3 oscillators and the "spread" is set to 40, + * the three oscillators would be detuned like this: [-20, 0, 20] + * for a total detune spread of 40 cents. See Tone.FatOscillator + * for more info. + * @memberOf Tone.OmniOscillator# + * @type {Cents} + * @name spread + */ + Object.defineProperty(Tone.OmniOscillator.prototype, 'spread', { + get: function () { + if (this._sourceType === OmniOscType.Fat) { + return this._oscillator.spread; + } + }, + set: function (spread) { + if (this._sourceType === OmniOscType.Fat) { + this._oscillator.spread = spread; + } + } + }); + /** + * The type of the modulator oscillator. Only if the oscillator + * is set to "am" or "fm" types. see. Tone.AMOscillator or Tone.FMOscillator + * for more info. + * @memberOf Tone.OmniOscillator# + * @type {String} + * @name modulationType + */ + Object.defineProperty(Tone.OmniOscillator.prototype, 'modulationType', { + get: function () { + if (this._sourceType === OmniOscType.FM || this._sourceType === OmniOscType.AM) { + return this._oscillator.modulationType; + } + }, + set: function (mType) { + if (this._sourceType === OmniOscType.FM || this._sourceType === OmniOscType.AM) { + this._oscillator.modulationType = mType; + } + } + }); + /** + * The modulation index which is in essence the depth or amount of the modulation. In other terms it is the + * ratio of the frequency of the modulating signal (mf) to the amplitude of the + * modulating signal (ma) -- as in ma/mf. + * See Tone.FMOscillator for more info. + * @type {Positive} + * @signal + * @name modulationIndex + */ + Object.defineProperty(Tone.OmniOscillator.prototype, 'modulationIndex', { + get: function () { + if (this._sourceType === OmniOscType.FM) { + return this._oscillator.modulationIndex; + } + } + }); + /** + * Harmonicity is the frequency ratio between the carrier and the modulator oscillators. + * A harmonicity of 1 gives both oscillators the same frequency. + * Harmonicity = 2 means a change of an octave. See Tone.AMOscillator or Tone.FMOscillator + * for more info. + * @memberOf Tone.OmniOscillator# + * @signal + * @type {Positive} + * @name harmonicity + */ + Object.defineProperty(Tone.OmniOscillator.prototype, 'harmonicity', { + get: function () { + if (this._sourceType === OmniOscType.FM || this._sourceType === OmniOscType.AM) { + return this._oscillator.harmonicity; + } + } + }); + /** + * The modulationFrequency Signal of the oscillator + * (only if the oscillator type is set to pwm). See + * Tone.PWMOscillator for more info. + * @memberOf Tone.OmniOscillator# + * @type {Frequency} + * @signal + * @name modulationFrequency + * @example + * var omniOsc = new Tone.OmniOscillator(440, "pwm"); + * //can access the modulationFrequency attribute only if type === "pwm" + * omniOsc.modulationFrequency.value = 0.2; + */ + Object.defineProperty(Tone.OmniOscillator.prototype, 'modulationFrequency', { + get: function () { + if (this._sourceType === OmniOscType.PWM) { + return this._oscillator.modulationFrequency; + } + } + }); + /** + * Clean up. + * @return {Tone.OmniOscillator} this + */ + Tone.OmniOscillator.prototype.dispose = function () { + Tone.Source.prototype.dispose.call(this); + this._writable([ + 'frequency', + 'detune' + ]); + this.detune.dispose(); + this.detune = null; + this.frequency.dispose(); + this.frequency = null; + this._oscillator.dispose(); + this._oscillator = null; + this._sourceType = null; + return this; + }; + return Tone.OmniOscillator; + }); + Module(function (Tone) { + + /** + * @class Base-class for all instruments + * + * @constructor + * @extends {Tone} + */ + Tone.Instrument = function (options) { + //get the defaults + options = this.defaultArg(options, Tone.Instrument.defaults); + /** + * The output and volume triming node + * @type {Tone.Volume} + * @private + */ + this._volume = this.output = new Tone.Volume(options.volume); + /** + * The volume of the output in decibels. + * @type {Decibels} + * @signal + * @example + * source.volume.value = -6; + */ + this.volume = this._volume.volume; + this._readOnly('volume'); + }; + Tone.extend(Tone.Instrument); + /** + * the default attributes + * @type {object} + */ + Tone.Instrument.defaults = { + /** the volume of the output in decibels */ + 'volume': 0 + }; + /** + * @abstract + * @param {string|number} note the note to trigger + * @param {Time} [time=now] the time to trigger the ntoe + * @param {number} [velocity=1] the velocity to trigger the note + */ + Tone.Instrument.prototype.triggerAttack = Tone.noOp; + /** + * @abstract + * @param {Time} [time=now] when to trigger the release + */ + Tone.Instrument.prototype.triggerRelease = Tone.noOp; + /** + * Trigger the attack and then the release after the duration. + * @param {Frequency} note The note to trigger. + * @param {Time} duration How long the note should be held for before + * triggering the release. + * @param {Time} [time=now] When the note should be triggered. + * @param {NormalRange} [velocity=1] The velocity the note should be triggered at. + * @returns {Tone.Instrument} this + * @example + * //trigger "C4" for the duration of an 8th note + * synth.triggerAttackRelease("C4", "8n"); + */ + Tone.Instrument.prototype.triggerAttackRelease = function (note, duration, time, velocity) { + if (this.isUndef(time)) { + time = this.now() + this.blockTime; + } else { + time = this.toSeconds(time); + } + duration = this.toSeconds(duration); + this.triggerAttack(note, time, velocity); + this.triggerRelease(time + duration); + return this; + }; + /** + * clean up + * @returns {Tone.Instrument} this + */ + Tone.Instrument.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._volume.dispose(); + this._volume = null; + this._writable(['volume']); + this.volume = null; + return this; + }; + return Tone.Instrument; + }); + Module(function (Tone) { + + /** + * @class This is an abstract base class for other monophonic instruments to + * extend. IMPORTANT: It does not make any sound on its own and + * shouldn't be directly instantiated. + * + * @constructor + * @abstract + * @extends {Tone.Instrument} + */ + Tone.Monophonic = function (options) { + //get the defaults + options = this.defaultArg(options, Tone.Monophonic.defaults); + Tone.Instrument.call(this, options); + /** + * The glide time between notes. + * @type {Time} + */ + this.portamento = options.portamento; + }; + Tone.extend(Tone.Monophonic, Tone.Instrument); + /** + * @static + * @const + * @type {Object} + */ + Tone.Monophonic.defaults = { 'portamento': 0 }; + /** + * Trigger the attack of the note optionally with a given velocity. + * + * + * @param {Frequency} note The note to trigger. + * @param {Time} [time=now] When the note should start. + * @param {number} [velocity=1] velocity The velocity scaler + * determines how "loud" the note + * will be triggered. + * @returns {Tone.Monophonic} this + * @example + * synth.triggerAttack("C4"); + * @example + * //trigger the note a half second from now at half velocity + * synth.triggerAttack("C4", "+0.5", 0.5); + */ + Tone.Monophonic.prototype.triggerAttack = function (note, time, velocity) { + if (this.isUndef(time)) { + time = this.now() + this.blockTime; + } else { + time = this.toSeconds(time); + } + this._triggerEnvelopeAttack(time, velocity); + this.setNote(note, time); + return this; + }; + /** + * Trigger the release portion of the envelope + * @param {Time} [time=now] If no time is given, the release happens immediatly + * @returns {Tone.Monophonic} this + * @example + * synth.triggerRelease(); + */ + Tone.Monophonic.prototype.triggerRelease = function (time) { + if (this.isUndef(time)) { + time = this.now() + this.blockTime; + } else { + time = this.toSeconds(time); + } + this._triggerEnvelopeRelease(time); + return this; + }; + /** + * override this method with the actual method + * @abstract + * @private + */ + Tone.Monophonic.prototype._triggerEnvelopeAttack = function () { + }; + /** + * override this method with the actual method + * @abstract + * @private + */ + Tone.Monophonic.prototype._triggerEnvelopeRelease = function () { + }; + /** + * Set the note at the given time. If no time is given, the note + * will set immediately. + * @param {Frequency} note The note to change to. + * @param {Time} [time=now] The time when the note should be set. + * @returns {Tone.Monophonic} this + * @example + * //change to F#6 in one quarter note from now. + * synth.setNote("F#6", "+4n"); + * @example + * //change to Bb4 right now + * synth.setNote("Bb4"); + */ + Tone.Monophonic.prototype.setNote = function (note, time) { + time = this.toSeconds(time); + if (this.portamento > 0) { + var currentNote = this.frequency.value; + this.frequency.setValueAtTime(currentNote, time); + var portTime = this.toSeconds(this.portamento); + this.frequency.exponentialRampToValueAtTime(note, time + portTime); + } else { + this.frequency.setValueAtTime(note, time); + } + return this; + }; + return Tone.Monophonic; + }); + Module(function (Tone) { + + /** + * @class Tone.Synth is composed simply of a Tone.OmniOscillator + * routed through a Tone.AmplitudeEnvelope. + * + * + * @constructor + * @extends {Tone.Monophonic} + * @param {Object} [options] the options available for the synth + * see defaults below + * @example + * var synth = new Tone.Synth().toMaster(); + * synth.triggerAttackRelease("C4", "8n"); + */ + Tone.Synth = function (options) { + //get the defaults + options = this.defaultArg(options, Tone.Synth.defaults); + Tone.Monophonic.call(this, options); + /** + * The oscillator. + * @type {Tone.OmniOscillator} + */ + this.oscillator = new Tone.OmniOscillator(options.oscillator); + /** + * The frequency control. + * @type {Frequency} + * @signal + */ + this.frequency = this.oscillator.frequency; + /** + * The detune control. + * @type {Cents} + * @signal + */ + this.detune = this.oscillator.detune; + /** + * The amplitude envelope. + * @type {Tone.AmplitudeEnvelope} + */ + this.envelope = new Tone.AmplitudeEnvelope(options.envelope); + //connect the oscillators to the output + this.oscillator.chain(this.envelope, this.output); + //start the oscillators + this.oscillator.start(); + this._readOnly([ + 'oscillator', + 'frequency', + 'detune', + 'envelope' + ]); + }; + Tone.extend(Tone.Synth, Tone.Monophonic); + /** + * @const + * @static + * @type {Object} + */ + Tone.Synth.defaults = { + 'oscillator': { 'type': 'triangle' }, + 'envelope': { + 'attack': 0.005, + 'decay': 0.1, + 'sustain': 0.3, + 'release': 1 + } + }; + /** + * start the attack portion of the envelope + * @param {Time} [time=now] the time the attack should start + * @param {number} [velocity=1] the velocity of the note (0-1) + * @returns {Tone.Synth} this + * @private + */ + Tone.Synth.prototype._triggerEnvelopeAttack = function (time, velocity) { + //the envelopes + this.envelope.triggerAttack(time, velocity); + return this; + }; + /** + * start the release portion of the envelope + * @param {Time} [time=now] the time the release should start + * @returns {Tone.Synth} this + * @private + */ + Tone.Synth.prototype._triggerEnvelopeRelease = function (time) { + this.envelope.triggerRelease(time); + return this; + }; + /** + * clean up + * @returns {Tone.Synth} this + */ + Tone.Synth.prototype.dispose = function () { + Tone.Monophonic.prototype.dispose.call(this); + this._writable([ + 'oscillator', + 'frequency', + 'detune', + 'envelope' + ]); + this.oscillator.dispose(); + this.oscillator = null; + this.envelope.dispose(); + this.envelope = null; + this.frequency = null; + this.detune = null; + return this; + }; + return Tone.Synth; + }); + Module(function (Tone) { + + /** + * @class AMSynth uses the output of one Tone.Synth to modulate the + * amplitude of another Tone.Synth. The harmonicity (the ratio between + * the two signals) affects the timbre of the output signal greatly. + * Read more about Amplitude Modulation Synthesis on + * [SoundOnSound](http://www.soundonsound.com/sos/mar00/articles/synthsecrets.htm). + * + * + * @constructor + * @extends {Tone.Monophonic} + * @param {Object} [options] the options available for the synth + * see defaults below + * @example + * var synth = new Tone.AMSynth().toMaster(); + * synth.triggerAttackRelease("C4", "4n"); + */ + Tone.AMSynth = function (options) { + options = this.defaultArg(options, Tone.AMSynth.defaults); + Tone.Monophonic.call(this, options); + /** + * The carrier voice. + * @type {Tone.Synth} + * @private + */ + this._carrier = new Tone.Synth(); + this._carrier.volume.value = -10; + /** + * The carrier's oscillator + * @type {Tone.Oscillator} + */ + this.oscillator = this._carrier.oscillator; + /** + * The carrier's envelope + * @type {Tone.Oscillator} + */ + this.envelope = this._carrier.envelope.set(options.envelope); + /** + * The modulator voice. + * @type {Tone.Synth} + * @private + */ + this._modulator = new Tone.Synth(); + this._modulator.volume.value = -10; + /** + * The modulator's oscillator which is applied + * to the amplitude of the oscillator + * @type {Tone.Oscillator} + */ + this.modulation = this._modulator.oscillator.set(options.modulation); + /** + * The modulator's envelope + * @type {Tone.Oscillator} + */ + this.modulationEnvelope = this._modulator.envelope.set(options.modulationEnvelope); + /** + * The frequency. + * @type {Frequency} + * @signal + */ + this.frequency = new Tone.Signal(440, Tone.Type.Frequency); + /** + * The detune in cents + * @type {Cents} + * @signal + */ + this.detune = new Tone.Signal(options.detune, Tone.Type.Cents); + /** + * Harmonicity is the ratio between the two voices. A harmonicity of + * 1 is no change. Harmonicity = 2 means a change of an octave. + * @type {Positive} + * @signal + * @example + * //pitch voice1 an octave below voice0 + * synth.harmonicity.value = 0.5; + */ + this.harmonicity = new Tone.Multiply(options.harmonicity); + this.harmonicity.units = Tone.Type.Positive; + /** + * convert the -1,1 output to 0,1 + * @type {Tone.AudioToGain} + * @private + */ + this._modulationScale = new Tone.AudioToGain(); + /** + * the node where the modulation happens + * @type {Tone.Gain} + * @private + */ + this._modulationNode = new Tone.Gain(); + //control the two voices frequency + this.frequency.connect(this._carrier.frequency); + this.frequency.chain(this.harmonicity, this._modulator.frequency); + this.detune.fan(this._carrier.detune, this._modulator.detune); + this._modulator.chain(this._modulationScale, this._modulationNode.gain); + this._carrier.chain(this._modulationNode, this.output); + this._readOnly([ + 'frequency', + 'harmonicity', + 'oscillator', + 'envelope', + 'modulation', + 'modulationEnvelope', + 'detune' + ]); + }; + Tone.extend(Tone.AMSynth, Tone.Monophonic); + /** + * @static + * @type {Object} + */ + Tone.AMSynth.defaults = { + 'harmonicity': 3, + 'detune': 0, + 'oscillator': { 'type': 'sine' }, + 'envelope': { + 'attack': 0.01, + 'decay': 0.01, + 'sustain': 1, + 'release': 0.5 + }, + 'modulation': { 'type': 'square' }, + 'modulationEnvelope': { + 'attack': 0.5, + 'decay': 0, + 'sustain': 1, + 'release': 0.5 + } + }; + /** + * trigger the attack portion of the note + * + * @param {Time} [time=now] the time the note will occur + * @param {NormalRange} [velocity=1] the velocity of the note + * @private + * @returns {Tone.AMSynth} this + */ + Tone.AMSynth.prototype._triggerEnvelopeAttack = function (time, velocity) { + //the port glide + time = this.toSeconds(time); + //the envelopes + this.envelope.triggerAttack(time, velocity); + this.modulationEnvelope.triggerAttack(time, velocity); + return this; + }; + /** + * trigger the release portion of the note + * + * @param {Time} [time=now] the time the note will release + * @private + * @returns {Tone.AMSynth} this + */ + Tone.AMSynth.prototype._triggerEnvelopeRelease = function (time) { + this.envelope.triggerRelease(time); + this.modulationEnvelope.triggerRelease(time); + return this; + }; + /** + * clean up + * @returns {Tone.AMSynth} this + */ + Tone.AMSynth.prototype.dispose = function () { + Tone.Monophonic.prototype.dispose.call(this); + this._writable([ + 'frequency', + 'harmonicity', + 'oscillator', + 'envelope', + 'modulation', + 'modulationEnvelope', + 'detune' + ]); + this._carrier.dispose(); + this._carrier = null; + this._modulator.dispose(); + this._modulator = null; + this.frequency.dispose(); + this.frequency = null; + this.detune.dispose(); + this.detune = null; + this.harmonicity.dispose(); + this.harmonicity = null; + this._modulationScale.dispose(); + this._modulationScale = null; + this._modulationNode.dispose(); + this._modulationNode = null; + this.oscillator = null; + this.envelope = null; + this.modulationEnvelope = null; + this.modulation = null; + return this; + }; + return Tone.AMSynth; + }); + Module(function (Tone) { + + /** + * @class Tone.MonoSynth is composed of one oscillator, one filter, and two envelopes. + * The amplitude of the Tone.Oscillator and the cutoff frequency of the + * Tone.Filter are controlled by Tone.Envelopes. + * + * + * @constructor + * @extends {Tone.Monophonic} + * @param {Object} [options] the options available for the synth + * see defaults below + * @example + * var synth = new Tone.MonoSynth({ + * "oscillator" : { + * "type" : "square" + * }, + * "envelope" : { + * "attack" : 0.1 + * } + * }).toMaster(); + * synth.triggerAttackRelease("C4", "8n"); + */ + Tone.MonoSynth = function (options) { + //get the defaults + options = this.defaultArg(options, Tone.MonoSynth.defaults); + Tone.Monophonic.call(this, options); + /** + * The oscillator. + * @type {Tone.OmniOscillator} + */ + this.oscillator = new Tone.OmniOscillator(options.oscillator); + /** + * The frequency control. + * @type {Frequency} + * @signal + */ + this.frequency = this.oscillator.frequency; + /** + * The detune control. + * @type {Cents} + * @signal + */ + this.detune = this.oscillator.detune; + /** + * The filter. + * @type {Tone.Filter} + */ + this.filter = new Tone.Filter(options.filter); + /** + * The filter envelope. + * @type {Tone.FrequencyEnvelope} + */ + this.filterEnvelope = new Tone.FrequencyEnvelope(options.filterEnvelope); + /** + * The amplitude envelope. + * @type {Tone.AmplitudeEnvelope} + */ + this.envelope = new Tone.AmplitudeEnvelope(options.envelope); + //connect the oscillators to the output + this.oscillator.chain(this.filter, this.envelope, this.output); + //start the oscillators + this.oscillator.start(); + //connect the filter envelope + this.filterEnvelope.connect(this.filter.frequency); + this._readOnly([ + 'oscillator', + 'frequency', + 'detune', + 'filter', + 'filterEnvelope', + 'envelope' + ]); + }; + Tone.extend(Tone.MonoSynth, Tone.Monophonic); + /** + * @const + * @static + * @type {Object} + */ + Tone.MonoSynth.defaults = { + 'frequency': 'C4', + 'detune': 0, + 'oscillator': { 'type': 'square' }, + 'filter': { + 'Q': 6, + 'type': 'lowpass', + 'rolloff': -24 + }, + 'envelope': { + 'attack': 0.005, + 'decay': 0.1, + 'sustain': 0.9, + 'release': 1 + }, + 'filterEnvelope': { + 'attack': 0.06, + 'decay': 0.2, + 'sustain': 0.5, + 'release': 2, + 'baseFrequency': 200, + 'octaves': 7, + 'exponent': 2 + } + }; + /** + * start the attack portion of the envelope + * @param {Time} [time=now] the time the attack should start + * @param {NormalRange} [velocity=1] the velocity of the note (0-1) + * @returns {Tone.MonoSynth} this + * @private + */ + Tone.MonoSynth.prototype._triggerEnvelopeAttack = function (time, velocity) { + //the envelopes + this.envelope.triggerAttack(time, velocity); + this.filterEnvelope.triggerAttack(time); + return this; + }; + /** + * start the release portion of the envelope + * @param {Time} [time=now] the time the release should start + * @returns {Tone.MonoSynth} this + * @private + */ + Tone.MonoSynth.prototype._triggerEnvelopeRelease = function (time) { + this.envelope.triggerRelease(time); + this.filterEnvelope.triggerRelease(time); + return this; + }; + /** + * clean up + * @returns {Tone.MonoSynth} this + */ + Tone.MonoSynth.prototype.dispose = function () { + Tone.Monophonic.prototype.dispose.call(this); + this._writable([ + 'oscillator', + 'frequency', + 'detune', + 'filter', + 'filterEnvelope', + 'envelope' + ]); + this.oscillator.dispose(); + this.oscillator = null; + this.envelope.dispose(); + this.envelope = null; + this.filterEnvelope.dispose(); + this.filterEnvelope = null; + this.filter.dispose(); + this.filter = null; + this.frequency = null; + this.detune = null; + return this; + }; + return Tone.MonoSynth; + }); + Module(function (Tone) { + + /** + * @class Tone.DuoSynth is a monophonic synth composed of two + * MonoSynths run in parallel with control over the + * frequency ratio between the two voices and vibrato effect. + * + * + * @constructor + * @extends {Tone.Monophonic} + * @param {Object} [options] the options available for the synth + * see defaults below + * @example + * var duoSynth = new Tone.DuoSynth().toMaster(); + * duoSynth.triggerAttackRelease("C4", "2n"); + */ + Tone.DuoSynth = function (options) { + options = this.defaultArg(options, Tone.DuoSynth.defaults); + Tone.Monophonic.call(this, options); + /** + * the first voice + * @type {Tone.MonoSynth} + */ + this.voice0 = new Tone.MonoSynth(options.voice0); + this.voice0.volume.value = -10; + /** + * the second voice + * @type {Tone.MonoSynth} + */ + this.voice1 = new Tone.MonoSynth(options.voice1); + this.voice1.volume.value = -10; + /** + * The vibrato LFO. + * @type {Tone.LFO} + * @private + */ + this._vibrato = new Tone.LFO(options.vibratoRate, -50, 50); + this._vibrato.start(); + /** + * the vibrato frequency + * @type {Frequency} + * @signal + */ + this.vibratoRate = this._vibrato.frequency; + /** + * the vibrato gain + * @type {Tone.Gain} + * @private + */ + this._vibratoGain = new Tone.Gain(options.vibratoAmount, Tone.Type.Positive); + /** + * The amount of vibrato + * @type {Positive} + * @signal + */ + this.vibratoAmount = this._vibratoGain.gain; + /** + * the frequency control + * @type {Frequency} + * @signal + */ + this.frequency = new Tone.Signal(440, Tone.Type.Frequency); + /** + * Harmonicity is the ratio between the two voices. A harmonicity of + * 1 is no change. Harmonicity = 2 means a change of an octave. + * @type {Positive} + * @signal + * @example + * //pitch voice1 an octave below voice0 + * duoSynth.harmonicity.value = 0.5; + */ + this.harmonicity = new Tone.Multiply(options.harmonicity); + this.harmonicity.units = Tone.Type.Positive; + //control the two voices frequency + this.frequency.connect(this.voice0.frequency); + this.frequency.chain(this.harmonicity, this.voice1.frequency); + this._vibrato.connect(this._vibratoGain); + this._vibratoGain.fan(this.voice0.detune, this.voice1.detune); + this.voice0.connect(this.output); + this.voice1.connect(this.output); + this._readOnly([ + 'voice0', + 'voice1', + 'frequency', + 'vibratoAmount', + 'vibratoRate' + ]); + }; + Tone.extend(Tone.DuoSynth, Tone.Monophonic); + /** + * @static + * @type {Object} + */ + Tone.DuoSynth.defaults = { + 'vibratoAmount': 0.5, + 'vibratoRate': 5, + 'harmonicity': 1.5, + 'voice0': { + 'volume': -10, + 'portamento': 0, + 'oscillator': { 'type': 'sine' }, + 'filterEnvelope': { + 'attack': 0.01, + 'decay': 0, + 'sustain': 1, + 'release': 0.5 + }, + 'envelope': { + 'attack': 0.01, + 'decay': 0, + 'sustain': 1, + 'release': 0.5 + } + }, + 'voice1': { + 'volume': -10, + 'portamento': 0, + 'oscillator': { 'type': 'sine' }, + 'filterEnvelope': { + 'attack': 0.01, + 'decay': 0, + 'sustain': 1, + 'release': 0.5 + }, + 'envelope': { + 'attack': 0.01, + 'decay': 0, + 'sustain': 1, + 'release': 0.5 + } + } + }; + /** + * start the attack portion of the envelopes + * + * @param {Time} [time=now] the time the attack should start + * @param {NormalRange} [velocity=1] the velocity of the note (0-1) + * @returns {Tone.DuoSynth} this + * @private + */ + Tone.DuoSynth.prototype._triggerEnvelopeAttack = function (time, velocity) { + time = this.toSeconds(time); + this.voice0.envelope.triggerAttack(time, velocity); + this.voice1.envelope.triggerAttack(time, velocity); + this.voice0.filterEnvelope.triggerAttack(time); + this.voice1.filterEnvelope.triggerAttack(time); + return this; + }; + /** + * start the release portion of the envelopes + * + * @param {Time} [time=now] the time the release should start + * @returns {Tone.DuoSynth} this + * @private + */ + Tone.DuoSynth.prototype._triggerEnvelopeRelease = function (time) { + this.voice0.triggerRelease(time); + this.voice1.triggerRelease(time); + return this; + }; + /** + * clean up + * @returns {Tone.DuoSynth} this + */ + Tone.DuoSynth.prototype.dispose = function () { + Tone.Monophonic.prototype.dispose.call(this); + this._writable([ + 'voice0', + 'voice1', + 'frequency', + 'vibratoAmount', + 'vibratoRate' + ]); + this.voice0.dispose(); + this.voice0 = null; + this.voice1.dispose(); + this.voice1 = null; + this.frequency.dispose(); + this.frequency = null; + this._vibratoGain.dispose(); + this._vibratoGain = null; + this._vibrato = null; + this.harmonicity.dispose(); + this.harmonicity = null; + this.vibratoAmount.dispose(); + this.vibratoAmount = null; + this.vibratoRate = null; + return this; + }; + return Tone.DuoSynth; + }); + Module(function (Tone) { + + /** + * @class FMSynth is composed of two Tone.Synths where one Tone.Synth modulates + * the frequency of a second Tone.Synth. A lot of spectral content + * can be explored using the modulationIndex parameter. Read more about + * frequency modulation synthesis on [SoundOnSound](http://www.soundonsound.com/sos/apr00/articles/synthsecrets.htm). + * + * + * @constructor + * @extends {Tone.Monophonic} + * @param {Object} [options] the options available for the synth + * see defaults below + * @example + * var fmSynth = new Tone.FMSynth().toMaster(); + * fmSynth.triggerAttackRelease("C5", "4n"); + */ + Tone.FMSynth = function (options) { + options = this.defaultArg(options, Tone.FMSynth.defaults); + Tone.Monophonic.call(this, options); + /** + * The carrier voice. + * @type {Tone.Synth} + * @private + */ + this._carrier = new Tone.Synth(options.carrier); + this._carrier.volume.value = -10; + /** + * The carrier's oscillator + * @type {Tone.Oscillator} + */ + this.oscillator = this._carrier.oscillator; + /** + * The carrier's envelope + * @type {Tone.Oscillator} + */ + this.envelope = this._carrier.envelope.set(options.envelope); + /** + * The modulator voice. + * @type {Tone.Synth} + * @private + */ + this._modulator = new Tone.Synth(options.modulator); + this._modulator.volume.value = -10; + /** + * The modulator's oscillator which is applied + * to the amplitude of the oscillator + * @type {Tone.Oscillator} + */ + this.modulation = this._modulator.oscillator.set(options.modulation); + /** + * The modulator's envelope + * @type {Tone.Oscillator} + */ + this.modulationEnvelope = this._modulator.envelope.set(options.modulationEnvelope); + /** + * The frequency control. + * @type {Frequency} + * @signal + */ + this.frequency = new Tone.Signal(440, Tone.Type.Frequency); + /** + * The detune in cents + * @type {Cents} + * @signal + */ + this.detune = new Tone.Signal(options.detune, Tone.Type.Cents); + /** + * Harmonicity is the ratio between the two voices. A harmonicity of + * 1 is no change. Harmonicity = 2 means a change of an octave. + * @type {Positive} + * @signal + * @example + * //pitch voice1 an octave below voice0 + * synth.harmonicity.value = 0.5; + */ + this.harmonicity = new Tone.Multiply(options.harmonicity); + this.harmonicity.units = Tone.Type.Positive; + /** + * The modulation index which essentially the depth or amount of the modulation. It is the + * ratio of the frequency of the modulating signal (mf) to the amplitude of the + * modulating signal (ma) -- as in ma/mf. + * @type {Positive} + * @signal + */ + this.modulationIndex = new Tone.Multiply(options.modulationIndex); + this.modulationIndex.units = Tone.Type.Positive; + /** + * the node where the modulation happens + * @type {GainNode} + * @private + */ + this._modulationNode = new Tone.Gain(0); + //control the two voices frequency + this.frequency.connect(this._carrier.frequency); + this.frequency.chain(this.harmonicity, this._modulator.frequency); + this.frequency.chain(this.modulationIndex, this._modulationNode); + this.detune.fan(this._carrier.detune, this._modulator.detune); + this._modulator.connect(this._modulationNode.gain); + this._modulationNode.connect(this._carrier.frequency); + this._carrier.connect(this.output); + this._readOnly([ + 'frequency', + 'harmonicity', + 'modulationIndex', + 'oscillator', + 'envelope', + 'modulation', + 'modulationEnvelope', + 'detune' + ]); + }; + Tone.extend(Tone.FMSynth, Tone.Monophonic); + /** + * @static + * @type {Object} + */ + Tone.FMSynth.defaults = { + 'harmonicity': 3, + 'modulationIndex': 10, + 'detune': 0, + 'oscillator': { 'type': 'sine' }, + 'envelope': { + 'attack': 0.01, + 'decay': 0.01, + 'sustain': 1, + 'release': 0.5 + }, + 'modulation': { 'type': 'square' }, + 'modulationEnvelope': { + 'attack': 0.5, + 'decay': 0, + 'sustain': 1, + 'release': 0.5 + } + }; + /** + * trigger the attack portion of the note + * + * @param {Time} [time=now] the time the note will occur + * @param {number} [velocity=1] the velocity of the note + * @returns {Tone.FMSynth} this + * @private + */ + Tone.FMSynth.prototype._triggerEnvelopeAttack = function (time, velocity) { + time = this.toSeconds(time); + //the envelopes + this.envelope.triggerAttack(time, velocity); + this.modulationEnvelope.triggerAttack(time); + return this; + }; + /** + * trigger the release portion of the note + * + * @param {Time} [time=now] the time the note will release + * @returns {Tone.FMSynth} this + * @private + */ + Tone.FMSynth.prototype._triggerEnvelopeRelease = function (time) { + time = this.toSeconds(time); + this.envelope.triggerRelease(time); + this.modulationEnvelope.triggerRelease(time); + return this; + }; + /** + * clean up + * @returns {Tone.FMSynth} this + */ + Tone.FMSynth.prototype.dispose = function () { + Tone.Monophonic.prototype.dispose.call(this); + this._writable([ + 'frequency', + 'harmonicity', + 'modulationIndex', + 'oscillator', + 'envelope', + 'modulation', + 'modulationEnvelope', + 'detune' + ]); + this._carrier.dispose(); + this._carrier = null; + this._modulator.dispose(); + this._modulator = null; + this.frequency.dispose(); + this.frequency = null; + this.detune.dispose(); + this.detune = null; + this.modulationIndex.dispose(); + this.modulationIndex = null; + this.harmonicity.dispose(); + this.harmonicity = null; + this._modulationNode.dispose(); + this._modulationNode = null; + this.oscillator = null; + this.envelope = null; + this.modulationEnvelope = null; + this.modulation = null; + return this; + }; + return Tone.FMSynth; + }); + Module(function (Tone) { + + /** + * @class Tone.MembraneSynth makes kick and tom sounds using a single oscillator + * with an amplitude envelope and frequency ramp. A Tone.OmniOscillator + * is routed through a Tone.AmplitudeEnvelope to the output. The drum + * quality of the sound comes from the frequency envelope applied + * during during Tone.MembraneSynth.triggerAttack(note). The frequency + * envelope starts at note * .octaves and ramps to + * note over the duration of .pitchDecay. + * + * @constructor + * @extends {Tone.Instrument} + * @param {Object} [options] the options available for the synth + * see defaults below + * @example + * var synth = new Tone.MembraneSynth().toMaster(); + * synth.triggerAttackRelease("C2", "8n"); + */ + Tone.MembraneSynth = function (options) { + options = this.defaultArg(options, Tone.MembraneSynth.defaults); + Tone.Instrument.call(this, options); + /** + * The oscillator. + * @type {Tone.OmniOscillator} + */ + this.oscillator = new Tone.OmniOscillator(options.oscillator).start(); + /** + * The amplitude envelope. + * @type {Tone.AmplitudeEnvelope} + */ + this.envelope = new Tone.AmplitudeEnvelope(options.envelope); + /** + * The number of octaves the pitch envelope ramps. + * @type {Positive} + */ + this.octaves = options.octaves; + /** + * The amount of time the frequency envelope takes. + * @type {Time} + */ + this.pitchDecay = options.pitchDecay; + this.oscillator.chain(this.envelope, this.output); + this._readOnly([ + 'oscillator', + 'envelope' + ]); + }; + Tone.extend(Tone.MembraneSynth, Tone.Instrument); + /** + * @static + * @type {Object} + */ + Tone.MembraneSynth.defaults = { + 'pitchDecay': 0.05, + 'octaves': 10, + 'oscillator': { 'type': 'sine' }, + 'envelope': { + 'attack': 0.001, + 'decay': 0.4, + 'sustain': 0.01, + 'release': 1.4, + 'attackCurve': 'exponential' + } + }; + /** + * Trigger the note at the given time with the given velocity. + * + * @param {Frequency} note the note + * @param {Time} [time=now] the time, if not given is now + * @param {number} [velocity=1] velocity defaults to 1 + * @returns {Tone.MembraneSynth} this + * @example + * kick.triggerAttack(60); + */ + Tone.MembraneSynth.prototype.triggerAttack = function (note, time, velocity) { + time = this.toSeconds(time); + note = this.toFrequency(note); + var maxNote = note * this.octaves; + this.oscillator.frequency.setValueAtTime(maxNote, time); + this.oscillator.frequency.exponentialRampToValueAtTime(note, time + this.toSeconds(this.pitchDecay)); + this.envelope.triggerAttack(time, velocity); + return this; + }; + /** + * Trigger the release portion of the note. + * + * @param {Time} [time=now] the time the note will release + * @returns {Tone.MembraneSynth} this + */ + Tone.MembraneSynth.prototype.triggerRelease = function (time) { + this.envelope.triggerRelease(time); + return this; + }; + /** + * Clean up. + * @returns {Tone.MembraneSynth} this + */ + Tone.MembraneSynth.prototype.dispose = function () { + Tone.Instrument.prototype.dispose.call(this); + this._writable([ + 'oscillator', + 'envelope' + ]); + this.oscillator.dispose(); + this.oscillator = null; + this.envelope.dispose(); + this.envelope = null; + return this; + }; + return Tone.MembraneSynth; + }); + Module(function (Tone) { + /** + * Inharmonic ratio of frequencies based on the Roland TR-808 + * Taken from https://ccrma.stanford.edu/papers/tr-808-cymbal-physically-informed-circuit-bendable-digital-model + * @private + * @static + * @type {Array} + */ + var inharmRatios = [ + 1, + 1.483, + 1.932, + 2.546, + 2.63, + 3.897 + ]; + /** + * @class A highly inharmonic and spectrally complex source with a highpass filter + * and amplitude envelope which is good for making metalophone sounds. Based + * on CymbalSynth by [@polyrhythmatic](https://github.com/polyrhythmatic). + * Inspiration from [Sound on Sound](http://www.soundonsound.com/sos/jul02/articles/synthsecrets0702.asp). + * + * @constructor + * @extends {Tone.Instrument} + * @param {Object} [options] The options availble for the synth + * see defaults below + */ + Tone.MetalSynth = function (options) { + options = this.defaultArg(options, Tone.MetalSynth.defaults); + Tone.Instrument.call(this, options); + /** + * The frequency of the cymbal + * @type {Frequency} + * @signal + */ + this.frequency = new Tone.Signal(options.frequency, Tone.Type.Frequency); + /** + * The array of FMOscillators + * @type {Array} + * @private + */ + this._oscillators = []; + /** + * The frequency multipliers + * @type {Array} + * @private + */ + this._freqMultipliers = []; + /** + * The amplitude for the body + * @type {Tone.Gain} + * @private + */ + this._amplitue = new Tone.Gain(0).connect(this.output); + /** + * highpass the output + * @type {Tone.Filter} + * @private + */ + this._highpass = new Tone.Filter({ + 'type': 'highpass', + 'Q': -3.0102999566398125 + }).connect(this._amplitue); + /** + * The number of octaves the highpass + * filter frequency ramps + * @type {Number} + * @private + */ + this._octaves = options.octaves; + /** + * Scale the body envelope + * for the bandpass + * @type {Tone.Scale} + * @private + */ + this._filterFreqScaler = new Tone.Scale(options.resonance, 7000); + /** + * The envelope which is connected both to the + * amplitude and highpass filter's cutoff frequency + * @type {Tone.Envelope} + */ + this.envelope = new Tone.Envelope({ + 'attack': options.envelope.attack, + 'attackCurve': 'linear', + 'decay': options.envelope.decay, + 'sustain': 0, + 'release': options.envelope.release + }).chain(this._filterFreqScaler, this._highpass.frequency); + this.envelope.connect(this._amplitue.gain); + for (var i = 0; i < inharmRatios.length; i++) { + var osc = new Tone.FMOscillator({ + 'type': 'square', + 'modulationType': 'square', + 'harmonicity': options.harmonicity, + 'modulationIndex': options.modulationIndex + }); + osc.connect(this._highpass).start(0); + this._oscillators[i] = osc; + var mult = new Tone.Multiply(inharmRatios[i]); + this._freqMultipliers[i] = mult; + this.frequency.chain(mult, osc.frequency); + } + //set the octaves + this.octaves = options.octaves; + }; + Tone.extend(Tone.MetalSynth, Tone.Instrument); + /** + * default values + * @static + * @const + * @type {Object} + */ + Tone.MetalSynth.defaults = { + 'frequency': 200, + 'envelope': { + 'attack': 0.001, + 'decay': 1.4, + 'release': 0.2 + }, + 'harmonicity': 5.1, + 'modulationIndex': 32, + 'resonance': 4000, + 'octaves': 1.5 + }; + /** + * Trigger the attack. + * @param {Time} time When the attack should be triggered. + * @param {NormalRange=1} velocity The velocity that the envelope should be triggered at. + * @return {Tone.MetalSynth} this + */ + Tone.MetalSynth.prototype.triggerAttack = function (time, vel) { + time = this.toSeconds(time); + vel = this.defaultArg(vel, 1); + this.envelope.triggerAttack(time, vel); + return this; + }; + /** + * Trigger the release of the envelope. + * @param {Time} time When the release should be triggered. + * @return {Tone.MetalSynth} this + */ + Tone.MetalSynth.prototype.triggerRelease = function (time) { + time = this.toSeconds(time); + this.envelope.triggerRelease(time); + return this; + }; + /** + * Trigger the attack and release of the envelope after the given + * duration. + * @param {Time} duration The duration before triggering the release + * @param {Time} time When the attack should be triggered. + * @param {NormalRange=1} velocity The velocity that the envelope should be triggered at. + * @return {Tone.MetalSynth} this + */ + Tone.MetalSynth.prototype.triggerAttackRelease = function (duration, time, velocity) { + time = this.toSeconds(time); + duration = this.toSeconds(duration); + this.triggerAttack(time, velocity); + this.triggerRelease(time + duration); + return this; + }; + /** + * The modulationIndex of the oscillators which make up the source. + * see Tone.FMOscillator.modulationIndex + * @memberOf Tone.MetalSynth# + * @type {Positive} + * @name modulationIndex + */ + Object.defineProperty(Tone.MetalSynth.prototype, 'modulationIndex', { + get: function () { + return this._oscillators[0].modulationIndex.value; + }, + set: function (val) { + for (var i = 0; i < this._oscillators.length; i++) { + this._oscillators[i].modulationIndex.value = val; + } + } + }); + /** + * The harmonicity of the oscillators which make up the source. + * see Tone.FMOscillator.harmonicity + * @memberOf Tone.MetalSynth# + * @type {Positive} + * @name harmonicity + */ + Object.defineProperty(Tone.MetalSynth.prototype, 'harmonicity', { + get: function () { + return this._oscillators[0].harmonicity.value; + }, + set: function (val) { + for (var i = 0; i < this._oscillators.length; i++) { + this._oscillators[i].harmonicity.value = val; + } + } + }); + /** + * The frequency of the highpass filter attached to the envelope + * @memberOf Tone.MetalSynth# + * @type {Frequency} + * @name resonance + */ + Object.defineProperty(Tone.MetalSynth.prototype, 'resonance', { + get: function () { + return this._filterFreqScaler.min; + }, + set: function (val) { + this._filterFreqScaler.min = val; + this.octaves = this._octaves; + } + }); + /** + * The number of octaves above the "resonance" frequency + * that the filter ramps during the attack/decay envelope + * @memberOf Tone.MetalSynth# + * @type {Number} + * @name octaves + */ + Object.defineProperty(Tone.MetalSynth.prototype, 'octaves', { + get: function () { + return this._octaves; + }, + set: function (octs) { + this._octaves = octs; + this._filterFreqScaler.max = this._filterFreqScaler.min * Math.pow(2, octs); + } + }); + /** + * Clean up + * @returns {Tone.MetalSynth} this + */ + Tone.MetalSynth.prototype.dispose = function () { + Tone.Instrument.prototype.dispose.call(this); + for (var i = 0; i < this._oscillators.length; i++) { + this._oscillators[i].dispose(); + this._freqMultipliers[i].dispose(); + } + this._oscillators = null; + this._freqMultipliers = null; + this.frequency.dispose(); + this.frequency = null; + this._filterFreqScaler.dispose(); + this._filterFreqScaler = null; + this._amplitue.dispose(); + this._amplitue = null; + this.envelope.dispose(); + this.envelope = null; + this._highpass.dispose(); + this._highpass = null; + }; + return Tone.MetalSynth; + }); + Module(function (Tone) { + + /** + * @class Tone.Noise is a noise generator. It uses looped noise buffers to save on performance. + * Tone.Noise supports the noise types: "pink", "white", and "brown". Read more about + * colors of noise on [Wikipedia](https://en.wikipedia.org/wiki/Colors_of_noise). + * + * @constructor + * @extends {Tone.Source} + * @param {string} type the noise type (white|pink|brown) + * @example + * //initialize the noise and start + * var noise = new Tone.Noise("pink").start(); + * + * //make an autofilter to shape the noise + * var autoFilter = new Tone.AutoFilter({ + * "frequency" : "8m", + * "min" : 800, + * "max" : 15000 + * }).connect(Tone.Master); + * + * //connect the noise + * noise.connect(autoFilter); + * //start the autofilter LFO + * autoFilter.start() + */ + Tone.Noise = function () { + var options = this.optionsObject(arguments, ['type'], Tone.Noise.defaults); + Tone.Source.call(this, options); + /** + * @private + * @type {AudioBufferSourceNode} + */ + this._source = null; + /** + * the buffer + * @private + * @type {AudioBuffer} + */ + this._buffer = null; + /** + * The playback rate of the noise. Affects + * the "frequency" of the noise. + * @type {Positive} + * @signal + */ + this._playbackRate = options.playbackRate; + this.type = options.type; + }; + Tone.extend(Tone.Noise, Tone.Source); + /** + * the default parameters + * + * @static + * @const + * @type {Object} + */ + Tone.Noise.defaults = { + 'type': 'white', + 'playbackRate': 1 + }; + /** + * The type of the noise. Can be "white", "brown", or "pink". + * @memberOf Tone.Noise# + * @type {string} + * @name type + * @example + * noise.type = "white"; + */ + Object.defineProperty(Tone.Noise.prototype, 'type', { + get: function () { + if (this._buffer === _whiteNoise) { + return 'white'; + } else if (this._buffer === _brownNoise) { + return 'brown'; + } else if (this._buffer === _pinkNoise) { + return 'pink'; + } + }, + set: function (type) { + if (this.type !== type) { + switch (type) { + case 'white': + this._buffer = _whiteNoise; + break; + case 'pink': + this._buffer = _pinkNoise; + break; + case 'brown': + this._buffer = _brownNoise; + break; + default: + throw new TypeError('Tone.Noise: invalid type: ' + type); + } + //if it's playing, stop and restart it + if (this.state === Tone.State.Started) { + var now = this.now() + this.blockTime; + //remove the listener + this._stop(now); + this._start(now); + } + } + } + }); + /** + * The playback rate of the noise. Affects + * the "frequency" of the noise. + * @type {Positive} + * @signal + */ + Object.defineProperty(Tone.Noise.prototype, 'playbackRate', { + get: function () { + return this._playbackRate; + }, + set: function (rate) { + this._playbackRate = rate; + if (this._source) { + this._source.playbackRate.value = rate; + } + } + }); + /** + * internal start method + * + * @param {Time} time + * @private + */ + Tone.Noise.prototype._start = function (time) { + this._source = this.context.createBufferSource(); + this._source.buffer = this._buffer; + this._source.loop = true; + this._source.playbackRate.value = this._playbackRate; + this._source.connect(this.output); + this._source.start(this.toSeconds(time), Math.random() * (this._buffer.duration - 0.001)); + }; + /** + * internal stop method + * + * @param {Time} time + * @private + */ + Tone.Noise.prototype._stop = function (time) { + if (this._source) { + this._source.stop(this.toSeconds(time)); + } + }; + /** + * Clean up. + * @returns {Tone.Noise} this + */ + Tone.Noise.prototype.dispose = function () { + Tone.Source.prototype.dispose.call(this); + if (this._source !== null) { + this._source.disconnect(); + this._source = null; + } + this._buffer = null; + return this; + }; + /////////////////////////////////////////////////////////////////////////// + // THE BUFFERS + // borrowed heavily from http://noisehack.com/generate-noise-web-audio-api/ + /////////////////////////////////////////////////////////////////////////// + /** + * static noise buffers + * + * @static + * @private + * @type {AudioBuffer} + */ + var _pinkNoise = null, _brownNoise = null, _whiteNoise = null; + Tone._initAudioContext(function (audioContext) { + var sampleRate = audioContext.sampleRate; + //four seconds per buffer + var bufferLength = sampleRate * 4; + //fill the buffers + _pinkNoise = function () { + var buffer = audioContext.createBuffer(2, bufferLength, sampleRate); + for (var channelNum = 0; channelNum < buffer.numberOfChannels; channelNum++) { + var channel = buffer.getChannelData(channelNum); + var b0, b1, b2, b3, b4, b5, b6; + b0 = b1 = b2 = b3 = b4 = b5 = b6 = 0; + for (var i = 0; i < bufferLength; i++) { + var white = Math.random() * 2 - 1; + b0 = 0.99886 * b0 + white * 0.0555179; + b1 = 0.99332 * b1 + white * 0.0750759; + b2 = 0.969 * b2 + white * 0.153852; + b3 = 0.8665 * b3 + white * 0.3104856; + b4 = 0.55 * b4 + white * 0.5329522; + b5 = -0.7616 * b5 - white * 0.016898; + channel[i] = b0 + b1 + b2 + b3 + b4 + b5 + b6 + white * 0.5362; + channel[i] *= 0.11; + // (roughly) compensate for gain + b6 = white * 0.115926; + } + } + return buffer; + }(); + _brownNoise = function () { + var buffer = audioContext.createBuffer(2, bufferLength, sampleRate); + for (var channelNum = 0; channelNum < buffer.numberOfChannels; channelNum++) { + var channel = buffer.getChannelData(channelNum); + var lastOut = 0; + for (var i = 0; i < bufferLength; i++) { + var white = Math.random() * 2 - 1; + channel[i] = (lastOut + 0.02 * white) / 1.02; + lastOut = channel[i]; + channel[i] *= 3.5; // (roughly) compensate for gain + } + } + return buffer; + }(); + _whiteNoise = function () { + var buffer = audioContext.createBuffer(2, bufferLength, sampleRate); + for (var channelNum = 0; channelNum < buffer.numberOfChannels; channelNum++) { + var channel = buffer.getChannelData(channelNum); + for (var i = 0; i < bufferLength; i++) { + channel[i] = Math.random() * 2 - 1; + } + } + return buffer; + }(); + }); + return Tone.Noise; + }); + Module(function (Tone) { + + /** + * @class Tone.NoiseSynth is composed of a noise generator (Tone.Noise), one filter (Tone.Filter), + * and two envelopes (Tone.Envelop). One envelope controls the amplitude + * of the noise and the other is controls the cutoff frequency of the filter. + * + * + * @constructor + * @extends {Tone.Instrument} + * @param {Object} [options] the options available for the synth + * see defaults below + * @example + * var noiseSynth = new Tone.NoiseSynth().toMaster(); + * noiseSynth.triggerAttackRelease("8n"); + */ + Tone.NoiseSynth = function (options) { + //get the defaults + options = this.defaultArg(options, Tone.NoiseSynth.defaults); + Tone.Instrument.call(this, options); + /** + * The noise source. + * @type {Tone.Noise} + * @example + * noiseSynth.set("noise.type", "brown"); + */ + this.noise = new Tone.Noise(); + /** + * The amplitude envelope. + * @type {Tone.AmplitudeEnvelope} + */ + this.envelope = new Tone.AmplitudeEnvelope(options.envelope); + //connect the noise to the output + this.noise.chain(this.envelope, this.output); + //start the noise + this.noise.start(); + this._readOnly([ + 'noise', + 'envelope' + ]); + }; + Tone.extend(Tone.NoiseSynth, Tone.Instrument); + /** + * @const + * @static + * @type {Object} + */ + Tone.NoiseSynth.defaults = { + 'noise': { 'type': 'white' }, + 'envelope': { + 'attack': 0.005, + 'decay': 0.1, + 'sustain': 0 + } + }; + /** + * Start the attack portion of the envelopes. Unlike other + * instruments, Tone.NoiseSynth doesn't have a note. + * @param {Time} [time=now] the time the attack should start + * @param {number} [velocity=1] the velocity of the note (0-1) + * @returns {Tone.NoiseSynth} this + * @example + * noiseSynth.triggerAttack(); + */ + Tone.NoiseSynth.prototype.triggerAttack = function (time, velocity) { + //the envelopes + this.envelope.triggerAttack(time, velocity); + return this; + }; + /** + * Start the release portion of the envelopes. + * @param {Time} [time=now] the time the release should start + * @returns {Tone.NoiseSynth} this + */ + Tone.NoiseSynth.prototype.triggerRelease = function (time) { + this.envelope.triggerRelease(time); + return this; + }; + /** + * Trigger the attack and then the release. + * @param {Time} duration the duration of the note + * @param {Time} [time=now] the time of the attack + * @param {number} [velocity=1] the velocity + * @returns {Tone.NoiseSynth} this + */ + Tone.NoiseSynth.prototype.triggerAttackRelease = function (duration, time, velocity) { + time = this.toSeconds(time); + duration = this.toSeconds(duration); + this.triggerAttack(time, velocity); + this.triggerRelease(time + duration); + return this; + }; + /** + * Clean up. + * @returns {Tone.NoiseSynth} this + */ + Tone.NoiseSynth.prototype.dispose = function () { + Tone.Instrument.prototype.dispose.call(this); + this._writable([ + 'noise', + 'envelope' + ]); + this.noise.dispose(); + this.noise = null; + this.envelope.dispose(); + this.envelope = null; + return this; + }; + return Tone.NoiseSynth; + }); + Module(function (Tone) { + + /** + * @class Karplus-String string synthesis. Often out of tune. + * Will change when the AudioWorkerNode is available across + * browsers. + * + * @constructor + * @extends {Tone.Instrument} + * @param {Object} [options] see the defaults + * @example + * var plucky = new Tone.PluckSynth().toMaster(); + * plucky.triggerAttack("C4"); + */ + Tone.PluckSynth = function (options) { + options = this.defaultArg(options, Tone.PluckSynth.defaults); + Tone.Instrument.call(this, options); + /** + * @type {Tone.Noise} + * @private + */ + this._noise = new Tone.Noise('pink'); + /** + * The amount of noise at the attack. + * Nominal range of [0.1, 20] + * @type {number} + */ + this.attackNoise = options.attackNoise; + /** + * the LFCF + * @type {Tone.LowpassCombFilter} + * @private + */ + this._lfcf = new Tone.LowpassCombFilter({ + 'resonance': options.resonance, + 'dampening': options.dampening + }); + /** + * The resonance control. + * @type {NormalRange} + * @signal + */ + this.resonance = this._lfcf.resonance; + /** + * The dampening control. i.e. the lowpass filter frequency of the comb filter + * @type {Frequency} + * @signal + */ + this.dampening = this._lfcf.dampening; + //connections + this._noise.connect(this._lfcf); + this._lfcf.connect(this.output); + this._readOnly([ + 'resonance', + 'dampening' + ]); + }; + Tone.extend(Tone.PluckSynth, Tone.Instrument); + /** + * @static + * @const + * @type {Object} + */ + Tone.PluckSynth.defaults = { + 'attackNoise': 1, + 'dampening': 4000, + 'resonance': 0.9 + }; + /** + * Trigger the note. + * @param {Frequency} note The note to trigger. + * @param {Time} [time=now] When the note should be triggered. + * @returns {Tone.PluckSynth} this + */ + Tone.PluckSynth.prototype.triggerAttack = function (note, time) { + note = this.toFrequency(note); + time = this.toSeconds(time); + var delayAmount = 1 / note; + this._lfcf.delayTime.setValueAtTime(delayAmount, time); + this._noise.start(time); + this._noise.stop(time + delayAmount * this.attackNoise); + return this; + }; + /** + * Clean up. + * @returns {Tone.PluckSynth} this + */ + Tone.PluckSynth.prototype.dispose = function () { + Tone.Instrument.prototype.dispose.call(this); + this._noise.dispose(); + this._lfcf.dispose(); + this._noise = null; + this._lfcf = null; + this._writable([ + 'resonance', + 'dampening' + ]); + this.dampening = null; + this.resonance = null; + return this; + }; + return Tone.PluckSynth; + }); + Module(function (Tone) { + + /** + * @class Tone.PolySynth handles voice creation and allocation for any + * instruments passed in as the second paramter. PolySynth is + * not a synthesizer by itself, it merely manages voices of + * one of the other types of synths, allowing any of the + * monophonic synthesizers to be polyphonic. + * + * @constructor + * @extends {Tone.Instrument} + * @param {number|Object} [polyphony=4] The number of voices to create + * @param {function} [voice=Tone.Synth] The constructor of the voices + * uses Tone.Synth by default. + * @example + * //a polysynth composed of 6 Voices of Synth + * var synth = new Tone.PolySynth(6, Tone.Synth).toMaster(); + * //set the attributes using the set interface + * synth.set("detune", -1200); + * //play a chord + * synth.triggerAttackRelease(["C4", "E4", "A4"], "4n"); + */ + Tone.PolySynth = function () { + Tone.Instrument.call(this); + var options = this.optionsObject(arguments, [ + 'polyphony', + 'voice' + ], Tone.PolySynth.defaults); + options = this.defaultArg(options, Tone.Instrument.defaults); + //max polyphony + options.polyphony = Math.min(Tone.PolySynth.MAX_POLYPHONY, options.polyphony); + /** + * the array of voices + * @type {Array} + */ + this.voices = new Array(options.polyphony); + /** + * The queue of voices with data about last trigger + * and the triggered note + * @private + * @type {Array} + */ + this._triggers = new Array(options.polyphony); + /** + * The detune in cents + * @type {Cents} + * @signal + */ + this.detune = new Tone.Signal(options.detune, Tone.Type.Cents); + this._readOnly('detune'); + //create the voices + for (var i = 0; i < options.polyphony; i++) { + var v = new options.voice(arguments[2], arguments[3]); + this.voices[i] = v; + v.connect(this.output); + if (v.hasOwnProperty('detune')) { + this.detune.connect(v.detune); + } + this._triggers[i] = { + release: -1, + note: null, + voice: v + }; + } + //set the volume initially + this.volume.value = options.volume; + }; + Tone.extend(Tone.PolySynth, Tone.Instrument); + /** + * the defaults + * @const + * @static + * @type {Object} + */ + Tone.PolySynth.defaults = { + 'polyphony': 4, + 'volume': 0, + 'detune': 0, + 'voice': Tone.Synth + }; + /** + * Trigger the attack portion of the note + * @param {Frequency|Array} notes The notes to play. Accepts a single + * Frequency or an array of frequencies. + * @param {Time} [time=now] The start time of the note. + * @param {number} [velocity=1] The velocity of the note. + * @returns {Tone.PolySynth} this + * @example + * //trigger a chord immediately with a velocity of 0.2 + * poly.triggerAttack(["Ab3", "C4", "F5"], undefined, 0.2); + */ + Tone.PolySynth.prototype.triggerAttack = function (notes, time, velocity) { + if (!Array.isArray(notes)) { + notes = [notes]; + } + time = this.toSeconds(time); + for (var i = 0; i < notes.length; i++) { + var val = notes[i]; + //trigger the oldest voice + var oldest = this._triggers[0]; + var oldestIndex = 0; + for (var j = 1; j < this._triggers.length; j++) { + if (this._triggers[j].release < oldest.release) { + oldest = this._triggers[j]; + oldestIndex = j; + } + } + oldest.release = Infinity; + oldest.note = JSON.stringify(val); + oldest.voice.triggerAttack(val, time, velocity); + } + return this; + }; + /** + * Trigger the attack and release after the specified duration + * + * @param {Frequency|Array} notes The notes to play. Accepts a single + * Frequency or an array of frequencies. + * @param {Time} duration the duration of the note + * @param {Time} [time=now] if no time is given, defaults to now + * @param {number} [velocity=1] the velocity of the attack (0-1) + * @returns {Tone.PolySynth} this + * @example + * //trigger a chord for a duration of a half note + * poly.triggerAttackRelease(["Eb3", "G4", "C5"], "2n"); + * @example + * //can pass in an array of durations as well + * poly.triggerAttackRelease(["Eb3", "G4", "C5"], ["2n", "4n", "4n"]); + */ + Tone.PolySynth.prototype.triggerAttackRelease = function (notes, duration, time, velocity) { + time = this.toSeconds(time); + this.triggerAttack(notes, time, velocity); + if (this.isArray(duration) && this.isArray(notes)) { + for (var i = 0; i < notes.length; i++) { + var d = duration[Math.min(i, duration.length - 1)]; + this.triggerRelease(notes[i], time + this.toSeconds(d)); + } + } else { + this.triggerRelease(notes, time + this.toSeconds(duration)); + } + return this; + }; + /** + * Trigger the release of the note. Unlike monophonic instruments, + * a note (or array of notes) needs to be passed in as the first argument. + * @param {Frequency|Array} notes The notes to play. Accepts a single + * Frequency or an array of frequencies. + * @param {Time} [time=now] When the release will be triggered. + * @returns {Tone.PolySynth} this + * @example + * poly.triggerRelease(["Ab3", "C4", "F5"], "+2n"); + */ + Tone.PolySynth.prototype.triggerRelease = function (notes, time) { + if (!Array.isArray(notes)) { + notes = [notes]; + } + time = this.toSeconds(time); + for (var i = 0; i < notes.length; i++) { + //get the voice + var stringified = JSON.stringify(notes[i]); + for (var v = 0; v < this._triggers.length; v++) { + var desc = this._triggers[v]; + if (desc.note === stringified && desc.release > time) { + desc.voice.triggerRelease(time); + desc.release = time; + } + } + } + return this; + }; + /** + * Set a member/attribute of the voices. + * @param {Object|string} params + * @param {number=} value + * @param {Time=} rampTime + * @returns {Tone.PolySynth} this + * @example + * poly.set({ + * "filter" : { + * "type" : "highpass" + * }, + * "envelope" : { + * "attack" : 0.25 + * } + * }); + */ + Tone.PolySynth.prototype.set = function (params, value, rampTime) { + for (var i = 0; i < this.voices.length; i++) { + this.voices[i].set(params, value, rampTime); + } + return this; + }; + /** + * Get the synth's attributes. Given no arguments get + * will return all available object properties and their corresponding + * values. Pass in a single attribute to retrieve or an array + * of attributes. The attribute strings can also include a "." + * to access deeper properties. + * @param {Array=} params the parameters to get, otherwise will return + * all available. + */ + Tone.PolySynth.prototype.get = function (params) { + return this.voices[0].get(params); + }; + /** + * Trigger the release portion of all the currently active voices. + * @param {Time} [time=now] When the notes should be released. + * @return {Tone.PolySynth} this + */ + Tone.PolySynth.prototype.releaseAll = function (time) { + time = this.toSeconds(time); + for (var i = 0; i < this._triggers.length; i++) { + var desc = this._triggers[i]; + if (desc.release > time) { + desc.release = time; + desc.voice.triggerRelease(time); + } + } + return this; + }; + /** + * Clean up. + * @returns {Tone.PolySynth} this + */ + Tone.PolySynth.prototype.dispose = function () { + Tone.Instrument.prototype.dispose.call(this); + for (var i = 0; i < this.voices.length; i++) { + this.voices[i].dispose(); + this.voices[i] = null; + } + this._writable('detune'); + this.detune.dispose(); + this.detune = null; + this.voices = null; + this._triggers = null; + return this; + }; + /** + * The maximum number of notes that can be allocated + * to a polysynth. + * @type {Number} + * @static + */ + Tone.PolySynth.MAX_POLYPHONY = 20; + return Tone.PolySynth; + }); + Module(function (Tone) { + + /** + * @class Tone.Player is an audio file player with start, loop, and stop functions. + * + * @constructor + * @extends {Tone.Source} + * @param {string|AudioBuffer} url Either the AudioBuffer or the url from + * which to load the AudioBuffer + * @param {function=} onload The function to invoke when the buffer is loaded. + * Recommended to use Tone.Buffer.on('load') instead. + * @example + * var player = new Tone.Player("./path/to/sample.mp3").toMaster(); + * //play as soon as the buffer is loaded + * player.autostart = true; + */ + Tone.Player = function (url) { + var options; + if (url instanceof Tone.Buffer) { + url = url.get(); + options = Tone.Player.defaults; + } else { + options = this.optionsObject(arguments, [ + 'url', + 'onload' + ], Tone.Player.defaults); + } + Tone.Source.call(this, options); + /** + * @private + * @type {AudioBufferSourceNode} + */ + this._source = null; + /** + * If the file should play as soon + * as the buffer is loaded. + * @type {boolean} + * @example + * //will play as soon as it's loaded + * var player = new Tone.Player({ + * "url" : "./path/to/sample.mp3", + * "autostart" : true, + * }).toMaster(); + */ + this.autostart = options.autostart; + /** + * the buffer + * @private + * @type {Tone.Buffer} + */ + this._buffer = new Tone.Buffer({ + 'url': options.url, + 'onload': this._onload.bind(this, options.onload), + 'reverse': options.reverse + }); + if (url instanceof AudioBuffer) { + this._buffer.set(url); + } + /** + * if the buffer should loop once it's over + * @type {boolean} + * @private + */ + this._loop = options.loop; + /** + * if 'loop' is true, the loop will start at this position + * @type {Time} + * @private + */ + this._loopStart = options.loopStart; + /** + * if 'loop' is true, the loop will end at this position + * @type {Time} + * @private + */ + this._loopEnd = options.loopEnd; + /** + * the playback rate + * @private + * @type {number} + */ + this._playbackRate = options.playbackRate; + /** + * Enabling retrigger will allow a player to be restarted + * before the the previous 'start' is done playing. Otherwise, + * successive calls to Tone.Player.start will only start + * the sample if it had played all the way through. + * @type {boolean} + */ + this.retrigger = options.retrigger; + }; + Tone.extend(Tone.Player, Tone.Source); + /** + * the default parameters + * @static + * @const + * @type {Object} + */ + Tone.Player.defaults = { + 'onload': Tone.noOp, + 'playbackRate': 1, + 'loop': false, + 'autostart': false, + 'loopStart': 0, + 'loopEnd': 0, + 'retrigger': false, + 'reverse': false + }; + /** + * Load the audio file as an audio buffer. + * Decodes the audio asynchronously and invokes + * the callback once the audio buffer loads. + * Note: this does not need to be called if a url + * was passed in to the constructor. Only use this + * if you want to manually load a new url. + * @param {string} url The url of the buffer to load. + * Filetype support depends on the + * browser. + * @param {function=} callback The function to invoke once + * the sample is loaded. + * @returns {Promise} + */ + Tone.Player.prototype.load = function (url, callback) { + return this._buffer.load(url, this._onload.bind(this, callback)); + }; + /** + * Internal callback when the buffer is loaded. + * @private + */ + Tone.Player.prototype._onload = function (callback) { + callback = this.defaultArg(callback, Tone.noOp); + callback(this); + if (this.autostart) { + this.start(); + } + }; + /** + * Play the buffer at the given startTime. Optionally add an offset + * and/or duration which will play the buffer from a position + * within the buffer for the given duration. + * + * @param {Time} [startTime=now] When the player should start. + * @param {Time} [offset=0] The offset from the beginning of the sample + * to start at. + * @param {Time=} duration How long the sample should play. If no duration + * is given, it will default to the full length + * of the sample (minus any offset) + * @returns {Tone.Player} this + * @memberOf Tone.Player# + * @method start + * @name start + */ + /** + * Internal start method + * @private + */ + Tone.Player.prototype._start = function (startTime, offset, duration) { + if (this._buffer.loaded) { + //if it's a loop the default offset is the loopstart point + if (this._loop) { + offset = this.defaultArg(offset, this._loopStart); + } else { + //otherwise the default offset is 0 + offset = this.defaultArg(offset, 0); + } + offset = this.toSeconds(offset); + //make sure it has a positive duration + duration = this.defaultArg(duration, Math.max(this._buffer.duration - offset, 0)); + duration = this.toSeconds(duration); + //the values in seconds + startTime = this.toSeconds(startTime); + //make the source + this._source = this.context.createBufferSource(); + this._source.buffer = this._buffer.get(); + //set the looping properties + if (this._loop) { + this._source.loop = this._loop; + this._source.loopStart = this.toSeconds(this._loopStart); + this._source.loopEnd = this.toSeconds(this._loopEnd); + } else { + //if it's not looping, set the state change at the end of the sample + this._state.setStateAtTime(Tone.State.Stopped, startTime + duration); + } + //and other properties + this._source.playbackRate.value = this._playbackRate; + this._source.connect(this.output); + //start it + if (this._loop) { + //modify the offset if it's greater than the loop time + var loopEnd = this._source.loopEnd || this._buffer.duration; + var loopStart = this._source.loopStart; + var loopDuration = loopEnd - loopStart; + if (offset > loopEnd) { + //move the offset back + while (offset > loopEnd) { + offset -= loopDuration; + } + } + this._source.start(startTime, offset); + } else { + this._source.start(startTime, offset, duration); + } + } else { + throw Error('Tone.Player: tried to start Player before the buffer was loaded'); + } + return this; + }; + /** + * Stop playback. + * @private + * @param {Time} [time=now] + * @returns {Tone.Player} this + */ + Tone.Player.prototype._stop = function (time) { + if (this._source) { + this._source.stop(this.toSeconds(time)); + this._source = null; + } + return this; + }; + /** + * Seek to a specific time in the player's buffer. If the + * source is no longer playing at that time, it will stop. + * If you seek to a time that + * @param {Time} offset The time to seek to. + * @param {Time=} time The time for the seek event to occur. + * @return {Tone.Player} this + * @example + * source.start(0.2); + * source.stop(0.4); + */ + Tone.Player.prototype.seek = function (offset, time) { + time = this.toSeconds(time); + if (this._state.getValueAtTime(time) === Tone.State.Started) { + offset = this.toSeconds(offset); + // if it's currently playing, stop it + this._stop(time); + //restart it at the given time + this._start(time, offset); + } + return this; + }; + /** + * Set the loop start and end. Will only loop if loop is + * set to true. + * @param {Time} loopStart The loop end time + * @param {Time} loopEnd The loop end time + * @returns {Tone.Player} this + * @example + * //loop 0.1 seconds of the file. + * player.setLoopPoints(0.2, 0.3); + * player.loop = true; + */ + Tone.Player.prototype.setLoopPoints = function (loopStart, loopEnd) { + this.loopStart = loopStart; + this.loopEnd = loopEnd; + return this; + }; + /** + * If loop is true, the loop will start at this position. + * @memberOf Tone.Player# + * @type {Time} + * @name loopStart + */ + Object.defineProperty(Tone.Player.prototype, 'loopStart', { + get: function () { + return this._loopStart; + }, + set: function (loopStart) { + this._loopStart = loopStart; + if (this._source) { + this._source.loopStart = this.toSeconds(loopStart); + } + } + }); + /** + * If loop is true, the loop will end at this position. + * @memberOf Tone.Player# + * @type {Time} + * @name loopEnd + */ + Object.defineProperty(Tone.Player.prototype, 'loopEnd', { + get: function () { + return this._loopEnd; + }, + set: function (loopEnd) { + this._loopEnd = loopEnd; + if (this._source) { + this._source.loopEnd = this.toSeconds(loopEnd); + } + } + }); + /** + * The audio buffer belonging to the player. + * @memberOf Tone.Player# + * @type {Tone.Buffer} + * @name buffer + */ + Object.defineProperty(Tone.Player.prototype, 'buffer', { + get: function () { + return this._buffer; + }, + set: function (buffer) { + this._buffer.set(buffer); + } + }); + /** + * If the buffer should loop once it's over. + * @memberOf Tone.Player# + * @type {boolean} + * @name loop + */ + Object.defineProperty(Tone.Player.prototype, 'loop', { + get: function () { + return this._loop; + }, + set: function (loop) { + this._loop = loop; + if (this._source) { + this._source.loop = loop; + } + } + }); + /** + * The playback speed. 1 is normal speed. This is not a signal because + * Safari and iOS currently don't support playbackRate as a signal. + * @memberOf Tone.Player# + * @type {number} + * @name playbackRate + */ + Object.defineProperty(Tone.Player.prototype, 'playbackRate', { + get: function () { + return this._playbackRate; + }, + set: function (rate) { + this._playbackRate = rate; + if (this._source) { + this._source.playbackRate.value = rate; + } + } + }); + /** + * The direction the buffer should play in + * @memberOf Tone.Player# + * @type {boolean} + * @name reverse + */ + Object.defineProperty(Tone.Player.prototype, 'reverse', { + get: function () { + return this._buffer.reverse; + }, + set: function (rev) { + this._buffer.reverse = rev; + } + }); + /** + * Dispose and disconnect. + * @return {Tone.Player} this + */ + Tone.Player.prototype.dispose = function () { + Tone.Source.prototype.dispose.call(this); + if (this._source !== null) { + this._source.disconnect(); + this._source = null; + } + this._buffer.dispose(); + this._buffer = null; + return this; + }; + return Tone.Player; + }); + Module(function (Tone) { + + /** + * @class Sampler wraps Tone.Player in an AmplitudeEnvelope. + * + * @constructor + * @extends {Tone.Instrument} + * @param {String} url the url of the audio file + * @param {Function=} onload The callback to invoke when the sample is loaded. + * @example + * var sampler = new Sampler("./audio/casio/A1.mp3", function(){ + * //repitch the sample down a half step + * sampler.triggerAttack(-1); + * }).toMaster(); + */ + Tone.Sampler = function () { + var options = this.optionsObject(arguments, [ + 'url', + 'onload' + ], Tone.Sampler.defaults); + Tone.Instrument.call(this, options); + /** + * The sample player. + * @type {Tone.Player} + */ + this.player = new Tone.Player(options.url, options.onload); + this.player.retrigger = true; + /** + * The amplitude envelope. + * @type {Tone.AmplitudeEnvelope} + */ + this.envelope = new Tone.AmplitudeEnvelope(options.envelope); + this.player.chain(this.envelope, this.output); + this._readOnly([ + 'player', + 'envelope' + ]); + this.loop = options.loop; + this.reverse = options.reverse; + }; + Tone.extend(Tone.Sampler, Tone.Instrument); + /** + * the default parameters + * @static + */ + Tone.Sampler.defaults = { + 'onload': Tone.noOp, + 'loop': false, + 'reverse': false, + 'envelope': { + 'attack': 0.001, + 'decay': 0, + 'sustain': 1, + 'release': 0.1 + } + }; + /** + * Trigger the start of the sample. + * @param {Interval} [pitch=0] The amount the sample should + * be repitched. + * @param {Time} [time=now] The time when the sample should start + * @param {NormalRange} [velocity=1] The velocity of the note + * @returns {Tone.Sampler} this + * @example + * sampler.triggerAttack(0, "+0.1", 0.5); + */ + Tone.Sampler.prototype.triggerAttack = function (pitch, time, velocity) { + time = this.toSeconds(time); + pitch = this.defaultArg(pitch, 0); + this.player.playbackRate = this.intervalToFrequencyRatio(pitch); + this.player.start(time); + this.envelope.triggerAttack(time, velocity); + return this; + }; + /** + * Start the release portion of the sample. Will stop the sample once the + * envelope has fully released. + * + * @param {Time} [time=now] The time when the note should release + * @returns {Tone.Sampler} this + * @example + * sampler.triggerRelease(); + */ + Tone.Sampler.prototype.triggerRelease = function (time) { + time = this.toSeconds(time); + this.envelope.triggerRelease(time); + this.player.stop(this.toSeconds(this.envelope.release) + time); + return this; + }; + /** + * Trigger the attack and then the release after the duration. + * @param {Interval} interval The interval in half-steps that the + * sample should be pitch shifted. + * @param {Time} duration How long the note should be held for before + * triggering the release. + * @param {Time} [time=now] When the note should be triggered. + * @param {NormalRange} [velocity=1] The velocity the note should be triggered at. + * @returns {Tone.Sampler} this + * @example + * //trigger the unpitched note for the duration of an 8th note + * synth.triggerAttackRelease(0, "8n"); + * @memberOf Tone.Sampler# + * @name triggerAttackRelease + * @method triggerAttackRelease + */ + /** + * If the output sample should loop or not. + * @memberOf Tone.Sampler# + * @type {number|string} + * @name loop + */ + Object.defineProperty(Tone.Sampler.prototype, 'loop', { + get: function () { + return this.player.loop; + }, + set: function (loop) { + this.player.loop = loop; + } + }); + /** + * The direction the buffer should play in + * @memberOf Tone.Sampler# + * @type {boolean} + * @name reverse + */ + Object.defineProperty(Tone.Sampler.prototype, 'reverse', { + get: function () { + return this.player.reverse; + }, + set: function (rev) { + this.player.reverse = rev; + } + }); + /** + * The buffer to play. + * @memberOf Tone.Sampler# + * @type {Tone.Buffer} + * @name buffer + */ + Object.defineProperty(Tone.Sampler.prototype, 'buffer', { + get: function () { + return this.player.buffer; + }, + set: function (buff) { + this.player.buffer = buff; + } + }); + /** + * Clean up. + * @returns {Tone.Sampler} this + */ + Tone.Sampler.prototype.dispose = function () { + Tone.Instrument.prototype.dispose.call(this); + this._writable([ + 'player', + 'envelope' + ]); + this.player.dispose(); + this.player = null; + this.envelope.dispose(); + this.envelope = null; + return this; + }; + return Tone.Sampler; + }); + Module(function (Tone) { + + /** + * @class Maps a NormalRange [0, 1] to an AudioRange [-1, 1]. + * See also Tone.AudioToGain. + * + * @extends {Tone.SignalBase} + * @constructor + * @example + * var g2a = new Tone.GainToAudio(); + */ + Tone.GainToAudio = function () { + /** + * @type {WaveShaperNode} + * @private + */ + this._norm = this.input = this.output = new Tone.WaveShaper(function (x) { + return Math.abs(x) * 2 - 1; + }); + }; + Tone.extend(Tone.GainToAudio, Tone.SignalBase); + /** + * clean up + * @returns {Tone.GainToAudio} this + */ + Tone.GainToAudio.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._norm.dispose(); + this._norm = null; + return this; + }; + return Tone.GainToAudio; + }); + Module(function (Tone) { + + /** + * @class Normalize takes an input min and max and maps it linearly to NormalRange [0,1] + * + * @extends {Tone.SignalBase} + * @constructor + * @param {number} inputMin the min input value + * @param {number} inputMax the max input value + * @example + * var norm = new Tone.Normalize(2, 4); + * var sig = new Tone.Signal(3).connect(norm); + * //output of norm is 0.5. + */ + Tone.Normalize = function (inputMin, inputMax) { + /** + * the min input value + * @type {number} + * @private + */ + this._inputMin = this.defaultArg(inputMin, 0); + /** + * the max input value + * @type {number} + * @private + */ + this._inputMax = this.defaultArg(inputMax, 1); + /** + * subtract the min from the input + * @type {Tone.Add} + * @private + */ + this._sub = this.input = new Tone.Add(0); + /** + * divide by the difference between the input and output + * @type {Tone.Multiply} + * @private + */ + this._div = this.output = new Tone.Multiply(1); + this._sub.connect(this._div); + this._setRange(); + }; + Tone.extend(Tone.Normalize, Tone.SignalBase); + /** + * The minimum value the input signal will reach. + * @memberOf Tone.Normalize# + * @type {number} + * @name min + */ + Object.defineProperty(Tone.Normalize.prototype, 'min', { + get: function () { + return this._inputMin; + }, + set: function (min) { + this._inputMin = min; + this._setRange(); + } + }); + /** + * The maximum value the input signal will reach. + * @memberOf Tone.Normalize# + * @type {number} + * @name max + */ + Object.defineProperty(Tone.Normalize.prototype, 'max', { + get: function () { + return this._inputMax; + }, + set: function (max) { + this._inputMax = max; + this._setRange(); + } + }); + /** + * set the values + * @private + */ + Tone.Normalize.prototype._setRange = function () { + this._sub.value = -this._inputMin; + this._div.value = 1 / (this._inputMax - this._inputMin); + }; + /** + * clean up + * @returns {Tone.Normalize} this + */ + Tone.Normalize.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._sub.dispose(); + this._sub = null; + this._div.dispose(); + this._div = null; + return this; + }; + return Tone.Normalize; + }); + Module(function (Tone) { + /** + * @class Wrapper around the native BufferSourceNode. + * @param {AudioBuffer|Tone.Buffer} buffer The buffer to play + * @param {Function} onended The callback to invoke when the + * buffer is done playing. + */ + Tone.BufferSource = function () { + var options = this.optionsObject(arguments, [ + 'buffer', + 'onended' + ], Tone.BufferSource.defaults); + /** + * The callback to invoke after the + * buffer source is done playing. + * @type {Function} + */ + this.onended = options.onended; + /** + * The time that the buffer was started. + * @type {Number} + * @private + */ + this._startTime = -1; + /** + * The time that the buffer is scheduled to stop. + * @type {Number} + * @private + */ + this._stopTime = -1; + /** + * The gain node which envelopes the BufferSource + * @type {Tone.Gain} + * @private + */ + this._gainNode = this.output = new Tone.Gain(); + /** + * The buffer source + * @type {AudioBufferSourceNode} + * @private + */ + this._source = this.context.createBufferSource(); + this._source.connect(this._gainNode); + /** + * The playbackRate of the buffer + * @type {Positive} + * @signal + */ + this.playbackRate = new Tone.Param(this._source.playbackRate, Tone.Type.Positive); + /** + * The fadeIn time of the amplitude envelope. + * @type {Time} + */ + this.fadeIn = options.fadeIn; + /** + * The fadeOut time of the amplitude envelope. + * @type {Time} + */ + this.fadeOut = options.fadeOut; + /** + * The value that the buffer ramps to + * @type {Gain} + * @private + */ + this._gain = 1; + /** + * The onended timeout + * @type {Number} + * @private + */ + this._onendedTimeout = -1; + //set the buffer initially + if (!this.isUndef(options.buffer)) { + this.buffer = options.buffer; + } + this.loop = options.loop; + }; + Tone.extend(Tone.BufferSource); + /** + * The defaults + * @const + * @type {Object} + */ + Tone.BufferSource.defaults = { + 'onended': Tone.noOp, + 'fadeIn': 0, + 'fadeOut': 0 + }; + /** + * Returns the playback state of the source, either "started" or "stopped". + * @type {Tone.State} + * @readOnly + * @memberOf Tone.BufferSource# + * @name state + */ + Object.defineProperty(Tone.BufferSource.prototype, 'state', { + get: function () { + var now = this.now(); + if (this._startTime !== -1 && now >= this._startTime && now < this._stopTime) { + return Tone.State.Started; + } else { + return Tone.State.Stopped; + } + } + }); + /** + * Start the buffer + * @param {Time} [startTime=now] When the player should start. + * @param {Time} [offset=0] The offset from the beginning of the sample + * to start at. + * @param {Time=} duration How long the sample should play. If no duration + * is given, it will default to the full length + * of the sample (minus any offset) + * @param {Gain} [gain=1] The gain to play the buffer back at. + * @param {Time=} fadeInTime The optional fadeIn ramp time. + * @return {Tone.BufferSource} this + */ + Tone.BufferSource.prototype.start = function (time, offset, duration, gain, fadeInTime) { + if (this._startTime !== -1) { + throw new Error('Tone.BufferSource: can only be started once.'); + } + if (this.buffer) { + time = this.toSeconds(time); + //if it's a loop the default offset is the loopstart point + if (this.loop) { + offset = this.defaultArg(offset, this.loopStart); + } else { + //otherwise the default offset is 0 + offset = this.defaultArg(offset, 0); + } + offset = this.toSeconds(offset); + //the values in seconds + time = this.toSeconds(time); + this._source.start(time, offset); + gain = this.defaultArg(gain, 1); + this._gain = gain; + //the fadeIn time + if (this.isUndef(fadeInTime)) { + fadeInTime = this.toSeconds(this.fadeIn); + } else { + fadeInTime = this.toSeconds(fadeInTime); + } + if (fadeInTime > 0) { + this._gainNode.gain.setValueAtTime(0, time); + this._gainNode.gain.linearRampToValueAtTime(this._gain, time + fadeInTime); + } else { + this._gainNode.gain.setValueAtTime(gain, time); + } + this._startTime = time + fadeInTime; + if (!this.isUndef(duration)) { + duration = this.defaultArg(duration, this.buffer.duration - offset); + duration = this.toSeconds(duration); + this.stop(time + duration + fadeInTime, fadeInTime); + } + } + return this; + }; + /** + * Stop the buffer. Optionally add a ramp time to fade the + * buffer out. + * @param {Time=} time The time the buffer should stop. + * @param {Time=} fadeOutTime How long the gain should fade out for + * @return {Tone.BufferSource} this + */ + Tone.BufferSource.prototype.stop = function (time, fadeOutTime) { + if (this.buffer) { + time = this.toSeconds(time); + //the fadeOut time + if (this.isUndef(fadeOutTime)) { + fadeOutTime = this.toSeconds(this.fadeOut); + } else { + fadeOutTime = this.toSeconds(fadeOutTime); + } + this._stopTime = time + fadeOutTime; + //cancel the end curve + this._gainNode.gain.cancelScheduledValues(this._startTime + this.sampleTime); + //set a new one + if (fadeOutTime > 0) { + this._gainNode.gain.setValueAtTime(this._gain, time); + this._gainNode.gain.linearRampToValueAtTime(0, time + fadeOutTime); + time += fadeOutTime; + } else { + this._gainNode.gain.setValueAtTime(0, time); + } + // fix for safari bug and old FF + if (!this.isNumber(this._source.playbackState) || this._source.playbackState === 2) { + this._source.stop(time); + } + clearTimeout(this._onendedTimeout); + this._onendedTimeout = setTimeout(this._onended.bind(this), (this._stopTime - this.now()) * 1000); + } + return this; + }; + /** + * Internal callback when the buffer is ended. + * Invokes `onended` and disposes the node. + * @private + */ + Tone.BufferSource.prototype._onended = function () { + this.onended(this); + this.dispose(); + }; + /** + * If loop is true, the loop will start at this position. + * @memberOf Tone.BufferSource# + * @type {Time} + * @name loopStart + */ + Object.defineProperty(Tone.BufferSource.prototype, 'loopStart', { + get: function () { + return this._source.loopStart; + }, + set: function (loopStart) { + this._source.loopStart = this.toSeconds(loopStart); + } + }); + /** + * If loop is true, the loop will end at this position. + * @memberOf Tone.BufferSource# + * @type {Time} + * @name loopEnd + */ + Object.defineProperty(Tone.BufferSource.prototype, 'loopEnd', { + get: function () { + return this._source.loopEnd; + }, + set: function (loopEnd) { + this._source.loopEnd = this.toSeconds(loopEnd); + } + }); + /** + * The audio buffer belonging to the player. + * @memberOf Tone.BufferSource# + * @type {AudioBuffer} + * @name buffer + */ + Object.defineProperty(Tone.BufferSource.prototype, 'buffer', { + get: function () { + if (this._source) { + return this._source.buffer; + } else { + return null; + } + }, + set: function (buffer) { + if (buffer instanceof Tone.Buffer) { + this._source.buffer = buffer.get(); + } else { + this._source.buffer = buffer; + } + } + }); + /** + * If the buffer should loop once it's over. + * @memberOf Tone.BufferSource# + * @type {boolean} + * @name loop + */ + Object.defineProperty(Tone.BufferSource.prototype, 'loop', { + get: function () { + return this._source.loop; + }, + set: function (loop) { + this._source.loop = loop; + } + }); + /** + * Clean up. + * @return {Tone.BufferSource} this + */ + Tone.BufferSource.prototype.dispose = function () { + this.onended = null; + if (this._source) { + this._source.disconnect(); + this._source = null; + } + if (this._gainNode) { + this._gainNode.dispose(); + this._gainNode = null; + } + this._startTime = -1; + this.playbackRate = null; + this.output = null; + clearTimeout(this._onendedTimeout); + return this; + }; + return Tone.BufferSource; + }); + Module(function (Tone) { + /** + * @class Tone.MultiPlayer is well suited for one-shots, multi-sampled instruments + * or any time you need to play a bunch of audio buffers. + * @param {Object|Array|Tone.Buffers} buffers The buffers which are available + * to the MultiPlayer + * @param {Function} onload The callback to invoke when all of the buffers are loaded. + * @extends {Tone} + * @example + * var multiPlayer = new MultiPlayer({ + * "kick" : "path/to/kick.mp3", + * "snare" : "path/to/snare.mp3", + * }, function(){ + * multiPlayer.start("kick"); + * }); + * @example + * //can also store the values in an array + * var multiPlayer = new MultiPlayer(["path/to/kick.mp3", "path/to/snare.mp3"], + * function(){ + * //if an array is passed in, the samples are referenced to by index + * multiPlayer.start(1); + * }); + */ + Tone.MultiPlayer = function () { + var options = this.optionsObject(arguments, [ + 'urls', + 'onload' + ], Tone.MultiPlayer.defaults); + if (options.urls instanceof Tone.Buffers) { + /** + * All the buffers belonging to the player. + * @type {Tone.Buffers} + */ + this.buffers = options.urls; + } else { + this.buffers = new Tone.Buffers(options.urls, options.onload); + } + /** + * Keeps track of the currently playing sources. + * @type {Object} + * @private + */ + this._activeSources = {}; + /** + * The fade in envelope which is applied + * to the beginning of the BufferSource + * @type {Time} + */ + this.fadeIn = options.fadeIn; + /** + * The fade out envelope which is applied + * to the end of the BufferSource + * @type {Time} + */ + this.fadeOut = options.fadeOut; + /** + * The output volume node + * @type {Tone.Volume} + * @private + */ + this._volume = this.output = new Tone.Volume(options.volume); + /** + * The volume of the output in decibels. + * @type {Decibels} + * @signal + * @example + * source.volume.value = -6; + */ + this.volume = this._volume.volume; + this._readOnly('volume'); + //make the output explicitly stereo + this._volume.output.output.channelCount = 2; + this._volume.output.output.channelCountMode = 'explicit'; + //mute initially + this.mute = options.mute; + }; + Tone.extend(Tone.MultiPlayer, Tone.Source); + /** + * The defaults + * @type {Object} + */ + Tone.MultiPlayer.defaults = { + 'onload': Tone.noOp, + 'fadeIn': 0, + 'fadeOut': 0 + }; + /** + * Make the source from the buffername + * @param {String} bufferName + * @return {Tone.BufferSource} + * @private + */ + Tone.MultiPlayer.prototype._makeSource = function (bufferName) { + var buffer; + if (this.isString(bufferName) || this.isNumber(bufferName)) { + buffer = this.buffers.get(bufferName).get(); + } else if (bufferName instanceof Tone.Buffer) { + buffer = bufferName.get(); + } else if (bufferName instanceof AudioBuffer) { + buffer = bufferName; + } + var source = new Tone.BufferSource(buffer).connect(this.output); + if (!this._activeSources.hasOwnProperty(bufferName)) { + this._activeSources[bufferName] = []; + } + this._activeSources[bufferName].push(source); + return source; + }; + /** + * Start a buffer by name. The `start` method allows a number of options + * to be passed in such as offset, interval, and gain. This is good for multi-sampled + * instruments and sound sprites where samples are repitched played back at different velocities. + * @param {String} bufferName The name of the buffer to start. + * @param {Time} time When to start the buffer. + * @param {Time} [offset=0] The offset into the buffer to play from. + * @param {Time=} duration How long to play the buffer for. + * @param {Interval} [pitch=0] The interval to repitch the buffer. + * @param {Gain} [gain=1] The gain to play the sample at. + * @return {Tone.MultiPlayer} this + */ + Tone.MultiPlayer.prototype.start = function (bufferName, time, offset, duration, pitch, gain) { + time = this.toSeconds(time); + var source = this._makeSource(bufferName); + source.start(time, offset, duration, this.defaultArg(gain, 1), this.fadeIn); + if (duration) { + source.stop(time + this.toSeconds(duration), this.fadeOut); + } + pitch = this.defaultArg(pitch, 0); + source.playbackRate.value = this.intervalToFrequencyRatio(pitch); + return this; + }; + /** + * Start a looping buffer by name. Similar to `start`, but the buffer + * is looped instead of played straight through. Can still be stopped with `stop`. + * @param {String} bufferName The name of the buffer to start. + * @param {Time} time When to start the buffer. + * @param {Time} [offset=0] The offset into the buffer to play from. + * @param {Time=} loopStart The start of the loop. + * @param {Time=} loopEnd The end of the loop. + * @param {Interval} [pitch=0] The interval to repitch the buffer. + * @param {Gain} [gain=1] The gain to play the sample at. + * @return {Tone.MultiPlayer} this + */ + Tone.MultiPlayer.prototype.startLoop = function (bufferName, time, offset, loopStart, loopEnd, pitch, gain) { + time = this.toSeconds(time); + var source = this._makeSource(bufferName); + source.loop = true; + source.loopStart = this.toSeconds(this.defaultArg(loopStart, 0)); + source.loopEnd = this.toSeconds(this.defaultArg(loopEnd, 0)); + source.start(time, offset, undefined, this.defaultArg(gain, 1), this.fadeIn); + pitch = this.defaultArg(pitch, 0); + source.playbackRate.value = this.intervalToFrequencyRatio(pitch); + return this; + }; + /** + * Stop the first played instance of the buffer name. + * @param {String} bufferName The buffer to stop. + * @param {Time=} time When to stop the buffer + * @return {Tone.MultiPlayer} this + */ + Tone.MultiPlayer.prototype.stop = function (bufferName, time) { + if (this._activeSources[bufferName] && this._activeSources[bufferName].length) { + time = this.toSeconds(time); + this._activeSources[bufferName].shift().stop(time, this.fadeOut); + } else { + throw new Error('Tone.MultiPlayer: cannot stop a buffer that hasn\'t been started or is already stopped'); + } + return this; + }; + /** + * Stop all currently playing buffers at the given time. + * @param {Time=} time When to stop the buffers. + * @return {Tone.MultiPlayer} this + */ + Tone.MultiPlayer.prototype.stopAll = function (time) { + time = this.toSeconds(time); + for (var bufferName in this._activeSources) { + var sources = this._activeSources[bufferName]; + for (var i = 0; i < sources.length; i++) { + sources[i].stop(time); + } + } + return this; + }; + /** + * Add another buffer to the available buffers. + * @param {String} name The name to that the buffer is refered + * to in start/stop methods. + * @param {String|Tone.Buffer} url The url of the buffer to load + * or the buffer. + * @param {Function} callback The function to invoke after the buffer is loaded. + */ + Tone.MultiPlayer.prototype.add = function (name, url, callback) { + this.buffers.add(name, url, callback); + return this; + }; + /** + * Returns the playback state of the source. "started" + * if there are any buffers playing. "stopped" otherwise. + * @type {Tone.State} + * @readOnly + * @memberOf Tone.MultiPlayer# + * @name state + */ + Object.defineProperty(Tone.MultiPlayer.prototype, 'state', { + get: function () { + return this._activeSources.length > 0 ? Tone.State.Started : Tone.State.Stopped; + } + }); + /** + * Mute the output. + * @memberOf Tone.MultiPlayer# + * @type {boolean} + * @name mute + * @example + * //mute the output + * source.mute = true; + */ + Object.defineProperty(Tone.MultiPlayer.prototype, 'mute', { + get: function () { + return this._volume.mute; + }, + set: function (mute) { + this._volume.mute = mute; + } + }); + /** + * Clean up. + * @return {Tone.MultiPlayer} this + */ + Tone.MultiPlayer.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._volume.dispose(); + this._volume = null; + this._writable('volume'); + this.volume = null; + for (var bufferName in this._activeSources) { + this._activeSources[bufferName].forEach(function (source) { + source.dispose(); + }); + } + this.buffers.dispose(); + this.buffers = null; + this._activeSources = null; + return this; + }; + return Tone.MultiPlayer; + }); + Module(function (Tone) { + /** + * @class Tone.GrainPlayer implements [granular synthesis](https://en.wikipedia.org/wiki/Granular_synthesis). + * Granular Synthesis enables you to adjust pitch and playback rate independently. The grainSize is the + * amount of time each small chunk of audio is played for and the overlap is the + * amount of crossfading transition time between successive grains. + * @extends {Tone} + * @param {String|Tone.Buffer} url The url to load, or the Tone.Buffer to play. + * @param {Function=} callback The callback to invoke after the url is loaded. + */ + Tone.GrainPlayer = function () { + var options = this.optionsObject(arguments, [ + 'url', + 'onload' + ], Tone.GrainPlayer.defaults); + Tone.Source.call(this); + /** + * The audio buffer belonging to the player. + * @type {Tone.Buffer} + */ + this.buffer = new Tone.Buffer(options.url, options.onload); + /** + * Plays the buffer with a small envelope + * @type {Tone.MultiPlayer} + * @private + */ + this._player = this.output = new Tone.MultiPlayer(); + /** + * Create a repeating tick to schedule + * the grains. + * @type {Tone.Clock} + * @private + */ + this._clock = new Tone.Clock(this._tick.bind(this), 1); + /** + * @type {Number} + * @private + */ + this._loopStart = 0; + /** + * @type {Number} + * @private + */ + this._loopEnd = 0; + /** + * @type {Number} + * @private + */ + this._playbackRate = options.playbackRate; + /** + * @type {Number} + * @private + */ + this._grainSize = options.grainSize; + /** + * @private + * @type {Number} + */ + this._overlap = options.overlap; + /** + * Adjust the pitch independently of the playbackRate. + * @type {Cents} + */ + this.detune = options.detune; + /** + * The amount of time randomly added + * or subtracted from the grain's offset + * @type {Time} + */ + this.drift = options.drift; + //setup + this.overlap = options.overlap; + this.loop = options.loop; + this.playbackRate = options.playbackRate; + this.grainSize = options.grainSize; + this.loopStart = options.loopStart; + this.loopEnd = options.loopEnd; + this.reverse = options.reverse; + }; + Tone.extend(Tone.GrainPlayer, Tone.Source); + /** + * the default parameters + * @static + * @const + * @type {Object} + */ + Tone.GrainPlayer.defaults = { + 'onload': Tone.noOp, + 'overlap': 0.1, + 'grainSize': 0.2, + 'drift': 0, + 'playbackRate': 1, + 'detune': 0, + 'loop': false, + 'loopStart': 0, + 'loopEnd': 0, + 'reverse': false + }; + /** + * Play the buffer at the given startTime. Optionally add an offset + * from the start of the buffer to play from. + * + * @param {Time} [startTime=now] When the player should start. + * @param {Time} [offset=0] The offset from the beginning of the sample + * to start at. + * @return {Tone.GrainPlayer} this + */ + /** + * Internal start method + * @param {Time} time + * @param {Time} offset + * @private + */ + Tone.GrainPlayer.prototype._start = function (time, offset) { + offset = this.defaultArg(offset, 0); + offset = this.toSeconds(offset); + time = this.toSeconds(time); + this._offset = offset; + this._clock.start(time); + }; + /** + * Internal start method + * @param {Time} time + * @private + */ + Tone.GrainPlayer.prototype._stop = function (time) { + this._clock.stop(time); + this._player.stop(this.buffer, time); + this._offset = 0; + }; + /** + * Invoked on each clock tick. scheduled a new + * grain at this time. + * @param {Time} time + * @private + */ + Tone.GrainPlayer.prototype._tick = function (time) { + var bufferDuration = this.buffer.duration; + if (this.loop && this._loopEnd > 0) { + bufferDuration = this._loopEnd; + } + var drift = (Math.random() * 2 - 1) * this.drift; + var offset = this._offset - this._overlap + drift; + var detune = this.detune / 100; + var originalFadeIn = this._player.fadeIn; + if (this.loop && this._offset > bufferDuration) { + //play the end + var endSegmentDuration = this._offset - bufferDuration; + this._player.start(this.buffer, time, offset, endSegmentDuration + this._overlap, detune); + //and play the beginning + offset = this._offset % bufferDuration; + this._offset = this._loopStart; + this._player.fadeIn = 0; + this._player.start(this.buffer, time + endSegmentDuration, this._offset, offset + this._overlap, detune); + } else if (this._offset > bufferDuration) { + //set the state to stopped. + this.stop(time); + } else { + if (offset < 0) { + this._player.fadeIn = Math.max(this._player.fadeIn + offset, 0); + offset = 0; + } + this._player.start(this.buffer, time, offset, this.grainSize + this._overlap, detune); + } + this._player.fadeIn = originalFadeIn; + //increment the offset + var duration = this._clock._nextTick - time; + this._offset += duration * this._playbackRate; + }; + /** + * Jump to a specific time and play it. + * @param {Time} offset The offset to jump to. + * @param {Time=} time When to make the jump. + * @return {[type]} [description] + */ + Tone.GrainPlayer.prototype.scrub = function (offset, time) { + this._offset = this.toSeconds(offset); + this._tick(this.toSeconds(time)); + return this; + }; + /** + * The playback rate of the sample + * @memberOf Tone.GrainPlayer# + * @type {Positive} + * @name playbackRate + */ + Object.defineProperty(Tone.GrainPlayer.prototype, 'playbackRate', { + get: function () { + return this._playbackRate; + }, + set: function (rate) { + this._playbackRate = rate; + this.grainSize = this._grainSize; + } + }); + /** + * The loop start time. + * @memberOf Tone.GrainPlayer# + * @type {Time} + * @name loopStart + */ + Object.defineProperty(Tone.GrainPlayer.prototype, 'loopStart', { + get: function () { + return this._loopStart; + }, + set: function (time) { + this._loopStart = this.toSeconds(time); + } + }); + /** + * The loop end time. + * @memberOf Tone.GrainPlayer# + * @type {Time} + * @name loopEnd + */ + Object.defineProperty(Tone.GrainPlayer.prototype, 'loopEnd', { + get: function () { + return this._loopEnd; + }, + set: function (time) { + this._loopEnd = this.toSeconds(time); + } + }); + /** + * The direction the buffer should play in + * @memberOf Tone.GrainPlayer# + * @type {boolean} + * @name reverse + */ + Object.defineProperty(Tone.GrainPlayer.prototype, 'reverse', { + get: function () { + return this.buffer.reverse; + }, + set: function (rev) { + this.buffer.reverse = rev; + } + }); + /** + * The size of each chunk of audio that the + * buffer is chopped into and played back at. + * @memberOf Tone.GrainPlayer# + * @type {Time} + * @name grainSize + */ + Object.defineProperty(Tone.GrainPlayer.prototype, 'grainSize', { + get: function () { + return this._grainSize; + }, + set: function (size) { + this._grainSize = this.toSeconds(size); + this._clock.frequency.value = this._playbackRate / this._grainSize; + } + }); + /** + * This is the duration of the cross-fade between + * sucessive grains. + * @memberOf Tone.GrainPlayer# + * @type {Time} + * @name overlap + */ + Object.defineProperty(Tone.GrainPlayer.prototype, 'overlap', { + get: function () { + return this._overlap; + }, + set: function (time) { + time = this.toSeconds(time); + this._overlap = time; + if (this._overlap < 0) { + this._player.fadeIn = 0.01; + this._player.fadeOut = 0.01; + } else { + this._player.fadeIn = time; + this._player.fadeOut = time; + } + } + }); + /** + * Clean up + * @return {Tone.GrainPlayer} this + */ + Tone.GrainPlayer.prototype.dispose = function () { + Tone.Source.prototype.dispose.call(this); + this.buffer.dispose(); + this.buffer = null; + this._player.dispose(); + this._player = null; + this._clock.dispose(); + this._clock = null; + return this; + }; + return Tone.GrainPlayer; + }); + Module(function (Tone) { + + /** + * @class Tone.UserMedia uses MediaDevices.getUserMedia to open up + * and external microphone or audio input. Check + * [MediaDevices API Support](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia) + * to see which browsers are supported. Access to an external input + * is limited to secure (HTTPS) connections. + * + * @constructor + * @extends {Tone} + * @param {Decibels=} volume The level of the input + * @example + * //list the inputs and open the third one + * var motu = new Tone.UserMedia(); + * + * //opening the input asks the user to activate their mic + * motu.open().then(function(){ + * //opening is activates the microphone + * //starting lets audio through + * motu.start(10); + * }); + */ + Tone.UserMedia = function () { + var options = this.optionsObject(arguments, ['volume'], Tone.UserMedia.defaults); + /** + * The MediaStreamNode + * @type {MediaStreamAudioSourceNode} + * @private + */ + this._mediaStream = null; + /** + * The media stream created by getUserMedia. + * @type {LocalMediaStream} + * @private + */ + this._stream = null; + /** + * The open device + * @type {MediaDeviceInfo} + * @private + */ + this._device = null; + /** + * The output volume node + * @type {Tone.Volume} + * @private + */ + this._volume = this.output = new Tone.Volume(options.volume); + /** + * The volume of the output in decibels. + * @type {Decibels} + * @signal + * @example + * input.volume.value = -6; + */ + this.volume = this._volume.volume; + this._readOnly('volume'); + this.mute = options.mute; + }; + Tone.extend(Tone.UserMedia); + /** + * the default parameters + * @type {Object} + */ + Tone.UserMedia.defaults = { + 'volume': 0, + 'mute': false + }; + /** + * Open the media stream. If a string is passed in, it is assumed + * to be the label or id of the stream, if a number is passed in, + * it is the input number of the stream. + * @param {String|Number} [labelOrId="default"] The label or id of the audio input media device. + * With no argument, the default stream is opened. + * @return {Promise} The promise is resolved when the stream is open. + */ + Tone.UserMedia.prototype.open = function (labelOrId) { + labelOrId = this.defaultArg(labelOrId, 'default'); + return this.enumerateDevices().then(function (devices) { + var device; + if (this.isNumber(labelOrId)) { + device = devices[labelOrId]; + } else { + device = devices.find(function (device) { + return device.label === labelOrId || device.deviceId === labelOrId; + }); + if (!device) { + //otherwise just take the first one + device = devices[0]; + } + } + //didn't find a matching device + if (!device) { + throw new Error('Tone.UserMedia: no matching audio inputs.'); + } + this._device = device; + //do getUserMedia + var constraints = { + audio: { + 'deviceId': device.deviceId, + 'echoCancellation': false, + 'sampleRate': this.context.sampleRate + } + }; + return navigator.mediaDevices.getUserMedia(constraints).then(function (stream) { + //start a new source only if the previous one is closed + if (!this._stream) { + this._stream = stream; + //Wrap a MediaStreamSourceNode around the live input stream. + this._mediaStream = this.context.createMediaStreamSource(stream); + //Connect the MediaStreamSourceNode to a gate gain node + this._mediaStream.connect(this.output); + } + return this; + }.bind(this)); + }.bind(this)); + }; + /** + * Close the media stream + * @return {Tone.UserMedia} this + */ + Tone.UserMedia.prototype.close = function () { + if (this._stream) { + this._stream.getAudioTracks().forEach(function (track) { + track.stop(); + }); + this._stream = null; + //remove the old media stream + this._mediaStream.disconnect(); + this._mediaStream = null; + } + this._device = null; + return this; + }; + /** + * Returns a promise which resolves with the list of audio input devices available. + * @return {Promise} The promise that is resolved with the devices + * @example + * extInput.enumerateDevices().then(function(devices){ + * console.log(devices) + * }) + */ + Tone.UserMedia.prototype.enumerateDevices = function () { + return navigator.mediaDevices.enumerateDevices().then(function (devices) { + return devices.filter(function (device) { + return device.kind === 'audioinput'; + }); + }); + }; + /** + * Returns the playback state of the source, "started" when the microphone is open + * and "stopped" when the mic is closed. + * @type {Tone.State} + * @readOnly + * @memberOf Tone.UserMedia# + * @name state + */ + Object.defineProperty(Tone.UserMedia.prototype, 'state', { + get: function () { + return this._stream && this._stream.active ? Tone.State.Started : Tone.State.Stopped; + } + }); + /** + * Returns an identifier for the represented device that is + * persisted across sessions. It is un-guessable by other applications and + * unique to the origin of the calling application. It is reset when the + * user clears cookies (for Private Browsing, a different identifier is + * used that is not persisted across sessions). Returns undefined when the + * device is not open. + * @type {String} + * @readOnly + * @memberOf Tone.UserMedia# + * @name deviceId + */ + Object.defineProperty(Tone.UserMedia.prototype, 'deviceId', { + get: function () { + if (this._device) { + return this._device.deviceId; + } + } + }); + /** + * Returns a group identifier. Two devices have the + * same group identifier if they belong to the same physical device. + * Returns undefined when the device is not open. + * @type {String} + * @readOnly + * @memberOf Tone.UserMedia# + * @name groupId + */ + Object.defineProperty(Tone.UserMedia.prototype, 'groupId', { + get: function () { + if (this._device) { + return this._device.groupId; + } + } + }); + /** + * Returns a label describing this device (for example "Built-in Microphone"). + * Returns undefined when the device is not open or label is not available + * because of permissions. + * @type {String} + * @readOnly + * @memberOf Tone.UserMedia# + * @name groupId + */ + Object.defineProperty(Tone.UserMedia.prototype, 'label', { + get: function () { + if (this._device) { + return this._device.label; + } + } + }); + /** + * Mute the output. + * @memberOf Tone.UserMedia# + * @type {boolean} + * @name mute + * @example + * //mute the output + * userMedia.mute = true; + */ + Object.defineProperty(Tone.UserMedia.prototype, 'mute', { + get: function () { + return this._volume.mute; + }, + set: function (mute) { + this._volume.mute = mute; + } + }); + /** + * Clean up. + * @return {Tone.UserMedia} this + */ + Tone.UserMedia.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this.close(); + this._writable('volume'); + this._volume.dispose(); + this._volume = null; + this.volume = null; + return this; + }; + /** + * If getUserMedia is supported by the browser. + * @type {Boolean} + * @memberOf Tone.UserMedia# + * @name supported + * @static + * @readOnly + */ + Object.defineProperty(Tone.UserMedia, 'supported', { + get: function () { + return !Tone.prototype.isUndef(navigator.mediaDevices) && Tone.prototype.isFunction(navigator.mediaDevices.getUserMedia); + } + }); + return Tone.UserMedia; + }); + + return Tone; +})); ADDED public/nexus-js/api/js/jquery.js Index: public/nexus-js/api/js/jquery.js ================================================================== --- public/nexus-js/api/js/jquery.js +++ public/nexus-js/api/js/jquery.js cannot compute difference between binary files ADDED public/nexus-js/api/js/moustache.min.js Index: public/nexus-js/api/js/moustache.min.js ================================================================== --- public/nexus-js/api/js/moustache.min.js +++ public/nexus-js/api/js/moustache.min.js cannot compute difference between binary files ADDED public/nexus-js/api/media/D-sharp.mp3 Index: public/nexus-js/api/media/D-sharp.mp3 ================================================================== --- public/nexus-js/api/media/D-sharp.mp3 +++ public/nexus-js/api/media/D-sharp.mp3 cannot compute difference between binary files ADDED public/nexus-js/api/media/hamburger.png Index: public/nexus-js/api/media/hamburger.png ================================================================== --- public/nexus-js/api/media/hamburger.png +++ public/nexus-js/api/media/hamburger.png cannot compute difference between binary files ADDED public/nexus-js/api/media/hamburger.svg Index: public/nexus-js/api/media/hamburger.svg ================================================================== --- public/nexus-js/api/media/hamburger.svg +++ public/nexus-js/api/media/hamburger.svg @@ -0,0 +1,1 @@ + ADDED public/nexus-js/api/media/piano-f3.mp3 Index: public/nexus-js/api/media/piano-f3.mp3 ================================================================== --- public/nexus-js/api/media/piano-f3.mp3 +++ public/nexus-js/api/media/piano-f3.mp3 cannot compute difference between binary files ADDED public/nexus-js/api/prism/prism.css Index: public/nexus-js/api/prism/prism.css ================================================================== --- public/nexus-js/api/prism/prism.css +++ public/nexus-js/api/prism/prism.css @@ -0,0 +1,139 @@ +/* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript */ +/** + * prism.js default theme for JavaScript, CSS and HTML + * Based on dabblet (http://dabblet.com) + * @author Lea Verou + */ + +code[class*="language-"], +pre[class*="language-"] { + color: black; + background: none; + text-shadow: 0 1px white; + font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + word-wrap: normal; + line-height: 1.5; + + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; + + -webkit-hyphens: none; + -moz-hyphens: none; + -ms-hyphens: none; + hyphens: none; +} + +pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection, +code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection { + text-shadow: none; + background: #b3d4fc; +} + +pre[class*="language-"]::selection, pre[class*="language-"] ::selection, +code[class*="language-"]::selection, code[class*="language-"] ::selection { + text-shadow: none; + background: #b3d4fc; +} + +@media print { + code[class*="language-"], + pre[class*="language-"] { + text-shadow: none; + } +} + +/* Code blocks */ +pre[class*="language-"] { + padding: 1em; + margin: .5em 0; + overflow: auto; +} + +:not(pre) > code[class*="language-"], +pre[class*="language-"] { + background: #f5f2f0; +} + +/* Inline code */ +:not(pre) > code[class*="language-"] { + padding: .1em; + border-radius: .3em; + white-space: normal; +} + +.token.comment, +.token.prolog, +.token.doctype, +.token.cdata { + color: slategray; +} + +.token.punctuation { + color: #999; +} + +.namespace { + opacity: .7; +} + +.token.property, +.token.tag, +.token.boolean, +.token.number, +.token.constant, +.token.symbol, +.token.deleted { + color: #905; +} + +.token.selector, +.token.attr-name, +.token.string, +.token.char, +.token.builtin, +.token.inserted { + color: #690; +} + +.token.operator, +.token.entity, +.token.url, +.language-css .token.string, +.style .token.string { + color: #a67f59; + background: hsla(0, 0%, 100%, .5); +} + +.token.atrule, +.token.attr-value, +.token.keyword { + color: #07a; +} + +.token.function { + color: #DD4A68; +} + +.token.regex, +.token.important, +.token.variable { + color: #e90; +} + +.token.important, +.token.bold { + font-weight: bold; +} +.token.italic { + font-style: italic; +} + +.token.entity { + cursor: help; +} + ADDED public/nexus-js/api/prism/prism.js Index: public/nexus-js/api/prism/prism.js ================================================================== --- public/nexus-js/api/prism/prism.js +++ public/nexus-js/api/prism/prism.js @@ -0,0 +1,6 @@ +/* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript */ +var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(){var e=/\blang(?:uage)?-(\w+)\b/i,t=0,n=_self.Prism={manual:_self.Prism&&_self.Prism.manual,util:{encode:function(e){return e instanceof a?new a(e.type,n.util.encode(e.content),e.alias):"Array"===n.util.type(e)?e.map(n.util.encode):e.replace(/&/g,"&").replace(/e.length)break e;if(!(v instanceof a)){u.lastIndex=0;var b=u.exec(v),k=1;if(!b&&h&&m!=r.length-1){if(u.lastIndex=y,b=u.exec(e),!b)break;for(var w=b.index+(c?b[1].length:0),_=b.index+b[0].length,P=m,A=y,j=r.length;j>P&&_>A;++P)A+=r[P].length,w>=A&&(++m,y=A);if(r[m]instanceof a||r[P-1].greedy)continue;k=P-m,v=e.slice(y,A),b.index-=y}if(b){c&&(f=b[1].length);var w=b.index+f,b=b[0].slice(f),_=w+b.length,x=v.slice(0,w),O=v.slice(_),S=[m,k];x&&S.push(x);var N=new a(i,g?n.tokenize(b,g):b,d,b,h);S.push(N),O&&S.push(O),Array.prototype.splice.apply(r,S)}}}}}return r},hooks:{all:{},add:function(e,t){var a=n.hooks.all;a[e]=a[e]||[],a[e].push(t)},run:function(e,t){var a=n.hooks.all[e];if(a&&a.length)for(var r,l=0;r=a[l++];)r(t)}}},a=n.Token=function(e,t,n,a,r){this.type=e,this.content=t,this.alias=n,this.length=0|(a||"").length,this.greedy=!!r};if(a.stringify=function(e,t,r){if("string"==typeof e)return e;if("Array"===n.util.type(e))return e.map(function(n){return a.stringify(n,t,e)}).join("");var l={type:e.type,content:a.stringify(e.content,t,r),tag:"span",classes:["token",e.type],attributes:{},language:t,parent:r};if("comment"==l.type&&(l.attributes.spellcheck="true"),e.alias){var i="Array"===n.util.type(e.alias)?e.alias:[e.alias];Array.prototype.push.apply(l.classes,i)}n.hooks.run("wrap",l);var o=Object.keys(l.attributes).map(function(e){return e+'="'+(l.attributes[e]||"").replace(/"/g,""")+'"'}).join(" ");return"<"+l.tag+' class="'+l.classes.join(" ")+'"'+(o?" "+o:"")+">"+l.content+""},!_self.document)return _self.addEventListener?(_self.addEventListener("message",function(e){var t=JSON.parse(e.data),a=t.language,r=t.code,l=t.immediateClose;_self.postMessage(n.highlight(r,n.languages[a],a)),l&&_self.close()},!1),_self.Prism):_self.Prism;var r=document.currentScript||[].slice.call(document.getElementsByTagName("script")).pop();return r&&(n.filename=r.src,!document.addEventListener||n.manual||r.hasAttribute("data-manual")||("loading"!==document.readyState?window.requestAnimationFrame?window.requestAnimationFrame(n.highlightAll):window.setTimeout(n.highlightAll,16):document.addEventListener("DOMContentLoaded",n.highlightAll))),_self.Prism}();"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism); +Prism.languages.markup={comment://,prolog:/<\?[\w\W]+?\?>/,doctype://i,cdata://i,tag:{pattern:/<\/?(?!\d)[^\s>\/=$<]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\\1|\\?(?!\1)[\w\W])*\1|[^\s'">=]+))?)*\s*\/?>/i,inside:{tag:{pattern:/^<\/?[^\s>\/]+/i,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"attr-value":{pattern:/=(?:('|")[\w\W]*?(\1)|[^\s>]+)/i,inside:{punctuation:/[=>"']/}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:/&#?[\da-z]{1,8};/i},Prism.hooks.add("wrap",function(a){"entity"===a.type&&(a.attributes.title=a.content.replace(/&/,"&"))}),Prism.languages.xml=Prism.languages.markup,Prism.languages.html=Prism.languages.markup,Prism.languages.mathml=Prism.languages.markup,Prism.languages.svg=Prism.languages.markup; +Prism.languages.css={comment:/\/\*[\w\W]*?\*\//,atrule:{pattern:/@[\w-]+?.*?(;|(?=\s*\{))/i,inside:{rule:/@[\w-]+/}},url:/url\((?:(["'])(\\(?:\r\n|[\w\W])|(?!\1)[^\\\r\n])*\1|.*?)\)/i,selector:/[^\{\}\s][^\{\};]*?(?=\s*\{)/,string:{pattern:/("|')(\\(?:\r\n|[\w\W])|(?!\1)[^\\\r\n])*\1/,greedy:!0},property:/(\b|\B)[\w-]+(?=\s*:)/i,important:/\B!important\b/i,"function":/[-a-z0-9]+(?=\()/i,punctuation:/[(){};:]/},Prism.languages.css.atrule.inside.rest=Prism.util.clone(Prism.languages.css),Prism.languages.markup&&(Prism.languages.insertBefore("markup","tag",{style:{pattern:/()[\w\W]*?(?=<\/style>)/i,lookbehind:!0,inside:Prism.languages.css,alias:"language-css"}}),Prism.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/\s*style=("|').*?\1/i,inside:{"attr-name":{pattern:/^\s*style/i,inside:Prism.languages.markup.tag.inside},punctuation:/^\s*=\s*['"]|['"]\s*$/,"attr-value":{pattern:/.+/i,inside:Prism.languages.css}},alias:"language-css"}},Prism.languages.markup.tag)); +Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\w\W]*?\*\//,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0}],string:{pattern:/(["'])(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/i,lookbehind:!0,inside:{punctuation:/(\.|\\)/}},keyword:/\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,"boolean":/\b(true|false)\b/,"function":/[a-z0-9_]+(?=\()/i,number:/\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)\b/i,operator:/--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/,punctuation:/[{}[\];(),.:]/}; +Prism.languages.javascript=Prism.languages.extend("clike",{keyword:/\b(as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|var|void|while|with|yield)\b/,number:/\b-?(0x[\dA-Fa-f]+|0b[01]+|0o[0-7]+|\d*\.?\d+([Ee][+-]?\d+)?|NaN|Infinity)\b/,"function":/[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*(?=\()/i,operator:/--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*\*?|\/|~|\^|%|\.{3}/}),Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/(^|[^\/])\/(?!\/)(\[.+?]|\\.|[^\/\\\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})]))/,lookbehind:!0,greedy:!0}}),Prism.languages.insertBefore("javascript","string",{"template-string":{pattern:/`(?:\\\\|\\?[^\\])*?`/,greedy:!0,inside:{interpolation:{pattern:/\$\{[^}]+\}/,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:Prism.languages.javascript}},string:/[\s\S]+/}}}),Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{script:{pattern:/()[\w\W]*?(?=<\/script>)/i,lookbehind:!0,inside:Prism.languages.javascript,alias:"language-javascript"}}),Prism.languages.js=Prism.languages.javascript; ADDED public/nexus-js/dist/NexusUI.js Index: public/nexus-js/dist/NexusUI.js ================================================================== --- public/nexus-js/dist/NexusUI.js +++ public/nexus-js/dist/NexusUI.js cannot compute difference between binary files ADDED public/nexus-js/dist/NexusUI.map Index: public/nexus-js/dist/NexusUI.map ================================================================== --- public/nexus-js/dist/NexusUI.map +++ public/nexus-js/dist/NexusUI.map @@ -0,0 +1,1 @@ +{"version":3,"sources":["webpack:///webpack/universalModuleDefinition","webpack:///webpack/bootstrap b2f31a6100da0c2ff488","webpack:///./index.js"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AACD,O;ACVA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,uBAAe;AACf;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;;;;;;ACtCA,aAAY,CAAC;;;;KAEN,OAAO,uCAAM,sIAAY;;kBAEjB,OAAO,C","file":"./dist/NexusUI.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"Nexus\"] = factory();\n\telse\n\t\troot[\"Nexus\"] = factory();\n})(this, function() {\nreturn \n\n\n// WEBPACK FOOTER //\n// webpack/universalModuleDefinition"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap b2f31a6100da0c2ff488","'use strict';\n\nimport NexusUI from './lib/main';\n\nexport default NexusUI;\n\n\n\n// WEBPACK FOOTER //\n// ./~/jshint-loader!./index.js"],"sourceRoot":""} ADDED public/nexus-js/dist/NexusUI.min.js Index: public/nexus-js/dist/NexusUI.min.js ================================================================== --- public/nexus-js/dist/NexusUI.min.js +++ public/nexus-js/dist/NexusUI.min.js cannot compute difference between binary files ADDED public/nexus-js/dist/NexusUI.min.map Index: public/nexus-js/dist/NexusUI.min.map ================================================================== --- public/nexus-js/dist/NexusUI.min.map +++ public/nexus-js/dist/NexusUI.min.map cannot compute difference between binary files ADDED public/nexus-js/example/add.html Index: public/nexus-js/example/add.html ================================================================== --- public/nexus-js/example/add.html +++ public/nexus-js/example/add.html @@ -0,0 +1,47 @@ + + + + + + Musician's Toolkit + + + + + + + + +
+ Testing Sandbox +
+ +
+ + + + + + ADDED public/nexus-js/example/all.html Index: public/nexus-js/example/all.html ================================================================== --- public/nexus-js/example/all.html +++ public/nexus-js/example/all.html @@ -0,0 +1,66 @@ + + + + + Musician's Toolkit + + + + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + ADDED public/nexus-js/example/demo.html Index: public/nexus-js/example/demo.html ================================================================== --- public/nexus-js/example/demo.html +++ public/nexus-js/example/demo.html @@ -0,0 +1,148 @@ + + + + + + Musician's Toolkit + + + + + + + +
+ NexusUI Basic Demo +
+ + + +
+
+
+
+ Power On +
+
+
+
+
Timbre
+
+
+
+
Pan
+
+ +
+
+
Filter
+
+ +
+ + +
+
+
+
+ +
+ + + + + + ADDED public/nexus-js/example/js/Tone9.js Index: public/nexus-js/example/js/Tone9.js ================================================================== --- public/nexus-js/example/js/Tone9.js +++ public/nexus-js/example/js/Tone9.js @@ -0,0 +1,22214 @@ +(function(root, factory){ + + //UMD + if ( typeof define === "function" && define.amd ) { + define(function() { + return factory(); + }); + } else if (typeof module === "object") { + module.exports = factory(); + } else { + root.Tone = factory(); + } + +}(this, function(){ + + "use strict"; + + var Tone; + //constructs the main Tone object + function Main(func){ + Tone = func(); + } + //invokes each of the modules with the main Tone object as the argument + function Module(func){ + func(Tone); + } /** + * Tone.js + * @author Yotam Mann + * @license http://opensource.org/licenses/MIT MIT License + * @copyright 2014-2017 Yotam Mann + */ + Main(function () { + + ////////////////////////////////////////////////////////////////////////// + // WEB AUDIO CONTEXT + /////////////////////////////////////////////////////////////////////////// + function isUndef(val) { + return typeof val === 'undefined'; + } + function isFunction(val) { + return typeof val === 'function'; + } + var audioContext; + //polyfill for AudioContext and OfflineAudioContext + if (isUndef(window.AudioContext)) { + window.AudioContext = window.webkitAudioContext; + } + if (isUndef(window.OfflineAudioContext)) { + window.OfflineAudioContext = window.webkitOfflineAudioContext; + } + if (!isUndef(AudioContext)) { + audioContext = new AudioContext(); + } else { + throw new Error('Web Audio is not supported in this browser'); + } + //SHIMS//////////////////////////////////////////////////////////////////// + if (!isFunction(AudioContext.prototype.createGain)) { + AudioContext.prototype.createGain = AudioContext.prototype.createGainNode; + } + if (!isFunction(AudioContext.prototype.createDelay)) { + AudioContext.prototype.createDelay = AudioContext.prototype.createDelayNode; + } + if (!isFunction(AudioContext.prototype.createPeriodicWave)) { + AudioContext.prototype.createPeriodicWave = AudioContext.prototype.createWaveTable; + } + if (!isFunction(AudioBufferSourceNode.prototype.start)) { + AudioBufferSourceNode.prototype.start = AudioBufferSourceNode.prototype.noteGrainOn; + } + if (!isFunction(AudioBufferSourceNode.prototype.stop)) { + AudioBufferSourceNode.prototype.stop = AudioBufferSourceNode.prototype.noteOff; + } + if (!isFunction(OscillatorNode.prototype.start)) { + OscillatorNode.prototype.start = OscillatorNode.prototype.noteOn; + } + if (!isFunction(OscillatorNode.prototype.stop)) { + OscillatorNode.prototype.stop = OscillatorNode.prototype.noteOff; + } + if (!isFunction(OscillatorNode.prototype.setPeriodicWave)) { + OscillatorNode.prototype.setPeriodicWave = OscillatorNode.prototype.setWaveTable; + } + //extend the connect function to include Tones + if (isUndef(AudioNode.prototype._nativeConnect)) { + AudioNode.prototype._nativeConnect = AudioNode.prototype.connect; + AudioNode.prototype.connect = function (B, outNum, inNum) { + if (B.input) { + if (Array.isArray(B.input)) { + if (isUndef(inNum)) { + inNum = 0; + } + this.connect(B.input[inNum]); + } else { + this.connect(B.input, outNum, inNum); + } + } else { + try { + if (B instanceof AudioNode) { + this._nativeConnect(B, outNum, inNum); + } else { + this._nativeConnect(B, outNum); + } + } catch (e) { + throw new Error('error connecting to node: ' + B); + } + } + }; + } + /////////////////////////////////////////////////////////////////////////// + // TONE + /////////////////////////////////////////////////////////////////////////// + /** + * @class Tone is the base class of all other classes. It provides + * a lot of methods and functionality to all classes that extend + * it. + * + * @constructor + * @alias Tone + * @param {number} [inputs=1] the number of input nodes + * @param {number} [outputs=1] the number of output nodes + */ + var Tone = function (inputs, outputs) { + /** + * the input node(s) + * @type {GainNode|Array} + */ + if (isUndef(inputs) || inputs === 1) { + this.input = this.context.createGain(); + } else if (inputs > 1) { + this.input = new Array(inputs); + } + /** + * the output node(s) + * @type {GainNode|Array} + */ + if (isUndef(outputs) || outputs === 1) { + this.output = this.context.createGain(); + } else if (outputs > 1) { + this.output = new Array(inputs); + } + }; + /** + * Set the parameters at once. Either pass in an + * object mapping parameters to values, or to set a + * single parameter, by passing in a string and value. + * The last argument is an optional ramp time which + * will ramp any signal values to their destination value + * over the duration of the rampTime. + * @param {Object|string} params + * @param {number=} value + * @param {Time=} rampTime + * @returns {Tone} this + * @example + * //set values using an object + * filter.set({ + * "frequency" : 300, + * "type" : highpass + * }); + * @example + * filter.set("type", "highpass"); + * @example + * //ramp to the value 220 over 3 seconds. + * oscillator.set({ + * "frequency" : 220 + * }, 3); + */ + Tone.prototype.set = function (params, value, rampTime) { + if (this.isObject(params)) { + rampTime = value; + } else if (this.isString(params)) { + var tmpObj = {}; + tmpObj[params] = value; + params = tmpObj; + } + paramLoop: + for (var attr in params) { + value = params[attr]; + var parent = this; + if (attr.indexOf('.') !== -1) { + var attrSplit = attr.split('.'); + for (var i = 0; i < attrSplit.length - 1; i++) { + parent = parent[attrSplit[i]]; + if (parent instanceof Tone) { + attrSplit.splice(0, i + 1); + var innerParam = attrSplit.join('.'); + parent.set(innerParam, value); + continue paramLoop; + } + } + attr = attrSplit[attrSplit.length - 1]; + } + var param = parent[attr]; + if (isUndef(param)) { + continue; + } + if (Tone.Signal && param instanceof Tone.Signal || Tone.Param && param instanceof Tone.Param) { + if (param.value !== value) { + if (isUndef(rampTime)) { + param.value = value; + } else { + param.rampTo(value, rampTime); + } + } + } else if (param instanceof AudioParam) { + if (param.value !== value) { + param.value = value; + } + } else if (param instanceof Tone) { + param.set(value); + } else if (param !== value) { + parent[attr] = value; + } + } + return this; + }; + /** + * Get the object's attributes. Given no arguments get + * will return all available object properties and their corresponding + * values. Pass in a single attribute to retrieve or an array + * of attributes. The attribute strings can also include a "." + * to access deeper properties. + * @example + * osc.get(); + * //returns {"type" : "sine", "frequency" : 440, ...etc} + * @example + * osc.get("type"); + * //returns { "type" : "sine"} + * @example + * //use dot notation to access deep properties + * synth.get(["envelope.attack", "envelope.release"]); + * //returns {"envelope" : {"attack" : 0.2, "release" : 0.4}} + * @param {Array=|string|undefined} params the parameters to get, otherwise will return + * all available. + * @returns {Object} + */ + Tone.prototype.get = function (params) { + if (isUndef(params)) { + params = this._collectDefaults(this.constructor); + } else if (this.isString(params)) { + params = [params]; + } + var ret = {}; + for (var i = 0; i < params.length; i++) { + var attr = params[i]; + var parent = this; + var subRet = ret; + if (attr.indexOf('.') !== -1) { + var attrSplit = attr.split('.'); + for (var j = 0; j < attrSplit.length - 1; j++) { + var subAttr = attrSplit[j]; + subRet[subAttr] = subRet[subAttr] || {}; + subRet = subRet[subAttr]; + parent = parent[subAttr]; + } + attr = attrSplit[attrSplit.length - 1]; + } + var param = parent[attr]; + if (this.isObject(params[attr])) { + subRet[attr] = param.get(); + } else if (Tone.Signal && param instanceof Tone.Signal) { + subRet[attr] = param.value; + } else if (Tone.Param && param instanceof Tone.Param) { + subRet[attr] = param.value; + } else if (param instanceof AudioParam) { + subRet[attr] = param.value; + } else if (param instanceof Tone) { + subRet[attr] = param.get(); + } else if (!isFunction(param) && !isUndef(param)) { + subRet[attr] = param; + } + } + return ret; + }; + /** + * collect all of the default attributes in one + * @private + * @param {function} constr the constructor to find the defaults from + * @return {Array} all of the attributes which belong to the class + */ + Tone.prototype._collectDefaults = function (constr) { + var ret = []; + if (!isUndef(constr.defaults)) { + ret = Object.keys(constr.defaults); + } + if (!isUndef(constr._super)) { + var superDefs = this._collectDefaults(constr._super); + //filter out repeats + for (var i = 0; i < superDefs.length; i++) { + if (ret.indexOf(superDefs[i]) === -1) { + ret.push(superDefs[i]); + } + } + } + return ret; + }; + /** + * @returns {string} returns the name of the class as a string + */ + Tone.prototype.toString = function () { + for (var className in Tone) { + var isLetter = className[0].match(/^[A-Z]$/); + var sameConstructor = Tone[className] === this.constructor; + if (isFunction(Tone[className]) && isLetter && sameConstructor) { + return className; + } + } + return 'Tone'; + }; + /////////////////////////////////////////////////////////////////////////// + // CLASS VARS + /////////////////////////////////////////////////////////////////////////// + /** + * A static pointer to the audio context accessible as Tone.context. + * @type {AudioContext} + */ + Tone.context = audioContext; + /** + * The audio context. + * @type {AudioContext} + */ + Tone.prototype.context = Tone.context; + /** + * the default buffer size + * @type {number} + * @static + * @const + */ + Tone.prototype.bufferSize = 2048; + /** + * The delay time of a single frame (128 samples according to the spec). + * @type {number} + * @static + * @const + */ + Tone.prototype.blockTime = 128 / Tone.context.sampleRate; + /** + * The time of a single sample + * @type {number} + * @static + * @const + */ + Tone.prototype.sampleTime = 1 / Tone.context.sampleRate; + /** + * The number of inputs feeding into the AudioNode. + * For source nodes, this will be 0. + * @memberOf Tone# + * @name numberOfInputs + * @readOnly + */ + Object.defineProperty(Tone.prototype, 'numberOfInputs', { + get: function () { + if (this.input) { + if (this.isArray(this.input)) { + return this.input.length; + } else { + return 1; + } + } else { + return 0; + } + } + }); + /** + * The number of outputs coming out of the AudioNode. + * For source nodes, this will be 0. + * @memberOf Tone# + * @name numberOfInputs + * @readOnly + */ + Object.defineProperty(Tone.prototype, 'numberOfOutputs', { + get: function () { + if (this.output) { + if (this.isArray(this.output)) { + return this.output.length; + } else { + return 1; + } + } else { + return 0; + } + } + }); + /////////////////////////////////////////////////////////////////////////// + // CONNECTIONS + /////////////////////////////////////////////////////////////////////////// + /** + * disconnect and dispose + * @returns {Tone} this + */ + Tone.prototype.dispose = function () { + if (!this.isUndef(this.input)) { + if (this.input instanceof AudioNode) { + this.input.disconnect(); + } + this.input = null; + } + if (!this.isUndef(this.output)) { + if (this.output instanceof AudioNode) { + this.output.disconnect(); + } + this.output = null; + } + return this; + }; + /** + * a silent connection to the DesinationNode + * which will ensure that anything connected to it + * will not be garbage collected + * + * @private + */ + var _silentNode = null; + /** + * makes a connection to ensure that the node will not be garbage collected + * until 'dispose' is explicitly called + * + * use carefully. circumvents JS and WebAudio's normal Garbage Collection behavior + * @returns {Tone} this + */ + Tone.prototype.noGC = function () { + this.output.connect(_silentNode); + return this; + }; + AudioNode.prototype.noGC = function () { + this.connect(_silentNode); + return this; + }; + /** + * connect the output of a ToneNode to an AudioParam, AudioNode, or ToneNode + * @param {Tone | AudioParam | AudioNode} unit + * @param {number} [outputNum=0] optionally which output to connect from + * @param {number} [inputNum=0] optionally which input to connect to + * @returns {Tone} this + */ + Tone.prototype.connect = function (unit, outputNum, inputNum) { + if (Array.isArray(this.output)) { + outputNum = this.defaultArg(outputNum, 0); + this.output[outputNum].connect(unit, 0, inputNum); + } else { + this.output.connect(unit, outputNum, inputNum); + } + return this; + }; + /** + * disconnect the output + * @param {Number|AudioNode} output Either the output index to disconnect + * if the output is an array, or the + * node to disconnect from. + * @returns {Tone} this + */ + Tone.prototype.disconnect = function (output) { + if (Array.isArray(this.output)) { + output = this.defaultArg(output, 0); + this.output[output].disconnect(); + } else if (!this.isUndef(output)) { + this.output.disconnect(output); + } else { + this.output.disconnect(); + } + return this; + }; + /** + * connect together all of the arguments in series + * @param {...AudioParam|Tone|AudioNode} nodes + * @returns {Tone} this + */ + Tone.prototype.connectSeries = function () { + if (arguments.length > 1) { + var currentUnit = arguments[0]; + for (var i = 1; i < arguments.length; i++) { + var toUnit = arguments[i]; + currentUnit.connect(toUnit); + currentUnit = toUnit; + } + } + return this; + }; + /** + * Connect the output of this node to the rest of the nodes in series. + * @example + * //connect a node to an effect, panVol and then to the master output + * node.chain(effect, panVol, Tone.Master); + * @param {...AudioParam|Tone|AudioNode} nodes + * @returns {Tone} this + */ + Tone.prototype.chain = function () { + if (arguments.length > 0) { + var currentUnit = this; + for (var i = 0; i < arguments.length; i++) { + var toUnit = arguments[i]; + currentUnit.connect(toUnit); + currentUnit = toUnit; + } + } + return this; + }; + /** + * connect the output of this node to the rest of the nodes in parallel. + * @param {...AudioParam|Tone|AudioNode} nodes + * @returns {Tone} this + */ + Tone.prototype.fan = function () { + if (arguments.length > 0) { + for (var i = 0; i < arguments.length; i++) { + this.connect(arguments[i]); + } + } + return this; + }; + //give native nodes chain and fan methods + AudioNode.prototype.chain = Tone.prototype.chain; + AudioNode.prototype.fan = Tone.prototype.fan; + /////////////////////////////////////////////////////////////////////////// + // UTILITIES / HELPERS / MATHS + /////////////////////////////////////////////////////////////////////////// + /** + * If the `given` parameter is undefined, use the `fallback`. + * If both `given` and `fallback` are object literals, it will + * return a deep copy which includes all of the parameters from both + * objects. If a parameter is undefined in given, it will return + * the fallback property. + *

+ * WARNING: if object is self referential, it will go into an an + * infinite recursive loop. + * + * @param {*} given + * @param {*} fallback + * @return {*} + */ + Tone.prototype.defaultArg = function (given, fallback) { + if (this.isObject(given) && this.isObject(fallback)) { + var ret = {}; + //make a deep copy of the given object + for (var givenProp in given) { + ret[givenProp] = this.defaultArg(fallback[givenProp], given[givenProp]); + } + for (var fallbackProp in fallback) { + ret[fallbackProp] = this.defaultArg(given[fallbackProp], fallback[fallbackProp]); + } + return ret; + } else { + return isUndef(given) ? fallback : given; + } + }; + /** + * returns the args as an options object with given arguments + * mapped to the names provided. + * + * if the args given is an array containing only one object, it is assumed + * that that's already the options object and will just return it. + * + * @param {Array} values the 'arguments' object of the function + * @param {Array} keys the names of the arguments as they + * should appear in the options object + * @param {Object=} defaults optional defaults to mixin to the returned + * options object + * @return {Object} the options object with the names mapped to the arguments + */ + Tone.prototype.optionsObject = function (values, keys, defaults) { + var options = {}; + if (values.length === 1 && this.isObject(values[0])) { + options = values[0]; + } else { + for (var i = 0; i < keys.length; i++) { + options[keys[i]] = values[i]; + } + } + if (!this.isUndef(defaults)) { + return this.defaultArg(options, defaults); + } else { + return options; + } + }; + /////////////////////////////////////////////////////////////////////////// + // TYPE CHECKING + /////////////////////////////////////////////////////////////////////////// + /** + * test if the arg is undefined + * @param {*} arg the argument to test + * @returns {boolean} true if the arg is undefined + * @function + */ + Tone.prototype.isUndef = isUndef; + /** + * test if the arg is a function + * @param {*} arg the argument to test + * @returns {boolean} true if the arg is a function + * @function + */ + Tone.prototype.isFunction = isFunction; + /** + * Test if the argument is a number. + * @param {*} arg the argument to test + * @returns {boolean} true if the arg is a number + */ + Tone.prototype.isNumber = function (arg) { + return typeof arg === 'number'; + }; + /** + * Test if the given argument is an object literal (i.e. `{}`); + * @param {*} arg the argument to test + * @returns {boolean} true if the arg is an object literal. + */ + Tone.prototype.isObject = function (arg) { + return Object.prototype.toString.call(arg) === '[object Object]' && arg.constructor === Object; + }; + /** + * Test if the argument is a boolean. + * @param {*} arg the argument to test + * @returns {boolean} true if the arg is a boolean + */ + Tone.prototype.isBoolean = function (arg) { + return typeof arg === 'boolean'; + }; + /** + * Test if the argument is an Array + * @param {*} arg the argument to test + * @returns {boolean} true if the arg is an array + */ + Tone.prototype.isArray = function (arg) { + return Array.isArray(arg); + }; + /** + * Test if the argument is a string. + * @param {*} arg the argument to test + * @returns {boolean} true if the arg is a string + */ + Tone.prototype.isString = function (arg) { + return typeof arg === 'string'; + }; + /** + * An empty function. + * @static + */ + Tone.noOp = function () { + }; + /** + * Make the property not writable. Internal use only. + * @private + * @param {string} property the property to make not writable + */ + Tone.prototype._readOnly = function (property) { + if (Array.isArray(property)) { + for (var i = 0; i < property.length; i++) { + this._readOnly(property[i]); + } + } else { + Object.defineProperty(this, property, { + writable: false, + enumerable: true + }); + } + }; + /** + * Make an attribute writeable. Interal use only. + * @private + * @param {string} property the property to make writable + */ + Tone.prototype._writable = function (property) { + if (Array.isArray(property)) { + for (var i = 0; i < property.length; i++) { + this._writable(property[i]); + } + } else { + Object.defineProperty(this, property, { writable: true }); + } + }; + /** + * Possible play states. + * @enum {string} + */ + Tone.State = { + Started: 'started', + Stopped: 'stopped', + Paused: 'paused' + }; + /////////////////////////////////////////////////////////////////////////// + // GAIN CONVERSIONS + /////////////////////////////////////////////////////////////////////////// + /** + * Equal power gain scale. Good for cross-fading. + * @param {NormalRange} percent (0-1) + * @return {Number} output gain (0-1) + */ + Tone.prototype.equalPowerScale = function (percent) { + var piFactor = 0.5 * Math.PI; + return Math.sin(percent * piFactor); + }; + /** + * Convert decibels into gain. + * @param {Decibels} db + * @return {Number} + */ + Tone.prototype.dbToGain = function (db) { + return Math.pow(2, db / 6); + }; + /** + * Convert gain to decibels. + * @param {Number} gain (0-1) + * @return {Decibels} + */ + Tone.prototype.gainToDb = function (gain) { + return 20 * (Math.log(gain) / Math.LN10); + }; + /** + * Convert an interval (in semitones) to a frequency ratio. + * @param {Interval} interval the number of semitones above the base note + * @return {number} the frequency ratio + * @example + * tone.intervalToFrequencyRatio(0); // 1 + * tone.intervalToFrequencyRatio(12); // 2 + * tone.intervalToFrequencyRatio(-12); // 0.5 + */ + Tone.prototype.intervalToFrequencyRatio = function (interval) { + return Math.pow(2, interval / 12); + }; + /////////////////////////////////////////////////////////////////////////// + // TIMING + /////////////////////////////////////////////////////////////////////////// + /** + * Return the current time of the AudioContext clock. + * @return {Number} the currentTime from the AudioContext + */ + Tone.prototype.now = function () { + return this.context.currentTime; + }; + /** + * Return the current time of the AudioContext clock. + * @return {Number} the currentTime from the AudioContext + * @static + */ + Tone.now = function () { + return Tone.context.currentTime; + }; + /////////////////////////////////////////////////////////////////////////// + // INHERITANCE + /////////////////////////////////////////////////////////////////////////// + /** + * have a child inherit all of Tone's (or a parent's) prototype + * to inherit the parent's properties, make sure to call + * Parent.call(this) in the child's constructor + * + * based on closure library's inherit function + * + * @static + * @param {function} child + * @param {function=} parent (optional) parent to inherit from + * if no parent is supplied, the child + * will inherit from Tone + */ + Tone.extend = function (child, parent) { + if (isUndef(parent)) { + parent = Tone; + } + function TempConstructor() { + } + TempConstructor.prototype = parent.prototype; + child.prototype = new TempConstructor(); + /** @override */ + child.prototype.constructor = child; + child._super = parent; + }; + /////////////////////////////////////////////////////////////////////////// + // CONTEXT + /////////////////////////////////////////////////////////////////////////// + /** + * array of callbacks to be invoked when a new context is added + * @private + * @private + */ + var newContextCallbacks = []; + /** + * invoke this callback when a new context is added + * will be invoked initially with the first context + * @private + * @static + * @param {function(AudioContext)} callback the callback to be invoked + * with the audio context + */ + Tone._initAudioContext = function (callback) { + //invoke the callback with the existing AudioContext + callback(Tone.context); + //add it to the array + newContextCallbacks.push(callback); + }; + /** + * Tone automatically creates a context on init, but if you are working + * with other libraries which also create an AudioContext, it can be + * useful to set your own. If you are going to set your own context, + * be sure to do it at the start of your code, before creating any objects. + * @static + * @param {AudioContext} ctx The new audio context to set + */ + Tone.setContext = function (ctx) { + //set the prototypes + Tone.prototype.context = ctx; + Tone.context = ctx; + //invoke all the callbacks + for (var i = 0; i < newContextCallbacks.length; i++) { + newContextCallbacks[i](ctx); + } + }; + //setup the context + Tone._initAudioContext(function (audioContext) { + //set the blockTime + Tone.prototype.blockTime = 128 / audioContext.sampleRate; + Tone.prototype.sampleTime = 1 / audioContext.sampleRate; + _silentNode = audioContext.createGain(); + _silentNode.gain.value = 0; + _silentNode.connect(audioContext.destination); + }); + Tone.version = 'r9'; + // allow optional silencing of this log + if (!window.TONE_SILENCE_VERSION_LOGGING) { + console.log('%c * Tone.js ' + Tone.version + ' * ', 'background: #000; color: #fff'); + } + return Tone; + }); + Module(function (Tone) { + + /** + * @class Base class for all Signals. Used Internally. + * + * @constructor + * @extends {Tone} + */ + Tone.SignalBase = function () { + }; + Tone.extend(Tone.SignalBase); + /** + * When signals connect to other signals or AudioParams, + * they take over the output value of that signal or AudioParam. + * For all other nodes, the behavior is the same as a default connect. + * + * @override + * @param {AudioParam|AudioNode|Tone.Signal|Tone} node + * @param {number} [outputNumber=0] The output number to connect from. + * @param {number} [inputNumber=0] The input number to connect to. + * @returns {Tone.SignalBase} this + */ + Tone.SignalBase.prototype.connect = function (node, outputNumber, inputNumber) { + //zero it out so that the signal can have full control + if (Tone.Signal && Tone.Signal === node.constructor || Tone.Param && Tone.Param === node.constructor || Tone.TimelineSignal && Tone.TimelineSignal === node.constructor) { + //cancel changes + node._param.cancelScheduledValues(0); + //reset the value + node._param.value = 0; + //mark the value as overridden + node.overridden = true; + } else if (node instanceof AudioParam) { + node.cancelScheduledValues(0); + node.value = 0; + } + Tone.prototype.connect.call(this, node, outputNumber, inputNumber); + return this; + }; + return Tone.SignalBase; + }); + Module(function (Tone) { + + /** + * @class Wraps the native Web Audio API + * [WaveShaperNode](http://webaudio.github.io/web-audio-api/#the-waveshapernode-interface). + * + * @extends {Tone.SignalBase} + * @constructor + * @param {function|Array|Number} mapping The function used to define the values. + * The mapping function should take two arguments: + * the first is the value at the current position + * and the second is the array position. + * If the argument is an array, that array will be + * set as the wave shaping function. The input + * signal is an AudioRange [-1, 1] value and the output + * signal can take on any numerical values. + * + * @param {Number} [bufferLen=1024] The length of the WaveShaperNode buffer. + * @example + * var timesTwo = new Tone.WaveShaper(function(val){ + * return val * 2; + * }, 2048); + * @example + * //a waveshaper can also be constructed with an array of values + * var invert = new Tone.WaveShaper([1, -1]); + */ + Tone.WaveShaper = function (mapping, bufferLen) { + /** + * the waveshaper + * @type {WaveShaperNode} + * @private + */ + this._shaper = this.input = this.output = this.context.createWaveShaper(); + /** + * the waveshapers curve + * @type {Float32Array} + * @private + */ + this._curve = null; + if (Array.isArray(mapping)) { + this.curve = mapping; + } else if (isFinite(mapping) || this.isUndef(mapping)) { + this._curve = new Float32Array(this.defaultArg(mapping, 1024)); + } else if (this.isFunction(mapping)) { + this._curve = new Float32Array(this.defaultArg(bufferLen, 1024)); + this.setMap(mapping); + } + }; + Tone.extend(Tone.WaveShaper, Tone.SignalBase); + /** + * Uses a mapping function to set the value of the curve. + * @param {function} mapping The function used to define the values. + * The mapping function take two arguments: + * the first is the value at the current position + * which goes from -1 to 1 over the number of elements + * in the curve array. The second argument is the array position. + * @returns {Tone.WaveShaper} this + * @example + * //map the input signal from [-1, 1] to [0, 10] + * shaper.setMap(function(val, index){ + * return (val + 1) * 5; + * }) + */ + Tone.WaveShaper.prototype.setMap = function (mapping) { + for (var i = 0, len = this._curve.length; i < len; i++) { + var normalized = i / (len - 1) * 2 - 1; + this._curve[i] = mapping(normalized, i); + } + this._shaper.curve = this._curve; + return this; + }; + /** + * The array to set as the waveshaper curve. For linear curves + * array length does not make much difference, but for complex curves + * longer arrays will provide smoother interpolation. + * @memberOf Tone.WaveShaper# + * @type {Array} + * @name curve + */ + Object.defineProperty(Tone.WaveShaper.prototype, 'curve', { + get: function () { + return this._shaper.curve; + }, + set: function (mapping) { + this._curve = new Float32Array(mapping); + this._shaper.curve = this._curve; + } + }); + /** + * Specifies what type of oversampling (if any) should be used when + * applying the shaping curve. Can either be "none", "2x" or "4x". + * @memberOf Tone.WaveShaper# + * @type {string} + * @name oversample + */ + Object.defineProperty(Tone.WaveShaper.prototype, 'oversample', { + get: function () { + return this._shaper.oversample; + }, + set: function (oversampling) { + if ([ + 'none', + '2x', + '4x' + ].indexOf(oversampling) !== -1) { + this._shaper.oversample = oversampling; + } else { + throw new RangeError('Tone.WaveShaper: oversampling must be either \'none\', \'2x\', or \'4x\''); + } + } + }); + /** + * Clean up. + * @returns {Tone.WaveShaper} this + */ + Tone.WaveShaper.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._shaper.disconnect(); + this._shaper = null; + this._curve = null; + return this; + }; + return Tone.WaveShaper; + }); + Module(function (Tone) { + /** + * @class Tone.TimeBase is a flexible encoding of time + * which can be evaluated to and from a string. + * Parsing code modified from https://code.google.com/p/tapdigit/ + * Copyright 2011 2012 Ariya Hidayat, New BSD License + * @extends {Tone} + * @param {Time} val The time value as a number or string + * @param {String=} units Unit values + * @example + * Tone.TimeBase(4, "n") + * Tone.TimeBase(2, "t") + * Tone.TimeBase("2t").add("1m") + * Tone.TimeBase("2t + 1m"); + */ + Tone.TimeBase = function (val, units) { + //allows it to be constructed with or without 'new' + if (this instanceof Tone.TimeBase) { + /** + * Any expressions parsed from the Time + * @type {Array} + * @private + */ + this._expr = this._noOp; + if (val instanceof Tone.TimeBase) { + this.copy(val); + } else if (!this.isUndef(units) || this.isNumber(val)) { + //default units + units = this.defaultArg(units, this._defaultUnits); + var method = this._primaryExpressions[units].method; + this._expr = method.bind(this, val); + } else if (this.isString(val)) { + this.set(val); + } else if (this.isUndef(val)) { + //default expression + this._expr = this._defaultExpr(); + } + } else { + return new Tone.TimeBase(val, units); + } + }; + Tone.extend(Tone.TimeBase); + /** + * Repalce the current time value with the value + * given by the expression string. + * @param {String} exprString + * @return {Tone.TimeBase} this + */ + Tone.TimeBase.prototype.set = function (exprString) { + this._expr = this._parseExprString(exprString); + return this; + }; + /** + * Return a clone of the TimeBase object. + * @return {Tone.TimeBase} The new cloned Tone.TimeBase + */ + Tone.TimeBase.prototype.clone = function () { + var instance = new this.constructor(); + instance.copy(this); + return instance; + }; + /** + * Copies the value of time to this Time + * @param {Tone.TimeBase} time + * @return {TimeBase} + */ + Tone.TimeBase.prototype.copy = function (time) { + var val = time._expr(); + return this.set(val); + }; + /////////////////////////////////////////////////////////////////////////// + // ABSTRACT SYNTAX TREE PARSER + /////////////////////////////////////////////////////////////////////////// + /** + * All the primary expressions. + * @private + * @type {Object} + */ + Tone.TimeBase.prototype._primaryExpressions = { + 'n': { + regexp: /^(\d+)n/i, + method: function (value) { + value = parseInt(value); + if (value === 1) { + return this._beatsToUnits(this._timeSignature()); + } else { + return this._beatsToUnits(4 / value); + } + } + }, + 't': { + regexp: /^(\d+)t/i, + method: function (value) { + value = parseInt(value); + return this._beatsToUnits(8 / (parseInt(value) * 3)); + } + }, + 'm': { + regexp: /^(\d+)m/i, + method: function (value) { + return this._beatsToUnits(parseInt(value) * this._timeSignature()); + } + }, + 'i': { + regexp: /^(\d+)i/i, + method: function (value) { + return this._ticksToUnits(parseInt(value)); + } + }, + 'hz': { + regexp: /^(\d+(?:\.\d+)?)hz/i, + method: function (value) { + return this._frequencyToUnits(parseFloat(value)); + } + }, + 'tr': { + regexp: /^(\d+(?:\.\d+)?):(\d+(?:\.\d+)?):?(\d+(?:\.\d+)?)?/, + method: function (m, q, s) { + var total = 0; + if (m && m !== '0') { + total += this._beatsToUnits(this._timeSignature() * parseFloat(m)); + } + if (q && q !== '0') { + total += this._beatsToUnits(parseFloat(q)); + } + if (s && s !== '0') { + total += this._beatsToUnits(parseFloat(s) / 4); + } + return total; + } + }, + 's': { + regexp: /^(\d+(?:\.\d+)?s)/, + method: function (value) { + return this._secondsToUnits(parseFloat(value)); + } + }, + 'samples': { + regexp: /^(\d+)samples/, + method: function (value) { + return parseInt(value) / this.context.sampleRate; + } + }, + 'default': { + regexp: /^(\d+(?:\.\d+)?)/, + method: function (value) { + return this._primaryExpressions[this._defaultUnits].method.call(this, value); + } + } + }; + /** + * All the binary expressions that TimeBase can accept. + * @private + * @type {Object} + */ + Tone.TimeBase.prototype._binaryExpressions = { + '+': { + regexp: /^\+/, + precedence: 2, + method: function (lh, rh) { + return lh() + rh(); + } + }, + '-': { + regexp: /^\-/, + precedence: 2, + method: function (lh, rh) { + return lh() - rh(); + } + }, + '*': { + regexp: /^\*/, + precedence: 1, + method: function (lh, rh) { + return lh() * rh(); + } + }, + '/': { + regexp: /^\//, + precedence: 1, + method: function (lh, rh) { + return lh() / rh(); + } + } + }; + /** + * All the unary expressions. + * @private + * @type {Object} + */ + Tone.TimeBase.prototype._unaryExpressions = { + 'neg': { + regexp: /^\-/, + method: function (lh) { + return -lh(); + } + } + }; + /** + * Syntactic glue which holds expressions together + * @private + * @type {Object} + */ + Tone.TimeBase.prototype._syntaxGlue = { + '(': { regexp: /^\(/ }, + ')': { regexp: /^\)/ } + }; + /** + * tokenize the expression based on the Expressions object + * @param {string} expr + * @return {Object} returns two methods on the tokenized list, next and peek + * @private + */ + Tone.TimeBase.prototype._tokenize = function (expr) { + var position = -1; + var tokens = []; + while (expr.length > 0) { + expr = expr.trim(); + var token = getNextToken(expr, this); + tokens.push(token); + expr = expr.substr(token.value.length); + } + function getNextToken(expr, context) { + var expressions = [ + '_binaryExpressions', + '_unaryExpressions', + '_primaryExpressions', + '_syntaxGlue' + ]; + for (var i = 0; i < expressions.length; i++) { + var group = context[expressions[i]]; + for (var opName in group) { + var op = group[opName]; + var reg = op.regexp; + var match = expr.match(reg); + if (match !== null) { + return { + method: op.method, + precedence: op.precedence, + regexp: op.regexp, + value: match[0] + }; + } + } + } + throw new SyntaxError('Tone.TimeBase: Unexpected token ' + expr); + } + return { + next: function () { + return tokens[++position]; + }, + peek: function () { + return tokens[position + 1]; + } + }; + }; + /** + * Given a token, find the value within the groupName + * @param {Object} token + * @param {String} groupName + * @param {Number} precedence + * @private + */ + Tone.TimeBase.prototype._matchGroup = function (token, group, prec) { + var ret = false; + if (!this.isUndef(token)) { + for (var opName in group) { + var op = group[opName]; + if (op.regexp.test(token.value)) { + if (!this.isUndef(prec)) { + if (op.precedence === prec) { + return op; + } + } else { + return op; + } + } + } + } + return ret; + }; + /** + * Match a binary expression given the token and the precedence + * @param {Lexer} lexer + * @param {Number} precedence + * @private + */ + Tone.TimeBase.prototype._parseBinary = function (lexer, precedence) { + if (this.isUndef(precedence)) { + precedence = 2; + } + var expr; + if (precedence < 0) { + expr = this._parseUnary(lexer); + } else { + expr = this._parseBinary(lexer, precedence - 1); + } + var token = lexer.peek(); + while (token && this._matchGroup(token, this._binaryExpressions, precedence)) { + token = lexer.next(); + expr = token.method.bind(this, expr, this._parseBinary(lexer, precedence - 1)); + token = lexer.peek(); + } + return expr; + }; + /** + * Match a unary expression. + * @param {Lexer} lexer + * @private + */ + Tone.TimeBase.prototype._parseUnary = function (lexer) { + var token, expr; + token = lexer.peek(); + var op = this._matchGroup(token, this._unaryExpressions); + if (op) { + token = lexer.next(); + expr = this._parseUnary(lexer); + return op.method.bind(this, expr); + } + return this._parsePrimary(lexer); + }; + /** + * Match a primary expression (a value). + * @param {Lexer} lexer + * @private + */ + Tone.TimeBase.prototype._parsePrimary = function (lexer) { + var token, expr; + token = lexer.peek(); + if (this.isUndef(token)) { + throw new SyntaxError('Tone.TimeBase: Unexpected end of expression'); + } + if (this._matchGroup(token, this._primaryExpressions)) { + token = lexer.next(); + var matching = token.value.match(token.regexp); + return token.method.bind(this, matching[1], matching[2], matching[3]); + } + if (token && token.value === '(') { + lexer.next(); + expr = this._parseBinary(lexer); + token = lexer.next(); + if (!(token && token.value === ')')) { + throw new SyntaxError('Expected )'); + } + return expr; + } + throw new SyntaxError('Tone.TimeBase: Cannot process token ' + token.value); + }; + /** + * Recursively parse the string expression into a syntax tree. + * @param {string} expr + * @return {Function} the bound method to be evaluated later + * @private + */ + Tone.TimeBase.prototype._parseExprString = function (exprString) { + if (!this.isString(exprString)) { + exprString = exprString.toString(); + } + var lexer = this._tokenize(exprString); + var tree = this._parseBinary(lexer); + return tree; + }; + /////////////////////////////////////////////////////////////////////////// + // DEFAULTS + /////////////////////////////////////////////////////////////////////////// + /** + * The initial expression value + * @return {Number} The initial value 0 + * @private + */ + Tone.TimeBase.prototype._noOp = function () { + return 0; + }; + /** + * The default expression value if no arguments are given + * @private + */ + Tone.TimeBase.prototype._defaultExpr = function () { + return this._noOp; + }; + /** + * The default units if none are given. + * @private + */ + Tone.TimeBase.prototype._defaultUnits = 's'; + /////////////////////////////////////////////////////////////////////////// + // UNIT CONVERSIONS + /////////////////////////////////////////////////////////////////////////// + /** + * Returns the value of a frequency in the current units + * @param {Frequency} freq + * @return {Number} + * @private + */ + Tone.TimeBase.prototype._frequencyToUnits = function (freq) { + return 1 / freq; + }; + /** + * Return the value of the beats in the current units + * @param {Number} beats + * @return {Number} + * @private + */ + Tone.TimeBase.prototype._beatsToUnits = function (beats) { + return 60 / Tone.Transport.bpm.value * beats; + }; + /** + * Returns the value of a second in the current units + * @param {Seconds} seconds + * @return {Number} + * @private + */ + Tone.TimeBase.prototype._secondsToUnits = function (seconds) { + return seconds; + }; + /** + * Returns the value of a tick in the current time units + * @param {Ticks} ticks + * @return {Number} + * @private + */ + Tone.TimeBase.prototype._ticksToUnits = function (ticks) { + return ticks * (this._beatsToUnits(1) / Tone.Transport.PPQ); + }; + /** + * Return the time signature. + * @return {Number} + * @private + */ + Tone.TimeBase.prototype._timeSignature = function () { + return Tone.Transport.timeSignature; + }; + /////////////////////////////////////////////////////////////////////////// + // EXPRESSIONS + /////////////////////////////////////////////////////////////////////////// + /** + * Push an expression onto the expression list + * @param {Time} val + * @param {String} type + * @param {String} units + * @return {Tone.TimeBase} + * @private + */ + Tone.TimeBase.prototype._pushExpr = function (val, name, units) { + //create the expression + if (!(val instanceof Tone.TimeBase)) { + val = new this.constructor(val, units); + } + this._expr = this._binaryExpressions[name].method.bind(this, this._expr, val._expr); + return this; + }; + /** + * Add to the current value. + * @param {Time} val The value to add + * @param {String=} units Optional units to use with the value. + * @return {Tone.TimeBase} this + * @example + * Tone.TimeBase("2m").add("1m"); //"3m" + */ + Tone.TimeBase.prototype.add = function (val, units) { + return this._pushExpr(val, '+', units); + }; + /** + * Subtract the value from the current time. + * @param {Time} val The value to subtract + * @param {String=} units Optional units to use with the value. + * @return {Tone.TimeBase} this + * @example + * Tone.TimeBase("2m").sub("1m"); //"1m" + */ + Tone.TimeBase.prototype.sub = function (val, units) { + return this._pushExpr(val, '-', units); + }; + /** + * Multiply the current value by the given time. + * @param {Time} val The value to multiply + * @param {String=} units Optional units to use with the value. + * @return {Tone.TimeBase} this + * @example + * Tone.TimeBase("2m").mult("2"); //"4m" + */ + Tone.TimeBase.prototype.mult = function (val, units) { + return this._pushExpr(val, '*', units); + }; + /** + * Divide the current value by the given time. + * @param {Time} val The value to divide by + * @param {String=} units Optional units to use with the value. + * @return {Tone.TimeBase} this + * @example + * Tone.TimeBase("2m").div(2); //"1m" + */ + Tone.TimeBase.prototype.div = function (val, units) { + return this._pushExpr(val, '/', units); + }; + /** + * Evaluate the time value. Returns the time + * in seconds. + * @return {Seconds} + */ + Tone.TimeBase.prototype.eval = function () { + return this._expr(); + }; + /** + * Clean up + * @return {Tone.TimeBase} this + */ + Tone.TimeBase.prototype.dispose = function () { + this._expr = null; + }; + return Tone.TimeBase; + }); + Module(function (Tone) { + /** + * @class Tone.Time is a primitive type for encoding Time values. + * Eventually all time values are evaluated to seconds + * using the `eval` method. Tone.Time can be constructed + * with or without the `new` keyword. Tone.Time can be passed + * into the parameter of any method which takes time as an argument. + * @constructor + * @extends {Tone.TimeBase} + * @param {String|Number} val The time value. + * @param {String=} units The units of the value. + * @example + * var t = Tone.Time("4n");//encodes a quarter note + * t.mult(4); // multiply that value by 4 + * t.toNotation(); //returns "1m" + */ + Tone.Time = function (val, units) { + if (this instanceof Tone.Time) { + /** + * If the current clock time should + * be added to the output + * @type {Boolean} + * @private + */ + this._plusNow = false; + Tone.TimeBase.call(this, val, units); + } else { + return new Tone.Time(val, units); + } + }; + Tone.extend(Tone.Time, Tone.TimeBase); + //clone the expressions so that + //we can add more without modifying the original + Tone.Time.prototype._unaryExpressions = Object.create(Tone.TimeBase.prototype._unaryExpressions); + /* + * Adds an additional unary expression + * which quantizes values to the next subdivision + * @type {Object} + * @private + */ + Tone.Time.prototype._unaryExpressions.quantize = { + regexp: /^@/, + method: function (rh) { + return Tone.Transport.nextSubdivision(rh()); + } + }; + /* + * Adds an additional unary expression + * which adds the current clock time. + * @type {Object} + * @private + */ + Tone.Time.prototype._unaryExpressions.now = { + regexp: /^\+/, + method: function (lh) { + this._plusNow = true; + return lh(); + } + }; + /** + * Quantize the time by the given subdivision. Optionally add a + * percentage which will move the time value towards the ideal + * quantized value by that percentage. + * @param {Number|Time} val The subdivision to quantize to + * @param {NormalRange} [percent=1] Move the time value + * towards the quantized value by + * a percentage. + * @return {Tone.Time} this + * @example + * Tone.Time(21).quantize(2).eval() //returns 22 + * Tone.Time(0.6).quantize("4n", 0.5).eval() //returns 0.55 + */ + Tone.Time.prototype.quantize = function (subdiv, percent) { + percent = this.defaultArg(percent, 1); + this._expr = function (expr, subdivision, percent) { + expr = expr(); + subdivision = subdivision.toSeconds(); + var multiple = Math.round(expr / subdivision); + var ideal = multiple * subdivision; + var diff = ideal - expr; + return expr + diff * percent; + }.bind(this, this._expr, new this.constructor(subdiv), percent); + return this; + }; + /** + * Adds the clock time to the time expression at the + * moment of evaluation. + * @return {Tone.Time} this + */ + Tone.Time.prototype.addNow = function () { + this._plusNow = true; + return this; + }; + /** + * @override + * Override the default value return when no arguments are passed in. + * The default value is 'now' + * @private + */ + Tone.Time.prototype._defaultExpr = function () { + this._plusNow = true; + return this._noOp; + }; + /** + * Copies the value of time to this Time + * @param {Tone.Time} time + * @return {Time} + */ + Tone.Time.prototype.copy = function (time) { + Tone.TimeBase.prototype.copy.call(this, time); + this._plusNow = time._plusNow; + return this; + }; + //CONVERSIONS////////////////////////////////////////////////////////////// + /** + * Convert a Time to Notation. Values will be thresholded to the nearest 128th note. + * @return {Notation} + * @example + * //if the Transport is at 120bpm: + * Tone.Time(2).toNotation();//returns "1m" + */ + Tone.Time.prototype.toNotation = function () { + var time = this.toSeconds(); + var testNotations = [ + '1m', + '2n', + '4n', + '8n', + '16n', + '32n', + '64n', + '128n' + ]; + var retNotation = this._toNotationHelper(time, testNotations); + //try the same thing but with tripelets + var testTripletNotations = [ + '1m', + '2n', + '2t', + '4n', + '4t', + '8n', + '8t', + '16n', + '16t', + '32n', + '32t', + '64n', + '64t', + '128n' + ]; + var retTripletNotation = this._toNotationHelper(time, testTripletNotations); + //choose the simpler expression of the two + if (retTripletNotation.split('+').length < retNotation.split('+').length) { + return retTripletNotation; + } else { + return retNotation; + } + }; + /** + * Helper method for Tone.toNotation + * @param {Number} units + * @param {Array} testNotations + * @return {String} + * @private + */ + Tone.Time.prototype._toNotationHelper = function (units, testNotations) { + //the threshold is the last value in the array + var threshold = this._notationToUnits(testNotations[testNotations.length - 1]); + var retNotation = ''; + for (var i = 0; i < testNotations.length; i++) { + var notationTime = this._notationToUnits(testNotations[i]); + //account for floating point errors (i.e. round up if the value is 0.999999) + var multiple = units / notationTime; + var floatingPointError = 0.000001; + if (1 - multiple % 1 < floatingPointError) { + multiple += floatingPointError; + } + multiple = Math.floor(multiple); + if (multiple > 0) { + if (multiple === 1) { + retNotation += testNotations[i]; + } else { + retNotation += multiple.toString() + '*' + testNotations[i]; + } + units -= multiple * notationTime; + if (units < threshold) { + break; + } else { + retNotation += ' + '; + } + } + } + if (retNotation === '') { + retNotation = '0'; + } + return retNotation; + }; + /** + * Convert a notation value to the current units + * @param {Notation} notation + * @return {Number} + * @private + */ + Tone.Time.prototype._notationToUnits = function (notation) { + var primaryExprs = this._primaryExpressions; + var notationExprs = [ + primaryExprs.n, + primaryExprs.t, + primaryExprs.m + ]; + for (var i = 0; i < notationExprs.length; i++) { + var expr = notationExprs[i]; + var match = notation.match(expr.regexp); + if (match) { + return expr.method.call(this, match[1]); + } + } + }; + /** + * Return the time encoded as Bars:Beats:Sixteenths. + * @return {BarsBeatsSixteenths} + */ + Tone.Time.prototype.toBarsBeatsSixteenths = function () { + var quarterTime = this._beatsToUnits(1); + var quarters = this.toSeconds() / quarterTime; + var measures = Math.floor(quarters / this._timeSignature()); + var sixteenths = quarters % 1 * 4; + quarters = Math.floor(quarters) % this._timeSignature(); + sixteenths = sixteenths.toString(); + if (sixteenths.length > 3) { + sixteenths = parseFloat(sixteenths).toFixed(3); + } + var progress = [ + measures, + quarters, + sixteenths + ]; + return progress.join(':'); + }; + /** + * Return the time in ticks. + * @return {Ticks} + */ + Tone.Time.prototype.toTicks = function () { + var quarterTime = this._beatsToUnits(1); + var quarters = this.eval() / quarterTime; + return Math.floor(quarters * Tone.Transport.PPQ); + }; + /** + * Return the time in samples + * @return {Samples} + */ + Tone.Time.prototype.toSamples = function () { + return this.toSeconds() * this.context.sampleRate; + }; + /** + * Return the time as a frequency value + * @return {Frequency} + * @example + * Tone.Time(2).toFrequency(); //0.5 + */ + Tone.Time.prototype.toFrequency = function () { + return 1 / this.toSeconds(); + }; + /** + * Return the time in seconds. + * @return {Seconds} + */ + Tone.Time.prototype.toSeconds = function () { + return this.eval(); + }; + /** + * Return the time in milliseconds. + * @return {Milliseconds} + */ + Tone.Time.prototype.toMilliseconds = function () { + return this.toSeconds() * 1000; + }; + /** + * Return the time in seconds. + * @return {Seconds} + */ + Tone.Time.prototype.eval = function () { + var val = this._expr(); + return val + (this._plusNow ? this.now() : 0); + }; + return Tone.Time; + }); + Module(function (Tone) { + /** + * @class Tone.Frequency is a primitive type for encoding Frequency values. + * Eventually all time values are evaluated to hertz + * using the `eval` method. + * @constructor + * @extends {Tone.TimeBase} + * @param {String|Number} val The time value. + * @param {String=} units The units of the value. + * @example + * Tone.Frequency("C3").eval() // 261 + * Tone.Frequency(38, "midi").eval() // + * Tone.Frequency("C3").transpose(4).eval(); + */ + Tone.Frequency = function (val, units) { + if (this instanceof Tone.Frequency) { + Tone.TimeBase.call(this, val, units); + } else { + return new Tone.Frequency(val, units); + } + }; + Tone.extend(Tone.Frequency, Tone.TimeBase); + /////////////////////////////////////////////////////////////////////////// + // AUGMENT BASE EXPRESSIONS + /////////////////////////////////////////////////////////////////////////// + //clone the expressions so that + //we can add more without modifying the original + Tone.Frequency.prototype._primaryExpressions = Object.create(Tone.TimeBase.prototype._primaryExpressions); + /* + * midi type primary expression + * @type {Object} + * @private + */ + Tone.Frequency.prototype._primaryExpressions.midi = { + regexp: /^(\d+(?:\.\d+)?midi)/, + method: function (value) { + return this.midiToFrequency(value); + } + }; + /* + * note type primary expression + * @type {Object} + * @private + */ + Tone.Frequency.prototype._primaryExpressions.note = { + regexp: /^([a-g]{1}(?:b|#|x|bb)?)(-?[0-9]+)/i, + method: function (pitch, octave) { + var index = noteToScaleIndex[pitch.toLowerCase()]; + var noteNumber = index + (parseInt(octave) + 1) * 12; + return this.midiToFrequency(noteNumber); + } + }; + /* + * BeatsBarsSixteenths type primary expression + * @type {Object} + * @private + */ + Tone.Frequency.prototype._primaryExpressions.tr = { + regexp: /^(\d+(?:\.\d+)?):(\d+(?:\.\d+)?):?(\d+(?:\.\d+)?)?/, + method: function (m, q, s) { + var total = 1; + if (m && m !== '0') { + total *= this._beatsToUnits(this._timeSignature() * parseFloat(m)); + } + if (q && q !== '0') { + total *= this._beatsToUnits(parseFloat(q)); + } + if (s && s !== '0') { + total *= this._beatsToUnits(parseFloat(s) / 4); + } + return total; + } + }; + /////////////////////////////////////////////////////////////////////////// + // EXPRESSIONS + /////////////////////////////////////////////////////////////////////////// + /** + * Transposes the frequency by the given number of semitones. + * @param {Interval} interval + * @return {Tone.Frequency} this + * @example + * Tone.Frequency("A4").transpose(3); //"C5" + */ + Tone.Frequency.prototype.transpose = function (interval) { + this._expr = function (expr, interval) { + var val = expr(); + return val * this.intervalToFrequencyRatio(interval); + }.bind(this, this._expr, interval); + return this; + }; + /** + * Takes an array of semitone intervals and returns + * an array of frequencies transposed by those intervals. + * @param {Array} intervals + * @return {Tone.Frequency} this + * @example + * Tone.Frequency("A4").harmonize([0, 3, 7]); //["A4", "C5", "E5"] + */ + Tone.Frequency.prototype.harmonize = function (intervals) { + this._expr = function (expr, intervals) { + var val = expr(); + var ret = []; + for (var i = 0; i < intervals.length; i++) { + ret[i] = val * this.intervalToFrequencyRatio(intervals[i]); + } + return ret; + }.bind(this, this._expr, intervals); + return this; + }; + /////////////////////////////////////////////////////////////////////////// + // UNIT CONVERSIONS + /////////////////////////////////////////////////////////////////////////// + /** + * Return the value of the frequency as a MIDI note + * @return {MIDI} + * @example + * Tone.Frequency("C4").toMidi(); //60 + */ + Tone.Frequency.prototype.toMidi = function () { + return this.frequencyToMidi(this.eval()); + }; + /** + * Return the value of the frequency in Scientific Pitch Notation + * @return {Note} + * @example + * Tone.Frequency(69, "midi").toNote(); //"A4" + */ + Tone.Frequency.prototype.toNote = function () { + var freq = this.eval(); + var log = Math.log(freq / Tone.Frequency.A4) / Math.LN2; + var noteNumber = Math.round(12 * log) + 57; + var octave = Math.floor(noteNumber / 12); + if (octave < 0) { + noteNumber += -12 * octave; + } + var noteName = scaleIndexToNote[noteNumber % 12]; + return noteName + octave.toString(); + }; + /** + * Return the duration of one cycle in seconds. + * @return {Seconds} + */ + Tone.Frequency.prototype.toSeconds = function () { + return 1 / this.eval(); + }; + /** + * Return the value in Hertz + * @return {Frequency} + */ + Tone.Frequency.prototype.toFrequency = function () { + return this.eval(); + }; + /** + * Return the duration of one cycle in ticks + * @return {Ticks} + */ + Tone.Frequency.prototype.toTicks = function () { + var quarterTime = this._beatsToUnits(1); + var quarters = this.eval() / quarterTime; + return Math.floor(quarters * Tone.Transport.PPQ); + }; + /////////////////////////////////////////////////////////////////////////// + // UNIT CONVERSIONS HELPERS + /////////////////////////////////////////////////////////////////////////// + /** + * Returns the value of a frequency in the current units + * @param {Frequency} freq + * @return {Number} + * @private + */ + Tone.Frequency.prototype._frequencyToUnits = function (freq) { + return freq; + }; + /** + * Returns the value of a tick in the current time units + * @param {Ticks} ticks + * @return {Number} + * @private + */ + Tone.Frequency.prototype._ticksToUnits = function (ticks) { + return 1 / (ticks * 60 / (Tone.Transport.bpm.value * Tone.Transport.PPQ)); + }; + /** + * Return the value of the beats in the current units + * @param {Number} beats + * @return {Number} + * @private + */ + Tone.Frequency.prototype._beatsToUnits = function (beats) { + return 1 / Tone.TimeBase.prototype._beatsToUnits.call(this, beats); + }; + /** + * Returns the value of a second in the current units + * @param {Seconds} seconds + * @return {Number} + * @private + */ + Tone.Frequency.prototype._secondsToUnits = function (seconds) { + return 1 / seconds; + }; + /** + * The default units if none are given. + * @private + */ + Tone.Frequency.prototype._defaultUnits = 'hz'; + /////////////////////////////////////////////////////////////////////////// + // FREQUENCY CONVERSIONS + /////////////////////////////////////////////////////////////////////////// + /** + * Note to scale index + * @type {Object} + */ + var noteToScaleIndex = { + 'cbb': -2, + 'cb': -1, + 'c': 0, + 'c#': 1, + 'cx': 2, + 'dbb': 0, + 'db': 1, + 'd': 2, + 'd#': 3, + 'dx': 4, + 'ebb': 2, + 'eb': 3, + 'e': 4, + 'e#': 5, + 'ex': 6, + 'fbb': 3, + 'fb': 4, + 'f': 5, + 'f#': 6, + 'fx': 7, + 'gbb': 5, + 'gb': 6, + 'g': 7, + 'g#': 8, + 'gx': 9, + 'abb': 7, + 'ab': 8, + 'a': 9, + 'a#': 10, + 'ax': 11, + 'bbb': 9, + 'bb': 10, + 'b': 11, + 'b#': 12, + 'bx': 13 + }; + /** + * scale index to note (sharps) + * @type {Array} + */ + var scaleIndexToNote = [ + 'C', + 'C#', + 'D', + 'D#', + 'E', + 'F', + 'F#', + 'G', + 'G#', + 'A', + 'A#', + 'B' + ]; + /** + * The [concert pitch](https://en.wikipedia.org/wiki/Concert_pitch) + * A4's values in Hertz. + * @type {Frequency} + * @static + */ + Tone.Frequency.A4 = 440; + /** + * Convert a MIDI note to frequency value. + * @param {MIDI} midi The midi number to convert. + * @return {Frequency} the corresponding frequency value + * @example + * tone.midiToFrequency(69); // returns 440 + */ + Tone.Frequency.prototype.midiToFrequency = function (midi) { + return Tone.Frequency.A4 * Math.pow(2, (midi - 69) / 12); + }; + /** + * Convert a frequency value to a MIDI note. + * @param {Frequency} frequency The value to frequency value to convert. + * @returns {MIDI} + * @example + * tone.midiToFrequency(440); // returns 69 + */ + Tone.Frequency.prototype.frequencyToMidi = function (frequency) { + return 69 + 12 * Math.log(frequency / Tone.Frequency.A4) / Math.LN2; + }; + return Tone.Frequency; + }); + Module(function (Tone) { + /** + * @class Tone.TransportTime is a the time along the Transport's + * timeline. It is similar to Tone.Time, but instead of evaluating + * against the AudioContext's clock, it is evaluated against + * the Transport's position. See [TransportTime wiki](https://github.com/Tonejs/Tone.js/wiki/TransportTime). + * @constructor + * @param {Time} val The time value as a number or string + * @param {String=} units Unit values + * @extends {Tone.Time} + */ + Tone.TransportTime = function (val, units) { + if (this instanceof Tone.TransportTime) { + Tone.Time.call(this, val, units); + } else { + return new Tone.TransportTime(val, units); + } + }; + Tone.extend(Tone.TransportTime, Tone.Time); + //clone the expressions so that + //we can add more without modifying the original + Tone.TransportTime.prototype._unaryExpressions = Object.create(Tone.Time.prototype._unaryExpressions); + /** + * Adds an additional unary expression + * which quantizes values to the next subdivision + * @type {Object} + * @private + */ + Tone.TransportTime.prototype._unaryExpressions.quantize = { + regexp: /^@/, + method: function (rh) { + var subdivision = this._secondsToTicks(rh()); + var multiple = Math.ceil(Tone.Transport.ticks / subdivision); + return this._ticksToUnits(multiple * subdivision); + } + }; + /** + * Convert seconds into ticks + * @param {Seconds} seconds + * @return {Ticks} + * @private + */ + Tone.TransportTime.prototype._secondsToTicks = function (seconds) { + var quarterTime = this._beatsToUnits(1); + var quarters = seconds / quarterTime; + return Math.round(quarters * Tone.Transport.PPQ); + }; + /** + * Evaluate the time expression. Returns values in ticks + * @return {Ticks} + */ + Tone.TransportTime.prototype.eval = function () { + var val = this._secondsToTicks(this._expr()); + return val + (this._plusNow ? Tone.Transport.ticks : 0); + }; + /** + * Return the time in ticks. + * @return {Ticks} + */ + Tone.TransportTime.prototype.toTicks = function () { + return this.eval(); + }; + /** + * Return the time in seconds. + * @return {Seconds} + */ + Tone.TransportTime.prototype.toSeconds = function () { + var val = this._expr(); + return val + (this._plusNow ? Tone.Transport.seconds : 0); + }; + /** + * Return the time as a frequency value + * @return {Frequency} + */ + Tone.TransportTime.prototype.toFrequency = function () { + return 1 / this.toSeconds(); + }; + return Tone.TransportTime; + }); + Module(function (Tone) { + /////////////////////////////////////////////////////////////////////////// + // TYPES + /////////////////////////////////////////////////////////////////////////// + /** + * Units which a value can take on. + * @enum {String} + */ + Tone.Type = { + /** + * Default units + * @typedef {Default} + */ + Default: 'number', + /** + * Time can be described in a number of ways. Read more [Time](https://github.com/Tonejs/Tone.js/wiki/Time). + * + *
    + *
  • Numbers, which will be taken literally as the time (in seconds).
  • + *
  • Notation, ("4n", "8t") describes time in BPM and time signature relative values.
  • + *
  • TransportTime, ("4:3:2") will also provide tempo and time signature relative times + * in the form BARS:QUARTERS:SIXTEENTHS.
  • + *
  • Frequency, ("8hz") is converted to the length of the cycle in seconds.
  • + *
  • Now-Relative, ("+1") prefix any of the above with "+" and it will be interpreted as + * "the current time plus whatever expression follows".
  • + *
  • Expressions, ("3:0 + 2 - (1m / 7)") any of the above can also be combined + * into a mathematical expression which will be evaluated to compute the desired time.
  • + *
  • No Argument, for methods which accept time, no argument will be interpreted as + * "now" (i.e. the currentTime).
  • + *
+ * + * @typedef {Time} + */ + Time: 'time', + /** + * Frequency can be described similar to time, except ultimately the + * values are converted to frequency instead of seconds. A number + * is taken literally as the value in hertz. Additionally any of the + * Time encodings can be used. Note names in the form + * of NOTE OCTAVE (i.e. C4) are also accepted and converted to their + * frequency value. + * @typedef {Frequency} + */ + Frequency: 'frequency', + /** + * TransportTime describes a position along the Transport's timeline. It is + * similar to Time in that it uses all the same encodings, but TransportTime specifically + * pertains to the Transport's timeline, which is startable, stoppable, loopable, and seekable. + * [Read more](https://github.com/Tonejs/Tone.js/wiki/TransportTime) + * @typedef {TransportTime} + */ + TransportTime: 'transportTime', + /** + * Ticks are the basic subunit of the Transport. They are + * the smallest unit of time that the Transport supports. + * @typedef {Ticks} + */ + Ticks: 'ticks', + /** + * Normal values are within the range [0, 1]. + * @typedef {NormalRange} + */ + NormalRange: 'normalRange', + /** + * AudioRange values are between [-1, 1]. + * @typedef {AudioRange} + */ + AudioRange: 'audioRange', + /** + * Decibels are a logarithmic unit of measurement which is useful for volume + * because of the logarithmic way that we perceive loudness. 0 decibels + * means no change in volume. -10db is approximately half as loud and 10db + * is twice is loud. + * @typedef {Decibels} + */ + Decibels: 'db', + /** + * Half-step note increments, i.e. 12 is an octave above the root. and 1 is a half-step up. + * @typedef {Interval} + */ + Interval: 'interval', + /** + * Beats per minute. + * @typedef {BPM} + */ + BPM: 'bpm', + /** + * The value must be greater than or equal to 0. + * @typedef {Positive} + */ + Positive: 'positive', + /** + * A cent is a hundredth of a semitone. + * @typedef {Cents} + */ + Cents: 'cents', + /** + * Angle between 0 and 360. + * @typedef {Degrees} + */ + Degrees: 'degrees', + /** + * A number representing a midi note. + * @typedef {MIDI} + */ + MIDI: 'midi', + /** + * A colon-separated representation of time in the form of + * Bars:Beats:Sixteenths. + * @typedef {BarsBeatsSixteenths} + */ + BarsBeatsSixteenths: 'barsBeatsSixteenths', + /** + * Sampling is the reduction of a continuous signal to a discrete signal. + * Audio is typically sampled 44100 times per second. + * @typedef {Samples} + */ + Samples: 'samples', + /** + * Hertz are a frequency representation defined as one cycle per second. + * @typedef {Hertz} + */ + Hertz: 'hertz', + /** + * A frequency represented by a letter name, + * accidental and octave. This system is known as + * [Scientific Pitch Notation](https://en.wikipedia.org/wiki/Scientific_pitch_notation). + * @typedef {Note} + */ + Note: 'note', + /** + * One millisecond is a thousandth of a second. + * @typedef {Milliseconds} + */ + Milliseconds: 'milliseconds', + /** + * Seconds are the time unit of the AudioContext. In the end, + * all values need to be evaluated to seconds. + * @typedef {Seconds} + */ + Seconds: 'seconds', + /** + * A string representing a duration relative to a measure. + *
    + *
  • "4n" = quarter note
  • + *
  • "2m" = two measures
  • + *
  • "8t" = eighth-note triplet
  • + *
+ * @typedef {Notation} + */ + Notation: 'notation' + }; + /////////////////////////////////////////////////////////////////////////// + // AUGMENT TONE's PROTOTYPE + /////////////////////////////////////////////////////////////////////////// + /** + * Convert Time into seconds. + * + * Unlike the method which it overrides, this takes into account + * transporttime and musical notation. + * + * Time : 1.40 + * Notation: 4n|1m|2t + * Now Relative: +3n + * Math: 3n+16n or even complicated expressions ((3n*2)/6 + 1) + * + * @param {Time} time + * @return {Seconds} + */ + Tone.prototype.toSeconds = function (time) { + if (this.isNumber(time)) { + return time; + } else if (this.isUndef(time)) { + return this.now(); + } else if (this.isString(time)) { + return new Tone.Time(time).toSeconds(); + } else if (time instanceof Tone.TimeBase) { + return time.toSeconds(); + } + }; + /** + * Convert a frequency representation into a number. + * @param {Frequency} freq + * @return {Hertz} the frequency in hertz + */ + Tone.prototype.toFrequency = function (freq) { + if (this.isNumber(freq)) { + return freq; + } else if (this.isString(freq) || this.isUndef(freq)) { + return new Tone.Frequency(freq).eval(); + } else if (freq instanceof Tone.TimeBase) { + return freq.toFrequency(); + } + }; + /** + * Convert a time representation into ticks. + * @param {Time} time + * @return {Ticks} the time in ticks + */ + Tone.prototype.toTicks = function (time) { + if (this.isNumber(time) || this.isString(time)) { + return new Tone.TransportTime(time).toTicks(); + } else if (this.isUndef(time)) { + return Tone.Transport.ticks; + } else if (time instanceof Tone.TimeBase) { + return time.toTicks(); + } + }; + return Tone; + }); + Module(function (Tone) { + + /** + * @class Tone.Param wraps the native Web Audio's AudioParam to provide + * additional unit conversion functionality. It also + * serves as a base-class for classes which have a single, + * automatable parameter. + * @extends {Tone} + * @param {AudioParam} param The parameter to wrap. + * @param {Tone.Type} units The units of the audio param. + * @param {Boolean} convert If the param should be converted. + */ + Tone.Param = function () { + var options = this.optionsObject(arguments, [ + 'param', + 'units', + 'convert' + ], Tone.Param.defaults); + /** + * The native parameter to control + * @type {AudioParam} + * @private + */ + this._param = this.input = options.param; + /** + * The units of the parameter + * @type {Tone.Type} + */ + this.units = options.units; + /** + * If the value should be converted or not + * @type {Boolean} + */ + this.convert = options.convert; + /** + * True if the signal value is being overridden by + * a connected signal. + * @readOnly + * @type {boolean} + * @private + */ + this.overridden = false; + /** + * If there is an LFO, this is where it is held. + * @type {Tone.LFO} + * @private + */ + this._lfo = null; + if (this.isObject(options.lfo)) { + this.value = options.lfo; + } else if (!this.isUndef(options.value)) { + this.value = options.value; + } + }; + Tone.extend(Tone.Param); + /** + * Defaults + * @type {Object} + * @const + */ + Tone.Param.defaults = { + 'units': Tone.Type.Default, + 'convert': true, + 'param': undefined + }; + /** + * The current value of the parameter. + * @memberOf Tone.Param# + * @type {Number} + * @name value + */ + Object.defineProperty(Tone.Param.prototype, 'value', { + get: function () { + return this._toUnits(this._param.value); + }, + set: function (value) { + if (this.isObject(value)) { + //throw an error if the LFO needs to be included + if (this.isUndef(Tone.LFO)) { + throw new Error('Include \'Tone.LFO\' to use an LFO as a Param value.'); + } + //remove the old one + if (this._lfo) { + this._lfo.dispose(); + } + this._lfo = new Tone.LFO(value).start(); + this._lfo.connect(this.input); + } else { + var convertedVal = this._fromUnits(value); + this._param.cancelScheduledValues(0); + this._param.value = convertedVal; + } + } + }); + /** + * Convert the given value from the type specified by Tone.Param.units + * into the destination value (such as Gain or Frequency). + * @private + * @param {*} val the value to convert + * @return {number} the number which the value should be set to + */ + Tone.Param.prototype._fromUnits = function (val) { + if (this.convert || this.isUndef(this.convert)) { + switch (this.units) { + case Tone.Type.Time: + return this.toSeconds(val); + case Tone.Type.Frequency: + return this.toFrequency(val); + case Tone.Type.Decibels: + return this.dbToGain(val); + case Tone.Type.NormalRange: + return Math.min(Math.max(val, 0), 1); + case Tone.Type.AudioRange: + return Math.min(Math.max(val, -1), 1); + case Tone.Type.Positive: + return Math.max(val, 0); + default: + return val; + } + } else { + return val; + } + }; + /** + * Convert the parameters value into the units specified by Tone.Param.units. + * @private + * @param {number} val the value to convert + * @return {number} + */ + Tone.Param.prototype._toUnits = function (val) { + if (this.convert || this.isUndef(this.convert)) { + switch (this.units) { + case Tone.Type.Decibels: + return this.gainToDb(val); + default: + return val; + } + } else { + return val; + } + }; + /** + * the minimum output value + * @type {Number} + * @private + */ + Tone.Param.prototype._minOutput = 0.00001; + /** + * Schedules a parameter value change at the given time. + * @param {*} value The value to set the signal. + * @param {Time} time The time when the change should occur. + * @returns {Tone.Param} this + * @example + * //set the frequency to "G4" in exactly 1 second from now. + * freq.setValueAtTime("G4", "+1"); + */ + Tone.Param.prototype.setValueAtTime = function (value, time) { + value = this._fromUnits(value); + time = this.toSeconds(time); + if (time <= this.now() + this.blockTime) { + this._param.value = value; + } else { + this._param.setValueAtTime(value, time); + } + return this; + }; + /** + * Creates a schedule point with the current value at the current time. + * This is useful for creating an automation anchor point in order to + * schedule changes from the current value. + * + * @param {number=} now (Optionally) pass the now value in. + * @returns {Tone.Param} this + */ + Tone.Param.prototype.setRampPoint = function (now) { + now = this.defaultArg(now, this.now()); + var currentVal = this._param.value; + // exponentialRampToValueAt cannot ever ramp from or to 0 + // More info: https://bugzilla.mozilla.org/show_bug.cgi?id=1125600#c2 + if (currentVal === 0) { + currentVal = this._minOutput; + } + this._param.setValueAtTime(currentVal, now); + return this; + }; + /** + * Schedules a linear continuous change in parameter value from the + * previous scheduled parameter value to the given value. + * + * @param {number} value + * @param {Time} endTime + * @returns {Tone.Param} this + */ + Tone.Param.prototype.linearRampToValueAtTime = function (value, endTime) { + value = this._fromUnits(value); + this._param.linearRampToValueAtTime(value, this.toSeconds(endTime)); + return this; + }; + /** + * Schedules an exponential continuous change in parameter value from + * the previous scheduled parameter value to the given value. + * + * @param {number} value + * @param {Time} endTime + * @returns {Tone.Param} this + */ + Tone.Param.prototype.exponentialRampToValueAtTime = function (value, endTime) { + value = this._fromUnits(value); + value = Math.max(this._minOutput, value); + this._param.exponentialRampToValueAtTime(value, this.toSeconds(endTime)); + return this; + }; + /** + * Schedules an exponential continuous change in parameter value from + * the current time and current value to the given value over the + * duration of the rampTime. + * + * @param {number} value The value to ramp to. + * @param {Time} rampTime the time that it takes the + * value to ramp from it's current value + * @param {Time} [startTime=now] When the ramp should start. + * @returns {Tone.Param} this + * @example + * //exponentially ramp to the value 2 over 4 seconds. + * signal.exponentialRampToValue(2, 4); + */ + Tone.Param.prototype.exponentialRampToValue = function (value, rampTime, startTime) { + startTime = this.toSeconds(startTime); + this.setRampPoint(startTime); + this.exponentialRampToValueAtTime(value, startTime + this.toSeconds(rampTime)); + return this; + }; + /** + * Schedules an linear continuous change in parameter value from + * the current time and current value to the given value over the + * duration of the rampTime. + * + * @param {number} value The value to ramp to. + * @param {Time} rampTime the time that it takes the + * value to ramp from it's current value + * @param {Time} [startTime=now] When the ramp should start. + * @returns {Tone.Param} this + * @example + * //linearly ramp to the value 4 over 3 seconds. + * signal.linearRampToValue(4, 3); + */ + Tone.Param.prototype.linearRampToValue = function (value, rampTime, startTime) { + startTime = this.toSeconds(startTime); + this.setRampPoint(startTime); + this.linearRampToValueAtTime(value, startTime + this.toSeconds(rampTime)); + return this; + }; + /** + * Start exponentially approaching the target value at the given time with + * a rate having the given time constant. + * @param {number} value + * @param {Time} startTime + * @param {number} timeConstant + * @returns {Tone.Param} this + */ + Tone.Param.prototype.setTargetAtTime = function (value, startTime, timeConstant) { + value = this._fromUnits(value); + // The value will never be able to approach without timeConstant > 0. + // http://www.w3.org/TR/webaudio/#dfn-setTargetAtTime, where the equation + // is described. 0 results in a division by 0. + value = Math.max(this._minOutput, value); + timeConstant = Math.max(this._minOutput, timeConstant); + this._param.setTargetAtTime(value, this.toSeconds(startTime), timeConstant); + return this; + }; + /** + * Sets an array of arbitrary parameter values starting at the given time + * for the given duration. + * + * @param {Array} values + * @param {Time} startTime + * @param {Time} duration + * @returns {Tone.Param} this + */ + Tone.Param.prototype.setValueCurveAtTime = function (values, startTime, duration) { + for (var i = 0; i < values.length; i++) { + values[i] = this._fromUnits(values[i]); + } + this._param.setValueCurveAtTime(values, this.toSeconds(startTime), this.toSeconds(duration)); + return this; + }; + /** + * Cancels all scheduled parameter changes with times greater than or + * equal to startTime. + * + * @param {Time} startTime + * @returns {Tone.Param} this + */ + Tone.Param.prototype.cancelScheduledValues = function (startTime) { + this._param.cancelScheduledValues(this.toSeconds(startTime)); + return this; + }; + /** + * Ramps to the given value over the duration of the rampTime. + * Automatically selects the best ramp type (exponential or linear) + * depending on the `units` of the signal + * + * @param {number} value + * @param {Time} rampTime The time that it takes the + * value to ramp from it's current value + * @param {Time} [startTime=now] When the ramp should start. + * @returns {Tone.Param} this + * @example + * //ramp to the value either linearly or exponentially + * //depending on the "units" value of the signal + * signal.rampTo(0, 10); + * @example + * //schedule it to ramp starting at a specific time + * signal.rampTo(0, 10, 5) + */ + Tone.Param.prototype.rampTo = function (value, rampTime, startTime) { + rampTime = this.defaultArg(rampTime, 0); + if (this.units === Tone.Type.Frequency || this.units === Tone.Type.BPM) { + this.exponentialRampToValue(value, rampTime, startTime); + } else { + this.linearRampToValue(value, rampTime, startTime); + } + return this; + }; + /** + * The LFO created by the signal instance. If none + * was created, this is null. + * @type {Tone.LFO} + * @readOnly + * @memberOf Tone.Param# + * @name lfo + */ + Object.defineProperty(Tone.Param.prototype, 'lfo', { + get: function () { + return this._lfo; + } + }); + /** + * Clean up + * @returns {Tone.Param} this + */ + Tone.Param.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._param = null; + if (this._lfo) { + this._lfo.dispose(); + this._lfo = null; + } + return this; + }; + return Tone.Param; + }); + Module(function (Tone) { + + /** + * @class A thin wrapper around the Native Web Audio GainNode. + * The GainNode is a basic building block of the Web Audio + * API and is useful for routing audio and adjusting gains. + * @extends {Tone} + * @param {Number=} gain The initial gain of the GainNode + * @param {Tone.Type=} units The units of the gain parameter. + */ + Tone.Gain = function () { + var options = this.optionsObject(arguments, [ + 'gain', + 'units' + ], Tone.Gain.defaults); + /** + * The GainNode + * @type {GainNode} + * @private + */ + this.input = this.output = this._gainNode = this.context.createGain(); + /** + * The gain parameter of the gain node. + * @type {Tone.Param} + * @signal + */ + this.gain = new Tone.Param({ + 'param': this._gainNode.gain, + 'units': options.units, + 'value': options.gain, + 'convert': options.convert + }); + this._readOnly('gain'); + }; + Tone.extend(Tone.Gain); + /** + * The defaults + * @const + * @type {Object} + */ + Tone.Gain.defaults = { + 'gain': 1, + 'convert': true + }; + /** + * Clean up. + * @return {Tone.Gain} this + */ + Tone.Gain.prototype.dispose = function () { + Tone.Param.prototype.dispose.call(this); + this._gainNode.disconnect(); + this._gainNode = null; + this._writable('gain'); + this.gain.dispose(); + this.gain = null; + }; + //STATIC/////////////////////////////////////////////////////////////////// + /** + * Create input and outputs for this object. + * @param {Number} input The number of inputs + * @param {Number=} outputs The number of outputs + * @return {Tone} this + * @internal + */ + Tone.prototype.createInsOuts = function (inputs, outputs) { + if (inputs === 1) { + this.input = new Tone.Gain(); + } else if (inputs > 1) { + this.input = new Array(inputs); + } + if (outputs === 1) { + this.output = new Tone.Gain(); + } else if (outputs > 1) { + this.output = new Array(inputs); + } + }; + /////////////////////////////////////////////////////////////////////////// + return Tone.Gain; + }); + Module(function (Tone) { + + /** + * @class A signal is an audio-rate value. Tone.Signal is a core component of the library. + * Unlike a number, Signals can be scheduled with sample-level accuracy. Tone.Signal + * has all of the methods available to native Web Audio + * [AudioParam](http://webaudio.github.io/web-audio-api/#the-audioparam-interface) + * as well as additional conveniences. Read more about working with signals + * [here](https://github.com/Tonejs/Tone.js/wiki/Signals). + * + * @constructor + * @extends {Tone.Param} + * @param {Number|AudioParam} [value] Initial value of the signal. If an AudioParam + * is passed in, that parameter will be wrapped + * and controlled by the Signal. + * @param {string} [units=Number] unit The units the signal is in. + * @example + * var signal = new Tone.Signal(10); + */ + Tone.Signal = function () { + var options = this.optionsObject(arguments, [ + 'value', + 'units' + ], Tone.Signal.defaults); + /** + * The node where the constant signal value is scaled. + * @type {GainNode} + * @private + */ + this.output = this._gain = this.context.createGain(); + options.param = this._gain.gain; + Tone.Param.call(this, options); + /** + * The node where the value is set. + * @type {Tone.Param} + * @private + */ + this.input = this._param = this._gain.gain; + //connect the const output to the node output + Tone.Signal._constant.chain(this._gain); + }; + Tone.extend(Tone.Signal, Tone.Param); + /** + * The default values + * @type {Object} + * @static + * @const + */ + Tone.Signal.defaults = { + 'value': 0, + 'units': Tone.Type.Default, + 'convert': true + }; + /** + * When signals connect to other signals or AudioParams, + * they take over the output value of that signal or AudioParam. + * For all other nodes, the behavior is the same as a default connect. + * + * @override + * @param {AudioParam|AudioNode|Tone.Signal|Tone} node + * @param {number} [outputNumber=0] The output number to connect from. + * @param {number} [inputNumber=0] The input number to connect to. + * @returns {Tone.SignalBase} this + * @method + */ + Tone.Signal.prototype.connect = Tone.SignalBase.prototype.connect; + /** + * dispose and disconnect + * @returns {Tone.Signal} this + */ + Tone.Signal.prototype.dispose = function () { + Tone.Param.prototype.dispose.call(this); + this._param = null; + this._gain.disconnect(); + this._gain = null; + return this; + }; + /////////////////////////////////////////////////////////////////////////// + // STATIC + /////////////////////////////////////////////////////////////////////////// + /** + * Generates a constant output of 1. + * @static + * @private + * @const + * @type {AudioBufferSourceNode} + */ + Tone.Signal._constant = null; + /** + * initializer function + */ + Tone._initAudioContext(function (audioContext) { + var buffer = audioContext.createBuffer(1, 128, audioContext.sampleRate); + var arr = buffer.getChannelData(0); + for (var i = 0; i < arr.length; i++) { + arr[i] = 1; + } + Tone.Signal._constant = audioContext.createBufferSource(); + Tone.Signal._constant.channelCount = 1; + Tone.Signal._constant.channelCountMode = 'explicit'; + Tone.Signal._constant.buffer = buffer; + Tone.Signal._constant.loop = true; + Tone.Signal._constant.start(0); + Tone.Signal._constant.noGC(); + }); + return Tone.Signal; + }); + Module(function (Tone) { + + /** + * @class A Timeline class for scheduling and maintaining state + * along a timeline. All events must have a "time" property. + * Internally, events are stored in time order for fast + * retrieval. + * @extends {Tone} + * @param {Positive} [memory=Infinity] The number of previous events that are retained. + */ + Tone.Timeline = function () { + var options = this.optionsObject(arguments, ['memory'], Tone.Timeline.defaults); + /** + * The array of scheduled timeline events + * @type {Array} + * @private + */ + this._timeline = []; + /** + * An array of items to remove from the list. + * @type {Array} + * @private + */ + this._toRemove = []; + /** + * Flag if the tieline is mid iteration + * @private + * @type {Boolean} + */ + this._iterating = false; + /** + * The memory of the timeline, i.e. + * how many events in the past it will retain + * @type {Positive} + */ + this.memory = options.memory; + }; + Tone.extend(Tone.Timeline); + /** + * the default parameters + * @static + * @const + */ + Tone.Timeline.defaults = { 'memory': Infinity }; + /** + * The number of items in the timeline. + * @type {Number} + * @memberOf Tone.Timeline# + * @name length + * @readOnly + */ + Object.defineProperty(Tone.Timeline.prototype, 'length', { + get: function () { + return this._timeline.length; + } + }); + /** + * Insert an event object onto the timeline. Events must have a "time" attribute. + * @param {Object} event The event object to insert into the + * timeline. + * @returns {Tone.Timeline} this + */ + Tone.Timeline.prototype.add = function (event) { + //the event needs to have a time attribute + if (this.isUndef(event.time)) { + throw new Error('Tone.Timeline: events must have a time attribute'); + } + if (this._timeline.length) { + var index = this._search(event.time); + this._timeline.splice(index + 1, 0, event); + } else { + this._timeline.push(event); + } + //if the length is more than the memory, remove the previous ones + if (this.length > this.memory) { + var diff = this.length - this.memory; + this._timeline.splice(0, diff); + } + return this; + }; + /** + * Remove an event from the timeline. + * @param {Object} event The event object to remove from the list. + * @returns {Tone.Timeline} this + */ + Tone.Timeline.prototype.remove = function (event) { + if (this._iterating) { + this._toRemove.push(event); + } else { + var index = this._timeline.indexOf(event); + if (index !== -1) { + this._timeline.splice(index, 1); + } + } + return this; + }; + /** + * Get the nearest event whose time is less than or equal to the given time. + * @param {Number} time The time to query. + * @returns {Object} The event object set after that time. + */ + Tone.Timeline.prototype.get = function (time) { + var index = this._search(time); + if (index !== -1) { + return this._timeline[index]; + } else { + return null; + } + }; + /** + * Return the first event in the timeline without removing it + * @returns {Object} The first event object + */ + Tone.Timeline.prototype.peek = function () { + return this._timeline[0]; + }; + /** + * Return the first event in the timeline and remove it + * @returns {Object} The first event object + */ + Tone.Timeline.prototype.shift = function () { + return this._timeline.shift(); + }; + /** + * Get the event which is scheduled after the given time. + * @param {Number} time The time to query. + * @returns {Object} The event object after the given time + */ + Tone.Timeline.prototype.getAfter = function (time) { + var index = this._search(time); + if (index + 1 < this._timeline.length) { + return this._timeline[index + 1]; + } else { + return null; + } + }; + /** + * Get the event before the event at the given time. + * @param {Number} time The time to query. + * @returns {Object} The event object before the given time + */ + Tone.Timeline.prototype.getBefore = function (time) { + var len = this._timeline.length; + //if it's after the last item, return the last item + if (len > 0 && this._timeline[len - 1].time < time) { + return this._timeline[len - 1]; + } + var index = this._search(time); + if (index - 1 >= 0) { + return this._timeline[index - 1]; + } else { + return null; + } + }; + /** + * Cancel events after the given time + * @param {Number} time The time to query. + * @returns {Tone.Timeline} this + */ + Tone.Timeline.prototype.cancel = function (after) { + if (this._timeline.length > 1) { + var index = this._search(after); + if (index >= 0) { + if (this._timeline[index].time === after) { + //get the first item with that time + for (var i = index; i >= 0; i--) { + if (this._timeline[i].time === after) { + index = i; + } else { + break; + } + } + this._timeline = this._timeline.slice(0, index); + } else { + this._timeline = this._timeline.slice(0, index + 1); + } + } else { + this._timeline = []; + } + } else if (this._timeline.length === 1) { + //the first item's time + if (this._timeline[0].time >= after) { + this._timeline = []; + } + } + return this; + }; + /** + * Cancel events before or equal to the given time. + * @param {Number} time The time to cancel before. + * @returns {Tone.Timeline} this + */ + Tone.Timeline.prototype.cancelBefore = function (time) { + if (this._timeline.length) { + var index = this._search(time); + if (index >= 0) { + this._timeline = this._timeline.slice(index + 1); + } + } + return this; + }; + /** + * Does a binary serach on the timeline array and returns the + * nearest event index whose time is after or equal to the given time. + * If a time is searched before the first index in the timeline, -1 is returned. + * If the time is after the end, the index of the last item is returned. + * @param {Number} time + * @return {Number} the index in the timeline array + * @private + */ + Tone.Timeline.prototype._search = function (time) { + var beginning = 0; + var len = this._timeline.length; + var end = len; + if (len > 0 && this._timeline[len - 1].time <= time) { + return len - 1; + } + while (beginning < end) { + // calculate the midpoint for roughly equal partition + var midPoint = Math.floor(beginning + (end - beginning) / 2); + var event = this._timeline[midPoint]; + var nextEvent = this._timeline[midPoint + 1]; + if (event.time === time) { + //choose the last one that has the same time + for (var i = midPoint; i < this._timeline.length; i++) { + var testEvent = this._timeline[i]; + if (testEvent.time === time) { + midPoint = i; + } + } + return midPoint; + } else if (event.time < time && nextEvent.time > time) { + return midPoint; + } else if (event.time > time) { + //search lower + end = midPoint; + } else if (event.time < time) { + //search upper + beginning = midPoint + 1; + } + } + return -1; + }; + /** + * Internal iterator. Applies extra safety checks for + * removing items from the array. + * @param {Function} callback + * @param {Number=} lowerBound + * @param {Number=} upperBound + * @private + */ + Tone.Timeline.prototype._iterate = function (callback, lowerBound, upperBound) { + this._iterating = true; + lowerBound = this.defaultArg(lowerBound, 0); + upperBound = this.defaultArg(upperBound, this._timeline.length - 1); + for (var i = lowerBound; i <= upperBound; i++) { + callback(this._timeline[i]); + } + this._iterating = false; + if (this._toRemove.length > 0) { + for (var j = 0; j < this._toRemove.length; j++) { + var index = this._timeline.indexOf(this._toRemove[j]); + if (index !== -1) { + this._timeline.splice(index, 1); + } + } + this._toRemove = []; + } + }; + /** + * Iterate over everything in the array + * @param {Function} callback The callback to invoke with every item + * @returns {Tone.Timeline} this + */ + Tone.Timeline.prototype.forEach = function (callback) { + this._iterate(callback); + return this; + }; + /** + * Iterate over everything in the array at or before the given time. + * @param {Number} time The time to check if items are before + * @param {Function} callback The callback to invoke with every item + * @returns {Tone.Timeline} this + */ + Tone.Timeline.prototype.forEachBefore = function (time, callback) { + //iterate over the items in reverse so that removing an item doesn't break things + var upperBound = this._search(time); + if (upperBound !== -1) { + this._iterate(callback, 0, upperBound); + } + return this; + }; + /** + * Iterate over everything in the array after the given time. + * @param {Number} time The time to check if items are before + * @param {Function} callback The callback to invoke with every item + * @returns {Tone.Timeline} this + */ + Tone.Timeline.prototype.forEachAfter = function (time, callback) { + //iterate over the items in reverse so that removing an item doesn't break things + var lowerBound = this._search(time); + this._iterate(callback, lowerBound + 1); + return this; + }; + /** + * Iterate over everything in the array at or after the given time. Similar to + * forEachAfter, but includes the item(s) at the given time. + * @param {Number} time The time to check if items are before + * @param {Function} callback The callback to invoke with every item + * @returns {Tone.Timeline} this + */ + Tone.Timeline.prototype.forEachFrom = function (time, callback) { + //iterate over the items in reverse so that removing an item doesn't break things + var lowerBound = this._search(time); + //work backwards until the event time is less than time + while (lowerBound >= 0 && this._timeline[lowerBound].time >= time) { + lowerBound--; + } + this._iterate(callback, lowerBound + 1); + return this; + }; + /** + * Iterate over everything in the array at the given time + * @param {Number} time The time to check if items are before + * @param {Function} callback The callback to invoke with every item + * @returns {Tone.Timeline} this + */ + Tone.Timeline.prototype.forEachAtTime = function (time, callback) { + //iterate over the items in reverse so that removing an item doesn't break things + var upperBound = this._search(time); + if (upperBound !== -1) { + this._iterate(function (event) { + if (event.time === time) { + callback(event); + } + }, 0, upperBound); + } + return this; + }; + /** + * Clean up. + * @return {Tone.Timeline} this + */ + Tone.Timeline.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._timeline = null; + this._toRemove = null; + }; + return Tone.Timeline; + }); + Module(function (Tone) { + + /** + * @class A signal which adds the method getValueAtTime. + * Code and inspiration from https://github.com/jsantell/web-audio-automation-timeline + * @extends {Tone.Param} + * @param {Number=} value The initial value of the signal + * @param {String=} units The conversion units of the signal. + */ + Tone.TimelineSignal = function () { + var options = this.optionsObject(arguments, [ + 'value', + 'units' + ], Tone.Signal.defaults); + /** + * The scheduled events + * @type {Tone.Timeline} + * @private + */ + this._events = new Tone.Timeline(10); + //constructors + Tone.Signal.apply(this, options); + options.param = this._param; + Tone.Param.call(this, options); + /** + * The initial scheduled value + * @type {Number} + * @private + */ + this._initial = this._fromUnits(this._param.value); + }; + Tone.extend(Tone.TimelineSignal, Tone.Param); + /** + * The event types of a schedulable signal. + * @enum {String} + * @private + */ + Tone.TimelineSignal.Type = { + Linear: 'linear', + Exponential: 'exponential', + Target: 'target', + Curve: 'curve', + Set: 'set' + }; + /** + * The current value of the signal. + * @memberOf Tone.TimelineSignal# + * @type {Number} + * @name value + */ + Object.defineProperty(Tone.TimelineSignal.prototype, 'value', { + get: function () { + var now = this.now(); + var val = this.getValueAtTime(now); + return this._toUnits(val); + }, + set: function (value) { + var convertedVal = this._fromUnits(value); + this._initial = convertedVal; + this.cancelScheduledValues(); + this._param.value = convertedVal; + } + }); + /////////////////////////////////////////////////////////////////////////// + // SCHEDULING + /////////////////////////////////////////////////////////////////////////// + /** + * Schedules a parameter value change at the given time. + * @param {*} value The value to set the signal. + * @param {Time} time The time when the change should occur. + * @returns {Tone.TimelineSignal} this + * @example + * //set the frequency to "G4" in exactly 1 second from now. + * freq.setValueAtTime("G4", "+1"); + */ + Tone.TimelineSignal.prototype.setValueAtTime = function (value, startTime) { + value = this._fromUnits(value); + startTime = this.toSeconds(startTime); + this._events.add({ + 'type': Tone.TimelineSignal.Type.Set, + 'value': value, + 'time': startTime + }); + //invoke the original event + this._param.setValueAtTime(value, startTime); + return this; + }; + /** + * Schedules a linear continuous change in parameter value from the + * previous scheduled parameter value to the given value. + * + * @param {number} value + * @param {Time} endTime + * @returns {Tone.TimelineSignal} this + */ + Tone.TimelineSignal.prototype.linearRampToValueAtTime = function (value, endTime) { + value = this._fromUnits(value); + endTime = this.toSeconds(endTime); + this._events.add({ + 'type': Tone.TimelineSignal.Type.Linear, + 'value': value, + 'time': endTime + }); + this._param.linearRampToValueAtTime(value, endTime); + return this; + }; + /** + * Schedules an exponential continuous change in parameter value from + * the previous scheduled parameter value to the given value. + * + * @param {number} value + * @param {Time} endTime + * @returns {Tone.TimelineSignal} this + */ + Tone.TimelineSignal.prototype.exponentialRampToValueAtTime = function (value, endTime) { + //get the previous event and make sure it's not starting from 0 + endTime = this.toSeconds(endTime); + var beforeEvent = this._searchBefore(endTime); + if (beforeEvent && beforeEvent.value === 0) { + //reschedule that event + this.setValueAtTime(this._minOutput, beforeEvent.time); + } + value = this._fromUnits(value); + var setValue = Math.max(value, this._minOutput); + this._events.add({ + 'type': Tone.TimelineSignal.Type.Exponential, + 'value': setValue, + 'time': endTime + }); + //if the ramped to value is 0, make it go to the min output, and then set to 0. + if (value < this._minOutput) { + this._param.exponentialRampToValueAtTime(this._minOutput, endTime - this.sampleTime); + this.setValueAtTime(0, endTime); + } else { + this._param.exponentialRampToValueAtTime(value, endTime); + } + return this; + }; + /** + * Start exponentially approaching the target value at the given time with + * a rate having the given time constant. + * @param {number} value + * @param {Time} startTime + * @param {number} timeConstant + * @returns {Tone.TimelineSignal} this + */ + Tone.TimelineSignal.prototype.setTargetAtTime = function (value, startTime, timeConstant) { + value = this._fromUnits(value); + value = Math.max(this._minOutput, value); + timeConstant = Math.max(this._minOutput, timeConstant); + startTime = this.toSeconds(startTime); + this._events.add({ + 'type': Tone.TimelineSignal.Type.Target, + 'value': value, + 'time': startTime, + 'constant': timeConstant + }); + this._param.setTargetAtTime(value, startTime, timeConstant); + return this; + }; + /** + * Set an array of arbitrary values starting at the given time for the given duration. + * @param {Float32Array} values + * @param {Time} startTime + * @param {Time} duration + * @param {NormalRange} [scaling=1] If the values in the curve should be scaled by some value + * @returns {Tone.TimelineSignal} this + */ + Tone.TimelineSignal.prototype.setValueCurveAtTime = function (values, startTime, duration, scaling) { + scaling = this.defaultArg(scaling, 1); + //copy the array + var floats = new Array(values.length); + for (var i = 0; i < floats.length; i++) { + floats[i] = this._fromUnits(values[i]) * scaling; + } + startTime = this.toSeconds(startTime); + duration = this.toSeconds(duration); + this._events.add({ + 'type': Tone.TimelineSignal.Type.Curve, + 'value': floats, + 'time': startTime, + 'duration': duration + }); + //set the first value + this._param.setValueAtTime(floats[0], startTime); + //schedule a lienar ramp for each of the segments + for (var j = 1; j < floats.length; j++) { + var segmentTime = startTime + j / (floats.length - 1) * duration; + this._param.linearRampToValueAtTime(floats[j], segmentTime); + } + return this; + }; + /** + * Cancels all scheduled parameter changes with times greater than or + * equal to startTime. + * + * @param {Time} startTime + * @returns {Tone.TimelineSignal} this + */ + Tone.TimelineSignal.prototype.cancelScheduledValues = function (after) { + after = this.toSeconds(after); + this._events.cancel(after); + this._param.cancelScheduledValues(after); + return this; + }; + /** + * Sets the computed value at the given time. This provides + * a point from which a linear or exponential curve + * can be scheduled after. Will cancel events after + * the given time and shorten the currently scheduled + * linear or exponential ramp so that it ends at `time` . + * This is to avoid discontinuities and clicks in envelopes. + * @param {Time} time When to set the ramp point + * @returns {Tone.TimelineSignal} this + */ + Tone.TimelineSignal.prototype.setRampPoint = function (time) { + time = this.toSeconds(time); + //get the value at the given time + var val = this._toUnits(this.getValueAtTime(time)); + //if there is an event at the given time + //and that even is not a "set" + var before = this._searchBefore(time); + if (before && before.time === time) { + //remove everything after + this.cancelScheduledValues(time + this.sampleTime); + } else if (before && before.type === Tone.TimelineSignal.Type.Curve && before.time + before.duration > time) { + //if the curve is still playing + //cancel the curve + this.cancelScheduledValues(time); + this.linearRampToValueAtTime(val, time); + } else { + //reschedule the next event to end at the given time + var after = this._searchAfter(time); + if (after) { + //cancel the next event(s) + this.cancelScheduledValues(time); + if (after.type === Tone.TimelineSignal.Type.Linear) { + this.linearRampToValueAtTime(val, time); + } else if (after.type === Tone.TimelineSignal.Type.Exponential) { + this.exponentialRampToValueAtTime(val, time); + } + } + this.setValueAtTime(val, time); + } + return this; + }; + /** + * Do a linear ramp to the given value between the start and finish times. + * @param {Number} value The value to ramp to. + * @param {Time} start The beginning anchor point to do the linear ramp + * @param {Time} finish The ending anchor point by which the value of + * the signal will equal the given value. + * @returns {Tone.TimelineSignal} this + */ + Tone.TimelineSignal.prototype.linearRampToValueBetween = function (value, start, finish) { + this.setRampPoint(start); + this.linearRampToValueAtTime(value, finish); + return this; + }; + /** + * Do a exponential ramp to the given value between the start and finish times. + * @param {Number} value The value to ramp to. + * @param {Time} start The beginning anchor point to do the exponential ramp + * @param {Time} finish The ending anchor point by which the value of + * the signal will equal the given value. + * @returns {Tone.TimelineSignal} this + */ + Tone.TimelineSignal.prototype.exponentialRampToValueBetween = function (value, start, finish) { + this.setRampPoint(start); + this.exponentialRampToValueAtTime(value, finish); + return this; + }; + /////////////////////////////////////////////////////////////////////////// + // GETTING SCHEDULED VALUES + /////////////////////////////////////////////////////////////////////////// + /** + * Returns the value before or equal to the given time + * @param {Number} time The time to query + * @return {Object} The event at or before the given time. + * @private + */ + Tone.TimelineSignal.prototype._searchBefore = function (time) { + return this._events.get(time); + }; + /** + * The event after the given time + * @param {Number} time The time to query. + * @return {Object} The next event after the given time + * @private + */ + Tone.TimelineSignal.prototype._searchAfter = function (time) { + return this._events.getAfter(time); + }; + /** + * Get the scheduled value at the given time. This will + * return the unconverted (raw) value. + * @param {Number} time The time in seconds. + * @return {Number} The scheduled value at the given time. + */ + Tone.TimelineSignal.prototype.getValueAtTime = function (time) { + time = this.toSeconds(time); + var after = this._searchAfter(time); + var before = this._searchBefore(time); + var value = this._initial; + //if it was set by + if (before === null) { + value = this._initial; + } else if (before.type === Tone.TimelineSignal.Type.Target) { + var previous = this._events.getBefore(before.time); + var previouVal; + if (previous === null) { + previouVal = this._initial; + } else { + previouVal = previous.value; + } + value = this._exponentialApproach(before.time, previouVal, before.value, before.constant, time); + } else if (before.type === Tone.TimelineSignal.Type.Curve) { + value = this._curveInterpolate(before.time, before.value, before.duration, time); + } else if (after === null) { + value = before.value; + } else if (after.type === Tone.TimelineSignal.Type.Linear) { + value = this._linearInterpolate(before.time, before.value, after.time, after.value, time); + } else if (after.type === Tone.TimelineSignal.Type.Exponential) { + value = this._exponentialInterpolate(before.time, before.value, after.time, after.value, time); + } else { + value = before.value; + } + return value; + }; + /** + * When signals connect to other signals or AudioParams, + * they take over the output value of that signal or AudioParam. + * For all other nodes, the behavior is the same as a default connect. + * + * @override + * @param {AudioParam|AudioNode|Tone.Signal|Tone} node + * @param {number} [outputNumber=0] The output number to connect from. + * @param {number} [inputNumber=0] The input number to connect to. + * @returns {Tone.TimelineSignal} this + * @method + */ + Tone.TimelineSignal.prototype.connect = Tone.SignalBase.prototype.connect; + /////////////////////////////////////////////////////////////////////////// + // AUTOMATION CURVE CALCULATIONS + // MIT License, copyright (c) 2014 Jordan Santell + /////////////////////////////////////////////////////////////////////////// + /** + * Calculates the the value along the curve produced by setTargetAtTime + * @private + */ + Tone.TimelineSignal.prototype._exponentialApproach = function (t0, v0, v1, timeConstant, t) { + return v1 + (v0 - v1) * Math.exp(-(t - t0) / timeConstant); + }; + /** + * Calculates the the value along the curve produced by linearRampToValueAtTime + * @private + */ + Tone.TimelineSignal.prototype._linearInterpolate = function (t0, v0, t1, v1, t) { + return v0 + (v1 - v0) * ((t - t0) / (t1 - t0)); + }; + /** + * Calculates the the value along the curve produced by exponentialRampToValueAtTime + * @private + */ + Tone.TimelineSignal.prototype._exponentialInterpolate = function (t0, v0, t1, v1, t) { + v0 = Math.max(this._minOutput, v0); + return v0 * Math.pow(v1 / v0, (t - t0) / (t1 - t0)); + }; + /** + * Calculates the the value along the curve produced by setValueCurveAtTime + * @private + */ + Tone.TimelineSignal.prototype._curveInterpolate = function (start, curve, duration, time) { + var len = curve.length; + // If time is after duration, return the last curve value + if (time >= start + duration) { + return curve[len - 1]; + } else if (time <= start) { + return curve[0]; + } else { + var progress = (time - start) / duration; + var lowerIndex = Math.floor((len - 1) * progress); + var upperIndex = Math.ceil((len - 1) * progress); + var lowerVal = curve[lowerIndex]; + var upperVal = curve[upperIndex]; + if (upperIndex === lowerIndex) { + return lowerVal; + } else { + return this._linearInterpolate(lowerIndex, lowerVal, upperIndex, upperVal, progress * (len - 1)); + } + } + }; + /** + * Clean up. + * @return {Tone.TimelineSignal} this + */ + Tone.TimelineSignal.prototype.dispose = function () { + Tone.Signal.prototype.dispose.call(this); + Tone.Param.prototype.dispose.call(this); + this._events.dispose(); + this._events = null; + }; + return Tone.TimelineSignal; + }); + Module(function (Tone) { + + /** + * @class Pow applies an exponent to the incoming signal. The incoming signal + * must be AudioRange. + * + * @extends {Tone.SignalBase} + * @constructor + * @param {Positive} exp The exponent to apply to the incoming signal, must be at least 2. + * @example + * var pow = new Tone.Pow(2); + * var sig = new Tone.Signal(0.5).connect(pow); + * //output of pow is 0.25. + */ + Tone.Pow = function (exp) { + /** + * the exponent + * @private + * @type {number} + */ + this._exp = this.defaultArg(exp, 1); + /** + * @type {WaveShaperNode} + * @private + */ + this._expScaler = this.input = this.output = new Tone.WaveShaper(this._expFunc(this._exp), 8192); + }; + Tone.extend(Tone.Pow, Tone.SignalBase); + /** + * The value of the exponent. + * @memberOf Tone.Pow# + * @type {number} + * @name value + */ + Object.defineProperty(Tone.Pow.prototype, 'value', { + get: function () { + return this._exp; + }, + set: function (exp) { + this._exp = exp; + this._expScaler.setMap(this._expFunc(this._exp)); + } + }); + /** + * the function which maps the waveshaper + * @param {number} exp + * @return {function} + * @private + */ + Tone.Pow.prototype._expFunc = function (exp) { + return function (val) { + return Math.pow(Math.abs(val), exp); + }; + }; + /** + * Clean up. + * @returns {Tone.Pow} this + */ + Tone.Pow.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._expScaler.dispose(); + this._expScaler = null; + return this; + }; + return Tone.Pow; + }); + Module(function (Tone) { + + /** + * @class Tone.Envelope is an [ADSR](https://en.wikipedia.org/wiki/Synthesizer#ADSR_envelope) + * envelope generator. Tone.Envelope outputs a signal which + * can be connected to an AudioParam or Tone.Signal. + * + * + * @constructor + * @extends {Tone} + * @param {Time} [attack] The amount of time it takes for the envelope to go from + * 0 to it's maximum value. + * @param {Time} [decay] The period of time after the attack that it takes for the envelope + * to fall to the sustain value. + * @param {NormalRange} [sustain] The percent of the maximum value that the envelope rests at until + * the release is triggered. + * @param {Time} [release] The amount of time after the release is triggered it takes to reach 0. + * @example + * //an amplitude envelope + * var gainNode = Tone.context.createGain(); + * var env = new Tone.Envelope({ + * "attack" : 0.1, + * "decay" : 0.2, + * "sustain" : 1, + * "release" : 0.8, + * }); + * env.connect(gainNode.gain); + */ + Tone.Envelope = function () { + //get all of the defaults + var options = this.optionsObject(arguments, [ + 'attack', + 'decay', + 'sustain', + 'release' + ], Tone.Envelope.defaults); + /** + * When triggerAttack is called, the attack time is the amount of + * time it takes for the envelope to reach it's maximum value. + * @type {Time} + */ + this.attack = options.attack; + /** + * After the attack portion of the envelope, the value will fall + * over the duration of the decay time to it's sustain value. + * @type {Time} + */ + this.decay = options.decay; + /** + * The sustain value is the value + * which the envelope rests at after triggerAttack is + * called, but before triggerRelease is invoked. + * @type {NormalRange} + */ + this.sustain = options.sustain; + /** + * After triggerRelease is called, the envelope's + * value will fall to it's miminum value over the + * duration of the release time. + * @type {Time} + */ + this.release = options.release; + /** + * the next time the envelope is at standby + * @type {number} + * @private + */ + this._attackCurve = 'linear'; + /** + * the next time the envelope is at standby + * @type {number} + * @private + */ + this._releaseCurve = 'exponential'; + /** + * the signal + * @type {Tone.TimelineSignal} + * @private + */ + this._sig = this.output = new Tone.TimelineSignal(); + this._sig.setValueAtTime(0, 0); + //set the attackCurve initially + this.attackCurve = options.attackCurve; + this.releaseCurve = options.releaseCurve; + }; + Tone.extend(Tone.Envelope); + /** + * the default parameters + * @static + * @const + */ + Tone.Envelope.defaults = { + 'attack': 0.01, + 'decay': 0.1, + 'sustain': 0.5, + 'release': 1, + 'attackCurve': 'linear', + 'releaseCurve': 'exponential' + }; + /** + * Read the current value of the envelope. Useful for + * syncronizing visual output to the envelope. + * @memberOf Tone.Envelope# + * @type {Number} + * @name value + * @readOnly + */ + Object.defineProperty(Tone.Envelope.prototype, 'value', { + get: function () { + return this.getValueAtTime(this.now()); + } + }); + /** + * The shape of the attack. + * Can be any of these strings: + *
    + *
  • linear
  • + *
  • exponential
  • + *
  • sine
  • + *
  • cosine
  • + *
  • bounce
  • + *
  • ripple
  • + *
  • step
  • + *
+ * Can also be an array which describes the curve. Values + * in the array are evenly subdivided and linearly + * interpolated over the duration of the attack. + * @memberOf Tone.Envelope# + * @type {String|Array} + * @name attackCurve + * @example + * env.attackCurve = "linear"; + * @example + * //can also be an array + * env.attackCurve = [0, 0.2, 0.3, 0.4, 1] + */ + Object.defineProperty(Tone.Envelope.prototype, 'attackCurve', { + get: function () { + if (this.isString(this._attackCurve)) { + return this._attackCurve; + } else if (this.isArray(this._attackCurve)) { + //look up the name in the curves array + for (var type in Tone.Envelope.Type) { + if (Tone.Envelope.Type[type].In === this._attackCurve) { + return type; + } + } + //otherwise just return the array + return this._attackCurve; + } + }, + set: function (curve) { + //check if it's a valid type + if (Tone.Envelope.Type.hasOwnProperty(curve)) { + var curveDef = Tone.Envelope.Type[curve]; + if (this.isObject(curveDef)) { + this._attackCurve = curveDef.In; + } else { + this._attackCurve = curveDef; + } + } else if (this.isArray(curve)) { + this._attackCurve = curve; + } else { + throw new Error('Tone.Envelope: invalid curve: ' + curve); + } + } + }); + /** + * The shape of the release. See the attack curve types. + * @memberOf Tone.Envelope# + * @type {String|Array} + * @name releaseCurve + * @example + * env.releaseCurve = "linear"; + */ + Object.defineProperty(Tone.Envelope.prototype, 'releaseCurve', { + get: function () { + if (this.isString(this._releaseCurve)) { + return this._releaseCurve; + } else if (this.isArray(this._releaseCurve)) { + //look up the name in the curves array + for (var type in Tone.Envelope.Type) { + if (Tone.Envelope.Type[type].Out === this._releaseCurve) { + return type; + } + } + //otherwise just return the array + return this._releaseCurve; + } + }, + set: function (curve) { + //check if it's a valid type + if (Tone.Envelope.Type.hasOwnProperty(curve)) { + var curveDef = Tone.Envelope.Type[curve]; + if (this.isObject(curveDef)) { + this._releaseCurve = curveDef.Out; + } else { + this._releaseCurve = curveDef; + } + } else if (this.isArray(curve)) { + this._releaseCurve = curve; + } else { + throw new Error('Tone.Envelope: invalid curve: ' + curve); + } + } + }); + /** + * Trigger the attack/decay portion of the ADSR envelope. + * @param {Time} [time=now] When the attack should start. + * @param {NormalRange} [velocity=1] The velocity of the envelope scales the vales. + * number between 0-1 + * @returns {Tone.Envelope} this + * @example + * //trigger the attack 0.5 seconds from now with a velocity of 0.2 + * env.triggerAttack("+0.5", 0.2); + */ + Tone.Envelope.prototype.triggerAttack = function (time, velocity) { + time = this.toSeconds(time); + var originalAttack = this.toSeconds(this.attack); + var attack = originalAttack; + var decay = this.toSeconds(this.decay); + velocity = this.defaultArg(velocity, 1); + //check if it's not a complete attack + var currentValue = this.getValueAtTime(time); + if (currentValue > 0) { + //subtract the current value from the attack time + var attackRate = 1 / attack; + var remainingDistance = 1 - currentValue; + //the attack is now the remaining time + attack = remainingDistance / attackRate; + } + //attack + if (this._attackCurve === 'linear') { + this._sig.linearRampToValue(velocity, attack, time); + } else if (this._attackCurve === 'exponential') { + this._sig.exponentialRampToValue(velocity, attack, time); + } else if (attack > 0) { + this._sig.setRampPoint(time); + var curve = this._attackCurve; + //take only a portion of the curve + if (attack < originalAttack) { + var percentComplete = 1 - attack / originalAttack; + var sliceIndex = Math.floor(percentComplete * this._attackCurve.length); + curve = this._attackCurve.slice(sliceIndex); + //the first index is the current value + curve[0] = currentValue; + } + this._sig.setValueCurveAtTime(curve, time, attack, velocity); + } + //decay + this._sig.exponentialRampToValue(velocity * this.sustain, decay, attack + time); + return this; + }; + /** + * Triggers the release of the envelope. + * @param {Time} [time=now] When the release portion of the envelope should start. + * @returns {Tone.Envelope} this + * @example + * //trigger release immediately + * env.triggerRelease(); + */ + Tone.Envelope.prototype.triggerRelease = function (time) { + time = this.toSeconds(time); + var currentValue = this.getValueAtTime(time); + if (currentValue > 0) { + var release = this.toSeconds(this.release); + if (this._releaseCurve === 'linear') { + this._sig.linearRampToValue(0, release, time); + } else if (this._releaseCurve === 'exponential') { + this._sig.exponentialRampToValue(0, release, time); + } else { + var curve = this._releaseCurve; + if (this.isArray(curve)) { + this._sig.setRampPoint(time); + this._sig.setValueCurveAtTime(curve, time, release, currentValue); + } + } + } + return this; + }; + /** + * Get the scheduled value at the given time. This will + * return the unconverted (raw) value. + * @param {Number} time The time in seconds. + * @return {Number} The scheduled value at the given time. + */ + Tone.Envelope.prototype.getValueAtTime = function (time) { + return this._sig.getValueAtTime(time); + }; + /** + * triggerAttackRelease is shorthand for triggerAttack, then waiting + * some duration, then triggerRelease. + * @param {Time} duration The duration of the sustain. + * @param {Time} [time=now] When the attack should be triggered. + * @param {number} [velocity=1] The velocity of the envelope. + * @returns {Tone.Envelope} this + * @example + * //trigger the attack and then the release after 0.6 seconds. + * env.triggerAttackRelease(0.6); + */ + Tone.Envelope.prototype.triggerAttackRelease = function (duration, time, velocity) { + time = this.toSeconds(time); + this.triggerAttack(time, velocity); + this.triggerRelease(time + this.toSeconds(duration)); + return this; + }; + /** + * Cancels all scheduled envelope changes after the given time. + * @param {Time} after + * @returns {Tone.Envelope} this + */ + Tone.Envelope.prototype.cancel = function (after) { + this._sig.cancelScheduledValues(after); + return this; + }; + /** + * Borrows the connect method from Tone.Signal. + * @function + * @private + */ + Tone.Envelope.prototype.connect = Tone.Signal.prototype.connect; + /** + * Generate some complex envelope curves. + */ + (function _createCurves() { + var curveLen = 128; + var i, k; + //cosine curve + var cosineCurve = []; + for (i = 0; i < curveLen; i++) { + cosineCurve[i] = Math.sin(i / (curveLen - 1) * (Math.PI / 2)); + } + //ripple curve + var rippleCurve = []; + var rippleCurveFreq = 6.4; + for (i = 0; i < curveLen - 1; i++) { + k = i / (curveLen - 1); + var sineWave = Math.sin(k * (Math.PI * 2) * rippleCurveFreq - Math.PI / 2) + 1; + rippleCurve[i] = sineWave / 10 + k * 0.83; + } + rippleCurve[curveLen - 1] = 1; + //stairs curve + var stairsCurve = []; + var steps = 5; + for (i = 0; i < curveLen; i++) { + stairsCurve[i] = Math.ceil(i / (curveLen - 1) * steps) / steps; + } + //in-out easing curve + var sineCurve = []; + for (i = 0; i < curveLen; i++) { + k = i / (curveLen - 1); + sineCurve[i] = 0.5 * (1 - Math.cos(Math.PI * k)); + } + //a bounce curve + var bounceCurve = []; + for (i = 0; i < curveLen; i++) { + k = i / (curveLen - 1); + var freq = Math.pow(k, 3) * 4 + 0.2; + var val = Math.cos(freq * Math.PI * 2 * k); + bounceCurve[i] = Math.abs(val * (1 - k)); + } + /** + * Invert a value curve to make it work for the release + * @private + */ + function invertCurve(curve) { + var out = new Array(curve.length); + for (var j = 0; j < curve.length; j++) { + out[j] = 1 - curve[j]; + } + return out; + } + /** + * reverse the curve + * @private + */ + function reverseCurve(curve) { + return curve.slice(0).reverse(); + } + /** + * attack and release curve arrays + * @type {Object} + * @private + */ + Tone.Envelope.Type = { + 'linear': 'linear', + 'exponential': 'exponential', + 'bounce': { + In: invertCurve(bounceCurve), + Out: bounceCurve + }, + 'cosine': { + In: cosineCurve, + Out: reverseCurve(cosineCurve) + }, + 'step': { + In: stairsCurve, + Out: invertCurve(stairsCurve) + }, + 'ripple': { + In: rippleCurve, + Out: invertCurve(rippleCurve) + }, + 'sine': { + In: sineCurve, + Out: invertCurve(sineCurve) + } + }; + }()); + /** + * Disconnect and dispose. + * @returns {Tone.Envelope} this + */ + Tone.Envelope.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._sig.dispose(); + this._sig = null; + this._attackCurve = null; + this._releaseCurve = null; + return this; + }; + return Tone.Envelope; + }); + Module(function (Tone) { + + /** + * @class Tone.AmplitudeEnvelope is a Tone.Envelope connected to a gain node. + * Unlike Tone.Envelope, which outputs the envelope's value, Tone.AmplitudeEnvelope accepts + * an audio signal as the input and will apply the envelope to the amplitude + * of the signal. Read more about ADSR Envelopes on [Wikipedia](https://en.wikipedia.org/wiki/Synthesizer#ADSR_envelope). + * + * @constructor + * @extends {Tone.Envelope} + * @param {Time|Object} [attack] The amount of time it takes for the envelope to go from + * 0 to it's maximum value. + * @param {Time} [decay] The period of time after the attack that it takes for the envelope + * to fall to the sustain value. + * @param {NormalRange} [sustain] The percent of the maximum value that the envelope rests at until + * the release is triggered. + * @param {Time} [release] The amount of time after the release is triggered it takes to reach 0. + * @example + * var ampEnv = new Tone.AmplitudeEnvelope({ + * "attack": 0.1, + * "decay": 0.2, + * "sustain": 1.0, + * "release": 0.8 + * }).toMaster(); + * //create an oscillator and connect it + * var osc = new Tone.Oscillator().connect(ampEnv).start(); + * //trigger the envelopes attack and release "8t" apart + * ampEnv.triggerAttackRelease("8t"); + */ + Tone.AmplitudeEnvelope = function () { + Tone.Envelope.apply(this, arguments); + /** + * the input node + * @type {GainNode} + * @private + */ + this.input = this.output = new Tone.Gain(); + this._sig.connect(this.output.gain); + }; + Tone.extend(Tone.AmplitudeEnvelope, Tone.Envelope); + /** + * Clean up + * @return {Tone.AmplitudeEnvelope} this + */ + Tone.AmplitudeEnvelope.prototype.dispose = function () { + this.input.dispose(); + this.input = null; + Tone.Envelope.prototype.dispose.call(this); + return this; + }; + return Tone.AmplitudeEnvelope; + }); + Module(function (Tone) { + + /** + * @class Wrapper around the native Web Audio's + * [AnalyserNode](http://webaudio.github.io/web-audio-api/#idl-def-AnalyserNode). + * Extracts FFT or Waveform data from the incoming signal. + * @extends {Tone} + * @param {String=} type The return type of the analysis, either "fft", or "waveform". + * @param {Number=} size The size of the FFT. Value must be a power of + * two in the range 32 to 32768. + */ + Tone.Analyser = function () { + var options = this.optionsObject(arguments, [ + 'type', + 'size' + ], Tone.Analyser.defaults); + /** + * The analyser node. + * @private + * @type {AnalyserNode} + */ + this._analyser = this.input = this.output = this.context.createAnalyser(); + /** + * The analysis type + * @type {String} + * @private + */ + this._type = options.type; + /** + * The return type of the analysis + * @type {String} + * @private + */ + this._returnType = options.returnType; + /** + * The buffer that the FFT data is written to + * @type {TypedArray} + * @private + */ + this._buffer = null; + //set the values initially + this.size = options.size; + this.type = options.type; + this.returnType = options.returnType; + this.minDecibels = options.minDecibels; + this.maxDecibels = options.maxDecibels; + }; + Tone.extend(Tone.Analyser); + /** + * The default values. + * @type {Object} + * @const + */ + Tone.Analyser.defaults = { + 'size': 1024, + 'returnType': 'byte', + 'type': 'fft', + 'smoothing': 0.8, + 'maxDecibels': -30, + 'minDecibels': -100 + }; + /** + * Possible return types of Tone.Analyser.analyse() + * @enum {String} + */ + Tone.Analyser.Type = { + Waveform: 'waveform', + FFT: 'fft' + }; + /** + * Possible return types of Tone.Analyser.analyse(). + * byte values are between [0,255]. float values are between + * [-1, 1] when the type is set to "waveform" and between + * [minDecibels,maxDecibels] when the type is "fft". + * @enum {String} + */ + Tone.Analyser.ReturnType = { + Byte: 'byte', + Float: 'float' + }; + /** + * Run the analysis given the current settings and return the + * result as a TypedArray. + * @returns {TypedArray} + */ + Tone.Analyser.prototype.analyse = function () { + if (this._type === Tone.Analyser.Type.FFT) { + if (this._returnType === Tone.Analyser.ReturnType.Byte) { + this._analyser.getByteFrequencyData(this._buffer); + } else { + this._analyser.getFloatFrequencyData(this._buffer); + } + } else if (this._type === Tone.Analyser.Type.Waveform) { + if (this._returnType === Tone.Analyser.ReturnType.Byte) { + this._analyser.getByteTimeDomainData(this._buffer); + } else { + if (this.isFunction(AnalyserNode.prototype.getFloatTimeDomainData)) { + this._analyser.getFloatTimeDomainData(this._buffer); + } else { + var uint8 = new Uint8Array(this._buffer.length); + this._analyser.getByteTimeDomainData(uint8); + //referenced https://github.com/mohayonao/get-float-time-domain-data + // POLYFILL + for (var i = 0; i < uint8.length; i++) { + this._buffer[i] = (uint8[i] - 128) * 0.0078125; + } + } + } + } + return this._buffer; + }; + /** + * The size of analysis. This must be a power of two in the range 32 to 32768. + * @memberOf Tone.Analyser# + * @type {Number} + * @name size + */ + Object.defineProperty(Tone.Analyser.prototype, 'size', { + get: function () { + return this._analyser.frequencyBinCount; + }, + set: function (size) { + this._analyser.fftSize = size * 2; + this.type = this._type; + } + }); + /** + * The return type of Tone.Analyser.analyse(), either "byte" or "float". + * When the type is set to "byte" the range of values returned in the array + * are between 0-255. "float" values are between + * [-1, 1] when the type is set to "waveform" and between + * [minDecibels,maxDecibels] when the type is "fft". + * @memberOf Tone.Analyser# + * @type {String} + * @name type + */ + Object.defineProperty(Tone.Analyser.prototype, 'returnType', { + get: function () { + return this._returnType; + }, + set: function (type) { + if (type === Tone.Analyser.ReturnType.Byte) { + this._buffer = new Uint8Array(this._analyser.frequencyBinCount); + } else if (type === Tone.Analyser.ReturnType.Float) { + this._buffer = new Float32Array(this._analyser.frequencyBinCount); + } else { + throw new TypeError('Tone.Analayser: invalid return type: ' + type); + } + this._returnType = type; + } + }); + /** + * The analysis function returned by Tone.Analyser.analyse(), either "fft" or "waveform". + * @memberOf Tone.Analyser# + * @type {String} + * @name type + */ + Object.defineProperty(Tone.Analyser.prototype, 'type', { + get: function () { + return this._type; + }, + set: function (type) { + if (type !== Tone.Analyser.Type.Waveform && type !== Tone.Analyser.Type.FFT) { + throw new TypeError('Tone.Analyser: invalid type: ' + type); + } + this._type = type; + } + }); + /** + * 0 represents no time averaging with the last analysis frame. + * @memberOf Tone.Analyser# + * @type {NormalRange} + * @name smoothing + */ + Object.defineProperty(Tone.Analyser.prototype, 'smoothing', { + get: function () { + return this._analyser.smoothingTimeConstant; + }, + set: function (val) { + this._analyser.smoothingTimeConstant = val; + } + }); + /** + * The smallest decibel value which is analysed by the FFT. + * @memberOf Tone.Analyser# + * @type {Decibels} + * @name minDecibels + */ + Object.defineProperty(Tone.Analyser.prototype, 'minDecibels', { + get: function () { + return this._analyser.minDecibels; + }, + set: function (val) { + this._analyser.minDecibels = val; + } + }); + /** + * The largest decibel value which is analysed by the FFT. + * @memberOf Tone.Analyser# + * @type {Decibels} + * @name maxDecibels + */ + Object.defineProperty(Tone.Analyser.prototype, 'maxDecibels', { + get: function () { + return this._analyser.maxDecibels; + }, + set: function (val) { + this._analyser.maxDecibels = val; + } + }); + /** + * Clean up. + * @return {Tone.Analyser} this + */ + Tone.Analyser.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._analyser.disconnect(); + this._analyser = null; + this._buffer = null; + }; + return Tone.Analyser; + }); + Module(function (Tone) { + + /** + * @class Tone.Compressor is a thin wrapper around the Web Audio + * [DynamicsCompressorNode](http://webaudio.github.io/web-audio-api/#the-dynamicscompressornode-interface). + * Compression reduces the volume of loud sounds or amplifies quiet sounds + * by narrowing or "compressing" an audio signal's dynamic range. + * Read more on [Wikipedia](https://en.wikipedia.org/wiki/Dynamic_range_compression). + * + * @extends {Tone} + * @constructor + * @param {Decibels|Object} [threshold] The value above which the compression starts to be applied. + * @param {Positive} [ratio] The gain reduction ratio. + * @example + * var comp = new Tone.Compressor(-30, 3); + */ + Tone.Compressor = function () { + var options = this.optionsObject(arguments, [ + 'threshold', + 'ratio' + ], Tone.Compressor.defaults); + /** + * the compressor node + * @type {DynamicsCompressorNode} + * @private + */ + this._compressor = this.input = this.output = this.context.createDynamicsCompressor(); + /** + * the threshold vaue + * @type {Decibels} + * @signal + */ + this.threshold = new Tone.Param({ + 'param': this._compressor.threshold, + 'units': Tone.Type.Decibels, + 'convert': false + }); + /** + * The attack parameter + * @type {Time} + * @signal + */ + this.attack = new Tone.Param(this._compressor.attack, Tone.Type.Time); + /** + * The release parameter + * @type {Time} + * @signal + */ + this.release = new Tone.Param(this._compressor.release, Tone.Type.Time); + /** + * The knee parameter + * @type {Decibels} + * @signal + */ + this.knee = new Tone.Param({ + 'param': this._compressor.knee, + 'units': Tone.Type.Decibels, + 'convert': false + }); + /** + * The ratio value + * @type {Number} + * @signal + */ + this.ratio = new Tone.Param({ + 'param': this._compressor.ratio, + 'convert': false + }); + //set the defaults + this._readOnly([ + 'knee', + 'release', + 'attack', + 'ratio', + 'threshold' + ]); + this.set(options); + }; + Tone.extend(Tone.Compressor); + /** + * @static + * @const + * @type {Object} + */ + Tone.Compressor.defaults = { + 'ratio': 12, + 'threshold': -24, + 'release': 0.25, + 'attack': 0.003, + 'knee': 30 + }; + /** + * clean up + * @returns {Tone.Compressor} this + */ + Tone.Compressor.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._writable([ + 'knee', + 'release', + 'attack', + 'ratio', + 'threshold' + ]); + this._compressor.disconnect(); + this._compressor = null; + this.attack.dispose(); + this.attack = null; + this.release.dispose(); + this.release = null; + this.threshold.dispose(); + this.threshold = null; + this.ratio.dispose(); + this.ratio = null; + this.knee.dispose(); + this.knee = null; + return this; + }; + return Tone.Compressor; + }); + Module(function (Tone) { + + /** + * @class Add a signal and a number or two signals. When no value is + * passed into the constructor, Tone.Add will sum input[0] + * and input[1]. If a value is passed into the constructor, + * the it will be added to the input. + * + * @constructor + * @extends {Tone.Signal} + * @param {number=} value If no value is provided, Tone.Add will sum the first + * and second inputs. + * @example + * var signal = new Tone.Signal(2); + * var add = new Tone.Add(2); + * signal.connect(add); + * //the output of add equals 4 + * @example + * //if constructed with no arguments + * //it will add the first and second inputs + * var add = new Tone.Add(); + * var sig0 = new Tone.Signal(3).connect(add, 0, 0); + * var sig1 = new Tone.Signal(4).connect(add, 0, 1); + * //the output of add equals 7. + */ + Tone.Add = function (value) { + this.createInsOuts(2, 0); + /** + * the summing node + * @type {GainNode} + * @private + */ + this._sum = this.input[0] = this.input[1] = this.output = new Tone.Gain(); + /** + * @private + * @type {Tone.Signal} + */ + this._param = this.input[1] = new Tone.Signal(value); + this._param.connect(this._sum); + }; + Tone.extend(Tone.Add, Tone.Signal); + /** + * Clean up. + * @returns {Tone.Add} this + */ + Tone.Add.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._sum.dispose(); + this._sum = null; + this._param.dispose(); + this._param = null; + return this; + }; + return Tone.Add; + }); + Module(function (Tone) { + + /** + * @class Multiply two incoming signals. Or, if a number is given in the constructor, + * multiplies the incoming signal by that value. + * + * @constructor + * @extends {Tone.Signal} + * @param {number=} value Constant value to multiple. If no value is provided, + * it will return the product of the first and second inputs + * @example + * var mult = new Tone.Multiply(); + * var sigA = new Tone.Signal(3); + * var sigB = new Tone.Signal(4); + * sigA.connect(mult, 0, 0); + * sigB.connect(mult, 0, 1); + * //output of mult is 12. + * @example + * var mult = new Tone.Multiply(10); + * var sig = new Tone.Signal(2).connect(mult); + * //the output of mult is 20. + */ + Tone.Multiply = function (value) { + this.createInsOuts(2, 0); + /** + * the input node is the same as the output node + * it is also the GainNode which handles the scaling of incoming signal + * + * @type {GainNode} + * @private + */ + this._mult = this.input[0] = this.output = new Tone.Gain(); + /** + * the scaling parameter + * @type {AudioParam} + * @private + */ + this._param = this.input[1] = this.output.gain; + this._param.value = this.defaultArg(value, 0); + }; + Tone.extend(Tone.Multiply, Tone.Signal); + /** + * clean up + * @returns {Tone.Multiply} this + */ + Tone.Multiply.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._mult.dispose(); + this._mult = null; + this._param = null; + return this; + }; + return Tone.Multiply; + }); + Module(function (Tone) { + + /** + * @class Negate the incoming signal. i.e. an input signal of 10 will output -10 + * + * @constructor + * @extends {Tone.SignalBase} + * @example + * var neg = new Tone.Negate(); + * var sig = new Tone.Signal(-2).connect(neg); + * //output of neg is positive 2. + */ + Tone.Negate = function () { + /** + * negation is done by multiplying by -1 + * @type {Tone.Multiply} + * @private + */ + this._multiply = this.input = this.output = new Tone.Multiply(-1); + }; + Tone.extend(Tone.Negate, Tone.SignalBase); + /** + * clean up + * @returns {Tone.Negate} this + */ + Tone.Negate.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._multiply.dispose(); + this._multiply = null; + return this; + }; + return Tone.Negate; + }); + Module(function (Tone) { + + /** + * @class Subtract the signal connected to input[1] from the signal connected + * to input[0]. If an argument is provided in the constructor, the + * signals .value will be subtracted from the incoming signal. + * + * @extends {Tone.Signal} + * @constructor + * @param {number=} value The value to subtract from the incoming signal. If the value + * is omitted, it will subtract the second signal from the first. + * @example + * var sub = new Tone.Subtract(1); + * var sig = new Tone.Signal(4).connect(sub); + * //the output of sub is 3. + * @example + * var sub = new Tone.Subtract(); + * var sigA = new Tone.Signal(10); + * var sigB = new Tone.Signal(2.5); + * sigA.connect(sub, 0, 0); + * sigB.connect(sub, 0, 1); + * //output of sub is 7.5 + */ + Tone.Subtract = function (value) { + this.createInsOuts(2, 0); + /** + * the summing node + * @type {GainNode} + * @private + */ + this._sum = this.input[0] = this.output = new Tone.Gain(); + /** + * negate the input of the second input before connecting it + * to the summing node. + * @type {Tone.Negate} + * @private + */ + this._neg = new Tone.Negate(); + /** + * the node where the value is set + * @private + * @type {Tone.Signal} + */ + this._param = this.input[1] = new Tone.Signal(value); + this._param.chain(this._neg, this._sum); + }; + Tone.extend(Tone.Subtract, Tone.Signal); + /** + * Clean up. + * @returns {Tone.SignalBase} this + */ + Tone.Subtract.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._neg.dispose(); + this._neg = null; + this._sum.disconnect(); + this._sum = null; + this._param.dispose(); + this._param = null; + return this; + }; + return Tone.Subtract; + }); + Module(function (Tone) { + + /** + * @class GreaterThanZero outputs 1 when the input is strictly greater than zero + * + * @constructor + * @extends {Tone.SignalBase} + * @example + * var gt0 = new Tone.GreaterThanZero(); + * var sig = new Tone.Signal(0.01).connect(gt0); + * //the output of gt0 is 1. + * sig.value = 0; + * //the output of gt0 is 0. + */ + Tone.GreaterThanZero = function () { + /** + * @type {Tone.WaveShaper} + * @private + */ + this._thresh = this.output = new Tone.WaveShaper(function (val) { + if (val <= 0) { + return 0; + } else { + return 1; + } + }, 127); + /** + * scale the first thresholded signal by a large value. + * this will help with values which are very close to 0 + * @type {Tone.Multiply} + * @private + */ + this._scale = this.input = new Tone.Multiply(10000); + //connections + this._scale.connect(this._thresh); + }; + Tone.extend(Tone.GreaterThanZero, Tone.SignalBase); + /** + * dispose method + * @returns {Tone.GreaterThanZero} this + */ + Tone.GreaterThanZero.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._scale.dispose(); + this._scale = null; + this._thresh.dispose(); + this._thresh = null; + return this; + }; + return Tone.GreaterThanZero; + }); + Module(function (Tone) { + + /** + * @class Output 1 if the signal is greater than the value, otherwise outputs 0. + * can compare two signals or a signal and a number. + * + * @constructor + * @extends {Tone.Signal} + * @param {number} [value=0] the value to compare to the incoming signal + * @example + * var gt = new Tone.GreaterThan(2); + * var sig = new Tone.Signal(4).connect(gt); + * //output of gt is equal 1. + */ + Tone.GreaterThan = function (value) { + this.createInsOuts(2, 0); + /** + * subtract the amount from the incoming signal + * @type {Tone.Subtract} + * @private + */ + this._param = this.input[0] = new Tone.Subtract(value); + this.input[1] = this._param.input[1]; + /** + * compare that amount to zero + * @type {Tone.GreaterThanZero} + * @private + */ + this._gtz = this.output = new Tone.GreaterThanZero(); + //connect + this._param.connect(this._gtz); + }; + Tone.extend(Tone.GreaterThan, Tone.Signal); + /** + * dispose method + * @returns {Tone.GreaterThan} this + */ + Tone.GreaterThan.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._param.dispose(); + this._param = null; + this._gtz.dispose(); + this._gtz = null; + return this; + }; + return Tone.GreaterThan; + }); + Module(function (Tone) { + + /** + * @class Return the absolute value of an incoming signal. + * + * @constructor + * @extends {Tone.SignalBase} + * @example + * var signal = new Tone.Signal(-1); + * var abs = new Tone.Abs(); + * signal.connect(abs); + * //the output of abs is 1. + */ + Tone.Abs = function () { + /** + * @type {Tone.LessThan} + * @private + */ + this._abs = this.input = this.output = new Tone.WaveShaper(function (val) { + if (val === 0) { + return 0; + } else { + return Math.abs(val); + } + }, 127); + }; + Tone.extend(Tone.Abs, Tone.SignalBase); + /** + * dispose method + * @returns {Tone.Abs} this + */ + Tone.Abs.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._abs.dispose(); + this._abs = null; + return this; + }; + return Tone.Abs; + }); + Module(function (Tone) { + + /** + * @class Signal-rate modulo operator. Only works in AudioRange [-1, 1] and for modulus + * values in the NormalRange. + * + * @constructor + * @extends {Tone.SignalBase} + * @param {NormalRange} modulus The modulus to apply. + * @example + * var mod = new Tone.Modulo(0.2) + * var sig = new Tone.Signal(0.5).connect(mod); + * //mod outputs 0.1 + */ + Tone.Modulo = function (modulus) { + this.createInsOuts(1, 0); + /** + * A waveshaper gets the integer multiple of + * the input signal and the modulus. + * @private + * @type {Tone.WaveShaper} + */ + this._shaper = new Tone.WaveShaper(Math.pow(2, 16)); + /** + * the integer multiple is multiplied by the modulus + * @type {Tone.Multiply} + * @private + */ + this._multiply = new Tone.Multiply(); + /** + * and subtracted from the input signal + * @type {Tone.Subtract} + * @private + */ + this._subtract = this.output = new Tone.Subtract(); + /** + * the modulus signal + * @type {Tone.Signal} + * @private + */ + this._modSignal = new Tone.Signal(modulus); + //connections + this.input.fan(this._shaper, this._subtract); + this._modSignal.connect(this._multiply, 0, 0); + this._shaper.connect(this._multiply, 0, 1); + this._multiply.connect(this._subtract, 0, 1); + this._setWaveShaper(modulus); + }; + Tone.extend(Tone.Modulo, Tone.SignalBase); + /** + * @param {number} mod the modulus to apply + * @private + */ + Tone.Modulo.prototype._setWaveShaper = function (mod) { + this._shaper.setMap(function (val) { + var multiple = Math.floor((val + 0.0001) / mod); + return multiple; + }); + }; + /** + * The modulus value. + * @memberOf Tone.Modulo# + * @type {NormalRange} + * @name value + */ + Object.defineProperty(Tone.Modulo.prototype, 'value', { + get: function () { + return this._modSignal.value; + }, + set: function (mod) { + this._modSignal.value = mod; + this._setWaveShaper(mod); + } + }); + /** + * clean up + * @returns {Tone.Modulo} this + */ + Tone.Modulo.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._shaper.dispose(); + this._shaper = null; + this._multiply.dispose(); + this._multiply = null; + this._subtract.dispose(); + this._subtract = null; + this._modSignal.dispose(); + this._modSignal = null; + return this; + }; + return Tone.Modulo; + }); + Module(function (Tone) { + + /** + * @class AudioToGain converts an input in AudioRange [-1,1] to NormalRange [0,1]. + * See Tone.GainToAudio. + * + * @extends {Tone.SignalBase} + * @constructor + * @example + * var a2g = new Tone.AudioToGain(); + */ + Tone.AudioToGain = function () { + /** + * @type {WaveShaperNode} + * @private + */ + this._norm = this.input = this.output = new Tone.WaveShaper(function (x) { + return (x + 1) / 2; + }); + }; + Tone.extend(Tone.AudioToGain, Tone.SignalBase); + /** + * clean up + * @returns {Tone.AudioToGain} this + */ + Tone.AudioToGain.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._norm.dispose(); + this._norm = null; + return this; + }; + return Tone.AudioToGain; + }); + Module(function (Tone) { + + /** + * @class Evaluate an expression at audio rate.

+ * Parsing code modified from https://code.google.com/p/tapdigit/ + * Copyright 2011 2012 Ariya Hidayat, New BSD License + * + * @extends {Tone.SignalBase} + * @constructor + * @param {string} expr the expression to generate + * @example + * //adds the signals from input[0] and input[1]. + * var expr = new Tone.Expr("$0 + $1"); + */ + Tone.Expr = function () { + var expr = this._replacements(Array.prototype.slice.call(arguments)); + var inputCount = this._parseInputs(expr); + /** + * hold onto all of the nodes for disposal + * @type {Array} + * @private + */ + this._nodes = []; + /** + * The inputs. The length is determined by the expression. + * @type {Array} + */ + this.input = new Array(inputCount); + //create a gain for each input + for (var i = 0; i < inputCount; i++) { + this.input[i] = this.context.createGain(); + } + //parse the syntax tree + var tree = this._parseTree(expr); + //evaluate the results + var result; + try { + result = this._eval(tree); + } catch (e) { + this._disposeNodes(); + throw new Error('Tone.Expr: Could evaluate expression: ' + expr); + } + /** + * The output node is the result of the expression + * @type {Tone} + */ + this.output = result; + }; + Tone.extend(Tone.Expr, Tone.SignalBase); + //some helpers to cut down the amount of code + function applyBinary(Constructor, args, self) { + var op = new Constructor(); + self._eval(args[0]).connect(op, 0, 0); + self._eval(args[1]).connect(op, 0, 1); + return op; + } + function applyUnary(Constructor, args, self) { + var op = new Constructor(); + self._eval(args[0]).connect(op, 0, 0); + return op; + } + function getNumber(arg) { + return arg ? parseFloat(arg) : undefined; + } + function literalNumber(arg) { + return arg && arg.args ? parseFloat(arg.args) : undefined; + } + /* + * the Expressions that Tone.Expr can parse. + * + * each expression belongs to a group and contains a regexp + * for selecting the operator as well as that operators method + * + * @type {Object} + * @private + */ + Tone.Expr._Expressions = { + //values + 'value': { + 'signal': { + regexp: /^\d+\.\d+|^\d+/, + method: function (arg) { + var sig = new Tone.Signal(getNumber(arg)); + return sig; + } + }, + 'input': { + regexp: /^\$\d/, + method: function (arg, self) { + return self.input[getNumber(arg.substr(1))]; + } + } + }, + //syntactic glue + 'glue': { + '(': { regexp: /^\(/ }, + ')': { regexp: /^\)/ }, + ',': { regexp: /^,/ } + }, + //functions + 'func': { + 'abs': { + regexp: /^abs/, + method: applyUnary.bind(this, Tone.Abs) + }, + 'mod': { + regexp: /^mod/, + method: function (args, self) { + var modulus = literalNumber(args[1]); + var op = new Tone.Modulo(modulus); + self._eval(args[0]).connect(op); + return op; + } + }, + 'pow': { + regexp: /^pow/, + method: function (args, self) { + var exp = literalNumber(args[1]); + var op = new Tone.Pow(exp); + self._eval(args[0]).connect(op); + return op; + } + }, + 'a2g': { + regexp: /^a2g/, + method: function (args, self) { + var op = new Tone.AudioToGain(); + self._eval(args[0]).connect(op); + return op; + } + } + }, + //binary expressions + 'binary': { + '+': { + regexp: /^\+/, + precedence: 1, + method: applyBinary.bind(this, Tone.Add) + }, + '-': { + regexp: /^\-/, + precedence: 1, + method: function (args, self) { + //both unary and binary op + if (args.length === 1) { + return applyUnary(Tone.Negate, args, self); + } else { + return applyBinary(Tone.Subtract, args, self); + } + } + }, + '*': { + regexp: /^\*/, + precedence: 0, + method: applyBinary.bind(this, Tone.Multiply) + } + }, + //unary expressions + 'unary': { + '-': { + regexp: /^\-/, + method: applyUnary.bind(this, Tone.Negate) + }, + '!': { + regexp: /^\!/, + method: applyUnary.bind(this, Tone.NOT) + } + } + }; + /** + * @param {string} expr the expression string + * @return {number} the input count + * @private + */ + Tone.Expr.prototype._parseInputs = function (expr) { + var inputArray = expr.match(/\$\d/g); + var inputMax = 0; + if (inputArray !== null) { + for (var i = 0; i < inputArray.length; i++) { + var inputNum = parseInt(inputArray[i].substr(1)) + 1; + inputMax = Math.max(inputMax, inputNum); + } + } + return inputMax; + }; + /** + * @param {Array} args an array of arguments + * @return {string} the results of the replacements being replaced + * @private + */ + Tone.Expr.prototype._replacements = function (args) { + var expr = args.shift(); + for (var i = 0; i < args.length; i++) { + expr = expr.replace(/\%/i, args[i]); + } + return expr; + }; + /** + * tokenize the expression based on the Expressions object + * @param {string} expr + * @return {Object} returns two methods on the tokenized list, next and peek + * @private + */ + Tone.Expr.prototype._tokenize = function (expr) { + var position = -1; + var tokens = []; + while (expr.length > 0) { + expr = expr.trim(); + var token = getNextToken(expr); + tokens.push(token); + expr = expr.substr(token.value.length); + } + function getNextToken(expr) { + for (var type in Tone.Expr._Expressions) { + var group = Tone.Expr._Expressions[type]; + for (var opName in group) { + var op = group[opName]; + var reg = op.regexp; + var match = expr.match(reg); + if (match !== null) { + return { + type: type, + value: match[0], + method: op.method + }; + } + } + } + throw new SyntaxError('Tone.Expr: Unexpected token ' + expr); + } + return { + next: function () { + return tokens[++position]; + }, + peek: function () { + return tokens[position + 1]; + } + }; + }; + /** + * recursively parse the string expression into a syntax tree + * + * @param {string} expr + * @return {Object} + * @private + */ + Tone.Expr.prototype._parseTree = function (expr) { + var lexer = this._tokenize(expr); + var isUndef = this.isUndef.bind(this); + function matchSyntax(token, syn) { + return !isUndef(token) && token.type === 'glue' && token.value === syn; + } + function matchGroup(token, groupName, prec) { + var ret = false; + var group = Tone.Expr._Expressions[groupName]; + if (!isUndef(token)) { + for (var opName in group) { + var op = group[opName]; + if (op.regexp.test(token.value)) { + if (!isUndef(prec)) { + if (op.precedence === prec) { + return true; + } + } else { + return true; + } + } + } + } + return ret; + } + function parseExpression(precedence) { + if (isUndef(precedence)) { + precedence = 5; + } + var expr; + if (precedence < 0) { + expr = parseUnary(); + } else { + expr = parseExpression(precedence - 1); + } + var token = lexer.peek(); + while (matchGroup(token, 'binary', precedence)) { + token = lexer.next(); + expr = { + operator: token.value, + method: token.method, + args: [ + expr, + parseExpression(precedence - 1) + ] + }; + token = lexer.peek(); + } + return expr; + } + function parseUnary() { + var token, expr; + token = lexer.peek(); + if (matchGroup(token, 'unary')) { + token = lexer.next(); + expr = parseUnary(); + return { + operator: token.value, + method: token.method, + args: [expr] + }; + } + return parsePrimary(); + } + function parsePrimary() { + var token, expr; + token = lexer.peek(); + if (isUndef(token)) { + throw new SyntaxError('Tone.Expr: Unexpected termination of expression'); + } + if (token.type === 'func') { + token = lexer.next(); + return parseFunctionCall(token); + } + if (token.type === 'value') { + token = lexer.next(); + return { + method: token.method, + args: token.value + }; + } + if (matchSyntax(token, '(')) { + lexer.next(); + expr = parseExpression(); + token = lexer.next(); + if (!matchSyntax(token, ')')) { + throw new SyntaxError('Expected )'); + } + return expr; + } + throw new SyntaxError('Tone.Expr: Parse error, cannot process token ' + token.value); + } + function parseFunctionCall(func) { + var token, args = []; + token = lexer.next(); + if (!matchSyntax(token, '(')) { + throw new SyntaxError('Tone.Expr: Expected ( in a function call "' + func.value + '"'); + } + token = lexer.peek(); + if (!matchSyntax(token, ')')) { + args = parseArgumentList(); + } + token = lexer.next(); + if (!matchSyntax(token, ')')) { + throw new SyntaxError('Tone.Expr: Expected ) in a function call "' + func.value + '"'); + } + return { + method: func.method, + args: args, + name: name + }; + } + function parseArgumentList() { + var token, expr, args = []; + while (true) { + expr = parseExpression(); + if (isUndef(expr)) { + // TODO maybe throw exception? + break; + } + args.push(expr); + token = lexer.peek(); + if (!matchSyntax(token, ',')) { + break; + } + lexer.next(); + } + return args; + } + return parseExpression(); + }; + /** + * recursively evaluate the expression tree + * @param {Object} tree + * @return {AudioNode} the resulting audio node from the expression + * @private + */ + Tone.Expr.prototype._eval = function (tree) { + if (!this.isUndef(tree)) { + var node = tree.method(tree.args, this); + this._nodes.push(node); + return node; + } + }; + /** + * dispose all the nodes + * @private + */ + Tone.Expr.prototype._disposeNodes = function () { + for (var i = 0; i < this._nodes.length; i++) { + var node = this._nodes[i]; + if (this.isFunction(node.dispose)) { + node.dispose(); + } else if (this.isFunction(node.disconnect)) { + node.disconnect(); + } + node = null; + this._nodes[i] = null; + } + this._nodes = null; + }; + /** + * clean up + */ + Tone.Expr.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._disposeNodes(); + }; + return Tone.Expr; + }); + Module(function (Tone) { + + /** + * @class Convert an incoming signal between 0, 1 to an equal power gain scale. + * + * @extends {Tone.SignalBase} + * @constructor + * @example + * var eqPowGain = new Tone.EqualPowerGain(); + */ + Tone.EqualPowerGain = function () { + /** + * @type {Tone.WaveShaper} + * @private + */ + this._eqPower = this.input = this.output = new Tone.WaveShaper(function (val) { + if (Math.abs(val) < 0.001) { + //should output 0 when input is 0 + return 0; + } else { + return this.equalPowerScale(val); + } + }.bind(this), 4096); + }; + Tone.extend(Tone.EqualPowerGain, Tone.SignalBase); + /** + * clean up + * @returns {Tone.EqualPowerGain} this + */ + Tone.EqualPowerGain.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._eqPower.dispose(); + this._eqPower = null; + return this; + }; + return Tone.EqualPowerGain; + }); + Module(function (Tone) { + + /** + * @class Tone.Crossfade provides equal power fading between two inputs. + * More on crossfading technique [here](https://en.wikipedia.org/wiki/Fade_(audio_engineering)#Crossfading). + * + * @constructor + * @extends {Tone} + * @param {NormalRange} [initialFade=0.5] + * @example + * var crossFade = new Tone.CrossFade(0.5); + * //connect effect A to crossfade from + * //effect output 0 to crossfade input 0 + * effectA.connect(crossFade, 0, 0); + * //connect effect B to crossfade from + * //effect output 0 to crossfade input 1 + * effectB.connect(crossFade, 0, 1); + * crossFade.fade.value = 0; + * // ^ only effectA is output + * crossFade.fade.value = 1; + * // ^ only effectB is output + * crossFade.fade.value = 0.5; + * // ^ the two signals are mixed equally. + */ + Tone.CrossFade = function (initialFade) { + this.createInsOuts(2, 1); + /** + * Alias for input[0]. + * @type {Tone.Gain} + */ + this.a = this.input[0] = new Tone.Gain(); + /** + * Alias for input[1]. + * @type {Tone.Gain} + */ + this.b = this.input[1] = new Tone.Gain(); + /** + * The mix between the two inputs. A fade value of 0 + * will output 100% input[0] and + * a value of 1 will output 100% input[1]. + * @type {NormalRange} + * @signal + */ + this.fade = new Tone.Signal(this.defaultArg(initialFade, 0.5), Tone.Type.NormalRange); + /** + * equal power gain cross fade + * @private + * @type {Tone.EqualPowerGain} + */ + this._equalPowerA = new Tone.EqualPowerGain(); + /** + * equal power gain cross fade + * @private + * @type {Tone.EqualPowerGain} + */ + this._equalPowerB = new Tone.EqualPowerGain(); + /** + * invert the incoming signal + * @private + * @type {Tone} + */ + this._invert = new Tone.Expr('1 - $0'); + //connections + this.a.connect(this.output); + this.b.connect(this.output); + this.fade.chain(this._equalPowerB, this.b.gain); + this.fade.chain(this._invert, this._equalPowerA, this.a.gain); + this._readOnly('fade'); + }; + Tone.extend(Tone.CrossFade); + /** + * clean up + * @returns {Tone.CrossFade} this + */ + Tone.CrossFade.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._writable('fade'); + this._equalPowerA.dispose(); + this._equalPowerA = null; + this._equalPowerB.dispose(); + this._equalPowerB = null; + this.fade.dispose(); + this.fade = null; + this._invert.dispose(); + this._invert = null; + this.a.dispose(); + this.a = null; + this.b.dispose(); + this.b = null; + return this; + }; + return Tone.CrossFade; + }); + Module(function (Tone) { + + /** + * @class Tone.Filter is a filter which allows for all of the same native methods + * as the [BiquadFilterNode](http://webaudio.github.io/web-audio-api/#the-biquadfilternode-interface). + * Tone.Filter has the added ability to set the filter rolloff at -12 + * (default), -24 and -48. + * + * @constructor + * @extends {Tone} + * @param {Frequency|Object} [frequency] The cutoff frequency of the filter. + * @param {string=} type The type of filter. + * @param {number=} rolloff The drop in decibels per octave after the cutoff frequency. + * 3 choices: -12, -24, and -48 + * @example + * var filter = new Tone.Filter(200, "highpass"); + */ + Tone.Filter = function () { + this.createInsOuts(1, 1); + var options = this.optionsObject(arguments, [ + 'frequency', + 'type', + 'rolloff' + ], Tone.Filter.defaults); + /** + * the filter(s) + * @type {Array} + * @private + */ + this._filters = []; + /** + * The cutoff frequency of the filter. + * @type {Frequency} + * @signal + */ + this.frequency = new Tone.Signal(options.frequency, Tone.Type.Frequency); + /** + * The detune parameter + * @type {Cents} + * @signal + */ + this.detune = new Tone.Signal(0, Tone.Type.Cents); + /** + * The gain of the filter, only used in certain filter types + * @type {Number} + * @signal + */ + this.gain = new Tone.Signal({ + 'value': options.gain, + 'convert': false + }); + /** + * The Q or Quality of the filter + * @type {Positive} + * @signal + */ + this.Q = new Tone.Signal(options.Q); + /** + * the type of the filter + * @type {string} + * @private + */ + this._type = options.type; + /** + * the rolloff value of the filter + * @type {number} + * @private + */ + this._rolloff = options.rolloff; + //set the rolloff; + this.rolloff = options.rolloff; + this._readOnly([ + 'detune', + 'frequency', + 'gain', + 'Q' + ]); + }; + Tone.extend(Tone.Filter); + /** + * the default parameters + * + * @static + * @type {Object} + */ + Tone.Filter.defaults = { + 'type': 'lowpass', + 'frequency': 350, + 'rolloff': -12, + 'Q': 1, + 'gain': 0 + }; + /** + * The type of the filter. Types: "lowpass", "highpass", + * "bandpass", "lowshelf", "highshelf", "notch", "allpass", or "peaking". + * @memberOf Tone.Filter# + * @type {string} + * @name type + */ + Object.defineProperty(Tone.Filter.prototype, 'type', { + get: function () { + return this._type; + }, + set: function (type) { + var types = [ + 'lowpass', + 'highpass', + 'bandpass', + 'lowshelf', + 'highshelf', + 'notch', + 'allpass', + 'peaking' + ]; + if (types.indexOf(type) === -1) { + throw new TypeError('Tone.Filter: invalid type ' + type); + } + this._type = type; + for (var i = 0; i < this._filters.length; i++) { + this._filters[i].type = type; + } + } + }); + /** + * The rolloff of the filter which is the drop in db + * per octave. Implemented internally by cascading filters. + * Only accepts the values -12, -24, -48 and -96. + * @memberOf Tone.Filter# + * @type {number} + * @name rolloff + */ + Object.defineProperty(Tone.Filter.prototype, 'rolloff', { + get: function () { + return this._rolloff; + }, + set: function (rolloff) { + rolloff = parseInt(rolloff, 10); + var possibilities = [ + -12, + -24, + -48, + -96 + ]; + var cascadingCount = possibilities.indexOf(rolloff); + //check the rolloff is valid + if (cascadingCount === -1) { + throw new RangeError('Tone.Filter: rolloff can only be -12, -24, -48 or -96'); + } + cascadingCount += 1; + this._rolloff = rolloff; + //first disconnect the filters and throw them away + this.input.disconnect(); + for (var i = 0; i < this._filters.length; i++) { + this._filters[i].disconnect(); + this._filters[i] = null; + } + this._filters = new Array(cascadingCount); + for (var count = 0; count < cascadingCount; count++) { + var filter = this.context.createBiquadFilter(); + filter.type = this._type; + this.frequency.connect(filter.frequency); + this.detune.connect(filter.detune); + this.Q.connect(filter.Q); + this.gain.connect(filter.gain); + this._filters[count] = filter; + } + //connect them up + var connectionChain = [this.input].concat(this._filters).concat([this.output]); + this.connectSeries.apply(this, connectionChain); + } + }); + /** + * Clean up. + * @return {Tone.Filter} this + */ + Tone.Filter.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + for (var i = 0; i < this._filters.length; i++) { + this._filters[i].disconnect(); + this._filters[i] = null; + } + this._filters = null; + this._writable([ + 'detune', + 'frequency', + 'gain', + 'Q' + ]); + this.frequency.dispose(); + this.Q.dispose(); + this.frequency = null; + this.Q = null; + this.detune.dispose(); + this.detune = null; + this.gain.dispose(); + this.gain = null; + return this; + }; + return Tone.Filter; + }); + Module(function (Tone) { + + /** + * @class Split the incoming signal into three bands (low, mid, high) + * with two crossover frequency controls. + * + * @extends {Tone} + * @constructor + * @param {Frequency|Object} [lowFrequency] the low/mid crossover frequency + * @param {Frequency} [highFrequency] the mid/high crossover frequency + */ + Tone.MultibandSplit = function () { + var options = this.optionsObject(arguments, [ + 'lowFrequency', + 'highFrequency' + ], Tone.MultibandSplit.defaults); + /** + * the input + * @type {Tone.Gain} + * @private + */ + this.input = new Tone.Gain(); + /** + * the outputs + * @type {Array} + * @private + */ + this.output = new Array(3); + /** + * The low band. Alias for output[0] + * @type {Tone.Filter} + */ + this.low = this.output[0] = new Tone.Filter(0, 'lowpass'); + /** + * the lower filter of the mid band + * @type {Tone.Filter} + * @private + */ + this._lowMidFilter = new Tone.Filter(0, 'highpass'); + /** + * The mid band output. Alias for output[1] + * @type {Tone.Filter} + */ + this.mid = this.output[1] = new Tone.Filter(0, 'lowpass'); + /** + * The high band output. Alias for output[2] + * @type {Tone.Filter} + */ + this.high = this.output[2] = new Tone.Filter(0, 'highpass'); + /** + * The low/mid crossover frequency. + * @type {Frequency} + * @signal + */ + this.lowFrequency = new Tone.Signal(options.lowFrequency, Tone.Type.Frequency); + /** + * The mid/high crossover frequency. + * @type {Frequency} + * @signal + */ + this.highFrequency = new Tone.Signal(options.highFrequency, Tone.Type.Frequency); + /** + * The quality of all the filters + * @type {Number} + * @signal + */ + this.Q = new Tone.Signal(options.Q); + this.input.fan(this.low, this.high); + this.input.chain(this._lowMidFilter, this.mid); + //the frequency control signal + this.lowFrequency.connect(this.low.frequency); + this.lowFrequency.connect(this._lowMidFilter.frequency); + this.highFrequency.connect(this.mid.frequency); + this.highFrequency.connect(this.high.frequency); + //the Q value + this.Q.connect(this.low.Q); + this.Q.connect(this._lowMidFilter.Q); + this.Q.connect(this.mid.Q); + this.Q.connect(this.high.Q); + this._readOnly([ + 'high', + 'mid', + 'low', + 'highFrequency', + 'lowFrequency' + ]); + }; + Tone.extend(Tone.MultibandSplit); + /** + * @private + * @static + * @type {Object} + */ + Tone.MultibandSplit.defaults = { + 'lowFrequency': 400, + 'highFrequency': 2500, + 'Q': 1 + }; + /** + * Clean up. + * @returns {Tone.MultibandSplit} this + */ + Tone.MultibandSplit.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._writable([ + 'high', + 'mid', + 'low', + 'highFrequency', + 'lowFrequency' + ]); + this.low.dispose(); + this.low = null; + this._lowMidFilter.dispose(); + this._lowMidFilter = null; + this.mid.dispose(); + this.mid = null; + this.high.dispose(); + this.high = null; + this.lowFrequency.dispose(); + this.lowFrequency = null; + this.highFrequency.dispose(); + this.highFrequency = null; + this.Q.dispose(); + this.Q = null; + return this; + }; + return Tone.MultibandSplit; + }); + Module(function (Tone) { + + /** + * @class Tone.EQ3 is a three band EQ with control over low, mid, and high gain as + * well as the low and high crossover frequencies. + * + * @constructor + * @extends {Tone} + * + * @param {Decibels|Object} [lowLevel] The gain applied to the lows. + * @param {Decibels} [midLevel] The gain applied to the mid. + * @param {Decibels} [highLevel] The gain applied to the high. + * @example + * var eq = new Tone.EQ3(-10, 3, -20); + */ + Tone.EQ3 = function () { + var options = this.optionsObject(arguments, [ + 'low', + 'mid', + 'high' + ], Tone.EQ3.defaults); + /** + * the output node + * @type {GainNode} + * @private + */ + this.output = new Tone.Gain(); + /** + * the multiband split + * @type {Tone.MultibandSplit} + * @private + */ + this._multibandSplit = this.input = new Tone.MultibandSplit({ + 'lowFrequency': options.lowFrequency, + 'highFrequency': options.highFrequency + }); + /** + * The gain for the lower signals + * @type {Tone.Gain} + * @private + */ + this._lowGain = new Tone.Gain(options.low, Tone.Type.Decibels); + /** + * The gain for the mid signals + * @type {Tone.Gain} + * @private + */ + this._midGain = new Tone.Gain(options.mid, Tone.Type.Decibels); + /** + * The gain in decibels of the high part + * @type {Tone.Gain} + * @private + */ + this._highGain = new Tone.Gain(options.high, Tone.Type.Decibels); + /** + * The gain in decibels of the low part + * @type {Decibels} + * @signal + */ + this.low = this._lowGain.gain; + /** + * The gain in decibels of the mid part + * @type {Decibels} + * @signal + */ + this.mid = this._midGain.gain; + /** + * The gain in decibels of the high part + * @type {Decibels} + * @signal + */ + this.high = this._highGain.gain; + /** + * The Q value for all of the filters. + * @type {Positive} + * @signal + */ + this.Q = this._multibandSplit.Q; + /** + * The low/mid crossover frequency. + * @type {Frequency} + * @signal + */ + this.lowFrequency = this._multibandSplit.lowFrequency; + /** + * The mid/high crossover frequency. + * @type {Frequency} + * @signal + */ + this.highFrequency = this._multibandSplit.highFrequency; + //the frequency bands + this._multibandSplit.low.chain(this._lowGain, this.output); + this._multibandSplit.mid.chain(this._midGain, this.output); + this._multibandSplit.high.chain(this._highGain, this.output); + this._readOnly([ + 'low', + 'mid', + 'high', + 'lowFrequency', + 'highFrequency' + ]); + }; + Tone.extend(Tone.EQ3); + /** + * the default values + */ + Tone.EQ3.defaults = { + 'low': 0, + 'mid': 0, + 'high': 0, + 'lowFrequency': 400, + 'highFrequency': 2500 + }; + /** + * clean up + * @returns {Tone.EQ3} this + */ + Tone.EQ3.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._writable([ + 'low', + 'mid', + 'high', + 'lowFrequency', + 'highFrequency' + ]); + this._multibandSplit.dispose(); + this._multibandSplit = null; + this.lowFrequency = null; + this.highFrequency = null; + this._lowGain.dispose(); + this._lowGain = null; + this._midGain.dispose(); + this._midGain = null; + this._highGain.dispose(); + this._highGain = null; + this.low = null; + this.mid = null; + this.high = null; + this.Q = null; + return this; + }; + return Tone.EQ3; + }); + Module(function (Tone) { + + /** + * @class Performs a linear scaling on an input signal. + * Scales a NormalRange input to between + * outputMin and outputMax. + * + * @constructor + * @extends {Tone.SignalBase} + * @param {number} [outputMin=0] The output value when the input is 0. + * @param {number} [outputMax=1] The output value when the input is 1. + * @example + * var scale = new Tone.Scale(50, 100); + * var signal = new Tone.Signal(0.5).connect(scale); + * //the output of scale equals 75 + */ + Tone.Scale = function (outputMin, outputMax) { + /** + * @private + * @type {number} + */ + this._outputMin = this.defaultArg(outputMin, 0); + /** + * @private + * @type {number} + */ + this._outputMax = this.defaultArg(outputMax, 1); + /** + * @private + * @type {Tone.Multiply} + * @private + */ + this._scale = this.input = new Tone.Multiply(1); + /** + * @private + * @type {Tone.Add} + * @private + */ + this._add = this.output = new Tone.Add(0); + this._scale.connect(this._add); + this._setRange(); + }; + Tone.extend(Tone.Scale, Tone.SignalBase); + /** + * The minimum output value. This number is output when + * the value input value is 0. + * @memberOf Tone.Scale# + * @type {number} + * @name min + */ + Object.defineProperty(Tone.Scale.prototype, 'min', { + get: function () { + return this._outputMin; + }, + set: function (min) { + this._outputMin = min; + this._setRange(); + } + }); + /** + * The maximum output value. This number is output when + * the value input value is 1. + * @memberOf Tone.Scale# + * @type {number} + * @name max + */ + Object.defineProperty(Tone.Scale.prototype, 'max', { + get: function () { + return this._outputMax; + }, + set: function (max) { + this._outputMax = max; + this._setRange(); + } + }); + /** + * set the values + * @private + */ + Tone.Scale.prototype._setRange = function () { + this._add.value = this._outputMin; + this._scale.value = this._outputMax - this._outputMin; + }; + /** + * Clean up. + * @returns {Tone.Scale} this + */ + Tone.Scale.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._add.dispose(); + this._add = null; + this._scale.dispose(); + this._scale = null; + return this; + }; + return Tone.Scale; + }); + Module(function (Tone) { + /** + * @class Performs an exponential scaling on an input signal. + * Scales a NormalRange value [0,1] exponentially + * to the output range of outputMin to outputMax. + * + * @constructor + * @extends {Tone.SignalBase} + * @param {number} [outputMin=0] The output value when the input is 0. + * @param {number} [outputMax=1] The output value when the input is 1. + * @param {number} [exponent=2] The exponent which scales the incoming signal. + * @example + * var scaleExp = new Tone.ScaleExp(0, 100, 2); + * var signal = new Tone.Signal(0.5).connect(scaleExp); + */ + Tone.ScaleExp = function (outputMin, outputMax, exponent) { + /** + * scale the input to the output range + * @type {Tone.Scale} + * @private + */ + this._scale = this.output = new Tone.Scale(outputMin, outputMax); + /** + * @private + * @type {Tone.Pow} + * @private + */ + this._exp = this.input = new Tone.Pow(this.defaultArg(exponent, 2)); + this._exp.connect(this._scale); + }; + Tone.extend(Tone.ScaleExp, Tone.SignalBase); + /** + * Instead of interpolating linearly between the min and + * max values, setting the exponent will interpolate between + * the two values with an exponential curve. + * @memberOf Tone.ScaleExp# + * @type {number} + * @name exponent + */ + Object.defineProperty(Tone.ScaleExp.prototype, 'exponent', { + get: function () { + return this._exp.value; + }, + set: function (exp) { + this._exp.value = exp; + } + }); + /** + * The minimum output value. This number is output when + * the value input value is 0. + * @memberOf Tone.ScaleExp# + * @type {number} + * @name min + */ + Object.defineProperty(Tone.ScaleExp.prototype, 'min', { + get: function () { + return this._scale.min; + }, + set: function (min) { + this._scale.min = min; + } + }); + /** + * The maximum output value. This number is output when + * the value input value is 1. + * @memberOf Tone.ScaleExp# + * @type {number} + * @name max + */ + Object.defineProperty(Tone.ScaleExp.prototype, 'max', { + get: function () { + return this._scale.max; + }, + set: function (max) { + this._scale.max = max; + } + }); + /** + * Clean up. + * @returns {Tone.ScaleExp} this + */ + Tone.ScaleExp.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._scale.dispose(); + this._scale = null; + this._exp.dispose(); + this._exp = null; + return this; + }; + return Tone.ScaleExp; + }); + Module(function (Tone) { + + /** + * @class Wrapper around Web Audio's native [DelayNode](http://webaudio.github.io/web-audio-api/#the-delaynode-interface). + * @extends {Tone} + * @param {Time=} delayTime The delay applied to the incoming signal. + * @param {Time=} maxDelay The maximum delay time. + */ + Tone.Delay = function () { + var options = this.optionsObject(arguments, [ + 'delayTime', + 'maxDelay' + ], Tone.Delay.defaults); + /** + * The native delay node + * @type {DelayNode} + * @private + */ + this._delayNode = this.input = this.output = this.context.createDelay(this.toSeconds(options.maxDelay)); + /** + * The amount of time the incoming signal is + * delayed. + * @type {Tone.Param} + * @signal + */ + this.delayTime = new Tone.Param({ + 'param': this._delayNode.delayTime, + 'units': Tone.Type.Time, + 'value': options.delayTime + }); + this._readOnly('delayTime'); + }; + Tone.extend(Tone.Delay); + /** + * The defaults + * @const + * @type {Object} + */ + Tone.Delay.defaults = { + 'maxDelay': 1, + 'delayTime': 0 + }; + /** + * Clean up. + * @return {Tone.Delay} this + */ + Tone.Delay.prototype.dispose = function () { + Tone.Param.prototype.dispose.call(this); + this._delayNode.disconnect(); + this._delayNode = null; + this._writable('delayTime'); + this.delayTime = null; + return this; + }; + return Tone.Delay; + }); + Module(function (Tone) { + + /** + * @class Comb filters are basic building blocks for physical modeling. Read more + * about comb filters on [CCRMA's website](https://ccrma.stanford.edu/~jos/pasp/Feedback_Comb_Filters.html). + * + * @extends {Tone} + * @constructor + * @param {Time|Object} [delayTime] The delay time of the filter. + * @param {NormalRange=} resonance The amount of feedback the filter has. + */ + Tone.FeedbackCombFilter = function () { + var options = this.optionsObject(arguments, [ + 'delayTime', + 'resonance' + ], Tone.FeedbackCombFilter.defaults); + /** + * the delay node + * @type {DelayNode} + * @private + */ + this._delay = this.input = this.output = new Tone.Delay(options.delayTime); + /** + * The amount of delay of the comb filter. + * @type {Time} + * @signal + */ + this.delayTime = this._delay.delayTime; + /** + * the feedback node + * @type {GainNode} + * @private + */ + this._feedback = new Tone.Gain(options.resonance, Tone.Type.NormalRange); + /** + * The amount of feedback of the delayed signal. + * @type {NormalRange} + * @signal + */ + this.resonance = this._feedback.gain; + this._delay.chain(this._feedback, this._delay); + this._readOnly([ + 'resonance', + 'delayTime' + ]); + }; + Tone.extend(Tone.FeedbackCombFilter); + /** + * the default parameters + * @static + * @const + * @type {Object} + */ + Tone.FeedbackCombFilter.defaults = { + 'delayTime': 0.1, + 'resonance': 0.5 + }; + /** + * clean up + * @returns {Tone.FeedbackCombFilter} this + */ + Tone.FeedbackCombFilter.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._writable([ + 'resonance', + 'delayTime' + ]); + this._delay.dispose(); + this._delay = null; + this.delayTime = null; + this._feedback.dispose(); + this._feedback = null; + this.resonance = null; + return this; + }; + return Tone.FeedbackCombFilter; + }); + Module(function (Tone) { + + /** + * @class Tone.Follower is a crude envelope follower which will follow + * the amplitude of an incoming signal. + * Take care with small (< 0.02) attack or decay values + * as follower has some ripple which is exaggerated + * at these values. Read more about envelope followers (also known + * as envelope detectors) on [Wikipedia](https://en.wikipedia.org/wiki/Envelope_detector). + * + * @constructor + * @extends {Tone} + * @param {Time|Object} [attack] The rate at which the follower rises. + * @param {Time=} release The rate at which the folower falls. + * @example + * var follower = new Tone.Follower(0.2, 0.4); + */ + Tone.Follower = function () { + this.createInsOuts(1, 1); + var options = this.optionsObject(arguments, [ + 'attack', + 'release' + ], Tone.Follower.defaults); + /** + * @type {Tone.Abs} + * @private + */ + this._abs = new Tone.Abs(); + /** + * the lowpass filter which smooths the input + * @type {BiquadFilterNode} + * @private + */ + this._filter = this.context.createBiquadFilter(); + this._filter.type = 'lowpass'; + this._filter.frequency.value = 0; + this._filter.Q.value = -100; + /** + * @type {WaveShaperNode} + * @private + */ + this._frequencyValues = new Tone.WaveShaper(); + /** + * @type {Tone.Subtract} + * @private + */ + this._sub = new Tone.Subtract(); + /** + * @type {Tone.Delay} + * @private + */ + this._delay = new Tone.Delay(this.blockTime); + /** + * this keeps it far from 0, even for very small differences + * @type {Tone.Multiply} + * @private + */ + this._mult = new Tone.Multiply(10000); + /** + * @private + * @type {number} + */ + this._attack = options.attack; + /** + * @private + * @type {number} + */ + this._release = options.release; + //the smoothed signal to get the values + this.input.chain(this._abs, this._filter, this.output); + //the difference path + this._abs.connect(this._sub, 0, 1); + this._filter.chain(this._delay, this._sub); + //threshold the difference and use the thresh to set the frequency + this._sub.chain(this._mult, this._frequencyValues, this._filter.frequency); + //set the attack and release values in the table + this._setAttackRelease(this._attack, this._release); + }; + Tone.extend(Tone.Follower); + /** + * @static + * @type {Object} + */ + Tone.Follower.defaults = { + 'attack': 0.05, + 'release': 0.5 + }; + /** + * sets the attack and release times in the wave shaper + * @param {Time} attack + * @param {Time} release + * @private + */ + Tone.Follower.prototype._setAttackRelease = function (attack, release) { + var minTime = this.blockTime; + attack = Tone.Time(attack).toFrequency(); + release = Tone.Time(release).toFrequency(); + attack = Math.max(attack, minTime); + release = Math.max(release, minTime); + this._frequencyValues.setMap(function (val) { + if (val <= 0) { + return attack; + } else { + return release; + } + }); + }; + /** + * The attack time. + * @memberOf Tone.Follower# + * @type {Time} + * @name attack + */ + Object.defineProperty(Tone.Follower.prototype, 'attack', { + get: function () { + return this._attack; + }, + set: function (attack) { + this._attack = attack; + this._setAttackRelease(this._attack, this._release); + } + }); + /** + * The release time. + * @memberOf Tone.Follower# + * @type {Time} + * @name release + */ + Object.defineProperty(Tone.Follower.prototype, 'release', { + get: function () { + return this._release; + }, + set: function (release) { + this._release = release; + this._setAttackRelease(this._attack, this._release); + } + }); + /** + * Borrows the connect method from Signal so that the output can be used + * as a Tone.Signal control signal. + * @function + */ + Tone.Follower.prototype.connect = Tone.Signal.prototype.connect; + /** + * dispose + * @returns {Tone.Follower} this + */ + Tone.Follower.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._filter.disconnect(); + this._filter = null; + this._frequencyValues.disconnect(); + this._frequencyValues = null; + this._delay.dispose(); + this._delay = null; + this._sub.disconnect(); + this._sub = null; + this._abs.dispose(); + this._abs = null; + this._mult.dispose(); + this._mult = null; + this._curve = null; + return this; + }; + return Tone.Follower; + }); + Module(function (Tone) { + + /** + * @class Tone.ScaledEnvelop is an envelope which can be scaled + * to any range. It's useful for applying an envelope + * to a frequency or any other non-NormalRange signal + * parameter. + * + * @extends {Tone.Envelope} + * @constructor + * @param {Time|Object} [attack] the attack time in seconds + * @param {Time} [decay] the decay time in seconds + * @param {number} [sustain] a percentage (0-1) of the full amplitude + * @param {Time} [release] the release time in seconds + * @example + * var scaledEnv = new Tone.ScaledEnvelope({ + * "attack" : 0.2, + * "min" : 200, + * "max" : 2000 + * }); + * scaledEnv.connect(oscillator.frequency); + */ + Tone.ScaledEnvelope = function () { + //get all of the defaults + var options = this.optionsObject(arguments, [ + 'attack', + 'decay', + 'sustain', + 'release' + ], Tone.Envelope.defaults); + Tone.Envelope.call(this, options); + options = this.defaultArg(options, Tone.ScaledEnvelope.defaults); + /** + * scale the incoming signal by an exponent + * @type {Tone.Pow} + * @private + */ + this._exp = this.output = new Tone.Pow(options.exponent); + /** + * scale the signal to the desired range + * @type {Tone.Multiply} + * @private + */ + this._scale = this.output = new Tone.Scale(options.min, options.max); + this._sig.chain(this._exp, this._scale); + }; + Tone.extend(Tone.ScaledEnvelope, Tone.Envelope); + /** + * the default parameters + * @static + */ + Tone.ScaledEnvelope.defaults = { + 'min': 0, + 'max': 1, + 'exponent': 1 + }; + /** + * The envelope's min output value. This is the value which it + * starts at. + * @memberOf Tone.ScaledEnvelope# + * @type {number} + * @name min + */ + Object.defineProperty(Tone.ScaledEnvelope.prototype, 'min', { + get: function () { + return this._scale.min; + }, + set: function (min) { + this._scale.min = min; + } + }); + /** + * The envelope's max output value. In other words, the value + * at the peak of the attack portion of the envelope. + * @memberOf Tone.ScaledEnvelope# + * @type {number} + * @name max + */ + Object.defineProperty(Tone.ScaledEnvelope.prototype, 'max', { + get: function () { + return this._scale.max; + }, + set: function (max) { + this._scale.max = max; + } + }); + /** + * The envelope's exponent value. + * @memberOf Tone.ScaledEnvelope# + * @type {number} + * @name exponent + */ + Object.defineProperty(Tone.ScaledEnvelope.prototype, 'exponent', { + get: function () { + return this._exp.value; + }, + set: function (exp) { + this._exp.value = exp; + } + }); + /** + * clean up + * @returns {Tone.ScaledEnvelope} this + */ + Tone.ScaledEnvelope.prototype.dispose = function () { + Tone.Envelope.prototype.dispose.call(this); + this._scale.dispose(); + this._scale = null; + this._exp.dispose(); + this._exp = null; + return this; + }; + return Tone.ScaledEnvelope; + }); + Module(function (Tone) { + + /** + * @class Tone.FrequencyEnvelope is a Tone.ScaledEnvelope, but instead of `min` and `max` + * it's got a `baseFrequency` and `octaves` parameter. + * + * @extends {Tone.Envelope} + * @constructor + * @param {Time|Object} [attack] the attack time in seconds + * @param {Time} [decay] the decay time in seconds + * @param {number} [sustain] a percentage (0-1) of the full amplitude + * @param {Time} [release] the release time in seconds + * @example + * var env = new Tone.FrequencyEnvelope({ + * "attack" : 0.2, + * "baseFrequency" : "C2", + * "octaves" : 4 + * }); + * scaledEnv.connect(oscillator.frequency); + */ + Tone.FrequencyEnvelope = function () { + var options = this.optionsObject(arguments, [ + 'attack', + 'decay', + 'sustain', + 'release' + ], Tone.Envelope.defaults); + Tone.ScaledEnvelope.call(this, options); + options = this.defaultArg(options, Tone.FrequencyEnvelope.defaults); + /** + * Stores the octave value + * @type {Positive} + * @private + */ + this._octaves = options.octaves; + //setup + this.baseFrequency = options.baseFrequency; + this.octaves = options.octaves; + }; + Tone.extend(Tone.FrequencyEnvelope, Tone.Envelope); + /** + * the default parameters + * @static + */ + Tone.FrequencyEnvelope.defaults = { + 'baseFrequency': 200, + 'octaves': 4, + 'exponent': 2 + }; + /** + * The envelope's mininum output value. This is the value which it + * starts at. + * @memberOf Tone.FrequencyEnvelope# + * @type {Frequency} + * @name baseFrequency + */ + Object.defineProperty(Tone.FrequencyEnvelope.prototype, 'baseFrequency', { + get: function () { + return this._scale.min; + }, + set: function (min) { + this._scale.min = this.toFrequency(min); + //also update the octaves + this.octaves = this._octaves; + } + }); + /** + * The number of octaves above the baseFrequency that the + * envelope will scale to. + * @memberOf Tone.FrequencyEnvelope# + * @type {Positive} + * @name octaves + */ + Object.defineProperty(Tone.FrequencyEnvelope.prototype, 'octaves', { + get: function () { + return this._octaves; + }, + set: function (octaves) { + this._octaves = octaves; + this._scale.max = this.baseFrequency * Math.pow(2, octaves); + } + }); + /** + * The envelope's exponent value. + * @memberOf Tone.FrequencyEnvelope# + * @type {number} + * @name exponent + */ + Object.defineProperty(Tone.FrequencyEnvelope.prototype, 'exponent', { + get: function () { + return this._exp.value; + }, + set: function (exp) { + this._exp.value = exp; + } + }); + /** + * clean up + * @returns {Tone.FrequencyEnvelope} this + */ + Tone.FrequencyEnvelope.prototype.dispose = function () { + Tone.ScaledEnvelope.prototype.dispose.call(this); + return this; + }; + return Tone.FrequencyEnvelope; + }); + Module(function (Tone) { + + /** + * @class Tone.Gate only passes a signal through when the incoming + * signal exceeds a specified threshold. To do this, Gate uses + * a Tone.Follower to follow the amplitude of the incoming signal. + * A common implementation of this class is a [Noise Gate](https://en.wikipedia.org/wiki/Noise_gate). + * + * @constructor + * @extends {Tone} + * @param {Decibels|Object} [threshold] The threshold above which the gate will open. + * @param {Time=} attack The follower's attack time + * @param {Time=} release The follower's release time + * @example + * var gate = new Tone.Gate(-30, 0.2, 0.3).toMaster(); + * var mic = new Tone.UserMedia().connect(gate); + * //the gate will only pass through the incoming + * //signal when it's louder than -30db + */ + Tone.Gate = function () { + this.createInsOuts(1, 1); + var options = this.optionsObject(arguments, [ + 'threshold', + 'attack', + 'release' + ], Tone.Gate.defaults); + /** + * @type {Tone.Follower} + * @private + */ + this._follower = new Tone.Follower(options.attack, options.release); + /** + * @type {Tone.GreaterThan} + * @private + */ + this._gt = new Tone.GreaterThan(this.dbToGain(options.threshold)); + //the connections + this.input.connect(this.output); + //the control signal + this.input.chain(this._gt, this._follower, this.output.gain); + }; + Tone.extend(Tone.Gate); + /** + * @const + * @static + * @type {Object} + */ + Tone.Gate.defaults = { + 'attack': 0.1, + 'release': 0.1, + 'threshold': -40 + }; + /** + * The threshold of the gate in decibels + * @memberOf Tone.Gate# + * @type {Decibels} + * @name threshold + */ + Object.defineProperty(Tone.Gate.prototype, 'threshold', { + get: function () { + return this.gainToDb(this._gt.value); + }, + set: function (thresh) { + this._gt.value = this.dbToGain(thresh); + } + }); + /** + * The attack speed of the gate + * @memberOf Tone.Gate# + * @type {Time} + * @name attack + */ + Object.defineProperty(Tone.Gate.prototype, 'attack', { + get: function () { + return this._follower.attack; + }, + set: function (attackTime) { + this._follower.attack = attackTime; + } + }); + /** + * The release speed of the gate + * @memberOf Tone.Gate# + * @type {Time} + * @name release + */ + Object.defineProperty(Tone.Gate.prototype, 'release', { + get: function () { + return this._follower.release; + }, + set: function (releaseTime) { + this._follower.release = releaseTime; + } + }); + /** + * Clean up. + * @returns {Tone.Gate} this + */ + Tone.Gate.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._follower.dispose(); + this._gt.dispose(); + this._follower = null; + this._gt = null; + return this; + }; + return Tone.Gate; + }); + Module(function (Tone) { + + /** + * @class A Timeline State. Provides the methods: setStateAtTime("state", time) + * and getValueAtTime(time). + * + * @extends {Tone.Timeline} + * @param {String} initial The initial state of the TimelineState. + * Defaults to undefined + */ + Tone.TimelineState = function (initial) { + Tone.Timeline.call(this); + /** + * The initial state + * @private + * @type {String} + */ + this._initial = initial; + }; + Tone.extend(Tone.TimelineState, Tone.Timeline); + /** + * Returns the scheduled state scheduled before or at + * the given time. + * @param {Number} time The time to query. + * @return {String} The name of the state input in setStateAtTime. + */ + Tone.TimelineState.prototype.getValueAtTime = function (time) { + var event = this.get(time); + if (event !== null) { + return event.state; + } else { + return this._initial; + } + }; + /** + * Returns the scheduled state scheduled before or at + * the given time. + * @param {String} state The name of the state to set. + * @param {Number} time The time to query. + */ + Tone.TimelineState.prototype.setStateAtTime = function (state, time) { + this.add({ + 'state': state, + 'time': time + }); + }; + return Tone.TimelineState; + }); + Module(function (Tone) { + + /** + * @class Tone.Emitter gives classes which extend it + * the ability to listen for and emit events. + * Inspiration and reference from Jerome Etienne's [MicroEvent](https://github.com/jeromeetienne/microevent.js). + * MIT (c) 2011 Jerome Etienne. + * + * @extends {Tone} + */ + Tone.Emitter = function () { + /** + * Contains all of the events. + * @private + * @type {Object} + */ + this._events = {}; + }; + Tone.extend(Tone.Emitter); + /** + * Bind a callback to a specific event. + * @param {String} event The name of the event to listen for. + * @param {Function} callback The callback to invoke when the + * event is emitted + * @return {Tone.Emitter} this + */ + Tone.Emitter.prototype.on = function (event, callback) { + //split the event + var events = event.split(/\W+/); + for (var i = 0; i < events.length; i++) { + var eventName = events[i]; + if (!this._events.hasOwnProperty(eventName)) { + this._events[eventName] = []; + } + this._events[eventName].push(callback); + } + return this; + }; + /** + * Remove the event listener. + * @param {String} event The event to stop listening to. + * @param {Function=} callback The callback which was bound to + * the event with Tone.Emitter.on. + * If no callback is given, all callbacks + * events are removed. + * @return {Tone.Emitter} this + */ + Tone.Emitter.prototype.off = function (event, callback) { + var events = event.split(/\W+/); + for (var ev = 0; ev < events.length; ev++) { + event = events[ev]; + if (this._events.hasOwnProperty(event)) { + if (Tone.prototype.isUndef(callback)) { + this._events[event] = []; + } else { + var eventList = this._events[event]; + for (var i = 0; i < eventList.length; i++) { + if (eventList[i] === callback) { + eventList.splice(i, 1); + } + } + } + } + } + return this; + }; + /** + * Invoke all of the callbacks bound to the event + * with any arguments passed in. + * @param {String} event The name of the event. + * @param {*...} args The arguments to pass to the functions listening. + * @return {Tone.Emitter} this + */ + Tone.Emitter.prototype.emit = function (event) { + if (this._events) { + var args = Array.prototype.slice.call(arguments, 1); + if (this._events.hasOwnProperty(event)) { + var eventList = this._events[event]; + for (var i = 0, len = eventList.length; i < len; i++) { + eventList[i].apply(this, args); + } + } + } + return this; + }; + /** + * Add Emitter functions (on/off/emit) to the object + * @param {Object|Function} object The object or class to extend. + */ + Tone.Emitter.mixin = function (object) { + var functions = [ + 'on', + 'off', + 'emit' + ]; + object._events = {}; + for (var i = 0; i < functions.length; i++) { + var func = functions[i]; + var emitterFunc = Tone.Emitter.prototype[func]; + object[func] = emitterFunc; + } + }; + /** + * Clean up + * @return {Tone.Emitter} this + */ + Tone.Emitter.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._events = null; + return this; + }; + return Tone.Emitter; + }); + Module(function (Tone) { + + /** + * @class A sample accurate clock which provides a callback at the given rate. + * While the callback is not sample-accurate (it is still susceptible to + * loose JS timing), the time passed in as the argument to the callback + * is precise. For most applications, it is better to use Tone.Transport + * instead of the Clock by itself since you can synchronize multiple callbacks. + * + * @constructor + * @extends {Tone.Emitter} + * @param {function} callback The callback to be invoked with the time of the audio event + * @param {Frequency} frequency The rate of the callback + * @example + * //the callback will be invoked approximately once a second + * //and will print the time exactly once a second apart. + * var clock = new Tone.Clock(function(time){ + * console.log(time); + * }, 1); + */ + Tone.Clock = function () { + Tone.Emitter.call(this); + var options = this.optionsObject(arguments, [ + 'callback', + 'frequency' + ], Tone.Clock.defaults); + /** + * The callback function to invoke at the scheduled tick. + * @type {Function} + */ + this.callback = options.callback; + /** + * The next time the callback is scheduled. + * @type {Number} + * @private + */ + this._nextTick = 0; + /** + * The last state of the clock. + * @type {State} + * @private + */ + this._lastState = Tone.State.Stopped; + /** + * The rate the callback function should be invoked. + * @type {BPM} + * @signal + */ + this.frequency = new Tone.TimelineSignal(options.frequency, Tone.Type.Frequency); + this._readOnly('frequency'); + /** + * The number of times the callback was invoked. Starts counting at 0 + * and increments after the callback was invoked. + * @type {Ticks} + * @readOnly + */ + this.ticks = 0; + /** + * The state timeline + * @type {Tone.TimelineState} + * @private + */ + this._state = new Tone.TimelineState(Tone.State.Stopped); + /** + * The loop function bound to its context. + * This is necessary to remove the event in the end. + * @type {Function} + * @private + */ + this._boundLoop = this._loop.bind(this); + //bind a callback to the worker thread + Tone.Clock._worker.addEventListener('message', this._boundLoop); + }; + Tone.extend(Tone.Clock, Tone.Emitter); + /** + * The defaults + * @const + * @type {Object} + */ + Tone.Clock.defaults = { + 'callback': Tone.noOp, + 'frequency': 1, + 'lookAhead': 'auto' + }; + /** + * Returns the playback state of the source, either "started", "stopped" or "paused". + * @type {Tone.State} + * @readOnly + * @memberOf Tone.Clock# + * @name state + */ + Object.defineProperty(Tone.Clock.prototype, 'state', { + get: function () { + return this._state.getValueAtTime(this.now()); + } + }); + /** + * Start the clock at the given time. Optionally pass in an offset + * of where to start the tick counter from. + * @param {Time} time The time the clock should start + * @param {Ticks=} offset Where the tick counter starts counting from. + * @return {Tone.Clock} this + */ + Tone.Clock.prototype.start = function (time, offset) { + time = this.toSeconds(time); + if (this._state.getValueAtTime(time) !== Tone.State.Started) { + this._state.add({ + 'state': Tone.State.Started, + 'time': time, + 'offset': offset + }); + } + return this; + }; + /** + * Stop the clock. Stopping the clock resets the tick counter to 0. + * @param {Time} [time=now] The time when the clock should stop. + * @returns {Tone.Clock} this + * @example + * clock.stop(); + */ + Tone.Clock.prototype.stop = function (time) { + time = this.toSeconds(time); + this._state.cancel(time); + this._state.setStateAtTime(Tone.State.Stopped, time); + return this; + }; + /** + * Pause the clock. Pausing does not reset the tick counter. + * @param {Time} [time=now] The time when the clock should stop. + * @returns {Tone.Clock} this + */ + Tone.Clock.prototype.pause = function (time) { + time = this.toSeconds(time); + if (this._state.getValueAtTime(time) === Tone.State.Started) { + this._state.setStateAtTime(Tone.State.Paused, time); + } + return this; + }; + /** + * The scheduling loop. + * @param {Number} time The current page time starting from 0 + * when the page was loaded. + * @private + */ + Tone.Clock.prototype._loop = function () { + //get the frequency value to compute the value of the next loop + var now = this.now(); + //if it's started + var lookAhead = Tone.Clock.lookAhead; + var updateInterval = Tone.Clock.updateInterval; + var lagCompensation = Tone.Clock.lag * 2; + var loopInterval = now + lookAhead + updateInterval + lagCompensation; + while (loopInterval > this._nextTick && this._state) { + var currentState = this._state.getValueAtTime(this._nextTick); + if (currentState !== this._lastState) { + this._lastState = currentState; + var event = this._state.get(this._nextTick); + // emit an event + if (currentState === Tone.State.Started) { + //correct the time + this._nextTick = event.time; + if (!this.isUndef(event.offset)) { + this.ticks = event.offset; + } + this.emit('start', event.time, this.ticks); + } else if (currentState === Tone.State.Stopped) { + this.ticks = 0; + this.emit('stop', event.time); + } else if (currentState === Tone.State.Paused) { + this.emit('pause', event.time); + } + } + var tickTime = this._nextTick; + if (this.frequency) { + this._nextTick += 1 / this.frequency.getValueAtTime(this._nextTick); + if (currentState === Tone.State.Started) { + this.callback(tickTime); + this.ticks++; + } + } + } + }; + /** + * Returns the scheduled state at the given time. + * @param {Time} time The time to query. + * @return {String} The name of the state input in setStateAtTime. + * @example + * clock.start("+0.1"); + * clock.getStateAtTime("+0.1"); //returns "started" + */ + Tone.Clock.prototype.getStateAtTime = function (time) { + time = this.toSeconds(time); + return this._state.getValueAtTime(time); + }; + /** + * Clean up + * @returns {Tone.Clock} this + */ + Tone.Clock.prototype.dispose = function () { + Tone.Emitter.prototype.dispose.call(this); + Tone.Clock._worker.removeEventListener('message', this._boundLoop); + this._writable('frequency'); + this.frequency.dispose(); + this.frequency = null; + this._boundLoop = null; + this._nextTick = Infinity; + this.callback = null; + this._state.dispose(); + this._state = null; + }; + /////////////////////////////////////////////////////////////////////////// + // WORKER + /////////////////////////////////////////////////////////////////////////// + //URL Shim + window.URL = window.URL || window.webkitURL; + /** + * The minimum amount of time events are + * scheduled in advance. + * @private + * @type {Number} + */ + Tone.Clock._lookAhead = 0.1; + /** + * How often the worker ticks + * @type {Seconds} + * @private + */ + Tone.Clock._updateInterval = Tone.Clock._lookAhead / 3; + /** + * The script which runs in a web worker + * @type {Blob} + * @private + */ + var blob = new Blob([//the initial timeout time + 'var timeoutTime = ' + Tone.Clock._updateInterval * 1000 + ';' + //onmessage callback + 'self.onmessage = function(msg){' + '\ttimeoutTime = parseInt(msg.data);' + '};' + //the tick function which posts a message + //and schedules a new tick + 'function tick(){' + '\tsetTimeout(tick, timeoutTime);' + '\tself.postMessage(\'tick\');' + '}' + //call tick initially + 'tick();']); + /** + * Create a blob url from the Blob + * @type {URL} + * @private + */ + var blobUrl = URL.createObjectURL(blob); + /** + * The Worker which generates a regular callback + * @type {Worker} + * @private + * @static + */ + Tone.Clock._worker = new Worker(blobUrl); + /** + * @private + * @type {Number} + * The time of the last update + */ + var lastUpdate = -1; + /** + * The current computed update rate of the clock. + * @type {Number} + * @private + */ + var computedUpdateInterval = 0; + //listen for message events and update the global clock lookahead + Tone.Clock._worker.addEventListener('message', function () { + var now = Tone.now(); + if (lastUpdate !== -1) { + var diff = now - lastUpdate; + computedUpdateInterval = Math.max(diff, computedUpdateInterval * 0.97); + } + lastUpdate = now; + }); + /** + * This is the time that the clock is falling behind + * the scheduled update interval. The Clock automatically + * adjusts for the lag and schedules further in advance. + * @type {Number} + * @memberOf Tone.Clock + * @name lag + * @static + * @readOnly + */ + Object.defineProperty(Tone.Clock, 'lag', { + get: function () { + var diff = computedUpdateInterval - Tone.Clock._updateInterval; + diff = Math.max(diff, 0); + return diff; + } + }); + /** + * The amount of time in advance that events are scheduled. + * The lookAhead will adjust slightly in response to the + * measured update time to try to avoid clicks. + * @type {Number} + * @memberOf Tone.Clock + * @name lookAhead + * @static + */ + Object.defineProperty(Tone.Clock, 'lookAhead', { + get: function () { + return Tone.Clock._lookAhead; + }, + set: function (lA) { + Tone.Clock._lookAhead = lA; + } + }); + /** + * How often the Web Worker callback is invoked. + * This number corresponds to how responsive the scheduling + * can be. Clock.updateInterval + Clock.lookAhead gives you the + * total latency between scheduling an event and hearing it. + * @type {Number} + * @memberOf Tone.Clock + * @name updateInterval + * @static + */ + Object.defineProperty(Tone.Clock, 'updateInterval', { + get: function () { + return Tone.Clock._updateInterval; + }, + set: function (interval) { + Tone.Clock._updateInterval = Math.max(interval, 0.01); + Tone.Clock._worker.postMessage(interval * 1000); + } + }); + /** + * The latency hint + * @private + * @type {String|Number} + */ + var latencyHint = 'interactive'; + /** + * The type of playback, which affects tradeoffs between audio + * output latency and responsiveness. + * + * In addition to setting the value in seconds, the latencyHint also + * accepts the strings "interactive" (prioritizes low latency), + * "playback" (prioritizes sustained playback), "balanced" (balances + * latency and performance), and "fastest" (lowest latency, might glitch more often). + * @type {String|Seconds} + * @memberOf Tone.Clock# + * @name latencyHint + * @static + * @example + * //set the lookAhead to 0.3 seconds + * Tone.Clock.latencyHint = 0.3; + */ + Object.defineProperty(Tone.Clock, 'latencyHint', { + get: function () { + return latencyHint; + }, + set: function (hint) { + var lookAhead = hint; + latencyHint = hint; + if (Tone.prototype.isString(hint)) { + switch (hint) { + case 'interactive': + lookAhead = 0.1; + Tone.context.latencyHint = hint; + break; + case 'playback': + lookAhead = 0.8; + Tone.context.latencyHint = hint; + break; + case 'balanced': + lookAhead = 0.25; + Tone.context.latencyHint = hint; + break; + case 'fastest': + lookAhead = 0.01; + break; + } + } + Tone.Clock.lookAhead = lookAhead; + Tone.Clock.updateInterval = lookAhead / 3; + } + }); + Tone._initAudioContext(function () { + lastUpdate = -1; + computedUpdateInterval = 0; + }); + return Tone.Clock; + }); + Module(function (Tone) { + + /** + * @class Similar to Tone.Timeline, but all events represent + * intervals with both "time" and "duration" times. The + * events are placed in a tree structure optimized + * for querying an intersection point with the timeline + * events. Internally uses an [Interval Tree](https://en.wikipedia.org/wiki/Interval_tree) + * to represent the data. + * @extends {Tone} + */ + Tone.IntervalTimeline = function () { + /** + * The root node of the inteval tree + * @type {IntervalNode} + * @private + */ + this._root = null; + /** + * Keep track of the length of the timeline. + * @type {Number} + * @private + */ + this._length = 0; + }; + Tone.extend(Tone.IntervalTimeline); + /** + * The event to add to the timeline. All events must + * have a time and duration value + * @param {Object} event The event to add to the timeline + * @return {Tone.IntervalTimeline} this + */ + Tone.IntervalTimeline.prototype.add = function (event) { + if (this.isUndef(event.time) || this.isUndef(event.duration)) { + throw new Error('Tone.IntervalTimeline: events must have time and duration parameters'); + } + var node = new IntervalNode(event.time, event.time + event.duration, event); + if (this._root === null) { + this._root = node; + } else { + this._root.insert(node); + } + this._length++; + // Restructure tree to be balanced + while (node !== null) { + node.updateHeight(); + node.updateMax(); + this._rebalance(node); + node = node.parent; + } + return this; + }; + /** + * Remove an event from the timeline. + * @param {Object} event The event to remove from the timeline + * @return {Tone.IntervalTimeline} this + */ + Tone.IntervalTimeline.prototype.remove = function (event) { + if (this._root !== null) { + var results = []; + this._root.search(event.time, results); + for (var i = 0; i < results.length; i++) { + var node = results[i]; + if (node.event === event) { + this._removeNode(node); + this._length--; + break; + } + } + } + return this; + }; + /** + * The number of items in the timeline. + * @type {Number} + * @memberOf Tone.IntervalTimeline# + * @name length + * @readOnly + */ + Object.defineProperty(Tone.IntervalTimeline.prototype, 'length', { + get: function () { + return this._length; + } + }); + /** + * Remove events whose time time is after the given time + * @param {Number} time The time to query. + * @returns {Tone.IntervalTimeline} this + */ + Tone.IntervalTimeline.prototype.cancel = function (after) { + this.forEachAfter(after, function (event) { + this.remove(event); + }.bind(this)); + return this; + }; + /** + * Set the root node as the given node + * @param {IntervalNode} node + * @private + */ + Tone.IntervalTimeline.prototype._setRoot = function (node) { + this._root = node; + if (this._root !== null) { + this._root.parent = null; + } + }; + /** + * Replace the references to the node in the node's parent + * with the replacement node. + * @param {IntervalNode} node + * @param {IntervalNode} replacement + * @private + */ + Tone.IntervalTimeline.prototype._replaceNodeInParent = function (node, replacement) { + if (node.parent !== null) { + if (node.isLeftChild()) { + node.parent.left = replacement; + } else { + node.parent.right = replacement; + } + this._rebalance(node.parent); + } else { + this._setRoot(replacement); + } + }; + /** + * Remove the node from the tree and replace it with + * a successor which follows the schema. + * @param {IntervalNode} node + * @private + */ + Tone.IntervalTimeline.prototype._removeNode = function (node) { + if (node.left === null && node.right === null) { + this._replaceNodeInParent(node, null); + } else if (node.right === null) { + this._replaceNodeInParent(node, node.left); + } else if (node.left === null) { + this._replaceNodeInParent(node, node.right); + } else { + var balance = node.getBalance(); + var replacement, temp; + if (balance > 0) { + if (node.left.right === null) { + replacement = node.left; + replacement.right = node.right; + temp = replacement; + } else { + replacement = node.left.right; + while (replacement.right !== null) { + replacement = replacement.right; + } + replacement.parent.right = replacement.left; + temp = replacement.parent; + replacement.left = node.left; + replacement.right = node.right; + } + } else { + if (node.right.left === null) { + replacement = node.right; + replacement.left = node.left; + temp = replacement; + } else { + replacement = node.right.left; + while (replacement.left !== null) { + replacement = replacement.left; + } + replacement.parent = replacement.parent; + replacement.parent.left = replacement.right; + temp = replacement.parent; + replacement.left = node.left; + replacement.right = node.right; + } + } + if (node.parent !== null) { + if (node.isLeftChild()) { + node.parent.left = replacement; + } else { + node.parent.right = replacement; + } + } else { + this._setRoot(replacement); + } + // this._replaceNodeInParent(node, replacement); + this._rebalance(temp); + } + node.dispose(); + }; + /** + * Rotate the tree to the left + * @param {IntervalNode} node + * @private + */ + Tone.IntervalTimeline.prototype._rotateLeft = function (node) { + var parent = node.parent; + var isLeftChild = node.isLeftChild(); + // Make node.right the new root of this sub tree (instead of node) + var pivotNode = node.right; + node.right = pivotNode.left; + pivotNode.left = node; + if (parent !== null) { + if (isLeftChild) { + parent.left = pivotNode; + } else { + parent.right = pivotNode; + } + } else { + this._setRoot(pivotNode); + } + }; + /** + * Rotate the tree to the right + * @param {IntervalNode} node + * @private + */ + Tone.IntervalTimeline.prototype._rotateRight = function (node) { + var parent = node.parent; + var isLeftChild = node.isLeftChild(); + // Make node.left the new root of this sub tree (instead of node) + var pivotNode = node.left; + node.left = pivotNode.right; + pivotNode.right = node; + if (parent !== null) { + if (isLeftChild) { + parent.left = pivotNode; + } else { + parent.right = pivotNode; + } + } else { + this._setRoot(pivotNode); + } + }; + /** + * Balance the BST + * @param {IntervalNode} node + * @private + */ + Tone.IntervalTimeline.prototype._rebalance = function (node) { + var balance = node.getBalance(); + if (balance > 1) { + if (node.left.getBalance() < 0) { + this._rotateLeft(node.left); + } else { + this._rotateRight(node); + } + } else if (balance < -1) { + if (node.right.getBalance() > 0) { + this._rotateRight(node.right); + } else { + this._rotateLeft(node); + } + } + }; + /** + * Get an event whose time and duration span the give time. Will + * return the match whose "time" value is closest to the given time. + * @param {Object} event The event to add to the timeline + * @return {Object} The event which spans the desired time + */ + Tone.IntervalTimeline.prototype.get = function (time) { + if (this._root !== null) { + var results = []; + this._root.search(time, results); + if (results.length > 0) { + var max = results[0]; + for (var i = 1; i < results.length; i++) { + if (results[i].low > max.low) { + max = results[i]; + } + } + return max.event; + } + } + return null; + }; + /** + * Iterate over everything in the timeline. + * @param {Function} callback The callback to invoke with every item + * @returns {Tone.IntervalTimeline} this + */ + Tone.IntervalTimeline.prototype.forEach = function (callback) { + if (this._root !== null) { + var allNodes = []; + if (this._root !== null) { + this._root.traverse(function (node) { + allNodes.push(node); + }); + } + for (var i = 0; i < allNodes.length; i++) { + var ev = allNodes[i].event; + if (ev) { + callback(ev); + } + } + } + return this; + }; + /** + * Iterate over everything in the array in which the given time + * overlaps with the time and duration time of the event. + * @param {Number} time The time to check if items are overlapping + * @param {Function} callback The callback to invoke with every item + * @returns {Tone.IntervalTimeline} this + */ + Tone.IntervalTimeline.prototype.forEachAtTime = function (time, callback) { + if (this._root !== null) { + var results = []; + this._root.search(time, results); + for (var i = results.length - 1; i >= 0; i--) { + var ev = results[i].event; + if (ev) { + callback(ev); + } + } + } + return this; + }; + /** + * Iterate over everything in the array in which the time is greater + * than the given time. + * @param {Number} time The time to check if items are before + * @param {Function} callback The callback to invoke with every item + * @returns {Tone.IntervalTimeline} this + */ + Tone.IntervalTimeline.prototype.forEachAfter = function (time, callback) { + if (this._root !== null) { + var results = []; + this._root.searchAfter(time, results); + for (var i = results.length - 1; i >= 0; i--) { + var ev = results[i].event; + if (ev) { + callback(ev); + } + } + } + return this; + }; + /** + * Clean up + * @return {Tone.IntervalTimeline} this + */ + Tone.IntervalTimeline.prototype.dispose = function () { + var allNodes = []; + if (this._root !== null) { + this._root.traverse(function (node) { + allNodes.push(node); + }); + } + for (var i = 0; i < allNodes.length; i++) { + allNodes[i].dispose(); + } + allNodes = null; + this._root = null; + return this; + }; + /////////////////////////////////////////////////////////////////////////// + // INTERVAL NODE HELPER + /////////////////////////////////////////////////////////////////////////// + /** + * Represents a node in the binary search tree, with the addition + * of a "high" value which keeps track of the highest value of + * its children. + * References: + * https://brooknovak.wordpress.com/2013/12/07/augmented-interval-tree-in-c/ + * http://www.mif.vu.lt/~valdas/ALGORITMAI/LITERATURA/Cormen/Cormen.pdf + * @param {Number} low + * @param {Number} high + * @private + */ + var IntervalNode = function (low, high, event) { + //the event container + this.event = event; + //the low value + this.low = low; + //the high value + this.high = high; + //the high value for this and all child nodes + this.max = this.high; + //the nodes to the left + this._left = null; + //the nodes to the right + this._right = null; + //the parent node + this.parent = null; + //the number of child nodes + this.height = 0; + }; + /** + * Insert a node into the correct spot in the tree + * @param {IntervalNode} node + */ + IntervalNode.prototype.insert = function (node) { + if (node.low <= this.low) { + if (this.left === null) { + this.left = node; + } else { + this.left.insert(node); + } + } else { + if (this.right === null) { + this.right = node; + } else { + this.right.insert(node); + } + } + }; + /** + * Search the tree for nodes which overlap + * with the given point + * @param {Number} point The point to query + * @param {Array} results The array to put the results + */ + IntervalNode.prototype.search = function (point, results) { + // If p is to the right of the rightmost point of any interval + // in this node and all children, there won't be any matches. + if (point > this.max) { + return; + } + // Search left children + if (this.left !== null) { + this.left.search(point, results); + } + // Check this node + if (this.low <= point && this.high > point) { + results.push(this); + } + // If p is to the left of the time of this interval, + // then it can't be in any child to the right. + if (this.low > point) { + return; + } + // Search right children + if (this.right !== null) { + this.right.search(point, results); + } + }; + /** + * Search the tree for nodes which are less + * than the given point + * @param {Number} point The point to query + * @param {Array} results The array to put the results + */ + IntervalNode.prototype.searchAfter = function (point, results) { + // Check this node + if (this.low >= point) { + results.push(this); + if (this.left !== null) { + this.left.searchAfter(point, results); + } + } + // search the right side + if (this.right !== null) { + this.right.searchAfter(point, results); + } + }; + /** + * Invoke the callback on this element and both it's branches + * @param {Function} callback + */ + IntervalNode.prototype.traverse = function (callback) { + callback(this); + if (this.left !== null) { + this.left.traverse(callback); + } + if (this.right !== null) { + this.right.traverse(callback); + } + }; + /** + * Update the height of the node + */ + IntervalNode.prototype.updateHeight = function () { + if (this.left !== null && this.right !== null) { + this.height = Math.max(this.left.height, this.right.height) + 1; + } else if (this.right !== null) { + this.height = this.right.height + 1; + } else if (this.left !== null) { + this.height = this.left.height + 1; + } else { + this.height = 0; + } + }; + /** + * Update the height of the node + */ + IntervalNode.prototype.updateMax = function () { + this.max = this.high; + if (this.left !== null) { + this.max = Math.max(this.max, this.left.max); + } + if (this.right !== null) { + this.max = Math.max(this.max, this.right.max); + } + }; + /** + * The balance is how the leafs are distributed on the node + * @return {Number} Negative numbers are balanced to the right + */ + IntervalNode.prototype.getBalance = function () { + var balance = 0; + if (this.left !== null && this.right !== null) { + balance = this.left.height - this.right.height; + } else if (this.left !== null) { + balance = this.left.height + 1; + } else if (this.right !== null) { + balance = -(this.right.height + 1); + } + return balance; + }; + /** + * @returns {Boolean} true if this node is the left child + * of its parent + */ + IntervalNode.prototype.isLeftChild = function () { + return this.parent !== null && this.parent.left === this; + }; + /** + * get/set the left node + * @type {IntervalNode} + */ + Object.defineProperty(IntervalNode.prototype, 'left', { + get: function () { + return this._left; + }, + set: function (node) { + this._left = node; + if (node !== null) { + node.parent = this; + } + this.updateHeight(); + this.updateMax(); + } + }); + /** + * get/set the right node + * @type {IntervalNode} + */ + Object.defineProperty(IntervalNode.prototype, 'right', { + get: function () { + return this._right; + }, + set: function (node) { + this._right = node; + if (node !== null) { + node.parent = this; + } + this.updateHeight(); + this.updateMax(); + } + }); + /** + * null out references. + */ + IntervalNode.prototype.dispose = function () { + this.parent = null; + this._left = null; + this._right = null; + this.event = null; + }; + /////////////////////////////////////////////////////////////////////////// + // END INTERVAL NODE HELPER + /////////////////////////////////////////////////////////////////////////// + return Tone.IntervalTimeline; + }); + Module(function (Tone) { + + /** + * @class Transport for timing musical events. + * Supports tempo curves and time changes. Unlike browser-based timing (setInterval, requestAnimationFrame) + * Tone.Transport timing events pass in the exact time of the scheduled event + * in the argument of the callback function. Pass that time value to the object + * you're scheduling.

+ * A single transport is created for you when the library is initialized. + *

+ * The transport emits the events: "start", "stop", "pause", and "loop" which are + * called with the time of that event as the argument. + * + * @extends {Tone.Emitter} + * @singleton + * @example + * //repeated event every 8th note + * Tone.Transport.scheduleRepeat(function(time){ + * //do something with the time + * }, "8n"); + * @example + * //schedule an event on the 16th measure + * Tone.Transport.schedule(function(time){ + * //do something with the time + * }, "16:0:0"); + */ + Tone.Transport = function () { + Tone.Emitter.call(this); + /////////////////////////////////////////////////////////////////////// + // LOOPING + ////////////////////////////////////////////////////////////////////// + /** + * If the transport loops or not. + * @type {boolean} + */ + this.loop = false; + /** + * The loop start position in ticks + * @type {Ticks} + * @private + */ + this._loopStart = 0; + /** + * The loop end position in ticks + * @type {Ticks} + * @private + */ + this._loopEnd = 0; + /////////////////////////////////////////////////////////////////////// + // CLOCK/TEMPO + ////////////////////////////////////////////////////////////////////// + /** + * Pulses per quarter is the number of ticks per quarter note. + * @private + * @type {Number} + */ + this._ppq = TransportConstructor.defaults.PPQ; + /** + * watches the main oscillator for timing ticks + * initially starts at 120bpm + * @private + * @type {Tone.Clock} + */ + this._clock = new Tone.Clock({ + 'callback': this._processTick.bind(this), + 'frequency': 0 + }); + this._bindClockEvents(); + /** + * The Beats Per Minute of the Transport. + * @type {BPM} + * @signal + * @example + * Tone.Transport.bpm.value = 80; + * //ramp the bpm to 120 over 10 seconds + * Tone.Transport.bpm.rampTo(120, 10); + */ + this.bpm = this._clock.frequency; + this.bpm._toUnits = this._toUnits.bind(this); + this.bpm._fromUnits = this._fromUnits.bind(this); + this.bpm.units = Tone.Type.BPM; + this.bpm.value = TransportConstructor.defaults.bpm; + this._readOnly('bpm'); + /** + * The time signature, or more accurately the numerator + * of the time signature over a denominator of 4. + * @type {Number} + * @private + */ + this._timeSignature = TransportConstructor.defaults.timeSignature; + /////////////////////////////////////////////////////////////////////// + // TIMELINE EVENTS + ////////////////////////////////////////////////////////////////////// + /** + * All the events in an object to keep track by ID + * @type {Object} + * @private + */ + this._scheduledEvents = {}; + /** + * The event ID counter + * @type {Number} + * @private + */ + this._eventID = 0; + /** + * The scheduled events. + * @type {Tone.Timeline} + * @private + */ + this._timeline = new Tone.Timeline(); + /** + * Repeated events + * @type {Array} + * @private + */ + this._repeatedEvents = new Tone.IntervalTimeline(); + /** + * Events that occur once + * @type {Array} + * @private + */ + this._onceEvents = new Tone.Timeline(); + /** + * All of the synced Signals + * @private + * @type {Array} + */ + this._syncedSignals = []; + /////////////////////////////////////////////////////////////////////// + // SWING + ////////////////////////////////////////////////////////////////////// + /** + * The subdivision of the swing + * @type {Ticks} + * @private + */ + this._swingTicks = TransportConstructor.defaults.PPQ / 2; + //8n + /** + * The swing amount + * @type {NormalRange} + * @private + */ + this._swingAmount = 0; + }; + Tone.extend(Tone.Transport, Tone.Emitter); + /** + * the defaults + * @type {Object} + * @const + * @static + */ + Tone.Transport.defaults = { + 'bpm': 120, + 'swing': 0, + 'swingSubdivision': '8n', + 'timeSignature': 4, + 'loopStart': 0, + 'loopEnd': '4m', + 'PPQ': 192 + }; + /////////////////////////////////////////////////////////////////////////////// + // TICKS + /////////////////////////////////////////////////////////////////////////////// + /** + * called on every tick + * @param {number} tickTime clock relative tick time + * @private + */ + Tone.Transport.prototype._processTick = function (tickTime) { + var ticks = this._clock.ticks; + //handle swing + if (this._swingAmount > 0 && ticks % this._ppq !== 0 && //not on a downbeat + ticks % (this._swingTicks * 2) !== 0) { + //add some swing + var progress = ticks % (this._swingTicks * 2) / (this._swingTicks * 2); + var amount = Math.sin(progress * Math.PI) * this._swingAmount; + tickTime += Tone.Time(this._swingTicks * 2 / 3, 'i').eval() * amount; + } + //do the loop test + if (this.loop) { + if (ticks === this._loopEnd) { + this.emit('loopEnd', tickTime); + this._clock.ticks = this._loopStart; + ticks = this._loopStart; + this.emit('loopStart', tickTime, this.seconds); + this.emit('loop', tickTime); + } + } + //process the single occurrence events + this._onceEvents.forEachBefore(ticks, function (event) { + event.callback(tickTime); + //remove the event + delete this._scheduledEvents[event.id.toString()]; + }.bind(this)); + //and clear the single occurrence timeline + this._onceEvents.cancelBefore(ticks); + //fire the next tick events if their time has come + this._timeline.forEachAtTime(ticks, function (event) { + event.callback(tickTime); + }); + //process the repeated events + this._repeatedEvents.forEachAtTime(ticks, function (event) { + if ((ticks - event.time) % event.interval === 0) { + event.callback(tickTime); + } + }); + }; + /////////////////////////////////////////////////////////////////////////////// + // SCHEDULABLE EVENTS + /////////////////////////////////////////////////////////////////////////////// + /** + * Schedule an event along the timeline. + * @param {Function} callback The callback to be invoked at the time. + * @param {TransportTime} time The time to invoke the callback at. + * @return {Number} The id of the event which can be used for canceling the event. + * @example + * //trigger the callback when the Transport reaches the desired time + * Tone.Transport.schedule(function(time){ + * envelope.triggerAttack(time); + * }, "128i"); + */ + Tone.Transport.prototype.schedule = function (callback, time) { + var event = { + 'time': this.toTicks(time), + 'callback': callback + }; + var id = this._eventID++; + this._scheduledEvents[id.toString()] = { + 'event': event, + 'timeline': this._timeline + }; + this._timeline.add(event); + return id; + }; + /** + * Schedule a repeated event along the timeline. The event will fire + * at the `interval` starting at the `startTime` and for the specified + * `duration`. + * @param {Function} callback The callback to invoke. + * @param {Time} interval The duration between successive + * callbacks. + * @param {TimelinePosition=} startTime When along the timeline the events should + * start being invoked. + * @param {Time} [duration=Infinity] How long the event should repeat. + * @return {Number} The ID of the scheduled event. Use this to cancel + * the event. + * @example + * //a callback invoked every eighth note after the first measure + * Tone.Transport.scheduleRepeat(callback, "8n", "1m"); + */ + Tone.Transport.prototype.scheduleRepeat = function (callback, interval, startTime, duration) { + if (interval <= 0) { + throw new Error('Tone.Transport: repeat events must have an interval larger than 0'); + } + var event = { + 'time': this.toTicks(startTime), + 'duration': this.toTicks(this.defaultArg(duration, Infinity)), + 'interval': this.toTicks(interval), + 'callback': callback + }; + var id = this._eventID++; + this._scheduledEvents[id.toString()] = { + 'event': event, + 'timeline': this._repeatedEvents + }; + this._repeatedEvents.add(event); + return id; + }; + /** + * Schedule an event that will be removed after it is invoked. + * Note that if the given time is less than the current transport time, + * the event will be invoked immediately. + * @param {Function} callback The callback to invoke once. + * @param {TransportTime} time The time the callback should be invoked. + * @returns {Number} The ID of the scheduled event. + */ + Tone.Transport.prototype.scheduleOnce = function (callback, time) { + var id = this._eventID++; + var event = { + 'time': this.toTicks(time), + 'callback': callback, + 'id': id + }; + this._scheduledEvents[id.toString()] = { + 'event': event, + 'timeline': this._onceEvents + }; + this._onceEvents.add(event); + return id; + }; + /** + * Clear the passed in event id from the timeline + * @param {Number} eventId The id of the event. + * @returns {Tone.Transport} this + */ + Tone.Transport.prototype.clear = function (eventId) { + if (this._scheduledEvents.hasOwnProperty(eventId)) { + var item = this._scheduledEvents[eventId.toString()]; + item.timeline.remove(item.event); + delete this._scheduledEvents[eventId.toString()]; + } + return this; + }; + /** + * Remove scheduled events from the timeline after + * the given time. Repeated events will be removed + * if their startTime is after the given time + * @param {TransportTime} [after=0] Clear all events after + * this time. + * @returns {Tone.Transport} this + */ + Tone.Transport.prototype.cancel = function (after) { + after = this.defaultArg(after, 0); + after = this.toTicks(after); + this._timeline.cancel(after); + this._onceEvents.cancel(after); + this._repeatedEvents.cancel(after); + return this; + }; + /////////////////////////////////////////////////////////////////////////////// + // START/STOP/PAUSE + /////////////////////////////////////////////////////////////////////////////// + /** + * Bind start/stop/pause events from the clock and emit them. + */ + Tone.Transport.prototype._bindClockEvents = function () { + this._clock.on('start', function (time, offset) { + offset = Tone.Time(this._clock.ticks, 'i').toSeconds(); + this.emit('start', time, offset); + }.bind(this)); + this._clock.on('stop', function (time) { + this.emit('stop', time); + }.bind(this)); + this._clock.on('pause', function (time) { + this.emit('pause', time); + }.bind(this)); + }; + /** + * Returns the playback state of the source, either "started", "stopped", or "paused" + * @type {Tone.State} + * @readOnly + * @memberOf Tone.Transport# + * @name state + */ + Object.defineProperty(Tone.Transport.prototype, 'state', { + get: function () { + return this._clock.getStateAtTime(this.now()); + } + }); + /** + * Start the transport and all sources synced to the transport. + * @param {Time} [time=now] The time when the transport should start. + * @param {TransportTime=} offset The timeline offset to start the transport. + * @returns {Tone.Transport} this + * @example + * //start the transport in one second starting at beginning of the 5th measure. + * Tone.Transport.start("+1", "4:0:0"); + */ + Tone.Transport.prototype.start = function (time, offset) { + //start the clock + if (!this.isUndef(offset)) { + offset = this.toTicks(offset); + } + this._clock.start(time, offset); + return this; + }; + /** + * Stop the transport and all sources synced to the transport. + * @param {Time} [time=now] The time when the transport should stop. + * @returns {Tone.Transport} this + * @example + * Tone.Transport.stop(); + */ + Tone.Transport.prototype.stop = function (time) { + this._clock.stop(time); + return this; + }; + /** + * Pause the transport and all sources synced to the transport. + * @param {Time} [time=now] + * @returns {Tone.Transport} this + */ + Tone.Transport.prototype.pause = function (time) { + this._clock.pause(time); + return this; + }; + /////////////////////////////////////////////////////////////////////////////// + // SETTERS/GETTERS + /////////////////////////////////////////////////////////////////////////////// + /** + * The time signature as just the numerator over 4. + * For example 4/4 would be just 4 and 6/8 would be 3. + * @memberOf Tone.Transport# + * @type {Number|Array} + * @name timeSignature + * @example + * //common time + * Tone.Transport.timeSignature = 4; + * // 7/8 + * Tone.Transport.timeSignature = [7, 8]; + * //this will be reduced to a single number + * Tone.Transport.timeSignature; //returns 3.5 + */ + Object.defineProperty(Tone.Transport.prototype, 'timeSignature', { + get: function () { + return this._timeSignature; + }, + set: function (timeSig) { + if (this.isArray(timeSig)) { + timeSig = timeSig[0] / timeSig[1] * 4; + } + this._timeSignature = timeSig; + } + }); + /** + * When the Tone.Transport.loop = true, this is the starting position of the loop. + * @memberOf Tone.Transport# + * @type {TransportTime} + * @name loopStart + */ + Object.defineProperty(Tone.Transport.prototype, 'loopStart', { + get: function () { + return Tone.TransportTime(this._loopStart, 'i').toSeconds(); + }, + set: function (startPosition) { + this._loopStart = this.toTicks(startPosition); + } + }); + /** + * When the Tone.Transport.loop = true, this is the ending position of the loop. + * @memberOf Tone.Transport# + * @type {TransportTime} + * @name loopEnd + */ + Object.defineProperty(Tone.Transport.prototype, 'loopEnd', { + get: function () { + return Tone.TransportTime(this._loopEnd, 'i').toSeconds(); + }, + set: function (endPosition) { + this._loopEnd = this.toTicks(endPosition); + } + }); + /** + * Set the loop start and stop at the same time. + * @param {TransportTime} startPosition + * @param {TransportTime} endPosition + * @returns {Tone.Transport} this + * @example + * //loop over the first measure + * Tone.Transport.setLoopPoints(0, "1m"); + * Tone.Transport.loop = true; + */ + Tone.Transport.prototype.setLoopPoints = function (startPosition, endPosition) { + this.loopStart = startPosition; + this.loopEnd = endPosition; + return this; + }; + /** + * The swing value. Between 0-1 where 1 equal to + * the note + half the subdivision. + * @memberOf Tone.Transport# + * @type {NormalRange} + * @name swing + */ + Object.defineProperty(Tone.Transport.prototype, 'swing', { + get: function () { + return this._swingAmount; + }, + set: function (amount) { + //scale the values to a normal range + this._swingAmount = amount; + } + }); + /** + * Set the subdivision which the swing will be applied to. + * The default value is an 8th note. Value must be less + * than a quarter note. + * + * @memberOf Tone.Transport# + * @type {Time} + * @name swingSubdivision + */ + Object.defineProperty(Tone.Transport.prototype, 'swingSubdivision', { + get: function () { + return Tone.Time(this._swingTicks, 'i').toNotation(); + }, + set: function (subdivision) { + this._swingTicks = this.toTicks(subdivision); + } + }); + /** + * The Transport's position in Bars:Beats:Sixteenths. + * Setting the value will jump to that position right away. + * @memberOf Tone.Transport# + * @type {BarsBeatsSixteenths} + * @name position + */ + Object.defineProperty(Tone.Transport.prototype, 'position', { + get: function () { + return Tone.TransportTime(this.ticks, 'i').toBarsBeatsSixteenths(); + }, + set: function (progress) { + var ticks = this.toTicks(progress); + this.ticks = ticks; + } + }); + /** + * The Transport's position in seconds + * Setting the value will jump to that position right away. + * @memberOf Tone.Transport# + * @type {Seconds} + * @name seconds + */ + Object.defineProperty(Tone.Transport.prototype, 'seconds', { + get: function () { + return Tone.TransportTime(this.ticks, 'i').toSeconds(); + }, + set: function (progress) { + var ticks = this.toTicks(progress); + this.ticks = ticks; + } + }); + /** + * The Transport's loop position as a normalized value. Always + * returns 0 if the transport if loop is not true. + * @memberOf Tone.Transport# + * @name progress + * @type {NormalRange} + */ + Object.defineProperty(Tone.Transport.prototype, 'progress', { + get: function () { + if (this.loop) { + return (this.ticks - this._loopStart) / (this._loopEnd - this._loopStart); + } else { + return 0; + } + } + }); + /** + * The transports current tick position. + * + * @memberOf Tone.Transport# + * @type {Ticks} + * @name ticks + */ + Object.defineProperty(Tone.Transport.prototype, 'ticks', { + get: function () { + return this._clock.ticks; + }, + set: function (t) { + var now = this.now(); + //stop everything synced to the transport + if (this.state === Tone.State.Started) { + this.emit('stop', now); + this._clock.ticks = t; + //restart it with the new time + this.emit('start', now, this.seconds); + } else { + this._clock.ticks = t; + } + } + }); + /** + * Pulses Per Quarter note. This is the smallest resolution + * the Transport timing supports. This should be set once + * on initialization and not set again. Changing this value + * after other objects have been created can cause problems. + * + * @memberOf Tone.Transport# + * @type {Number} + * @name PPQ + */ + Object.defineProperty(Tone.Transport.prototype, 'PPQ', { + get: function () { + return this._ppq; + }, + set: function (ppq) { + var bpm = this.bpm.value; + this._ppq = ppq; + this.bpm.value = bpm; + } + }); + /** + * The hint to the type of playback. Affects tradeoffs between audio + * output latency and responsiveness. + * + * In addition to setting the value in seconds, the latencyHint also + * accepts the strings "interactive" (prioritizes low latency), + * "playback" (prioritizes sustained playback), "balanced" (balances + * latency and performance), and "fastest" (lowest latency, might glitch more often). + * @memberOf Tone.Transport# + * @type {Seconds|String} + * @name latencyHint + */ + Object.defineProperty(Tone.Transport.prototype, 'latencyHint', { + get: function () { + return Tone.Clock.latencyHint; + }, + set: function (hint) { + Tone.Clock.latencyHint = hint; + } + }); + /** + * Convert from BPM to frequency (factoring in PPQ) + * @param {BPM} bpm The BPM value to convert to frequency + * @return {Frequency} The BPM as a frequency with PPQ factored in. + * @private + */ + Tone.Transport.prototype._fromUnits = function (bpm) { + return 1 / (60 / bpm / this.PPQ); + }; + /** + * Convert from frequency (with PPQ) into BPM + * @param {Frequency} freq The clocks frequency to convert to BPM + * @return {BPM} The frequency value as BPM. + * @private + */ + Tone.Transport.prototype._toUnits = function (freq) { + return freq / this.PPQ * 60; + }; + /////////////////////////////////////////////////////////////////////////////// + // SYNCING + /////////////////////////////////////////////////////////////////////////////// + /** + * Returns the time aligned to the next subdivision + * of the Transport. If the Transport is not started, + * it will return 0. + * Note: this will not work precisely during tempo ramps. + * @param {Time} subdivision The subdivision to quantize to + * @return {Number} The context time of the next subdivision. + * @example + * Tone.Transport.start(); //the transport must be started + * Tone.Transport.nextSubdivision("4n"); + */ + Tone.Transport.prototype.nextSubdivision = function (subdivision) { + subdivision = this.toSeconds(subdivision); + //if the transport's not started, return 0 + var now; + if (this.state === Tone.State.Started) { + now = this._clock._nextTick; + } else { + return 0; + } + var transportPos = Tone.Time(this.ticks, 'i').eval(); + var remainingTime = subdivision - transportPos % subdivision; + if (remainingTime === 0) { + remainingTime = subdivision; + } + return now + remainingTime; + }; + /** + * Attaches the signal to the tempo control signal so that + * any changes in the tempo will change the signal in the same + * ratio. + * + * @param {Tone.Signal} signal + * @param {number=} ratio Optionally pass in the ratio between + * the two signals. Otherwise it will be computed + * based on their current values. + * @returns {Tone.Transport} this + */ + Tone.Transport.prototype.syncSignal = function (signal, ratio) { + if (!ratio) { + //get the sync ratio + if (signal._param.value !== 0) { + ratio = signal._param.value / this.bpm._param.value; + } else { + ratio = 0; + } + } + var ratioSignal = new Tone.Gain(ratio); + this.bpm.chain(ratioSignal, signal._param); + this._syncedSignals.push({ + 'ratio': ratioSignal, + 'signal': signal, + 'initial': signal._param.value + }); + signal._param.value = 0; + return this; + }; + /** + * Unsyncs a previously synced signal from the transport's control. + * See Tone.Transport.syncSignal. + * @param {Tone.Signal} signal + * @returns {Tone.Transport} this + */ + Tone.Transport.prototype.unsyncSignal = function (signal) { + for (var i = this._syncedSignals.length - 1; i >= 0; i--) { + var syncedSignal = this._syncedSignals[i]; + if (syncedSignal.signal === signal) { + syncedSignal.ratio.dispose(); + syncedSignal.signal._param.value = syncedSignal.initial; + this._syncedSignals.splice(i, 1); + } + } + return this; + }; + /** + * Clean up. + * @returns {Tone.Transport} this + * @private + */ + Tone.Transport.prototype.dispose = function () { + Tone.Emitter.prototype.dispose.call(this); + this._clock.dispose(); + this._clock = null; + this._writable('bpm'); + this.bpm = null; + this._timeline.dispose(); + this._timeline = null; + this._onceEvents.dispose(); + this._onceEvents = null; + this._repeatedEvents.dispose(); + this._repeatedEvents = null; + return this; + }; + /////////////////////////////////////////////////////////////////////////////// + // INITIALIZATION + /////////////////////////////////////////////////////////////////////////////// + var TransportConstructor = Tone.Transport; + Tone._initAudioContext(function () { + if (typeof Tone.Transport === 'function') { + //a single transport object + Tone.Transport = new Tone.Transport(); + } else { + //stop the clock + Tone.Transport.stop(); + //get the previous values + var prevSettings = Tone.Transport.get(); + //destory the old transport + Tone.Transport.dispose(); + //make new Transport insides + TransportConstructor.call(Tone.Transport); + //set the previous config + Tone.Transport.set(prevSettings); + } + }); + return Tone.Transport; + }); + Module(function (Tone) { + + /** + * @class Tone.Volume is a simple volume node, useful for creating a volume fader. + * + * @extends {Tone} + * @constructor + * @param {Decibels} [volume=0] the initial volume + * @example + * var vol = new Tone.Volume(-12); + * instrument.chain(vol, Tone.Master); + */ + Tone.Volume = function () { + var options = this.optionsObject(arguments, ['volume'], Tone.Volume.defaults); + /** + * the output node + * @type {GainNode} + * @private + */ + this.output = this.input = new Tone.Gain(options.volume, Tone.Type.Decibels); + /** + * The unmuted volume + * @type {Decibels} + * @private + */ + this._unmutedVolume = 0; + /** + * if the volume is muted + * @type {Boolean} + * @private + */ + this._muted = false; + /** + * The volume control in decibels. + * @type {Decibels} + * @signal + */ + this.volume = this.output.gain; + this._readOnly('volume'); + //set the mute initially + this.mute = options.mute; + }; + Tone.extend(Tone.Volume); + /** + * Defaults + * @type {Object} + * @const + * @static + */ + Tone.Volume.defaults = { + 'volume': 0, + 'mute': false + }; + /** + * Mute the output. + * @memberOf Tone.Volume# + * @type {boolean} + * @name mute + * @example + * //mute the output + * volume.mute = true; + */ + Object.defineProperty(Tone.Volume.prototype, 'mute', { + get: function () { + return this._muted; + }, + set: function (mute) { + if (!this._muted && mute) { + this._unmutedVolume = this.volume.value; + //maybe it should ramp here? + this.volume.value = -Infinity; + } else if (this._muted && !mute) { + this.volume.value = this._unmutedVolume; + } + this._muted = mute; + } + }); + /** + * clean up + * @returns {Tone.Volume} this + */ + Tone.Volume.prototype.dispose = function () { + this.input.dispose(); + Tone.prototype.dispose.call(this); + this._writable('volume'); + this.volume.dispose(); + this.volume = null; + return this; + }; + return Tone.Volume; + }); + Module(function (Tone) { + + /** + * @class A single master output which is connected to the + * AudioDestinationNode (aka your speakers). + * It provides useful conveniences such as the ability + * to set the volume and mute the entire application. + * It also gives you the ability to apply master effects to your application. + *

+ * Like Tone.Transport, A single Tone.Master is created + * on initialization and you do not need to explicitly construct one. + * + * @constructor + * @extends {Tone} + * @singleton + * @example + * //the audio will go from the oscillator to the speakers + * oscillator.connect(Tone.Master); + * //a convenience for connecting to the master output is also provided: + * oscillator.toMaster(); + * //the above two examples are equivalent. + */ + Tone.Master = function () { + this.createInsOuts(1, 1); + /** + * The private volume node + * @type {Tone.Volume} + * @private + */ + this._volume = this.output = new Tone.Volume(); + /** + * The volume of the master output. + * @type {Decibels} + * @signal + */ + this.volume = this._volume.volume; + this._readOnly('volume'); + //connections + this.input.chain(this.output, this.context.destination); + }; + Tone.extend(Tone.Master); + /** + * @type {Object} + * @const + */ + Tone.Master.defaults = { + 'volume': 0, + 'mute': false + }; + /** + * Mute the output. + * @memberOf Tone.Master# + * @type {boolean} + * @name mute + * @example + * //mute the output + * Tone.Master.mute = true; + */ + Object.defineProperty(Tone.Master.prototype, 'mute', { + get: function () { + return this._volume.mute; + }, + set: function (mute) { + this._volume.mute = mute; + } + }); + /** + * Add a master effects chain. NOTE: this will disconnect any nodes which were previously + * chained in the master effects chain. + * @param {AudioNode|Tone...} args All arguments will be connected in a row + * and the Master will be routed through it. + * @return {Tone.Master} this + * @example + * //some overall compression to keep the levels in check + * var masterCompressor = new Tone.Compressor({ + * "threshold" : -6, + * "ratio" : 3, + * "attack" : 0.5, + * "release" : 0.1 + * }); + * //give a little boost to the lows + * var lowBump = new Tone.Filter(200, "lowshelf"); + * //route everything through the filter + * //and compressor before going to the speakers + * Tone.Master.chain(lowBump, masterCompressor); + */ + Tone.Master.prototype.chain = function () { + this.input.disconnect(); + this.input.chain.apply(this.input, arguments); + arguments[arguments.length - 1].connect(this.output); + }; + /** + * Clean up + * @return {Tone.Master} this + */ + Tone.Master.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._writable('volume'); + this._volume.dispose(); + this._volume = null; + this.volume = null; + }; + /////////////////////////////////////////////////////////////////////////// + // AUGMENT TONE's PROTOTYPE + /////////////////////////////////////////////////////////////////////////// + /** + * Connect 'this' to the master output. Shorthand for this.connect(Tone.Master) + * @returns {Tone} this + * @example + * //connect an oscillator to the master output + * var osc = new Tone.Oscillator().toMaster(); + */ + Tone.prototype.toMaster = function () { + this.connect(Tone.Master); + return this; + }; + /** + * Also augment AudioNode's prototype to include toMaster + * as a convenience + * @returns {AudioNode} this + */ + AudioNode.prototype.toMaster = function () { + this.connect(Tone.Master); + return this; + }; + var MasterConstructor = Tone.Master; + /** + * initialize the module and listen for new audio contexts + */ + Tone._initAudioContext(function () { + //a single master output + if (!Tone.prototype.isUndef(Tone.Master)) { + Tone.Master = new MasterConstructor(); + } else { + MasterConstructor.prototype.dispose.call(Tone.Master); + MasterConstructor.call(Tone.Master); + } + }); + return Tone.Master; + }); + Module(function (Tone) { + + /** + * @class Base class for sources. Sources have start/stop methods + * and the ability to be synced to the + * start/stop of Tone.Transport. + * + * @constructor + * @extends {Tone} + * @example + * //Multiple state change events can be chained together, + * //but must be set in the correct order and with ascending times + * + * // OK + * state.start().stop("+0.2"); + * // AND + * state.start().stop("+0.2").start("+0.4").stop("+0.7") + * + * // BAD + * state.stop("+0.2").start(); + * // OR + * state.start("+0.3").stop("+0.2"); + * + */ + Tone.Source = function (options) { + // this.createInsOuts(0, 1); + options = this.defaultArg(options, Tone.Source.defaults); + /** + * The output volume node + * @type {Tone.Volume} + * @private + */ + this._volume = this.output = new Tone.Volume(options.volume); + /** + * The volume of the output in decibels. + * @type {Decibels} + * @signal + * @example + * source.volume.value = -6; + */ + this.volume = this._volume.volume; + this._readOnly('volume'); + /** + * Keep track of the scheduled state. + * @type {Tone.TimelineState} + * @private + */ + this._state = new Tone.TimelineState(Tone.State.Stopped); + this._state.memory = 10; + /** + * The synced `start` callback function from the transport + * @type {Function} + * @private + */ + this._synced = false; + /** + * Keep track of all of the scheduled event ids + * @type {Array} + * @private + */ + this._scheduled = []; + //make the output explicitly stereo + this._volume.output.output.channelCount = 2; + this._volume.output.output.channelCountMode = 'explicit'; + //mute initially + this.mute = options.mute; + }; + Tone.extend(Tone.Source); + /** + * The default parameters + * @static + * @const + * @type {Object} + */ + Tone.Source.defaults = { + 'volume': 0, + 'mute': false + }; + /** + * Returns the playback state of the source, either "started" or "stopped". + * @type {Tone.State} + * @readOnly + * @memberOf Tone.Source# + * @name state + */ + Object.defineProperty(Tone.Source.prototype, 'state', { + get: function () { + if (this._synced) { + if (Tone.Transport.state === Tone.State.Started) { + return this._state.getValueAtTime(Tone.Transport.seconds); + } else { + return Tone.State.Stopped; + } + } else { + return this._state.getValueAtTime(this.now()); + } + } + }); + /** + * Mute the output. + * @memberOf Tone.Source# + * @type {boolean} + * @name mute + * @example + * //mute the output + * source.mute = true; + */ + Object.defineProperty(Tone.Source.prototype, 'mute', { + get: function () { + return this._volume.mute; + }, + set: function (mute) { + this._volume.mute = mute; + } + }); + //overwrite these functions + Tone.Source.prototype._start = Tone.noOp; + Tone.Source.prototype._stop = Tone.noOp; + /** + * Start the source at the specified time. If no time is given, + * start the source now. + * @param {Time} [time=now] When the source should be started. + * @returns {Tone.Source} this + * @example + * source.start("+0.5"); //starts the source 0.5 seconds from now + */ + Tone.Source.prototype.start = function (time, offset, duration) { + if (this.isUndef(time) && this._synced) { + time = Tone.Transport.seconds; + } else { + time = this.toSeconds(time); + } + //if it's started, stop it and restart it + if (!this.retrigger && this._state.getValueAtTime(time) === Tone.State.Started) { + this.stop(time); + } + this._state.setStateAtTime(Tone.State.Started, time); + if (this._synced) { + // add the offset time to the event + var event = this._state.get(time); + event.offset = this.defaultArg(offset, 0); + event.duration = duration; + var sched = Tone.Transport.schedule(function (t) { + this._start(t, offset, duration); + }.bind(this), time); + this._scheduled.push(sched); + } else { + this._start.apply(this, arguments); + } + return this; + }; + /** + * Stop the source at the specified time. If no time is given, + * stop the source now. + * @param {Time} [time=now] When the source should be stopped. + * @returns {Tone.Source} this + * @example + * source.stop(); // stops the source immediately + */ + Tone.Source.prototype.stop = function (time) { + if (this.isUndef(time) && this._synced) { + time = Tone.Transport.seconds; + } else { + time = this.toSeconds(time); + } + this._state.cancel(time); + this._state.setStateAtTime(Tone.State.Stopped, time); + if (!this._synced) { + this._stop.apply(this, arguments); + } else { + var sched = Tone.Transport.schedule(this._stop.bind(this), time); + this._scheduled.push(sched); + } + return this; + }; + /** + * Sync the source to the Transport so that all subsequent + * calls to `start` and `stop` are synced to the TransportTime + * instead of the AudioContext time. + * + * @returns {Tone.Source} this + * @example + * //sync the source so that it plays between 0 and 0.3 on the Transport's timeline + * source.sync().start(0).stop(0.3); + * //start the transport. + * Tone.Transport.start(); + * + * @example + * //start the transport with an offset and the sync'ed sources + * //will start in the correct position + * source.sync().start(0.1); + * //the source will be invoked with an offset of 0.4 + * Tone.Transport.start("+0.5", 0.5); + */ + Tone.Source.prototype.sync = function () { + this._synced = true; + Tone.Transport.on('start loopStart', function (time, offset) { + if (offset > 0) { + // get the playback state at that time + var stateEvent = this._state.get(offset); + // listen for start events which may occur in the middle of the sync'ed time + if (stateEvent && stateEvent.state === Tone.State.Started && stateEvent.time !== offset) { + // get the offset + var startOffset = offset - this.toSeconds(stateEvent.time); + var duration; + if (stateEvent.duration) { + duration = this.toSeconds(stateEvent.duration) - startOffset; + } + this._start(time, this.toSeconds(stateEvent.offset) + startOffset, duration); + } + } + }.bind(this)); + Tone.Transport.on('stop pause loopEnd', function (time) { + if (this._state.getValueAtTime(Tone.Transport.seconds) === Tone.State.Started) { + this._stop(time); + } + }.bind(this)); + return this; + }; + /** + * Unsync the source to the Transport. See Tone.Source.sync + * @returns {Tone.Source} this + */ + Tone.Source.prototype.unsync = function () { + this._synced = false; + Tone.Transport.off('start stop pause loopEnd loopStart'); + // clear all of the scheduled ids + for (var i = 0; i < this._scheduled.length; i++) { + var id = this._scheduled[i]; + Tone.Transport.clear(id); + } + this._scheduled = []; + this._state.cancel(0); + return this; + }; + /** + * Clean up. + * @return {Tone.Source} this + */ + Tone.Source.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this.unsync(); + this._scheduled = null; + this._writable('volume'); + this._volume.dispose(); + this._volume = null; + this.volume = null; + this._state.dispose(); + this._state = null; + }; + return Tone.Source; + }); + Module(function (Tone) { + + /** + * @class Tone.Oscillator supports a number of features including + * phase rotation, multiple oscillator types (see Tone.Oscillator.type), + * and Transport syncing (see Tone.Oscillator.syncFrequency). + * + * @constructor + * @extends {Tone.Source} + * @param {Frequency} [frequency] Starting frequency + * @param {string} [type] The oscillator type. Read more about type below. + * @example + * //make and start a 440hz sine tone + * var osc = new Tone.Oscillator(440, "sine").toMaster().start(); + */ + Tone.Oscillator = function () { + var options = this.optionsObject(arguments, [ + 'frequency', + 'type' + ], Tone.Oscillator.defaults); + Tone.Source.call(this, options); + /** + * the main oscillator + * @type {OscillatorNode} + * @private + */ + this._oscillator = null; + /** + * The frequency control. + * @type {Frequency} + * @signal + */ + this.frequency = new Tone.Signal(options.frequency, Tone.Type.Frequency); + /** + * The detune control signal. + * @type {Cents} + * @signal + */ + this.detune = new Tone.Signal(options.detune, Tone.Type.Cents); + /** + * the periodic wave + * @type {PeriodicWave} + * @private + */ + this._wave = null; + /** + * The partials of the oscillator + * @type {Array} + * @private + */ + this._partials = this.defaultArg(options.partials, [1]); + /** + * the phase of the oscillator + * between 0 - 360 + * @type {number} + * @private + */ + this._phase = options.phase; + /** + * the type of the oscillator + * @type {string} + * @private + */ + this._type = null; + //setup + this.type = options.type; + this.phase = this._phase; + this._readOnly([ + 'frequency', + 'detune' + ]); + }; + Tone.extend(Tone.Oscillator, Tone.Source); + /** + * the default parameters + * @type {Object} + */ + Tone.Oscillator.defaults = { + 'type': 'sine', + 'frequency': 440, + 'detune': 0, + 'phase': 0, + 'partials': [] + }; + /** + * The Oscillator types + * @enum {String} + */ + Tone.Oscillator.Type = { + Sine: 'sine', + Triangle: 'triangle', + Sawtooth: 'sawtooth', + Square: 'square', + Custom: 'custom' + }; + /** + * start the oscillator + * @param {Time} [time=now] + * @private + */ + Tone.Oscillator.prototype._start = function (time) { + //new oscillator with previous values + this._oscillator = this.context.createOscillator(); + this._oscillator.setPeriodicWave(this._wave); + //connect the control signal to the oscillator frequency & detune + this._oscillator.connect(this.output); + this.frequency.connect(this._oscillator.frequency); + this.detune.connect(this._oscillator.detune); + //start the oscillator + this._oscillator.start(this.toSeconds(time)); + }; + /** + * stop the oscillator + * @private + * @param {Time} [time=now] (optional) timing parameter + * @returns {Tone.Oscillator} this + */ + Tone.Oscillator.prototype._stop = function (time) { + if (this._oscillator) { + this._oscillator.stop(this.toSeconds(time)); + this._oscillator = null; + } + return this; + }; + /** + * Sync the signal to the Transport's bpm. Any changes to the transports bpm, + * will also affect the oscillators frequency. + * @returns {Tone.Oscillator} this + * @example + * Tone.Transport.bpm.value = 120; + * osc.frequency.value = 440; + * //the ration between the bpm and the frequency will be maintained + * osc.syncFrequency(); + * Tone.Transport.bpm.value = 240; + * // the frequency of the oscillator is doubled to 880 + */ + Tone.Oscillator.prototype.syncFrequency = function () { + Tone.Transport.syncSignal(this.frequency); + return this; + }; + /** + * Unsync the oscillator's frequency from the Transport. + * See Tone.Oscillator.syncFrequency + * @returns {Tone.Oscillator} this + */ + Tone.Oscillator.prototype.unsyncFrequency = function () { + Tone.Transport.unsyncSignal(this.frequency); + return this; + }; + /** + * The type of the oscillator: either sine, square, triangle, or sawtooth. Also capable of + * setting the first x number of partials of the oscillator. For example: "sine4" would + * set be the first 4 partials of the sine wave and "triangle8" would set the first + * 8 partials of the triangle wave. + *

+ * Uses PeriodicWave internally even for native types so that it can set the phase. + * PeriodicWave equations are from the + * [Webkit Web Audio implementation](https://code.google.com/p/chromium/codesearch#chromium/src/third_party/WebKit/Source/modules/webaudio/PeriodicWave.cpp&sq=package:chromium). + * + * @memberOf Tone.Oscillator# + * @type {string} + * @name type + * @example + * //set it to a square wave + * osc.type = "square"; + * @example + * //set the first 6 partials of a sawtooth wave + * osc.type = "sawtooth6"; + */ + Object.defineProperty(Tone.Oscillator.prototype, 'type', { + get: function () { + return this._type; + }, + set: function (type) { + var coefs = this._getRealImaginary(type, this._phase); + var periodicWave = this.context.createPeriodicWave(coefs[0], coefs[1]); + this._wave = periodicWave; + if (this._oscillator !== null) { + this._oscillator.setPeriodicWave(this._wave); + } + this._type = type; + } + }); + /** + * Returns the real and imaginary components based + * on the oscillator type. + * @returns {Array} [real, imaginary] + * @private + */ + Tone.Oscillator.prototype._getRealImaginary = function (type, phase) { + var fftSize = 4096; + var periodicWaveSize = fftSize / 2; + var real = new Float32Array(periodicWaveSize); + var imag = new Float32Array(periodicWaveSize); + var partialCount = 1; + if (type === Tone.Oscillator.Type.Custom) { + partialCount = this._partials.length + 1; + periodicWaveSize = partialCount; + } else { + var partial = /^(sine|triangle|square|sawtooth)(\d+)$/.exec(type); + if (partial) { + partialCount = parseInt(partial[2]) + 1; + type = partial[1]; + partialCount = Math.max(partialCount, 2); + periodicWaveSize = partialCount; + } + } + for (var n = 1; n < periodicWaveSize; ++n) { + var piFactor = 2 / (n * Math.PI); + var b; + switch (type) { + case Tone.Oscillator.Type.Sine: + b = n <= partialCount ? 1 : 0; + break; + case Tone.Oscillator.Type.Square: + b = n & 1 ? 2 * piFactor : 0; + break; + case Tone.Oscillator.Type.Sawtooth: + b = piFactor * (n & 1 ? 1 : -1); + break; + case Tone.Oscillator.Type.Triangle: + if (n & 1) { + b = 2 * (piFactor * piFactor) * (n - 1 >> 1 & 1 ? -1 : 1); + } else { + b = 0; + } + break; + case Tone.Oscillator.Type.Custom: + b = this._partials[n - 1]; + break; + default: + throw new TypeError('Tone.Oscillator: invalid type: ' + type); + } + if (b !== 0) { + real[n] = -b * Math.sin(phase * n); + imag[n] = b * Math.cos(phase * n); + } else { + real[n] = 0; + imag[n] = 0; + } + } + return [ + real, + imag + ]; + }; + /** + * Compute the inverse FFT for a given phase. + * @param {Float32Array} real + * @param {Float32Array} imag + * @param {NormalRange} phase + * @return {AudioRange} + * @private + */ + Tone.Oscillator.prototype._inverseFFT = function (real, imag, phase) { + var sum = 0; + var len = real.length; + for (var i = 0; i < len; i++) { + sum += real[i] * Math.cos(i * phase) + imag[i] * Math.sin(i * phase); + } + return sum; + }; + /** + * Returns the initial value of the oscillator. + * @return {AudioRange} + * @private + */ + Tone.Oscillator.prototype._getInitialValue = function () { + var coefs = this._getRealImaginary(this._type, 0); + var real = coefs[0]; + var imag = coefs[1]; + var maxValue = 0; + var twoPi = Math.PI * 2; + //check for peaks in 8 places + for (var i = 0; i < 8; i++) { + maxValue = Math.max(this._inverseFFT(real, imag, i / 8 * twoPi), maxValue); + } + return -this._inverseFFT(real, imag, this._phase) / maxValue; + }; + /** + * The partials of the waveform. A partial represents + * the amplitude at a harmonic. The first harmonic is the + * fundamental frequency, the second is the octave and so on + * following the harmonic series. + * Setting this value will automatically set the type to "custom". + * The value is an empty array when the type is not "custom". + * @memberOf Tone.Oscillator# + * @type {Array} + * @name partials + * @example + * osc.partials = [1, 0.2, 0.01]; + */ + Object.defineProperty(Tone.Oscillator.prototype, 'partials', { + get: function () { + if (this._type !== Tone.Oscillator.Type.Custom) { + return []; + } else { + return this._partials; + } + }, + set: function (partials) { + this._partials = partials; + this.type = Tone.Oscillator.Type.Custom; + } + }); + /** + * The phase of the oscillator in degrees. + * @memberOf Tone.Oscillator# + * @type {Degrees} + * @name phase + * @example + * osc.phase = 180; //flips the phase of the oscillator + */ + Object.defineProperty(Tone.Oscillator.prototype, 'phase', { + get: function () { + return this._phase * (180 / Math.PI); + }, + set: function (phase) { + this._phase = phase * Math.PI / 180; + //reset the type + this.type = this._type; + } + }); + /** + * Dispose and disconnect. + * @return {Tone.Oscillator} this + */ + Tone.Oscillator.prototype.dispose = function () { + Tone.Source.prototype.dispose.call(this); + if (this._oscillator !== null) { + this._oscillator.disconnect(); + this._oscillator = null; + } + this._wave = null; + this._writable([ + 'frequency', + 'detune' + ]); + this.frequency.dispose(); + this.frequency = null; + this.detune.dispose(); + this.detune = null; + this._partials = null; + return this; + }; + return Tone.Oscillator; + }); + Module(function (Tone) { + /** + * @class Tone.Zero outputs 0's at audio-rate. The reason this has to be + * it's own class is that many browsers optimize out Tone.Signal + * with a value of 0 and will not process nodes further down the graph. + * @extends {Tone} + */ + Tone.Zero = function () { + /** + * The gain node + * @type {Tone.Gain} + * @private + */ + this._gain = this.input = this.output = new Tone.Gain(); + Tone.Zero._zeros.connect(this._gain); + }; + Tone.extend(Tone.Zero); + /** + * clean up + * @return {Tone.Zero} this + */ + Tone.Zero.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._gain.dispose(); + this._gain = null; + return this; + }; + /** + * Generates a constant output of 0. This is so + * the processing graph doesn't optimize out this + * segment of the graph. + * @static + * @private + * @const + * @type {AudioBufferSourceNode} + */ + Tone.Zero._zeros = null; + /** + * initializer function + */ + Tone._initAudioContext(function (audioContext) { + var buffer = audioContext.createBuffer(1, 128, audioContext.sampleRate); + var arr = buffer.getChannelData(0); + for (var i = 0; i < arr.length; i++) { + arr[i] = 0; + } + Tone.Zero._zeros = audioContext.createBufferSource(); + Tone.Zero._zeros.channelCount = 1; + Tone.Zero._zeros.channelCountMode = 'explicit'; + Tone.Zero._zeros.buffer = buffer; + Tone.Zero._zeros.loop = true; + Tone.Zero._zeros.start(0); + Tone.Zero._zeros.noGC(); + }); + return Tone.Zero; + }); + Module(function (Tone) { + + /** + * @class LFO stands for low frequency oscillator. Tone.LFO produces an output signal + * which can be attached to an AudioParam or Tone.Signal + * in order to modulate that parameter with an oscillator. The LFO can + * also be synced to the transport to start/stop and change when the tempo changes. + * + * @constructor + * @extends {Tone.Oscillator} + * @param {Frequency|Object} [frequency] The frequency of the oscillation. Typically, LFOs will be + * in the frequency range of 0.1 to 10 hertz. + * @param {number=} min The minimum output value of the LFO. + * @param {number=} max The maximum value of the LFO. + * @example + * var lfo = new Tone.LFO("4n", 400, 4000); + * lfo.connect(filter.frequency); + */ + Tone.LFO = function () { + var options = this.optionsObject(arguments, [ + 'frequency', + 'min', + 'max' + ], Tone.LFO.defaults); + /** + * The oscillator. + * @type {Tone.Oscillator} + * @private + */ + this._oscillator = new Tone.Oscillator({ + 'frequency': options.frequency, + 'type': options.type + }); + /** + * the lfo's frequency + * @type {Frequency} + * @signal + */ + this.frequency = this._oscillator.frequency; + /** + * The amplitude of the LFO, which controls the output range between + * the min and max output. For example if the min is -10 and the max + * is 10, setting the amplitude to 0.5 would make the LFO modulate + * between -5 and 5. + * @type {Number} + * @signal + */ + this.amplitude = this._oscillator.volume; + this.amplitude.units = Tone.Type.NormalRange; + this.amplitude.value = options.amplitude; + /** + * The signal which is output when the LFO is stopped + * @type {Tone.Signal} + * @private + */ + this._stoppedSignal = new Tone.Signal(0, Tone.Type.AudioRange); + /** + * Just outputs zeros. + * @type {Tone.Zero} + * @private + */ + this._zeros = new Tone.Zero(); + /** + * The value that the LFO outputs when it's stopped + * @type {AudioRange} + * @private + */ + this._stoppedValue = 0; + /** + * @type {Tone.AudioToGain} + * @private + */ + this._a2g = new Tone.AudioToGain(); + /** + * @type {Tone.Scale} + * @private + */ + this._scaler = this.output = new Tone.Scale(options.min, options.max); + /** + * the units of the LFO (used for converting) + * @type {Tone.Type} + * @private + */ + this._units = Tone.Type.Default; + this.units = options.units; + //connect it up + this._oscillator.chain(this._a2g, this._scaler); + this._zeros.connect(this._a2g); + this._stoppedSignal.connect(this._a2g); + this._readOnly([ + 'amplitude', + 'frequency' + ]); + this.phase = options.phase; + }; + Tone.extend(Tone.LFO, Tone.Oscillator); + /** + * the default parameters + * + * @static + * @const + * @type {Object} + */ + Tone.LFO.defaults = { + 'type': 'sine', + 'min': 0, + 'max': 1, + 'phase': 0, + 'frequency': '4n', + 'amplitude': 1, + 'units': Tone.Type.Default + }; + /** + * Start the LFO. + * @param {Time} [time=now] the time the LFO will start + * @returns {Tone.LFO} this + */ + Tone.LFO.prototype.start = function (time) { + time = this.toSeconds(time); + this._stoppedSignal.setValueAtTime(0, time); + this._oscillator.start(time); + return this; + }; + /** + * Stop the LFO. + * @param {Time} [time=now] the time the LFO will stop + * @returns {Tone.LFO} this + */ + Tone.LFO.prototype.stop = function (time) { + time = this.toSeconds(time); + this._stoppedSignal.setValueAtTime(this._stoppedValue, time); + this._oscillator.stop(time); + return this; + }; + /** + * Sync the start/stop/pause to the transport + * and the frequency to the bpm of the transport + * @returns {Tone.LFO} this + * @example + * lfo.frequency.value = "8n"; + * lfo.sync().start(0) + * //the rate of the LFO will always be an eighth note, + * //even as the tempo changes + */ + Tone.LFO.prototype.sync = function () { + this._oscillator.sync(); + this._oscillator.syncFrequency(); + return this; + }; + /** + * unsync the LFO from transport control + * @returns {Tone.LFO} this + */ + Tone.LFO.prototype.unsync = function () { + this._oscillator.unsync(); + this._oscillator.unsyncFrequency(); + return this; + }; + /** + * The miniumum output of the LFO. + * @memberOf Tone.LFO# + * @type {number} + * @name min + */ + Object.defineProperty(Tone.LFO.prototype, 'min', { + get: function () { + return this._toUnits(this._scaler.min); + }, + set: function (min) { + min = this._fromUnits(min); + this._scaler.min = min; + } + }); + /** + * The maximum output of the LFO. + * @memberOf Tone.LFO# + * @type {number} + * @name max + */ + Object.defineProperty(Tone.LFO.prototype, 'max', { + get: function () { + return this._toUnits(this._scaler.max); + }, + set: function (max) { + max = this._fromUnits(max); + this._scaler.max = max; + } + }); + /** + * The type of the oscillator: sine, square, sawtooth, triangle. + * @memberOf Tone.LFO# + * @type {string} + * @name type + */ + Object.defineProperty(Tone.LFO.prototype, 'type', { + get: function () { + return this._oscillator.type; + }, + set: function (type) { + this._oscillator.type = type; + this._stoppedValue = this._oscillator._getInitialValue(); + this._stoppedSignal.value = this._stoppedValue; + } + }); + /** + * The phase of the LFO. + * @memberOf Tone.LFO# + * @type {number} + * @name phase + */ + Object.defineProperty(Tone.LFO.prototype, 'phase', { + get: function () { + return this._oscillator.phase; + }, + set: function (phase) { + this._oscillator.phase = phase; + this._stoppedValue = this._oscillator._getInitialValue(); + this._stoppedSignal.value = this._stoppedValue; + } + }); + /** + * The output units of the LFO. + * @memberOf Tone.LFO# + * @type {Tone.Type} + * @name units + */ + Object.defineProperty(Tone.LFO.prototype, 'units', { + get: function () { + return this._units; + }, + set: function (val) { + var currentMin = this.min; + var currentMax = this.max; + //convert the min and the max + this._units = val; + this.min = currentMin; + this.max = currentMax; + } + }); + /** + * Mute the output. + * @memberOf Tone.LFO# + * @type {Boolean} + * @name mute + */ + Object.defineProperty(Tone.LFO.prototype, 'mute', { + get: function () { + return this._oscillator.mute; + }, + set: function (mute) { + this._oscillator.mute = mute; + } + }); + /** + * Returns the playback state of the source, either "started" or "stopped". + * @type {Tone.State} + * @readOnly + * @memberOf Tone.LFO# + * @name state + */ + Object.defineProperty(Tone.LFO.prototype, 'state', { + get: function () { + return this._oscillator.state; + } + }); + /** + * Connect the output of the LFO to an AudioParam, AudioNode, or Tone Node. + * Tone.LFO will automatically convert to the destination units of the + * will get the units from the connected node. + * @param {Tone | AudioParam | AudioNode} node + * @param {number} [outputNum=0] optionally which output to connect from + * @param {number} [inputNum=0] optionally which input to connect to + * @returns {Tone.LFO} this + * @private + */ + Tone.LFO.prototype.connect = function (node) { + if (node.constructor === Tone.Signal || node.constructor === Tone.Param || node.constructor === Tone.TimelineSignal) { + this.convert = node.convert; + this.units = node.units; + } + Tone.Signal.prototype.connect.apply(this, arguments); + return this; + }; + /** + * private method borrowed from Param converts + * units from their destination value + * @function + * @private + */ + Tone.LFO.prototype._fromUnits = Tone.Param.prototype._fromUnits; + /** + * private method borrowed from Param converts + * units to their destination value + * @function + * @private + */ + Tone.LFO.prototype._toUnits = Tone.Param.prototype._toUnits; + /** + * disconnect and dispose + * @returns {Tone.LFO} this + */ + Tone.LFO.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._writable([ + 'amplitude', + 'frequency' + ]); + this._oscillator.dispose(); + this._oscillator = null; + this._stoppedSignal.dispose(); + this._stoppedSignal = null; + this._zeros.dispose(); + this._zeros = null; + this._scaler.dispose(); + this._scaler = null; + this._a2g.dispose(); + this._a2g = null; + this.frequency = null; + this.amplitude = null; + return this; + }; + return Tone.LFO; + }); + Module(function (Tone) { + + /** + * @class Tone.Limiter will limit the loudness of an incoming signal. + * It is composed of a Tone.Compressor with a fast attack + * and release. Limiters are commonly used to safeguard against + * signal clipping. Unlike a compressor, limiters do not provide + * smooth gain reduction and almost completely prevent + * additional gain above the threshold. + * + * @extends {Tone} + * @constructor + * @param {number} threshold The theshold above which the limiting is applied. + * @example + * var limiter = new Tone.Limiter(-6); + */ + Tone.Limiter = function () { + var options = this.optionsObject(arguments, ['threshold'], Tone.Limiter.defaults); + /** + * the compressor + * @private + * @type {Tone.Compressor} + */ + this._compressor = this.input = this.output = new Tone.Compressor({ + 'attack': 0.001, + 'decay': 0.001, + 'threshold': options.threshold + }); + /** + * The threshold of of the limiter + * @type {Decibel} + * @signal + */ + this.threshold = this._compressor.threshold; + this._readOnly('threshold'); + }; + Tone.extend(Tone.Limiter); + /** + * The default value + * @type {Object} + * @const + * @static + */ + Tone.Limiter.defaults = { 'threshold': -12 }; + /** + * Clean up. + * @returns {Tone.Limiter} this + */ + Tone.Limiter.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._compressor.dispose(); + this._compressor = null; + this._writable('threshold'); + this.threshold = null; + return this; + }; + return Tone.Limiter; + }); + Module(function (Tone) { + + /** + * @class Tone.Lowpass is a lowpass feedback comb filter. It is similar to + * Tone.FeedbackCombFilter, but includes a lowpass filter. + * + * @extends {Tone} + * @constructor + * @param {Time|Object} [delayTime] The delay time of the comb filter + * @param {NormalRange=} resonance The resonance (feedback) of the comb filter + * @param {Frequency=} dampening The cutoff of the lowpass filter dampens the + * signal as it is fedback. + */ + Tone.LowpassCombFilter = function () { + this.createInsOuts(1, 1); + var options = this.optionsObject(arguments, [ + 'delayTime', + 'resonance', + 'dampening' + ], Tone.LowpassCombFilter.defaults); + /** + * the delay node + * @type {DelayNode} + * @private + */ + this._delay = this.input = new Tone.Delay(options.delayTime); + /** + * The delayTime of the comb filter. + * @type {Time} + * @signal + */ + this.delayTime = this._delay.delayTime; + /** + * the lowpass filter + * @type {BiquadFilterNode} + * @private + */ + this._lowpass = this.output = this.context.createBiquadFilter(); + this._lowpass.Q.value = -3.0102999566398125; + this._lowpass.type = 'lowpass'; + /** + * The dampening control of the feedback + * @type {Frequency} + * @signal + */ + this.dampening = new Tone.Param({ + 'param': this._lowpass.frequency, + 'units': Tone.Type.Frequency, + 'value': options.dampening + }); + /** + * the feedback gain + * @type {Tone.Gain} + * @private + */ + this._feedback = new Tone.Gain(options.resonance, Tone.Type.NormalRange); + /** + * The amount of feedback of the delayed signal. + * @type {NormalRange} + * @signal + */ + this.resonance = this._feedback.gain; + //connections + this._delay.chain(this._lowpass, this._feedback, this._delay); + this._readOnly([ + 'dampening', + 'resonance', + 'delayTime' + ]); + }; + Tone.extend(Tone.LowpassCombFilter); + /** + * the default parameters + * @static + * @const + * @type {Object} + */ + Tone.LowpassCombFilter.defaults = { + 'delayTime': 0.1, + 'resonance': 0.5, + 'dampening': 3000 + }; + /** + * Clean up. + * @returns {Tone.LowpassCombFilter} this + */ + Tone.LowpassCombFilter.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._writable([ + 'dampening', + 'resonance', + 'delayTime' + ]); + this.dampening.dispose(); + this.dampening = null; + this.resonance.dispose(); + this.resonance = null; + this._delay.dispose(); + this._delay = null; + this.delayTime = null; + this._lowpass.disconnect(); + this._lowpass = null; + this._feedback.disconnect(); + this._feedback = null; + return this; + }; + return Tone.LowpassCombFilter; + }); + Module(function (Tone) { + + /** + * @class Tone.Merge brings two signals into the left and right + * channels of a single stereo channel. + * + * @constructor + * @extends {Tone} + * @example + * var merge = new Tone.Merge().toMaster(); + * //routing a sine tone in the left channel + * //and noise in the right channel + * var osc = new Tone.Oscillator().connect(merge.left); + * var noise = new Tone.Noise().connect(merge.right); + * //starting our oscillators + * noise.start(); + * osc.start(); + */ + Tone.Merge = function () { + this.createInsOuts(2, 0); + /** + * The left input channel. + * Alias for input[0] + * @type {GainNode} + */ + this.left = this.input[0] = new Tone.Gain(); + /** + * The right input channel. + * Alias for input[1]. + * @type {GainNode} + */ + this.right = this.input[1] = new Tone.Gain(); + /** + * the merger node for the two channels + * @type {ChannelMergerNode} + * @private + */ + this._merger = this.output = this.context.createChannelMerger(2); + //connections + this.left.connect(this._merger, 0, 0); + this.right.connect(this._merger, 0, 1); + this.left.channelCount = 1; + this.right.channelCount = 1; + this.left.channelCountMode = 'explicit'; + this.right.channelCountMode = 'explicit'; + }; + Tone.extend(Tone.Merge); + /** + * Clean up. + * @returns {Tone.Merge} this + */ + Tone.Merge.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this.left.dispose(); + this.left = null; + this.right.dispose(); + this.right = null; + this._merger.disconnect(); + this._merger = null; + return this; + }; + return Tone.Merge; + }); + Module(function (Tone) { + + /** + * @class Tone.Meter gets the [RMS](https://en.wikipedia.org/wiki/Root_mean_square) + * of an input signal with some averaging applied. It can also get the raw + * value of the input signal. + * + * @constructor + * @extends {Tone} + * @param {String} type Either "level" or "signal". + * @param {Number} smoothing The amount of smoothing applied between frames. + * @example + * var meter = new Tone.Meter(); + * var mic = new Tone.UserMedia().start(); + * //connect mic to the meter + * mic.connect(meter); + * //the current level of the mic input + * var level = meter.value; + */ + Tone.Meter = function () { + var options = this.optionsObject(arguments, [ + 'type', + 'smoothing' + ], Tone.Meter.defaults); + /** + * The type of the meter, either "level" or "signal". + * A "level" meter will return the volume level (rms) of the + * input signal and a "signal" meter will return + * the signal value of the input. + * @type {String} + */ + this.type = options.type; + /** + * The analyser node which computes the levels. + * @private + * @type {Tone.Analyser} + */ + this.input = this.output = this._analyser = new Tone.Analyser('waveform', 512); + this._analyser.returnType = 'float'; + /** + * The amount of carryover between the current and last frame. + * Only applied meter for "level" type. + * @type {Number} + */ + this.smoothing = options.smoothing; + /** + * The last computed value + * @type {Number} + * @private + */ + this._lastValue = 0; + }; + Tone.extend(Tone.Meter); + /** + * @private + * @enum {String} + */ + Tone.Meter.Type = { + Level: 'level', + Signal: 'signal' + }; + /** + * The defaults + * @type {Object} + * @static + * @const + */ + Tone.Meter.defaults = { + 'smoothing': 0.8, + 'type': Tone.Meter.Type.Level + }; + /** + * The current value of the meter. A value of 1 is + * "unity". + * @memberOf Tone.Meter# + * @type {Number} + * @name value + * @readOnly + */ + Object.defineProperty(Tone.Meter.prototype, 'value', { + get: function () { + var signal = this._analyser.analyse(); + if (this.type === Tone.Meter.Type.Level) { + //rms + var sum = 0; + for (var i = 0; i < signal.length; i++) { + sum += Math.pow(signal[i], 2); + } + var rms = Math.sqrt(sum / signal.length); + //smooth it + rms = Math.max(rms, this._lastValue * this.smoothing); + this._lastValue = rms; + //scale it + var unity = 0.35; + var val = rms / unity; + //scale the output curve + return Math.sqrt(val); + } else { + return signal[0]; + } + } + }); + /** + * Clean up. + * @returns {Tone.Meter} this + */ + Tone.Meter.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._analyser.dispose(); + this._analyser = null; + return this; + }; + return Tone.Meter; + }); + Module(function (Tone) { + + /** + * @class Tone.Split splits an incoming signal into left and right channels. + * + * @constructor + * @extends {Tone} + * @example + * var split = new Tone.Split(); + * stereoSignal.connect(split); + */ + Tone.Split = function () { + this.createInsOuts(0, 2); + /** + * @type {ChannelSplitterNode} + * @private + */ + this._splitter = this.input = this.context.createChannelSplitter(2); + /** + * Left channel output. + * Alias for output[0] + * @type {Tone.Gain} + */ + this.left = this.output[0] = new Tone.Gain(); + /** + * Right channel output. + * Alias for output[1] + * @type {Tone.Gain} + */ + this.right = this.output[1] = new Tone.Gain(); + //connections + this._splitter.connect(this.left, 0, 0); + this._splitter.connect(this.right, 1, 0); + }; + Tone.extend(Tone.Split); + /** + * Clean up. + * @returns {Tone.Split} this + */ + Tone.Split.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._splitter.disconnect(); + this.left.dispose(); + this.left = null; + this.right.dispose(); + this.right = null; + this._splitter = null; + return this; + }; + return Tone.Split; + }); + Module(function (Tone) { + + /** + * @class Mid/Side processing separates the the 'mid' signal + * (which comes out of both the left and the right channel) + * and the 'side' (which only comes out of the the side channels).

+ * + * Mid = (Left+Right)/sqrt(2); // obtain mid-signal from left and right
+ * Side = (Left-Right)/sqrt(2); // obtain side-signal from left and righ
+ *
+ * + * @extends {Tone} + * @constructor + */ + Tone.MidSideSplit = function () { + this.createInsOuts(0, 2); + /** + * split the incoming signal into left and right channels + * @type {Tone.Split} + * @private + */ + this._split = this.input = new Tone.Split(); + /** + * The mid send. Connect to mid processing. Alias for + * output[0] + * @type {Tone.Expr} + */ + this.mid = this.output[0] = new Tone.Expr('($0 + $1) * $2'); + /** + * The side output. Connect to side processing. Alias for + * output[1] + * @type {Tone.Expr} + */ + this.side = this.output[1] = new Tone.Expr('($0 - $1) * $2'); + this._split.connect(this.mid, 0, 0); + this._split.connect(this.mid, 1, 1); + this._split.connect(this.side, 0, 0); + this._split.connect(this.side, 1, 1); + sqrtTwo.connect(this.mid, 0, 2); + sqrtTwo.connect(this.side, 0, 2); + }; + Tone.extend(Tone.MidSideSplit); + /** + * a constant signal equal to 1 / sqrt(2) + * @type {Number} + * @signal + * @private + * @static + */ + var sqrtTwo = null; + Tone._initAudioContext(function () { + sqrtTwo = new Tone.Signal(1 / Math.sqrt(2)); + }); + /** + * clean up + * @returns {Tone.MidSideSplit} this + */ + Tone.MidSideSplit.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this.mid.dispose(); + this.mid = null; + this.side.dispose(); + this.side = null; + this._split.dispose(); + this._split = null; + return this; + }; + return Tone.MidSideSplit; + }); + Module(function (Tone) { + + /** + * @class Mid/Side processing separates the the 'mid' signal + * (which comes out of both the left and the right channel) + * and the 'side' (which only comes out of the the side channels). + * MidSideMerge merges the mid and side signal after they've been seperated + * by Tone.MidSideSplit.

+ * + * Left = (Mid+Side)/sqrt(2); // obtain left signal from mid and side
+ * Right = (Mid-Side)/sqrt(2); // obtain right signal from mid and side
+ *
+ * + * @extends {Tone.StereoEffect} + * @constructor + */ + Tone.MidSideMerge = function () { + this.createInsOuts(2, 0); + /** + * The mid signal input. Alias for + * input[0] + * @type {Tone.Gain} + */ + this.mid = this.input[0] = new Tone.Gain(); + /** + * recombine the mid/side into Left + * @type {Tone.Expr} + * @private + */ + this._left = new Tone.Expr('($0 + $1) * $2'); + /** + * The side signal input. Alias for + * input[1] + * @type {Tone.Gain} + */ + this.side = this.input[1] = new Tone.Gain(); + /** + * recombine the mid/side into Right + * @type {Tone.Expr} + * @private + */ + this._right = new Tone.Expr('($0 - $1) * $2'); + /** + * Merge the left/right signal back into a stereo signal. + * @type {Tone.Merge} + * @private + */ + this._merge = this.output = new Tone.Merge(); + this.mid.connect(this._left, 0, 0); + this.side.connect(this._left, 0, 1); + this.mid.connect(this._right, 0, 0); + this.side.connect(this._right, 0, 1); + this._left.connect(this._merge, 0, 0); + this._right.connect(this._merge, 0, 1); + sqrtTwo.connect(this._left, 0, 2); + sqrtTwo.connect(this._right, 0, 2); + }; + Tone.extend(Tone.MidSideMerge); + /** + * A constant signal equal to 1 / sqrt(2). + * @type {Number} + * @signal + * @private + * @static + */ + var sqrtTwo = null; + Tone._initAudioContext(function () { + sqrtTwo = new Tone.Signal(1 / Math.sqrt(2)); + }); + /** + * clean up + * @returns {Tone.MidSideMerge} this + */ + Tone.MidSideMerge.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this.mid.dispose(); + this.mid = null; + this.side.dispose(); + this.side = null; + this._left.dispose(); + this._left = null; + this._right.dispose(); + this._right = null; + this._merge.dispose(); + this._merge = null; + return this; + }; + return Tone.MidSideMerge; + }); + Module(function (Tone) { + + /** + * @class Tone.MidSideCompressor applies two different compressors to the mid + * and side signal components. See Tone.MidSideSplit. + * + * @extends {Tone} + * @param {Object} options The options that are passed to the mid and side + * compressors. + * @constructor + */ + Tone.MidSideCompressor = function (options) { + options = this.defaultArg(options, Tone.MidSideCompressor.defaults); + /** + * the mid/side split + * @type {Tone.MidSideSplit} + * @private + */ + this._midSideSplit = this.input = new Tone.MidSideSplit(); + /** + * the mid/side recombination + * @type {Tone.MidSideMerge} + * @private + */ + this._midSideMerge = this.output = new Tone.MidSideMerge(); + /** + * The compressor applied to the mid signal + * @type {Tone.Compressor} + */ + this.mid = new Tone.Compressor(options.mid); + /** + * The compressor applied to the side signal + * @type {Tone.Compressor} + */ + this.side = new Tone.Compressor(options.side); + this._midSideSplit.mid.chain(this.mid, this._midSideMerge.mid); + this._midSideSplit.side.chain(this.side, this._midSideMerge.side); + this._readOnly([ + 'mid', + 'side' + ]); + }; + Tone.extend(Tone.MidSideCompressor); + /** + * @const + * @static + * @type {Object} + */ + Tone.MidSideCompressor.defaults = { + 'mid': { + 'ratio': 3, + 'threshold': -24, + 'release': 0.03, + 'attack': 0.02, + 'knee': 16 + }, + 'side': { + 'ratio': 6, + 'threshold': -30, + 'release': 0.25, + 'attack': 0.03, + 'knee': 10 + } + }; + /** + * Clean up. + * @returns {Tone.MidSideCompressor} this + */ + Tone.MidSideCompressor.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._writable([ + 'mid', + 'side' + ]); + this.mid.dispose(); + this.mid = null; + this.side.dispose(); + this.side = null; + this._midSideSplit.dispose(); + this._midSideSplit = null; + this._midSideMerge.dispose(); + this._midSideMerge = null; + return this; + }; + return Tone.MidSideCompressor; + }); + Module(function (Tone) { + + /** + * @class Tone.Mono coerces the incoming mono or stereo signal into a mono signal + * where both left and right channels have the same value. This can be useful + * for [stereo imaging](https://en.wikipedia.org/wiki/Stereo_imaging). + * + * @extends {Tone} + * @constructor + */ + Tone.Mono = function () { + this.createInsOuts(1, 0); + /** + * merge the signal + * @type {Tone.Merge} + * @private + */ + this._merge = this.output = new Tone.Merge(); + this.input.connect(this._merge, 0, 0); + this.input.connect(this._merge, 0, 1); + this.input.gain.value = this.dbToGain(-10); + }; + Tone.extend(Tone.Mono); + /** + * clean up + * @returns {Tone.Mono} this + */ + Tone.Mono.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._merge.dispose(); + this._merge = null; + return this; + }; + return Tone.Mono; + }); + Module(function (Tone) { + + /** + * @class A compressor with seperate controls over low/mid/high dynamics + * + * @extends {Tone} + * @constructor + * @param {Object} options The low/mid/high compressor settings. + * @example + * var multiband = new Tone.MultibandCompressor({ + * "lowFrequency" : 200, + * "highFrequency" : 1300 + * "low" : { + * "threshold" : -12 + * } + * }) + */ + Tone.MultibandCompressor = function (options) { + options = this.defaultArg(arguments, Tone.MultibandCompressor.defaults); + /** + * split the incoming signal into high/mid/low + * @type {Tone.MultibandSplit} + * @private + */ + this._splitter = this.input = new Tone.MultibandSplit({ + 'lowFrequency': options.lowFrequency, + 'highFrequency': options.highFrequency + }); + /** + * low/mid crossover frequency. + * @type {Frequency} + * @signal + */ + this.lowFrequency = this._splitter.lowFrequency; + /** + * mid/high crossover frequency. + * @type {Frequency} + * @signal + */ + this.highFrequency = this._splitter.highFrequency; + /** + * the output + * @type {Tone.Gain} + * @private + */ + this.output = new Tone.Gain(); + /** + * The compressor applied to the low frequencies. + * @type {Tone.Compressor} + */ + this.low = new Tone.Compressor(options.low); + /** + * The compressor applied to the mid frequencies. + * @type {Tone.Compressor} + */ + this.mid = new Tone.Compressor(options.mid); + /** + * The compressor applied to the high frequencies. + * @type {Tone.Compressor} + */ + this.high = new Tone.Compressor(options.high); + //connect the compressor + this._splitter.low.chain(this.low, this.output); + this._splitter.mid.chain(this.mid, this.output); + this._splitter.high.chain(this.high, this.output); + this._readOnly([ + 'high', + 'mid', + 'low', + 'highFrequency', + 'lowFrequency' + ]); + }; + Tone.extend(Tone.MultibandCompressor); + /** + * @const + * @static + * @type {Object} + */ + Tone.MultibandCompressor.defaults = { + 'low': Tone.Compressor.defaults, + 'mid': Tone.Compressor.defaults, + 'high': Tone.Compressor.defaults, + 'lowFrequency': 250, + 'highFrequency': 2000 + }; + /** + * clean up + * @returns {Tone.MultibandCompressor} this + */ + Tone.MultibandCompressor.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._splitter.dispose(); + this._writable([ + 'high', + 'mid', + 'low', + 'highFrequency', + 'lowFrequency' + ]); + this.low.dispose(); + this.mid.dispose(); + this.high.dispose(); + this._splitter = null; + this.low = null; + this.mid = null; + this.high = null; + this.lowFrequency = null; + this.highFrequency = null; + return this; + }; + return Tone.MultibandCompressor; + }); + Module(function (Tone) { + + /** + * @class Tone.Panner is an equal power Left/Right Panner and does not + * support 3D. Panner uses the StereoPannerNode when available. + * + * @constructor + * @extends {Tone} + * @param {NormalRange} [initialPan=0] The initail panner value (defaults to 0 = center) + * @example + * //pan the input signal hard right. + * var panner = new Tone.Panner(1); + */ + Tone.Panner = function (initialPan) { + if (this._hasStereoPanner) { + /** + * the panner node + * @type {StereoPannerNode} + * @private + */ + this._panner = this.input = this.output = this.context.createStereoPanner(); + /** + * The pan control. -1 = hard left, 1 = hard right. + * @type {NormalRange} + * @signal + */ + this.pan = this._panner.pan; + } else { + /** + * the dry/wet knob + * @type {Tone.CrossFade} + * @private + */ + this._crossFade = new Tone.CrossFade(); + /** + * @type {Tone.Merge} + * @private + */ + this._merger = this.output = new Tone.Merge(); + /** + * @type {Tone.Split} + * @private + */ + this._splitter = this.input = new Tone.Split(); + /** + * The pan control. -1 = hard left, 1 = hard right. + * @type {AudioRange} + * @signal + */ + this.pan = new Tone.Signal(0, Tone.Type.AudioRange); + /** + * always sends 0 + * @type {Tone.Zero} + * @private + */ + this._zero = new Tone.Zero(); + /** + * The analog to gain conversion + * @type {Tone.AudioToGain} + * @private + */ + this._a2g = new Tone.AudioToGain(); + //CONNECTIONS: + this._zero.connect(this._a2g); + this.pan.chain(this._a2g, this._crossFade.fade); + //left channel is a, right channel is b + this._splitter.connect(this._crossFade, 0, 0); + this._splitter.connect(this._crossFade, 1, 1); + //merge it back together + this._crossFade.a.connect(this._merger, 0, 0); + this._crossFade.b.connect(this._merger, 0, 1); + } + //initial value + this.pan.value = this.defaultArg(initialPan, 0); + this._readOnly('pan'); + }; + Tone.extend(Tone.Panner); + /** + * indicates if the panner is using the new StereoPannerNode internally + * @type {boolean} + * @private + */ + Tone.Panner.prototype._hasStereoPanner = Tone.prototype.isFunction(Tone.context.createStereoPanner); + /** + * Clean up. + * @returns {Tone.Panner} this + */ + Tone.Panner.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._writable('pan'); + if (this._hasStereoPanner) { + this._panner.disconnect(); + this._panner = null; + this.pan = null; + } else { + this._zero.dispose(); + this._zero = null; + this._crossFade.dispose(); + this._crossFade = null; + this._splitter.dispose(); + this._splitter = null; + this._merger.dispose(); + this._merger = null; + this.pan.dispose(); + this.pan = null; + this._a2g.dispose(); + this._a2g = null; + } + return this; + }; + return Tone.Panner; + }); + Module(function (Tone) { + + /** + * @class A spatialized panner node which supports equalpower or HRTF panning. + * Tries to normalize the API across various browsers. See Tone.Listener + * + * @constructor + * @extends {Tone} + * @param {Number} positionX The initial x position. + * @param {Number} positionY The initial y position. + * @param {Number} positionZ The initial z position. + */ + Tone.Panner3D = function () { + var options = this.optionsObject(arguments, [ + 'positionX', + 'positionY', + 'positionZ' + ], Tone.Panner3D.defaults); + /** + * The panner node + * @type {PannerNode} + * @private + */ + this._panner = this.input = this.output = this.context.createPanner(); + //set some values + this._panner.panningModel = options.panningModel; + this._panner.maxDistance = options.maxDistance; + this._panner.distanceModel = options.distanceModel; + this._panner.coneOuterGain = options.coneOuterGain; + this._panner.coneOuterAngle = options.coneOuterAngle; + this._panner.coneInnerAngle = options.coneInnerAngle; + this._panner.refDistance = options.refDistance; + this._panner.rolloffFactor = options.rolloffFactor; + /** + * Holds the current orientation + * @type {Array} + * @private + */ + this._orientation = [ + options.orientationX, + options.orientationY, + options.orientationZ + ]; + /** + * Holds the current position + * @type {Array} + * @private + */ + this._position = [ + options.positionX, + options.positionY, + options.positionZ + ]; + // set the default position/orientation + this.orientationX = options.orientationX; + this.orientationY = options.orientationY; + this.orientationZ = options.orientationZ; + this.positionX = options.positionX; + this.positionY = options.positionY; + this.positionZ = options.positionZ; + }; + Tone.extend(Tone.Panner3D); + /** + * the default parameters + * @static + * @const + * @type {Object} + * Defaults according to the specification + */ + Tone.Panner3D.defaults = { + 'positionX': 0, + 'positionY': 0, + 'positionZ': 0, + 'orientationX': 0, + 'orientationY': 0, + 'orientationZ': 0, + 'panningModel': 'equalpower', + 'maxDistance': 10000, + 'distanceModel': 'inverse', + 'coneOuterGain': 0, + 'coneOuterAngle': 360, + 'coneInnerAngle': 360, + 'refDistance': 1, + 'rolloffFactor': 1 + }; + /** + * The ramp time which is applied to the setTargetAtTime + * @type {Number} + * @private + */ + Tone.Panner3D.prototype._rampTimeConstant = 0.01; + /** + * Sets the position of the source in 3d space. + * @param {Number} x + * @param {Number} y + * @param {Number} z + * @return {Tone.Panner3D} this + */ + Tone.Panner3D.prototype.setPosition = function (x, y, z) { + if (this._panner.positionX) { + var now = this.now(); + this._panner.positionX.setTargetAtTime(x, now, this._rampTimeConstant); + this._panner.positionY.setTargetAtTime(y, now, this._rampTimeConstant); + this._panner.positionZ.setTargetAtTime(z, now, this._rampTimeConstant); + } else { + this._panner.setPosition(x, y, z); + } + this._position = Array.prototype.slice.call(arguments); + return this; + }; + /** + * Sets the orientation of the source in 3d space. + * @param {Number} x + * @param {Number} y + * @param {Number} z + * @return {Tone.Panner3D} this + */ + Tone.Panner3D.prototype.setOrientation = function (x, y, z) { + if (this._panner.orientationX) { + var now = this.now(); + this._panner.orientationX.setTargetAtTime(x, now, this._rampTimeConstant); + this._panner.orientationY.setTargetAtTime(y, now, this._rampTimeConstant); + this._panner.orientationZ.setTargetAtTime(z, now, this._rampTimeConstant); + } else { + this._panner.setOrientation(x, y, z); + } + this._orientation = Array.prototype.slice.call(arguments); + return this; + }; + /** + * The x position of the panner object. + * @type {Number} + * @memberOf Tone.Panner3D# + * @name positionX + */ + Object.defineProperty(Tone.Panner3D.prototype, 'positionX', { + set: function (pos) { + this._position[0] = pos; + this.setPosition.apply(this, this._position); + }, + get: function () { + return this._position[0]; + } + }); + /** + * The y position of the panner object. + * @type {Number} + * @memberOf Tone.Panner3D# + * @name positionY + */ + Object.defineProperty(Tone.Panner3D.prototype, 'positionY', { + set: function (pos) { + this._position[1] = pos; + this.setPosition.apply(this, this._position); + }, + get: function () { + return this._position[1]; + } + }); + /** + * The z position of the panner object. + * @type {Number} + * @memberOf Tone.Panner3D# + * @name positionZ + */ + Object.defineProperty(Tone.Panner3D.prototype, 'positionZ', { + set: function (pos) { + this._position[2] = pos; + this.setPosition.apply(this, this._position); + }, + get: function () { + return this._position[2]; + } + }); + /** + * The x orientation of the panner object. + * @type {Number} + * @memberOf Tone.Panner3D# + * @name orientationX + */ + Object.defineProperty(Tone.Panner3D.prototype, 'orientationX', { + set: function (pos) { + this._orientation[0] = pos; + this.setOrientation.apply(this, this._orientation); + }, + get: function () { + return this._orientation[0]; + } + }); + /** + * The y orientation of the panner object. + * @type {Number} + * @memberOf Tone.Panner3D# + * @name orientationY + */ + Object.defineProperty(Tone.Panner3D.prototype, 'orientationY', { + set: function (pos) { + this._orientation[1] = pos; + this.setOrientation.apply(this, this._orientation); + }, + get: function () { + return this._orientation[1]; + } + }); + /** + * The z orientation of the panner object. + * @type {Number} + * @memberOf Tone.Panner3D# + * @name orientationZ + */ + Object.defineProperty(Tone.Panner3D.prototype, 'orientationZ', { + set: function (pos) { + this._orientation[2] = pos; + this.setOrientation.apply(this, this._orientation); + }, + get: function () { + return this._orientation[2]; + } + }); + /** + * Proxy a property on the panner to an exposed public propery + * @param {String} prop + * @private + */ + Tone.Panner3D._aliasProperty = function (prop) { + Object.defineProperty(Tone.Panner3D.prototype, prop, { + set: function (val) { + this._panner[prop] = val; + }, + get: function () { + return this._panner[prop]; + } + }); + }; + /** + * The panning model. Either "equalpower" or "HRTF". + * @type {String} + * @memberOf Tone.Panner3D# + * @name panningModel + */ + Tone.Panner3D._aliasProperty('panningModel'); + /** + * A reference distance for reducing volume as source move further from the listener + * @type {Number} + * @memberOf Tone.Panner3D# + * @name refDistance + */ + Tone.Panner3D._aliasProperty('refDistance'); + /** + * Describes how quickly the volume is reduced as source moves away from listener. + * @type {Number} + * @memberOf Tone.Panner3D# + * @name rolloffFactor + */ + Tone.Panner3D._aliasProperty('rolloffFactor'); + /** + * The distance model used by, "linear", "inverse", or "exponential". + * @type {String} + * @memberOf Tone.Panner3D# + * @name distanceModel + */ + Tone.Panner3D._aliasProperty('distanceModel'); + /** + * The angle, in degrees, inside of which there will be no volume reduction + * @type {Degrees} + * @memberOf Tone.Panner3D# + * @name coneInnerAngle + */ + Tone.Panner3D._aliasProperty('coneInnerAngle'); + /** + * The angle, in degrees, outside of which the volume will be reduced + * to a constant value of coneOuterGain + * @type {Degrees} + * @memberOf Tone.Panner3D# + * @name coneOuterAngle + */ + Tone.Panner3D._aliasProperty('coneOuterAngle'); + /** + * The gain outside of the coneOuterAngle + * @type {Gain} + * @memberOf Tone.Panner3D# + * @name coneOuterGain + */ + Tone.Panner3D._aliasProperty('coneOuterGain'); + /** + * The maximum distance between source and listener, + * after which the volume will not be reduced any further. + * @type {Positive} + * @memberOf Tone.Panner3D# + * @name maxDistance + */ + Tone.Panner3D._aliasProperty('maxDistance'); + /** + * Clean up. + * @returns {Tone.Panner3D} this + */ + Tone.Panner3D.prototype.dispose = function () { + this._panner.disconnect(); + this._panner = null; + this._orientation = null; + this._position = null; + return this; + }; + return Tone.Panner3D; + }); + Module(function (Tone) { + + /** + * @class Tone.PanVol is a Tone.Panner and Tone.Volume in one. + * + * @extends {Tone} + * @constructor + * @param {AudioRange} pan the initial pan + * @param {number} volume The output volume. + * @example + * //pan the incoming signal left and drop the volume + * var panVol = new Tone.PanVol(0.25, -12); + */ + Tone.PanVol = function () { + var options = this.optionsObject(arguments, [ + 'pan', + 'volume' + ], Tone.PanVol.defaults); + /** + * The panning node + * @type {Tone.Panner} + * @private + */ + this._panner = this.input = new Tone.Panner(options.pan); + /** + * The L/R panning control. + * @type {AudioRange} + * @signal + */ + this.pan = this._panner.pan; + /** + * The volume node + * @type {Tone.Volume} + */ + this._volume = this.output = new Tone.Volume(options.volume); + /** + * The volume control in decibels. + * @type {Decibels} + * @signal + */ + this.volume = this._volume.volume; + //connections + this._panner.connect(this._volume); + this._readOnly([ + 'pan', + 'volume' + ]); + }; + Tone.extend(Tone.PanVol); + /** + * The defaults + * @type {Object} + * @const + * @static + */ + Tone.PanVol.defaults = { + 'pan': 0.5, + 'volume': 0 + }; + /** + * clean up + * @returns {Tone.PanVol} this + */ + Tone.PanVol.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._writable([ + 'pan', + 'volume' + ]); + this._panner.dispose(); + this._panner = null; + this.pan = null; + this._volume.dispose(); + this._volume = null; + this.volume = null; + return this; + }; + return Tone.PanVol; + }); + Module(function (Tone) { + + /** + * @class Tone.CtrlInterpolate will interpolate between given values based + * on the "index" property. Passing in an array or object literal + * will interpolate each of the parameters. Note (i.e. "C3") + * and Time (i.e. "4n + 2") can be interpolated. All other values are + * assumed to be numbers. + * @example + * var interp = new Tone.CtrlInterpolate([0, 2, 9, 4]); + * interp.index = 0.75; + * interp.value; //returns 1.5 + * + * @example + * var interp = new Tone.CtrlInterpolate([ + * [2, 4, 5], + * [9, 3, 2], + * ]); + * @param {Array} values The array of values to interpolate over + * @param {Positive} index The initial interpolation index. + * @extends {Tone} + */ + Tone.CtrlInterpolate = function () { + var options = this.optionsObject(arguments, [ + 'values', + 'index' + ], Tone.CtrlInterpolate.defaults); + /** + * The values to interpolate between + * @type {Array} + */ + this.values = options.values; + /** + * The interpolated index between values. For example: a value of 1.5 + * would interpolate equally between the value at index 1 + * and the value at index 2. + * @example + * interp.index = 0; + * interp.value; //returns the value at 0 + * interp.index = 0.5; + * interp.value; //returns the value between indices 0 and 1. + * @type {Positive} + */ + this.index = options.index; + }; + Tone.extend(Tone.CtrlInterpolate); + /** + * The defaults + * @const + * @type {Object} + */ + Tone.CtrlInterpolate.defaults = { + 'index': 0, + 'values': [] + }; + /** + * The current interpolated value based on the index + * @readOnly + * @memberOf Tone.CtrlInterpolate# + * @type {*} + * @name value + */ + Object.defineProperty(Tone.CtrlInterpolate.prototype, 'value', { + get: function () { + var index = this.index; + index = Math.min(index, this.values.length - 1); + var lowerPosition = Math.floor(index); + var lower = this.values[lowerPosition]; + var upper = this.values[Math.ceil(index)]; + return this._interpolate(index - lowerPosition, lower, upper); + } + }); + /** + * Internal interpolation routine + * @param {NormalRange} index The index between the lower and upper + * @param {*} lower + * @param {*} upper + * @return {*} The interpolated value + * @private + */ + Tone.CtrlInterpolate.prototype._interpolate = function (index, lower, upper) { + if (this.isArray(lower)) { + var retArray = []; + for (var i = 0; i < lower.length; i++) { + retArray[i] = this._interpolate(index, lower[i], upper[i]); + } + return retArray; + } else if (this.isObject(lower)) { + var retObj = {}; + for (var attr in lower) { + retObj[attr] = this._interpolate(index, lower[attr], upper[attr]); + } + return retObj; + } else { + lower = this._toNumber(lower); + upper = this._toNumber(upper); + return (1 - index) * lower + index * upper; + } + }; + /** + * Convert from the given type into a number + * @param {Number|String} value + * @return {Number} + * @private + */ + Tone.CtrlInterpolate.prototype._toNumber = function (val) { + if (this.isNumber(val)) { + return val; + } else { + //otherwise assume that it's Time... + return this.toSeconds(val); + } + }; + /** + * Clean up + * @return {Tone.CtrlInterpolate} this + */ + Tone.CtrlInterpolate.prototype.dispose = function () { + this.values = null; + }; + return Tone.CtrlInterpolate; + }); + Module(function (Tone) { + + /** + * @class Tone.CtrlMarkov represents a Markov Chain where each call + * to Tone.CtrlMarkov.next will move to the next state. If the next + * state choice is an array, the next state is chosen randomly with + * even probability for all of the choices. For a weighted probability + * of the next choices, pass in an object with "state" and "probability" attributes. + * The probabilities will be normalized and then chosen. If no next options + * are given for the current state, the state will stay there. + * @extends {Tone} + * @example + * var chain = new Tone.CtrlMarkov({ + * "beginning" : ["end", "middle"], + * "middle" : "end" + * }); + * chain.value = "beginning"; + * chain.next(); //returns "end" or "middle" with 50% probability + * + * @example + * var chain = new Tone.CtrlMarkov({ + * "beginning" : [{"value" : "end", "probability" : 0.8}, + * {"value" : "middle", "probability" : 0.2}], + * "middle" : "end" + * }); + * chain.value = "beginning"; + * chain.next(); //returns "end" with 80% probability or "middle" with 20%. + * @param {Object} values An object with the state names as the keys + * and the next state(s) as the values. + */ + Tone.CtrlMarkov = function (values, initial) { + /** + * The Markov values with states as the keys + * and next state(s) as the values. + * @type {Object} + */ + this.values = this.defaultArg(values, {}); + /** + * The current state of the Markov values. The next + * state will be evaluated and returned when Tone.CtrlMarkov.next + * is invoked. + * @type {String} + */ + this.value = this.defaultArg(initial, Object.keys(this.values)[0]); + }; + Tone.extend(Tone.CtrlMarkov); + /** + * Returns the next state of the Markov values. + * @return {String} + */ + Tone.CtrlMarkov.prototype.next = function () { + if (this.values.hasOwnProperty(this.value)) { + var next = this.values[this.value]; + if (this.isArray(next)) { + var distribution = this._getProbDistribution(next); + var rand = Math.random(); + var total = 0; + for (var i = 0; i < distribution.length; i++) { + var dist = distribution[i]; + if (rand > total && rand < total + dist) { + var chosen = next[i]; + if (this.isObject(chosen)) { + this.value = chosen.value; + } else { + this.value = chosen; + } + } + total += dist; + } + } else { + this.value = next; + } + } + return this.value; + }; + /** + * Choose randomly from an array weighted options in the form + * {"state" : string, "probability" : number} or an array of values + * @param {Array} options + * @return {Array} The randomly selected choice + * @private + */ + Tone.CtrlMarkov.prototype._getProbDistribution = function (options) { + var distribution = []; + var total = 0; + var needsNormalizing = false; + for (var i = 0; i < options.length; i++) { + var option = options[i]; + if (this.isObject(option)) { + needsNormalizing = true; + distribution[i] = option.probability; + } else { + distribution[i] = 1 / options.length; + } + total += distribution[i]; + } + if (needsNormalizing) { + //normalize the values + for (var j = 0; j < distribution.length; j++) { + distribution[j] = distribution[j] / total; + } + } + return distribution; + }; + /** + * Clean up + * @return {Tone.CtrlMarkov} this + */ + Tone.CtrlMarkov.prototype.dispose = function () { + this.values = null; + }; + return Tone.CtrlMarkov; + }); + Module(function (Tone) { + + /** + * @class Generate patterns from an array of values. + * Has a number of arpeggiation and randomized + * selection patterns. + *
    + *
  • "up" - cycles upward
  • + *
  • "down" - cycles downward
  • + *
  • "upDown" - up then and down
  • + *
  • "downUp" - cycles down then and up
  • + *
  • "alternateUp" - jump up two and down one
  • + *
  • "alternateDown" - jump down two and up one
  • + *
  • "random" - randomly select an index
  • + *
  • "randomWalk" - randomly moves one index away from the current position
  • + *
  • "randomOnce" - randomly select an index without repeating until all values have been chosen.
  • + *
+ * @param {Array} values An array of options to choose from. + * @param {Tone.CtrlPattern.Type=} type The name of the pattern. + * @extends {Tone} + */ + Tone.CtrlPattern = function () { + var options = this.optionsObject(arguments, [ + 'values', + 'type' + ], Tone.CtrlPattern.defaults); + /** + * The array of values to arpeggiate over + * @type {Array} + */ + this.values = options.values; + /** + * The current position in the values array + * @type {Number} + */ + this.index = 0; + /** + * The type placeholder + * @type {Tone.CtrlPattern.Type} + * @private + */ + this._type = null; + /** + * Shuffled values for the RandomOnce type + * @type {Array} + * @private + */ + this._shuffled = null; + /** + * The direction of the movement + * @type {String} + * @private + */ + this._direction = null; + this.type = options.type; + }; + Tone.extend(Tone.CtrlPattern); + /** + * The Control Patterns + * @type {Object} + * @static + */ + Tone.CtrlPattern.Type = { + Up: 'up', + Down: 'down', + UpDown: 'upDown', + DownUp: 'downUp', + AlternateUp: 'alternateUp', + AlternateDown: 'alternateDown', + Random: 'random', + RandomWalk: 'randomWalk', + RandomOnce: 'randomOnce' + }; + /** + * The default values. + * @type {Object} + */ + Tone.CtrlPattern.defaults = { + 'type': Tone.CtrlPattern.Type.Up, + 'values': [] + }; + /** + * The value at the current index of the pattern. + * @readOnly + * @memberOf Tone.CtrlPattern# + * @type {*} + * @name value + */ + Object.defineProperty(Tone.CtrlPattern.prototype, 'value', { + get: function () { + //some safeguards + if (this.values.length === 0) { + return; + } else if (this.values.length === 1) { + return this.values[0]; + } + this.index = Math.min(this.index, this.values.length - 1); + var val = this.values[this.index]; + if (this.type === Tone.CtrlPattern.Type.RandomOnce) { + if (this.values.length !== this._shuffled.length) { + this._shuffleValues(); + } + val = this.values[this._shuffled[this.index]]; + } + return val; + } + }); + /** + * The pattern used to select the next + * item from the values array + * @memberOf Tone.CtrlPattern# + * @type {Tone.CtrlPattern.Type} + * @name type + */ + Object.defineProperty(Tone.CtrlPattern.prototype, 'type', { + get: function () { + return this._type; + }, + set: function (type) { + this._type = type; + this._shuffled = null; + //the first index + if (this._type === Tone.CtrlPattern.Type.Up || this._type === Tone.CtrlPattern.Type.UpDown || this._type === Tone.CtrlPattern.Type.RandomOnce || this._type === Tone.CtrlPattern.Type.AlternateUp) { + this.index = 0; + } else if (this._type === Tone.CtrlPattern.Type.Down || this._type === Tone.CtrlPattern.Type.DownUp || this._type === Tone.CtrlPattern.Type.AlternateDown) { + this.index = this.values.length - 1; + } + //the direction + if (this._type === Tone.CtrlPattern.Type.UpDown || this._type === Tone.CtrlPattern.Type.AlternateUp) { + this._direction = Tone.CtrlPattern.Type.Up; + } else if (this._type === Tone.CtrlPattern.Type.DownUp || this._type === Tone.CtrlPattern.Type.AlternateDown) { + this._direction = Tone.CtrlPattern.Type.Down; + } + //randoms + if (this._type === Tone.CtrlPattern.Type.RandomOnce) { + this._shuffleValues(); + } else if (this._type === Tone.CtrlPattern.Random) { + this.index = Math.floor(Math.random() * this.values.length); + } + } + }); + /** + * Return the next value given the current position + * and pattern. + * @return {*} The next value + */ + Tone.CtrlPattern.prototype.next = function () { + var type = this.type; + //choose the next index + if (type === Tone.CtrlPattern.Type.Up) { + this.index++; + if (this.index >= this.values.length) { + this.index = 0; + } + } else if (type === Tone.CtrlPattern.Type.Down) { + this.index--; + if (this.index < 0) { + this.index = this.values.length - 1; + } + } else if (type === Tone.CtrlPattern.Type.UpDown || type === Tone.CtrlPattern.Type.DownUp) { + if (this._direction === Tone.CtrlPattern.Type.Up) { + this.index++; + } else { + this.index--; + } + if (this.index < 0) { + this.index = 1; + this._direction = Tone.CtrlPattern.Type.Up; + } else if (this.index >= this.values.length) { + this.index = this.values.length - 2; + this._direction = Tone.CtrlPattern.Type.Down; + } + } else if (type === Tone.CtrlPattern.Type.Random) { + this.index = Math.floor(Math.random() * this.values.length); + } else if (type === Tone.CtrlPattern.Type.RandomWalk) { + if (Math.random() < 0.5) { + this.index--; + this.index = Math.max(this.index, 0); + } else { + this.index++; + this.index = Math.min(this.index, this.values.length - 1); + } + } else if (type === Tone.CtrlPattern.Type.RandomOnce) { + this.index++; + if (this.index >= this.values.length) { + this.index = 0; + //reshuffle the values for next time + this._shuffleValues(); + } + } else if (type === Tone.CtrlPattern.Type.AlternateUp) { + if (this._direction === Tone.CtrlPattern.Type.Up) { + this.index += 2; + this._direction = Tone.CtrlPattern.Type.Down; + } else { + this.index -= 1; + this._direction = Tone.CtrlPattern.Type.Up; + } + if (this.index >= this.values.length) { + this.index = 0; + this._direction = Tone.CtrlPattern.Type.Up; + } + } else if (type === Tone.CtrlPattern.Type.AlternateDown) { + if (this._direction === Tone.CtrlPattern.Type.Up) { + this.index += 1; + this._direction = Tone.CtrlPattern.Type.Down; + } else { + this.index -= 2; + this._direction = Tone.CtrlPattern.Type.Up; + } + if (this.index < 0) { + this.index = this.values.length - 1; + this._direction = Tone.CtrlPattern.Type.Down; + } + } + return this.value; + }; + /** + * Shuffles the values and places the results into the _shuffled + * @private + */ + Tone.CtrlPattern.prototype._shuffleValues = function () { + var copy = []; + this._shuffled = []; + for (var i = 0; i < this.values.length; i++) { + copy[i] = i; + } + while (copy.length > 0) { + var randVal = copy.splice(Math.floor(copy.length * Math.random()), 1); + this._shuffled.push(randVal[0]); + } + }; + /** + * Clean up + * @returns {Tone.CtrlPattern} this + */ + Tone.CtrlPattern.prototype.dispose = function () { + this._shuffled = null; + this.values = null; + }; + return Tone.CtrlPattern; + }); + Module(function (Tone) { + + /** + * @class Choose a random value. + * @extends {Tone} + * @example + * var randomWalk = new Tone.CtrlRandom({ + * "min" : 0, + * "max" : 10, + * "integer" : true + * }); + * randomWalk.eval(); + * + * @param {Number|Time=} min The minimum return value. + * @param {Number|Time=} max The maximum return value. + */ + Tone.CtrlRandom = function () { + var options = this.optionsObject(arguments, [ + 'min', + 'max' + ], Tone.CtrlRandom.defaults); + /** + * The minimum return value + * @type {Number|Time} + */ + this.min = options.min; + /** + * The maximum return value + * @type {Number|Time} + */ + this.max = options.max; + /** + * If the return value should be an integer + * @type {Boolean} + */ + this.integer = options.integer; + }; + Tone.extend(Tone.CtrlRandom); + /** + * The defaults + * @const + * @type {Object} + */ + Tone.CtrlRandom.defaults = { + 'min': 0, + 'max': 1, + 'integer': false + }; + /** + * Return a random value between min and max. + * @readOnly + * @memberOf Tone.CtrlRandom# + * @type {*} + * @name value + */ + Object.defineProperty(Tone.CtrlRandom.prototype, 'value', { + get: function () { + var min = this.toSeconds(this.min); + var max = this.toSeconds(this.max); + var rand = Math.random(); + var val = rand * min + (1 - rand) * max; + if (this.integer) { + val = Math.floor(val); + } + return val; + } + }); + return Tone.CtrlRandom; + }); + Module(function (Tone) { + + /** + * @class Buffer loading and storage. Tone.Buffer is used internally by all + * classes that make requests for audio files such as Tone.Player, + * Tone.Sampler and Tone.Convolver. + *

+ * Aside from load callbacks from individual buffers, Tone.Buffer + * provides static methods which keep track of the loading progress + * of all of the buffers. These methods are Tone.Buffer.on("load" / "progress" / "error") + * + * @constructor + * @extends {Tone} + * @param {AudioBuffer|string} url The url to load, or the audio buffer to set. + * @param {Function=} onload A callback which is invoked after the buffer is loaded. + * It's recommended to use Tone.Buffer.onload instead + * since it will give you a callback when ALL buffers are loaded. + * @param {Function=} onerror The callback to invoke if there is an error + * @example + * var buffer = new Tone.Buffer("path/to/sound.mp3", function(){ + * //the buffer is now available. + * var buff = buffer.get(); + * }); + */ + Tone.Buffer = function () { + var options = this.optionsObject(arguments, [ + 'url', + 'onload', + 'onerror' + ], Tone.Buffer.defaults); + /** + * stores the loaded AudioBuffer + * @type {AudioBuffer} + * @private + */ + this._buffer = null; + /** + * indicates if the buffer should be reversed or not + * @type {Boolean} + * @private + */ + this._reversed = options.reverse; + /** + * The XHR + * @type {XMLHttpRequest} + * @private + */ + this._xhr = null; + if (options.url instanceof AudioBuffer || options.url instanceof Tone.Buffer) { + this.set(options.url); + // invoke the onload callback + if (options.onload) { + options.onload(this); + } + } else if (this.isString(options.url)) { + this.load(options.url, options.onload, options.onerror); + } + }; + Tone.extend(Tone.Buffer); + /** + * the default parameters + * @type {Object} + */ + Tone.Buffer.defaults = { + 'url': undefined, + 'reverse': false + }; + /** + * Pass in an AudioBuffer or Tone.Buffer to set the value + * of this buffer. + * @param {AudioBuffer|Tone.Buffer} buffer the buffer + * @returns {Tone.Buffer} this + */ + Tone.Buffer.prototype.set = function (buffer) { + if (buffer instanceof Tone.Buffer) { + this._buffer = buffer.get(); + } else { + this._buffer = buffer; + } + return this; + }; + /** + * @return {AudioBuffer} The audio buffer stored in the object. + */ + Tone.Buffer.prototype.get = function () { + return this._buffer; + }; + /** + * Makes an xhr reqest for the selected url then decodes + * the file as an audio buffer. Invokes + * the callback once the audio buffer loads. + * @param {String} url The url of the buffer to load. + * filetype support depends on the + * browser. + * @returns {Promise} returns a Promise which resolves with the Tone.Buffer + */ + Tone.Buffer.prototype.load = function (url, onload, onerror) { + var promise = new Promise(function (load, error) { + this._xhr = Tone.Buffer.load(url, //success + function (buff) { + this._xhr = null; + this.set(buff); + load(this); + if (onload) { + onload(this); + } + }.bind(this), //error + function (err) { + this._xhr = null; + error(err); + if (onerror) { + onerror(err); + } + }.bind(this)); + }.bind(this)); + return promise; + }; + /** + * dispose and disconnect + * @returns {Tone.Buffer} this + */ + Tone.Buffer.prototype.dispose = function () { + Tone.Emitter.prototype.dispose.call(this); + this._buffer = null; + if (this._xhr) { + Tone.Buffer._currentDownloads--; + this._xhr.abort(); + this._xhr = null; + } + return this; + }; + /** + * If the buffer is loaded or not + * @memberOf Tone.Buffer# + * @type {Boolean} + * @name loaded + * @readOnly + */ + Object.defineProperty(Tone.Buffer.prototype, 'loaded', { + get: function () { + return this.length > 0; + } + }); + /** + * The duration of the buffer. + * @memberOf Tone.Buffer# + * @type {Number} + * @name duration + * @readOnly + */ + Object.defineProperty(Tone.Buffer.prototype, 'duration', { + get: function () { + if (this._buffer) { + return this._buffer.duration; + } else { + return 0; + } + } + }); + /** + * The length of the buffer in samples + * @memberOf Tone.Buffer# + * @type {Number} + * @name length + * @readOnly + */ + Object.defineProperty(Tone.Buffer.prototype, 'length', { + get: function () { + if (this._buffer) { + return this._buffer.length; + } else { + return 0; + } + } + }); + /** + * The number of discrete audio channels. Returns 0 if no buffer + * is loaded. + * @memberOf Tone.Buffer# + * @type {Number} + * @name numberOfChannels + * @readOnly + */ + Object.defineProperty(Tone.Buffer.prototype, 'numberOfChannels', { + get: function () { + if (this._buffer) { + return this._buffer.numberOfChannels; + } else { + return 0; + } + } + }); + /** + * Set the audio buffer from the array + * @param {Float32Array} array The array to fill the audio buffer + * @param {Number} [channels=1] The number of channels contained in the array. + * If the channel is more than 1, the input array + * is expected to be a multidimensional array + * with dimensions equal to the number of channels. + * @return {Tone.Buffer} this + */ + Tone.Buffer.prototype.fromArray = function (array) { + var isMultidimensional = array[0].length > 0; + var channels = isMultidimensional ? array.length : 1; + var len = isMultidimensional ? array[0].length : array.length; + var buffer = this.context.createBuffer(channels, len, this.context.sampleRate); + if (!isMultidimensional && channels === 1) { + array = [array]; + } + for (var c = 0; c < channels; c++) { + if (this.isFunction(buffer.copyToChannel)) { + buffer.copyToChannel(array[c], c); + } else { + var channel = buffer.getChannelData(c); + var channelArray = array[c]; + for (var i = 0; i < channelArray.length; i++) { + channel[i] = channelArray[i]; + } + } + } + this._buffer = buffer; + return this; + }; + /** + * Get the buffer as an array. Single channel buffers will return a 1-dimensional + * Float32Array, and multichannel buffers will return multidimensional arrays. + * @param {Number=} channel Optionally only copy a single channel from the array. + * @return {Array} + */ + Tone.Buffer.prototype.toArray = function (channel) { + if (this.isNumber(channel)) { + return this._buffer.getChannelData(channel); + } else { + var ret = []; + for (var c = 0; c < this.numberOfChannels; c++) { + ret[c] = new Float32Array(this.length); + if (this.isFunction(this._buffer.copyFromChannel)) { + this._buffer.copyFromChannel(ret[c], c); + } else { + var channelData = this._buffer.getChannelData(c); + var retArray = ret[c]; + for (var i = 0; i < channelData.length; i++) { + retArray[i] = channelData[i]; + } + } + } + if (ret.length === 1) { + return ret[0]; + } else { + return ret; + } + } + }; + /** + * Cut a subsection of the array and return a buffer of the + * subsection. Does not modify the original buffer + * @param {Time} start The time to start the slice + * @param {Time=} end The end time to slice. If none is given + * will default to the end of the buffer + * @return {Tone.Buffer} this + */ + Tone.Buffer.prototype.slice = function (start, end) { + end = this.defaultArg(end, this.duration); + var startSamples = Math.floor(this.context.sampleRate * this.toSeconds(start)); + var endSamples = Math.floor(this.context.sampleRate * this.toSeconds(end)); + var replacement = []; + for (var i = 0; i < this.numberOfChannels; i++) { + replacement[i] = this.toArray(i).slice(startSamples, endSamples); + } + var retBuffer = new Tone.Buffer().fromArray(replacement); + return retBuffer; + }; + /** + * Reverse the buffer. + * @private + * @return {Tone.Buffer} this + */ + Tone.Buffer.prototype._reverse = function () { + if (this.loaded) { + for (var i = 0; i < this._buffer.numberOfChannels; i++) { + Array.prototype.reverse.call(this._buffer.getChannelData(i)); + } + } + return this; + }; + /** + * Reverse the buffer. + * @memberOf Tone.Buffer# + * @type {Boolean} + * @name reverse + */ + Object.defineProperty(Tone.Buffer.prototype, 'reverse', { + get: function () { + return this._reversed; + }, + set: function (rev) { + if (this._reversed !== rev) { + this._reversed = rev; + this._reverse(); + } + } + }); + /////////////////////////////////////////////////////////////////////////// + // STATIC METHODS + /////////////////////////////////////////////////////////////////////////// + //statically inherits Emitter methods + Tone.Emitter.mixin(Tone.Buffer); + /** + * the static queue for all of the xhr requests + * @type {Array} + * @private + */ + Tone.Buffer._downloadQueue = []; + /** + * the total number of downloads + * @type {Number} + * @private + */ + Tone.Buffer._currentDownloads = 0; + /** + * A path which is prefixed before every url. + * @type {String} + * @static + */ + Tone.Buffer.baseUrl = ''; + /** + * Loads a url using XMLHttpRequest. + * @param {String} url + * @param {Function} onload + * @param {Function} onerror + * @param {Function} onprogress + * @return {XMLHttpRequest} + */ + Tone.Buffer.load = function (url, onload, onerror) { + //default + onload = onload || Tone.noOp; + function onError(e) { + if (onerror) { + onerror(e); + } else { + throw new Error(e); + } + } + function onProgress() { + //calculate the progress + var totalProgress = 0; + for (var i = 0; i < Tone.Buffer._downloadQueue.length; i++) { + totalProgress += Tone.Buffer._downloadQueue[i].progress; + } + Tone.Buffer.emit('progress', totalProgress / Tone.Buffer._downloadQueue.length); + } + var request = new XMLHttpRequest(); + request.open('GET', Tone.Buffer.baseUrl + url, true); + request.responseType = 'arraybuffer'; + //start out as 0 + request.progress = 0; + Tone.Buffer._currentDownloads++; + Tone.Buffer._downloadQueue.push(request); + request.addEventListener('load', function () { + if (request.status === 200) { + Tone.context.decodeAudioData(request.response, function (buff) { + request.progress = 1; + onProgress(); + onload(buff); + Tone.Buffer._currentDownloads--; + if (Tone.Buffer._currentDownloads === 0) { + // clear the downloads + Tone.Buffer._downloadQueue = []; + //emit the event at the end + Tone.Buffer.emit('load'); + } + }, function () { + onError('Tone.Buffer: could not decode audio data: ' + url); + }); + } else { + onError('Tone.Buffer: could not locate file: ' + url); + } + }); + request.addEventListener('error', onError); + request.addEventListener('progress', function (event) { + if (event.lengthComputable) { + //only go to 95%, the last 5% is when the audio is decoded + request.progress = event.loaded / event.total * 0.95; + onProgress(); + } + }); + request.send(); + return request; + }; + /** + * Stop all of the downloads in progress + * @return {Tone.Buffer} + */ + Tone.Buffer.stopDownloads = function () { + Tone.Buffer._downloadQueue.forEach(function (request) { + request.abort(); + }); + Tone.Buffer._currentDownloads = 0; + return Tone.Buffer; + }; + /** + * Checks a url's extension to see if the current browser can play that file type. + * @param {String} url The url/extension to test + * @return {Boolean} If the file extension can be played + * @static + * @example + * Tone.Buffer.supportsType("wav"); //returns true + * Tone.Buffer.supportsType("path/to/file.wav"); //returns true + */ + Tone.Buffer.supportsType = function (url) { + var extension = url.split('.'); + extension = extension[extension.length - 1]; + var response = document.createElement('audio').canPlayType('audio/' + extension); + return response !== ''; + }; + return Tone.Buffer; + }); + Module(function (Tone) { + /** + * @class A data structure for holding multiple buffers. + * + * @param {Object|Array} urls An object literal or array + * of urls to load. + * @param {Function=} callback The callback to invoke when + * the buffers are loaded. + * @extends {Tone} + * @example + * //load a whole bank of piano samples + * var pianoSamples = new Tone.Buffers({ + * "C4" : "path/to/C4.mp3" + * "C#4" : "path/to/C#4.mp3" + * "D4" : "path/to/D4.mp3" + * "D#4" : "path/to/D#4.mp3" + * ... + * }, function(){ + * //play one of the samples when they all load + * player.buffer = pianoSamples.get("C4"); + * player.start(); + * }); + * + */ + Tone.Buffers = function (urls, onload, baseUrl) { + /** + * All of the buffers + * @type {Object} + * @private + */ + this._buffers = {}; + /** + * A path which is prefixed before every url. + * @type {String} + */ + this.baseUrl = this.defaultArg(baseUrl, ''); + urls = this._flattenUrls(urls); + this._loadingCount = 0; + //add each one + for (var key in urls) { + this._loadingCount++; + this.add(key, urls[key], this._bufferLoaded.bind(this, onload)); + } + }; + Tone.extend(Tone.Buffers); + /** + * True if the buffers object has a buffer by that name. + * @param {String|Number} name The key or index of the + * buffer. + * @return {Boolean} + */ + Tone.Buffers.prototype.has = function (name) { + return this._buffers.hasOwnProperty(name); + }; + /** + * Get a buffer by name. If an array was loaded, + * then use the array index. + * @param {String|Number} name The key or index of the + * buffer. + * @return {Tone.Buffer} + */ + Tone.Buffers.prototype.get = function (name) { + if (this.has(name)) { + return this._buffers[name]; + } else { + throw new Error('Tone.Buffers: no buffer named ' + name); + } + }; + /** + * A buffer was loaded. decrement the counter. + * @param {Function} callback + * @private + */ + Tone.Buffers.prototype._bufferLoaded = function (callback) { + this._loadingCount--; + if (this._loadingCount === 0 && callback) { + callback(this); + } + }; + /** + * If the buffers are loaded or not + * @memberOf Tone.Buffers# + * @type {Boolean} + * @name loaded + * @readOnly + */ + Object.defineProperty(Tone.Buffers.prototype, 'loaded', { + get: function () { + var isLoaded = true; + for (var buffName in this._buffers) { + var buff = this.get(buffName); + isLoaded = isLoaded && buff.loaded; + } + return isLoaded; + } + }); + /** + * Add a buffer by name and url to the Buffers + * @param {String} name A unique name to give + * the buffer + * @param {String|Tone.Buffer|Audiobuffer} url Either the url of the bufer, + * or a buffer which will be added + * with the given name. + * @param {Function=} callback The callback to invoke + * when the url is loaded. + */ + Tone.Buffers.prototype.add = function (name, url, callback) { + callback = this.defaultArg(callback, Tone.noOp); + if (url instanceof Tone.Buffer) { + this._buffers[name] = url; + callback(this); + } else if (url instanceof AudioBuffer) { + this._buffers[name] = new Tone.Buffer(url); + callback(this); + } else if (this.isString(url)) { + this._buffers[name] = new Tone.Buffer(this.baseUrl + url, callback); + } + return this; + }; + /** + * Flatten an object into a single depth object. + * thanks to https://gist.github.com/penguinboy/762197 + * @param {Object} ob + * @return {Object} + * @private + */ + Tone.Buffers.prototype._flattenUrls = function (ob) { + var toReturn = {}; + for (var i in ob) { + if (!ob.hasOwnProperty(i)) + continue; + if (this.isObject(ob[i])) { + var flatObject = this._flattenUrls(ob[i]); + for (var x in flatObject) { + if (!flatObject.hasOwnProperty(x)) + continue; + toReturn[i + '.' + x] = flatObject[x]; + } + } else { + toReturn[i] = ob[i]; + } + } + return toReturn; + }; + /** + * Clean up. + * @return {Tone.Buffers} this + */ + Tone.Buffers.prototype.dispose = function () { + for (var name in this._buffers) { + this._buffers[name].dispose(); + } + this._buffers = null; + return this; + }; + return Tone.Buffers; + }); + Module(function (Tone) { + + /** + * buses are another way of routing audio + * + * augments Tone.prototype to include send and recieve + */ + /** + * All of the routes + * + * @type {Object} + * @static + * @private + */ + var Buses = {}; + /** + * Send this signal to the channel name. + * @param {string} channelName A named channel to send the signal to. + * @param {Decibels} amount The amount of the source to send to the bus. + * @return {GainNode} The gain node which connects this node to the desired channel. + * Can be used to adjust the levels of the send. + * @example + * source.send("reverb", -12); + */ + Tone.prototype.send = function (channelName, amount) { + if (!Buses.hasOwnProperty(channelName)) { + Buses[channelName] = this.context.createGain(); + } + amount = this.defaultArg(amount, 0); + var sendKnob = new Tone.Gain(amount, Tone.Type.Decibels); + this.output.chain(sendKnob, Buses[channelName]); + return sendKnob; + }; + /** + * Recieve the input from the desired channelName to the input + * + * @param {string} channelName A named channel to send the signal to. + * @param {AudioNode} [input] If no input is selected, the + * input of the current node is + * chosen. + * @returns {Tone} this + * @example + * reverbEffect.receive("reverb"); + */ + Tone.prototype.receive = function (channelName, input) { + if (!Buses.hasOwnProperty(channelName)) { + Buses[channelName] = this.context.createGain(); + } + if (this.isUndef(input)) { + input = this.input; + } + Buses[channelName].connect(input); + return this; + }; + //remove all the send/receives when a new audio context is passed in + Tone._initAudioContext(function () { + Buses = {}; + }); + return Tone; + }); + Module(function (Tone) { + + /** + * @class Tone.Draw is useful for synchronizing visuals and audio events. + * Callbacks from Tone.Transport or any of the Tone.Event classes + * always happen _before_ the scheduled time and are not synchronized + * to the animation frame so they are not good for triggering tightly + * synchronized visuals and sound. Tone.Draw makes it easy to schedule + * callbacks using the AudioContext time and uses requestAnimationFrame. + * + * @singleton + * @extends {Tone} + * @example + * Tone.Transport.schedule(function(time){ + * //use the time argument to schedule a callback with Tone.Draw + * Tone.Draw.schedule(function(){ + * //do drawing or DOM manipulation here + * }, time) + * }, "+0.5") + */ + Tone.Draw = function () { + /** + * All of the events. + * @type {Tone.Timeline} + * @private + */ + this._events = new Tone.Timeline(); + /** + * The duration after which events are not invoked. + * @type {Number} + * @default 0.25 + */ + this.expiration = 0.25; + /** + * The amount of time before the scheduled time + * that the callback can be invoked. Default is + * half the time of an animation frame (0.008 seconds). + * @type {Number} + * @default 0.008 + */ + this.anticipation = 0.008; + /** + * The draw loop + * @type {Function} + * @private + */ + this._boundDrawLoop = this._drawLoop.bind(this); + //start the loop + this._drawLoop(); + }; + Tone.extend(Tone.Draw); + /** + * Schedule a function at the given time to be invoked + * on the nearest animation frame. + * @param {Function} callback Callback is invoked at the given time. + * @param {Time} time The time relative to the AudioContext time + * to invoke the callback. + * @return {Tone.Draw} this + */ + Tone.Draw.prototype.schedule = function (callback, time) { + this._events.add({ + callback: callback, + time: this.toSeconds(time) + }); + return this; + }; + /** + * Cancel events scheduled after the given time + * @param {Time=} after Time after which scheduled events will + * be removed from the scheduling timeline. + * @return {Tone.Draw} this + */ + Tone.Draw.prototype.cancel = function (after) { + this._events.cancel(this.toSeconds(after)); + return this; + }; + /** + * The draw loop + * @private + */ + Tone.Draw.prototype._drawLoop = function () { + requestAnimationFrame(this._boundDrawLoop); + var now = Tone.now(); + while (this._events.length && this._events.peek().time - this.anticipation <= now) { + var event = this._events.shift(); + if (now - event.time <= this.expiration) { + event.callback(); + } + } + }; + //make a singleton + Tone.Draw = new Tone.Draw(); + return Tone.Draw; + }); + Module(function (Tone) { + + /** + * @class Both Tone.Panner3D and Tone.Listener have a position in 3D space + * using a right-handed cartesian coordinate system. + * The units used in the coordinate system are not defined; + * these coordinates are independent/invariant of any particular + * units such as meters or feet. Tone.Panner3D objects have an forward + * vector representing the direction the sound is projecting. Additionally, + * they have a sound cone representing how directional the sound is. + * For example, the sound could be omnidirectional, in which case it would + * be heard anywhere regardless of its forward, or it can be more directional + * and heard only if it is facing the listener. Tone.Listener objects + * (representing a person's ears) have an forward and up vector + * representing in which direction the person is facing. Because both the + * source stream and the listener can be moving, they both have a velocity + * vector representing both the speed and direction of movement. Taken together, + * these two velocities can be used to generate a doppler shift effect which changes the pitch. + *

+ * Note: the position of the Listener will have no effect on nodes not connected to a Tone.Panner3D + * + * @constructor + * @extends {Tone} + * @singleton + * @param {Number} positionX The initial x position. + * @param {Number} positionY The initial y position. + * @param {Number} positionZ The initial z position. + */ + Tone.Listener = function () { + var options = this.optionsObject(arguments, [ + 'positionX', + 'positionY', + 'positionZ' + ], ListenerConstructor.defaults); + /** + * The listener node + * @type {AudioListener} + * @private + */ + this._listener = this.context.listener; + /** + * Holds the current forward orientation + * @type {Array} + * @private + */ + this._orientation = [ + options.forwardX, + options.forwardY, + options.forwardZ, + options.upX, + options.upY, + options.upZ + ]; + /** + * Holds the current position + * @type {Array} + * @private + */ + this._position = [ + options.positionX, + options.positionY, + options.positionZ + ]; + // set the default position/forward + this.forwardX = options.forwardX; + this.forwardY = options.forwardY; + this.forwardZ = options.forwardZ; + this.upX = options.upX; + this.upY = options.upY; + this.upZ = options.upZ; + this.positionX = options.positionX; + this.positionY = options.positionY; + this.positionZ = options.positionZ; + }; + Tone.extend(Tone.Listener); + /** + * the default parameters + * @static + * @const + * @type {Object} + * Defaults according to the specification + */ + Tone.Listener.defaults = { + 'positionX': 0, + 'positionY': 0, + 'positionZ': 0, + 'forwardX': 0, + 'forwardY': 0, + 'forwardZ': 1, + 'upX': 0, + 'upY': 1, + 'upZ': 0 + }; + /** + * The ramp time which is applied to the setTargetAtTime + * @type {Number} + * @private + */ + Tone.Listener.prototype._rampTimeConstant = 0.01; + /** + * Sets the position of the listener in 3d space. + * @param {Number} x + * @param {Number} y + * @param {Number} z + * @return {Tone.Listener} this + */ + Tone.Listener.prototype.setPosition = function (x, y, z) { + if (this._listener.positionX) { + var now = this.now(); + this._listener.positionX.setTargetAtTime(x, now, this._rampTimeConstant); + this._listener.positionY.setTargetAtTime(y, now, this._rampTimeConstant); + this._listener.positionZ.setTargetAtTime(z, now, this._rampTimeConstant); + } else { + this._listener.setPosition(x, y, z); + } + this._position = Array.prototype.slice.call(arguments); + return this; + }; + /** + * Sets the orientation of the listener using two vectors, the forward + * vector (which direction the listener is facing) and the up vector + * (which the up direction of the listener). An up vector + * of 0, 0, 1 is equivalent to the listener standing up in the Z direction. + * @param {Number} x + * @param {Number} y + * @param {Number} z + * @param {Number} upX + * @param {Number} upY + * @param {Number} upZ + * @return {Tone.Listener} this + */ + Tone.Listener.prototype.setOrientation = function (x, y, z, upX, upY, upZ) { + if (this._listener.forwardX) { + var now = this.now(); + this._listener.forwardX.setTargetAtTime(x, now, this._rampTimeConstant); + this._listener.forwardY.setTargetAtTime(y, now, this._rampTimeConstant); + this._listener.forwardZ.setTargetAtTime(z, now, this._rampTimeConstant); + this._listener.upX.setTargetAtTime(upX, now, this._rampTimeConstant); + this._listener.upY.setTargetAtTime(upY, now, this._rampTimeConstant); + this._listener.upZ.setTargetAtTime(upZ, now, this._rampTimeConstant); + } else { + this._listener.setOrientation(x, y, z, upX, upY, upZ); + } + this._orientation = Array.prototype.slice.call(arguments); + return this; + }; + /** + * The x position of the panner object. + * @type {Number} + * @memberOf Tone.Listener# + * @name positionX + */ + Object.defineProperty(Tone.Listener.prototype, 'positionX', { + set: function (pos) { + this._position[0] = pos; + this.setPosition.apply(this, this._position); + }, + get: function () { + return this._position[0]; + } + }); + /** + * The y position of the panner object. + * @type {Number} + * @memberOf Tone.Listener# + * @name positionY + */ + Object.defineProperty(Tone.Listener.prototype, 'positionY', { + set: function (pos) { + this._position[1] = pos; + this.setPosition.apply(this, this._position); + }, + get: function () { + return this._position[1]; + } + }); + /** + * The z position of the panner object. + * @type {Number} + * @memberOf Tone.Listener# + * @name positionZ + */ + Object.defineProperty(Tone.Listener.prototype, 'positionZ', { + set: function (pos) { + this._position[2] = pos; + this.setPosition.apply(this, this._position); + }, + get: function () { + return this._position[2]; + } + }); + /** + * The x coordinate of the listeners front direction. i.e. + * which way they are facing. + * @type {Number} + * @memberOf Tone.Listener# + * @name forwardX + */ + Object.defineProperty(Tone.Listener.prototype, 'forwardX', { + set: function (pos) { + this._orientation[0] = pos; + this.setOrientation.apply(this, this._orientation); + }, + get: function () { + return this._orientation[0]; + } + }); + /** + * The y coordinate of the listeners front direction. i.e. + * which way they are facing. + * @type {Number} + * @memberOf Tone.Listener# + * @name forwardY + */ + Object.defineProperty(Tone.Listener.prototype, 'forwardY', { + set: function (pos) { + this._orientation[1] = pos; + this.setOrientation.apply(this, this._orientation); + }, + get: function () { + return this._orientation[1]; + } + }); + /** + * The z coordinate of the listeners front direction. i.e. + * which way they are facing. + * @type {Number} + * @memberOf Tone.Listener# + * @name forwardZ + */ + Object.defineProperty(Tone.Listener.prototype, 'forwardZ', { + set: function (pos) { + this._orientation[2] = pos; + this.setOrientation.apply(this, this._orientation); + }, + get: function () { + return this._orientation[2]; + } + }); + /** + * The x coordinate of the listener's up direction. i.e. + * the direction the listener is standing in. + * @type {Number} + * @memberOf Tone.Listener# + * @name upX + */ + Object.defineProperty(Tone.Listener.prototype, 'upX', { + set: function (pos) { + this._orientation[3] = pos; + this.setOrientation.apply(this, this._orientation); + }, + get: function () { + return this._orientation[3]; + } + }); + /** + * The y coordinate of the listener's up direction. i.e. + * the direction the listener is standing in. + * @type {Number} + * @memberOf Tone.Listener# + * @name upY + */ + Object.defineProperty(Tone.Listener.prototype, 'upY', { + set: function (pos) { + this._orientation[4] = pos; + this.setOrientation.apply(this, this._orientation); + }, + get: function () { + return this._orientation[4]; + } + }); + /** + * The z coordinate of the listener's up direction. i.e. + * the direction the listener is standing in. + * @type {Number} + * @memberOf Tone.Listener# + * @name upZ + */ + Object.defineProperty(Tone.Listener.prototype, 'upZ', { + set: function (pos) { + this._orientation[5] = pos; + this.setOrientation.apply(this, this._orientation); + }, + get: function () { + return this._orientation[5]; + } + }); + /** + * Clean up. + * @returns {Tone.Listener} this + */ + Tone.Listener.prototype.dispose = function () { + this._listener.disconnect(); + this._listener = null; + this._orientation = null; + this._position = null; + return this; + }; + //SINGLETON SETUP + var ListenerConstructor = Tone.Listener; + Tone._initAudioContext(function () { + if (typeof Tone.Listener === 'function') { + //a single listener object + Tone.Listener = new Tone.Listener(); + } else { + //make new Listener insides + ListenerConstructor.call(Tone.Listener); + } + }); + //END SINGLETON SETUP + return Tone.Listener; + }); + Module(function (Tone) { + + /** + * @class Tone.Effect is the base class for effects. Connect the effect between + * the effectSend and effectReturn GainNodes, then control the amount of + * effect which goes to the output using the wet control. + * + * @constructor + * @extends {Tone} + * @param {NormalRange|Object} [wet] The starting wet value. + */ + Tone.Effect = function () { + this.createInsOuts(1, 1); + //get all of the defaults + var options = this.optionsObject(arguments, ['wet'], Tone.Effect.defaults); + /** + * the drywet knob to control the amount of effect + * @type {Tone.CrossFade} + * @private + */ + this._dryWet = new Tone.CrossFade(options.wet); + /** + * The wet control is how much of the effected + * will pass through to the output. 1 = 100% effected + * signal, 0 = 100% dry signal. + * @type {NormalRange} + * @signal + */ + this.wet = this._dryWet.fade; + /** + * connect the effectSend to the input of hte effect + * @type {Tone.Gain} + * @private + */ + this.effectSend = new Tone.Gain(); + /** + * connect the output of the effect to the effectReturn + * @type {Tone.Gain} + * @private + */ + this.effectReturn = new Tone.Gain(); + //connections + this.input.connect(this._dryWet.a); + this.input.connect(this.effectSend); + this.effectReturn.connect(this._dryWet.b); + this._dryWet.connect(this.output); + this._readOnly(['wet']); + }; + Tone.extend(Tone.Effect); + /** + * @static + * @type {Object} + */ + Tone.Effect.defaults = { 'wet': 1 }; + /** + * chains the effect in between the effectSend and effectReturn + * @param {Tone} effect + * @private + * @returns {Tone.Effect} this + */ + Tone.Effect.prototype.connectEffect = function (effect) { + this.effectSend.chain(effect, this.effectReturn); + return this; + }; + /** + * Clean up. + * @returns {Tone.Effect} this + */ + Tone.Effect.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._dryWet.dispose(); + this._dryWet = null; + this.effectSend.dispose(); + this.effectSend = null; + this.effectReturn.dispose(); + this.effectReturn = null; + this._writable(['wet']); + this.wet = null; + return this; + }; + return Tone.Effect; + }); + Module(function (Tone) { + + /** + * @class Tone.AutoFilter is a Tone.Filter with a Tone.LFO connected to the filter cutoff frequency. + * Setting the LFO rate and depth allows for control over the filter modulation rate + * and depth. + * + * @constructor + * @extends {Tone.Effect} + * @param {Time|Object} [frequency] The rate of the LFO. + * @param {Frequency=} baseFrequency The lower value of the LFOs oscillation + * @param {Frequency=} octaves The number of octaves above the baseFrequency + * @example + * //create an autofilter and start it's LFO + * var autoFilter = new Tone.AutoFilter("4n").toMaster().start(); + * //route an oscillator through the filter and start it + * var oscillator = new Tone.Oscillator().connect(autoFilter).start(); + */ + Tone.AutoFilter = function () { + var options = this.optionsObject(arguments, [ + 'frequency', + 'baseFrequency', + 'octaves' + ], Tone.AutoFilter.defaults); + Tone.Effect.call(this, options); + /** + * the lfo which drives the filter cutoff + * @type {Tone.LFO} + * @private + */ + this._lfo = new Tone.LFO({ + 'frequency': options.frequency, + 'amplitude': options.depth + }); + /** + * The range of the filter modulating between the min and max frequency. + * 0 = no modulation. 1 = full modulation. + * @type {NormalRange} + * @signal + */ + this.depth = this._lfo.amplitude; + /** + * How fast the filter modulates between min and max. + * @type {Frequency} + * @signal + */ + this.frequency = this._lfo.frequency; + /** + * The filter node + * @type {Tone.Filter} + */ + this.filter = new Tone.Filter(options.filter); + /** + * The octaves placeholder + * @type {Positive} + * @private + */ + this._octaves = 0; + //connections + this.connectEffect(this.filter); + this._lfo.connect(this.filter.frequency); + this.type = options.type; + this._readOnly([ + 'frequency', + 'depth' + ]); + this.octaves = options.octaves; + this.baseFrequency = options.baseFrequency; + }; + //extend Effect + Tone.extend(Tone.AutoFilter, Tone.Effect); + /** + * defaults + * @static + * @type {Object} + */ + Tone.AutoFilter.defaults = { + 'frequency': 1, + 'type': 'sine', + 'depth': 1, + 'baseFrequency': 200, + 'octaves': 2.6, + 'filter': { + 'type': 'lowpass', + 'rolloff': -12, + 'Q': 1 + } + }; + /** + * Start the effect. + * @param {Time} [time=now] When the LFO will start. + * @returns {Tone.AutoFilter} this + */ + Tone.AutoFilter.prototype.start = function (time) { + this._lfo.start(time); + return this; + }; + /** + * Stop the effect. + * @param {Time} [time=now] When the LFO will stop. + * @returns {Tone.AutoFilter} this + */ + Tone.AutoFilter.prototype.stop = function (time) { + this._lfo.stop(time); + return this; + }; + /** + * Sync the filter to the transport. + * @param {Time} [delay=0] Delay time before starting the effect after the + * Transport has started. + * @returns {Tone.AutoFilter} this + */ + Tone.AutoFilter.prototype.sync = function (delay) { + this._lfo.sync(delay); + return this; + }; + /** + * Unsync the filter from the transport. + * @returns {Tone.AutoFilter} this + */ + Tone.AutoFilter.prototype.unsync = function () { + this._lfo.unsync(); + return this; + }; + /** + * Type of oscillator attached to the AutoFilter. + * Possible values: "sine", "square", "triangle", "sawtooth". + * @memberOf Tone.AutoFilter# + * @type {string} + * @name type + */ + Object.defineProperty(Tone.AutoFilter.prototype, 'type', { + get: function () { + return this._lfo.type; + }, + set: function (type) { + this._lfo.type = type; + } + }); + /** + * The minimum value of the filter's cutoff frequency. + * @memberOf Tone.AutoFilter# + * @type {Frequency} + * @name min + */ + Object.defineProperty(Tone.AutoFilter.prototype, 'baseFrequency', { + get: function () { + return this._lfo.min; + }, + set: function (freq) { + this._lfo.min = this.toFrequency(freq); + //and set the max + this.octaves = this._octaves; + } + }); + /** + * The maximum value of the filter's cutoff frequency. + * @memberOf Tone.AutoFilter# + * @type {Positive} + * @name octaves + */ + Object.defineProperty(Tone.AutoFilter.prototype, 'octaves', { + get: function () { + return this._octaves; + }, + set: function (oct) { + this._octaves = oct; + this._lfo.max = this.baseFrequency * Math.pow(2, oct); + } + }); + /** + * Clean up. + * @returns {Tone.AutoFilter} this + */ + Tone.AutoFilter.prototype.dispose = function () { + Tone.Effect.prototype.dispose.call(this); + this._lfo.dispose(); + this._lfo = null; + this.filter.dispose(); + this.filter = null; + this._writable([ + 'frequency', + 'depth' + ]); + this.frequency = null; + this.depth = null; + return this; + }; + return Tone.AutoFilter; + }); + Module(function (Tone) { + + /** + * @class Tone.AutoPanner is a Tone.Panner with an LFO connected to the pan amount. + * More on using autopanners [here](https://www.ableton.com/en/blog/autopan-chopper-effect-and-more-liveschool/). + * + * @constructor + * @extends {Tone.Effect} + * @param {Frequency|Object} [frequency] Rate of left-right oscillation. + * @example + * //create an autopanner and start it's LFO + * var autoPanner = new Tone.AutoPanner("4n").toMaster().start(); + * //route an oscillator through the panner and start it + * var oscillator = new Tone.Oscillator().connect(autoPanner).start(); + */ + Tone.AutoPanner = function () { + var options = this.optionsObject(arguments, ['frequency'], Tone.AutoPanner.defaults); + Tone.Effect.call(this, options); + /** + * the lfo which drives the panning + * @type {Tone.LFO} + * @private + */ + this._lfo = new Tone.LFO({ + 'frequency': options.frequency, + 'amplitude': options.depth, + 'min': -1, + 'max': 1 + }); + /** + * The amount of panning between left and right. + * 0 = always center. 1 = full range between left and right. + * @type {NormalRange} + * @signal + */ + this.depth = this._lfo.amplitude; + /** + * the panner node which does the panning + * @type {Tone.Panner} + * @private + */ + this._panner = new Tone.Panner(); + /** + * How fast the panner modulates between left and right. + * @type {Frequency} + * @signal + */ + this.frequency = this._lfo.frequency; + //connections + this.connectEffect(this._panner); + this._lfo.connect(this._panner.pan); + this.type = options.type; + this._readOnly([ + 'depth', + 'frequency' + ]); + }; + //extend Effect + Tone.extend(Tone.AutoPanner, Tone.Effect); + /** + * defaults + * @static + * @type {Object} + */ + Tone.AutoPanner.defaults = { + 'frequency': 1, + 'type': 'sine', + 'depth': 1 + }; + /** + * Start the effect. + * @param {Time} [time=now] When the LFO will start. + * @returns {Tone.AutoPanner} this + */ + Tone.AutoPanner.prototype.start = function (time) { + this._lfo.start(time); + return this; + }; + /** + * Stop the effect. + * @param {Time} [time=now] When the LFO will stop. + * @returns {Tone.AutoPanner} this + */ + Tone.AutoPanner.prototype.stop = function (time) { + this._lfo.stop(time); + return this; + }; + /** + * Sync the panner to the transport. + * @param {Time} [delay=0] Delay time before starting the effect after the + * Transport has started. + * @returns {Tone.AutoPanner} this + */ + Tone.AutoPanner.prototype.sync = function (delay) { + this._lfo.sync(delay); + return this; + }; + /** + * Unsync the panner from the transport + * @returns {Tone.AutoPanner} this + */ + Tone.AutoPanner.prototype.unsync = function () { + this._lfo.unsync(); + return this; + }; + /** + * Type of oscillator attached to the AutoFilter. + * Possible values: "sine", "square", "triangle", "sawtooth". + * @memberOf Tone.AutoFilter# + * @type {string} + * @name type + */ + Object.defineProperty(Tone.AutoPanner.prototype, 'type', { + get: function () { + return this._lfo.type; + }, + set: function (type) { + this._lfo.type = type; + } + }); + /** + * clean up + * @returns {Tone.AutoPanner} this + */ + Tone.AutoPanner.prototype.dispose = function () { + Tone.Effect.prototype.dispose.call(this); + this._lfo.dispose(); + this._lfo = null; + this._panner.dispose(); + this._panner = null; + this._writable([ + 'depth', + 'frequency' + ]); + this.frequency = null; + this.depth = null; + return this; + }; + return Tone.AutoPanner; + }); + Module(function (Tone) { + + /** + * @class Tone.AutoWah connects a Tone.Follower to a bandpass filter (Tone.Filter). + * The frequency of the filter is adjusted proportionally to the + * incoming signal's amplitude. Inspiration from [Tuna.js](https://github.com/Dinahmoe/tuna). + * + * @constructor + * @extends {Tone.Effect} + * @param {Frequency|Object} [baseFrequency] The frequency the filter is set + * to at the low point of the wah + * @param {Positive} [octaves] The number of octaves above the baseFrequency + * the filter will sweep to when fully open + * @param {Decibels} [sensitivity] The decibel threshold sensitivity for + * the incoming signal. Normal range of -40 to 0. + * @example + * var autoWah = new Tone.AutoWah(50, 6, -30).toMaster(); + * //initialize the synth and connect to autowah + * var synth = new Synth.connect(autoWah); + * //Q value influences the effect of the wah - default is 2 + * autoWah.Q.value = 6; + * //more audible on higher notes + * synth.triggerAttackRelease("C4", "8n") + */ + Tone.AutoWah = function () { + var options = this.optionsObject(arguments, [ + 'baseFrequency', + 'octaves', + 'sensitivity' + ], Tone.AutoWah.defaults); + Tone.Effect.call(this, options); + /** + * The envelope follower. Set the attack/release + * timing to adjust how the envelope is followed. + * @type {Tone.Follower} + * @private + */ + this.follower = new Tone.Follower(options.follower); + /** + * scales the follower value to the frequency domain + * @type {Tone} + * @private + */ + this._sweepRange = new Tone.ScaleExp(0, 1, 0.5); + /** + * @type {number} + * @private + */ + this._baseFrequency = options.baseFrequency; + /** + * @type {number} + * @private + */ + this._octaves = options.octaves; + /** + * the input gain to adjust the sensitivity + * @type {Tone.Gain} + * @private + */ + this._inputBoost = new Tone.Gain(); + /** + * @type {BiquadFilterNode} + * @private + */ + this._bandpass = new Tone.Filter({ + 'rolloff': -48, + 'frequency': 0, + 'Q': options.Q + }); + /** + * @type {Tone.Filter} + * @private + */ + this._peaking = new Tone.Filter(0, 'peaking'); + this._peaking.gain.value = options.gain; + /** + * The gain of the filter. + * @type {Number} + * @signal + */ + this.gain = this._peaking.gain; + /** + * The quality of the filter. + * @type {Positive} + * @signal + */ + this.Q = this._bandpass.Q; + //the control signal path + this.effectSend.chain(this._inputBoost, this.follower, this._sweepRange); + this._sweepRange.connect(this._bandpass.frequency); + this._sweepRange.connect(this._peaking.frequency); + //the filtered path + this.effectSend.chain(this._bandpass, this._peaking, this.effectReturn); + //set the initial value + this._setSweepRange(); + this.sensitivity = options.sensitivity; + this._readOnly([ + 'gain', + 'Q' + ]); + }; + Tone.extend(Tone.AutoWah, Tone.Effect); + /** + * @static + * @type {Object} + */ + Tone.AutoWah.defaults = { + 'baseFrequency': 100, + 'octaves': 6, + 'sensitivity': 0, + 'Q': 2, + 'gain': 2, + 'follower': { + 'attack': 0.3, + 'release': 0.5 + } + }; + /** + * The number of octaves that the filter will sweep above the + * baseFrequency. + * @memberOf Tone.AutoWah# + * @type {Number} + * @name octaves + */ + Object.defineProperty(Tone.AutoWah.prototype, 'octaves', { + get: function () { + return this._octaves; + }, + set: function (octaves) { + this._octaves = octaves; + this._setSweepRange(); + } + }); + /** + * The base frequency from which the sweep will start from. + * @memberOf Tone.AutoWah# + * @type {Frequency} + * @name baseFrequency + */ + Object.defineProperty(Tone.AutoWah.prototype, 'baseFrequency', { + get: function () { + return this._baseFrequency; + }, + set: function (baseFreq) { + this._baseFrequency = baseFreq; + this._setSweepRange(); + } + }); + /** + * The sensitivity to control how responsive to the input signal the filter is. + * @memberOf Tone.AutoWah# + * @type {Decibels} + * @name sensitivity + */ + Object.defineProperty(Tone.AutoWah.prototype, 'sensitivity', { + get: function () { + return this.gainToDb(1 / this._inputBoost.gain.value); + }, + set: function (sensitivy) { + this._inputBoost.gain.value = 1 / this.dbToGain(sensitivy); + } + }); + /** + * sets the sweep range of the scaler + * @private + */ + Tone.AutoWah.prototype._setSweepRange = function () { + this._sweepRange.min = this._baseFrequency; + this._sweepRange.max = Math.min(this._baseFrequency * Math.pow(2, this._octaves), this.context.sampleRate / 2); + }; + /** + * Clean up. + * @returns {Tone.AutoWah} this + */ + Tone.AutoWah.prototype.dispose = function () { + Tone.Effect.prototype.dispose.call(this); + this.follower.dispose(); + this.follower = null; + this._sweepRange.dispose(); + this._sweepRange = null; + this._bandpass.dispose(); + this._bandpass = null; + this._peaking.dispose(); + this._peaking = null; + this._inputBoost.dispose(); + this._inputBoost = null; + this._writable([ + 'gain', + 'Q' + ]); + this.gain = null; + this.Q = null; + return this; + }; + return Tone.AutoWah; + }); + Module(function (Tone) { + + /** + * @class Tone.Bitcrusher downsamples the incoming signal to a different bitdepth. + * Lowering the bitdepth of the signal creates distortion. Read more about Bitcrushing + * on [Wikipedia](https://en.wikipedia.org/wiki/Bitcrusher). + * + * @constructor + * @extends {Tone.Effect} + * @param {Number} bits The number of bits to downsample the signal. Nominal range + * of 1 to 8. + * @example + * //initialize crusher and route a synth through it + * var crusher = new Tone.BitCrusher(4).toMaster(); + * var synth = new Tone.MonoSynth().connect(crusher); + */ + Tone.BitCrusher = function () { + var options = this.optionsObject(arguments, ['bits'], Tone.BitCrusher.defaults); + Tone.Effect.call(this, options); + var invStepSize = 1 / Math.pow(2, options.bits - 1); + /** + * Subtract the input signal and the modulus of the input signal + * @type {Tone.Subtract} + * @private + */ + this._subtract = new Tone.Subtract(); + /** + * The mod function + * @type {Tone.Modulo} + * @private + */ + this._modulo = new Tone.Modulo(invStepSize); + /** + * keeps track of the bits + * @type {number} + * @private + */ + this._bits = options.bits; + //connect it up + this.effectSend.fan(this._subtract, this._modulo); + this._modulo.connect(this._subtract, 0, 1); + this._subtract.connect(this.effectReturn); + }; + Tone.extend(Tone.BitCrusher, Tone.Effect); + /** + * the default values + * @static + * @type {Object} + */ + Tone.BitCrusher.defaults = { 'bits': 4 }; + /** + * The bit depth of the effect. Nominal range of 1-8. + * @memberOf Tone.BitCrusher# + * @type {number} + * @name bits + */ + Object.defineProperty(Tone.BitCrusher.prototype, 'bits', { + get: function () { + return this._bits; + }, + set: function (bits) { + this._bits = bits; + var invStepSize = 1 / Math.pow(2, bits - 1); + this._modulo.value = invStepSize; + } + }); + /** + * Clean up. + * @returns {Tone.BitCrusher} this + */ + Tone.BitCrusher.prototype.dispose = function () { + Tone.Effect.prototype.dispose.call(this); + this._subtract.dispose(); + this._subtract = null; + this._modulo.dispose(); + this._modulo = null; + return this; + }; + return Tone.BitCrusher; + }); + Module(function (Tone) { + + /** + * @class Tone.ChebyShev is a Chebyshev waveshaper, an effect which is good + * for making different types of distortion sounds. + * Note that odd orders sound very different from even ones, + * and order = 1 is no change. + * Read more at [music.columbia.edu](http://music.columbia.edu/cmc/musicandcomputers/chapter4/04_06.php). + * + * @extends {Tone.Effect} + * @constructor + * @param {Positive|Object} [order] The order of the chebyshev polynomial. Normal range between 1-100. + * @example + * //create a new cheby + * var cheby = new Tone.Chebyshev(50); + * //create a monosynth connected to our cheby + * synth = new Tone.MonoSynth().connect(cheby); + */ + Tone.Chebyshev = function () { + var options = this.optionsObject(arguments, ['order'], Tone.Chebyshev.defaults); + Tone.Effect.call(this, options); + /** + * @type {WaveShaperNode} + * @private + */ + this._shaper = new Tone.WaveShaper(4096); + /** + * holds onto the order of the filter + * @type {number} + * @private + */ + this._order = options.order; + this.connectEffect(this._shaper); + this.order = options.order; + this.oversample = options.oversample; + }; + Tone.extend(Tone.Chebyshev, Tone.Effect); + /** + * @static + * @const + * @type {Object} + */ + Tone.Chebyshev.defaults = { + 'order': 1, + 'oversample': 'none' + }; + /** + * get the coefficient for that degree + * @param {number} x the x value + * @param {number} degree + * @param {Object} memo memoize the computed value. + * this speeds up computation greatly. + * @return {number} the coefficient + * @private + */ + Tone.Chebyshev.prototype._getCoefficient = function (x, degree, memo) { + if (memo.hasOwnProperty(degree)) { + return memo[degree]; + } else if (degree === 0) { + memo[degree] = 0; + } else if (degree === 1) { + memo[degree] = x; + } else { + memo[degree] = 2 * x * this._getCoefficient(x, degree - 1, memo) - this._getCoefficient(x, degree - 2, memo); + } + return memo[degree]; + }; + /** + * The order of the Chebyshev polynomial which creates + * the equation which is applied to the incoming + * signal through a Tone.WaveShaper. The equations + * are in the form:
+ * order 2: 2x^2 + 1
+ * order 3: 4x^3 + 3x
+ * @memberOf Tone.Chebyshev# + * @type {Positive} + * @name order + */ + Object.defineProperty(Tone.Chebyshev.prototype, 'order', { + get: function () { + return this._order; + }, + set: function (order) { + this._order = order; + var curve = new Array(4096); + var len = curve.length; + for (var i = 0; i < len; ++i) { + var x = i * 2 / len - 1; + if (x === 0) { + //should output 0 when input is 0 + curve[i] = 0; + } else { + curve[i] = this._getCoefficient(x, order, {}); + } + } + this._shaper.curve = curve; + } + }); + /** + * The oversampling of the effect. Can either be "none", "2x" or "4x". + * @memberOf Tone.Chebyshev# + * @type {string} + * @name oversample + */ + Object.defineProperty(Tone.Chebyshev.prototype, 'oversample', { + get: function () { + return this._shaper.oversample; + }, + set: function (oversampling) { + this._shaper.oversample = oversampling; + } + }); + /** + * Clean up. + * @returns {Tone.Chebyshev} this + */ + Tone.Chebyshev.prototype.dispose = function () { + Tone.Effect.prototype.dispose.call(this); + this._shaper.dispose(); + this._shaper = null; + return this; + }; + return Tone.Chebyshev; + }); + Module(function (Tone) { + + /** + * @class Base class for Stereo effects. Provides effectSendL/R and effectReturnL/R. + * + * @constructor + * @extends {Tone.Effect} + */ + Tone.StereoEffect = function () { + this.createInsOuts(1, 1); + //get the defaults + var options = this.optionsObject(arguments, ['wet'], Tone.Effect.defaults); + /** + * the drywet knob to control the amount of effect + * @type {Tone.CrossFade} + * @private + */ + this._dryWet = new Tone.CrossFade(options.wet); + /** + * The wet control, i.e. how much of the effected + * will pass through to the output. + * @type {NormalRange} + * @signal + */ + this.wet = this._dryWet.fade; + /** + * then split it + * @type {Tone.Split} + * @private + */ + this._split = new Tone.Split(); + /** + * the effects send LEFT + * @type {GainNode} + * @private + */ + this.effectSendL = this._split.left; + /** + * the effects send RIGHT + * @type {GainNode} + * @private + */ + this.effectSendR = this._split.right; + /** + * the stereo effect merger + * @type {Tone.Merge} + * @private + */ + this._merge = new Tone.Merge(); + /** + * the effect return LEFT + * @type {GainNode} + * @private + */ + this.effectReturnL = this._merge.left; + /** + * the effect return RIGHT + * @type {GainNode} + * @private + */ + this.effectReturnR = this._merge.right; + //connections + this.input.connect(this._split); + //dry wet connections + this.input.connect(this._dryWet, 0, 0); + this._merge.connect(this._dryWet, 0, 1); + this._dryWet.connect(this.output); + this._readOnly(['wet']); + }; + Tone.extend(Tone.StereoEffect, Tone.Effect); + /** + * Clean up. + * @returns {Tone.StereoEffect} this + */ + Tone.StereoEffect.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._dryWet.dispose(); + this._dryWet = null; + this._split.dispose(); + this._split = null; + this._merge.dispose(); + this._merge = null; + this.effectSendL = null; + this.effectSendR = null; + this.effectReturnL = null; + this.effectReturnR = null; + this._writable(['wet']); + this.wet = null; + return this; + }; + return Tone.StereoEffect; + }); + Module(function (Tone) { + + /** + * @class Tone.FeedbackEffect provides a loop between an + * audio source and its own output. This is a base-class + * for feedback effects. + * + * @constructor + * @extends {Tone.Effect} + * @param {NormalRange|Object} [feedback] The initial feedback value. + */ + Tone.FeedbackEffect = function () { + var options = this.optionsObject(arguments, ['feedback']); + options = this.defaultArg(options, Tone.FeedbackEffect.defaults); + Tone.Effect.call(this, options); + /** + * the gain which controls the feedback + * @type {Tone.Gain} + * @private + */ + this._feedbackGain = new Tone.Gain(options.feedback, Tone.Type.NormalRange); + /** + * The amount of signal which is fed back into the effect input. + * @type {NormalRange} + * @signal + */ + this.feedback = this._feedbackGain.gain; + //the feedback loop + this.effectReturn.chain(this._feedbackGain, this.effectSend); + this._readOnly(['feedback']); + }; + Tone.extend(Tone.FeedbackEffect, Tone.Effect); + /** + * @static + * @type {Object} + */ + Tone.FeedbackEffect.defaults = { 'feedback': 0.125 }; + /** + * Clean up. + * @returns {Tone.FeedbackEffect} this + */ + Tone.FeedbackEffect.prototype.dispose = function () { + Tone.Effect.prototype.dispose.call(this); + this._writable(['feedback']); + this._feedbackGain.dispose(); + this._feedbackGain = null; + this.feedback = null; + return this; + }; + return Tone.FeedbackEffect; + }); + Module(function (Tone) { + + /** + * @class Just like a stereo feedback effect, but the feedback is routed from left to right + * and right to left instead of on the same channel. + * + * @constructor + * @extends {Tone.FeedbackEffect} + */ + Tone.StereoXFeedbackEffect = function () { + var options = this.optionsObject(arguments, ['feedback'], Tone.FeedbackEffect.defaults); + Tone.StereoEffect.call(this, options); + /** + * The amount of feedback from the output + * back into the input of the effect (routed + * across left and right channels). + * @type {NormalRange} + * @signal + */ + this.feedback = new Tone.Signal(options.feedback, Tone.Type.NormalRange); + /** + * the left side feeback + * @type {Tone.Gain} + * @private + */ + this._feedbackLR = new Tone.Gain(); + /** + * the right side feeback + * @type {Tone.Gain} + * @private + */ + this._feedbackRL = new Tone.Gain(); + //connect it up + this.effectReturnL.chain(this._feedbackLR, this.effectSendR); + this.effectReturnR.chain(this._feedbackRL, this.effectSendL); + this.feedback.fan(this._feedbackLR.gain, this._feedbackRL.gain); + this._readOnly(['feedback']); + }; + Tone.extend(Tone.StereoXFeedbackEffect, Tone.FeedbackEffect); + /** + * clean up + * @returns {Tone.StereoXFeedbackEffect} this + */ + Tone.StereoXFeedbackEffect.prototype.dispose = function () { + Tone.StereoEffect.prototype.dispose.call(this); + this._writable(['feedback']); + this.feedback.dispose(); + this.feedback = null; + this._feedbackLR.dispose(); + this._feedbackLR = null; + this._feedbackRL.dispose(); + this._feedbackRL = null; + return this; + }; + return Tone.StereoXFeedbackEffect; + }); + Module(function (Tone) { + + /** + * @class Tone.Chorus is a stereo chorus effect with feedback composed of + * a left and right delay with a Tone.LFO applied to the delayTime of each channel. + * Inspiration from [Tuna.js](https://github.com/Dinahmoe/tuna/blob/master/tuna.js). + * Read more on the chorus effect on [SoundOnSound](http://www.soundonsound.com/sos/jun04/articles/synthsecrets.htm). + * + * @constructor + * @extends {Tone.StereoXFeedbackEffect} + * @param {Frequency|Object} [frequency] The frequency of the LFO. + * @param {Milliseconds} [delayTime] The delay of the chorus effect in ms. + * @param {NormalRange} [depth] The depth of the chorus. + * @example + * var chorus = new Tone.Chorus(4, 2.5, 0.5); + * var synth = new Tone.PolySynth(4, Tone.MonoSynth).connect(chorus); + * synth.triggerAttackRelease(["C3","E3","G3"], "8n"); + */ + Tone.Chorus = function () { + var options = this.optionsObject(arguments, [ + 'frequency', + 'delayTime', + 'depth' + ], Tone.Chorus.defaults); + Tone.StereoXFeedbackEffect.call(this, options); + /** + * the depth of the chorus + * @type {number} + * @private + */ + this._depth = options.depth; + /** + * the delayTime + * @type {number} + * @private + */ + this._delayTime = options.delayTime / 1000; + /** + * the lfo which controls the delayTime + * @type {Tone.LFO} + * @private + */ + this._lfoL = new Tone.LFO({ + 'frequency': options.frequency, + 'min': 0, + 'max': 1 + }); + /** + * another LFO for the right side with a 180 degree phase diff + * @type {Tone.LFO} + * @private + */ + this._lfoR = new Tone.LFO({ + 'frequency': options.frequency, + 'min': 0, + 'max': 1, + 'phase': 180 + }); + /** + * delay for left + * @type {Tone.Delay} + * @private + */ + this._delayNodeL = new Tone.Delay(); + /** + * delay for right + * @type {Tone.Delay} + * @private + */ + this._delayNodeR = new Tone.Delay(); + /** + * The frequency of the LFO which modulates the delayTime. + * @type {Frequency} + * @signal + */ + this.frequency = this._lfoL.frequency; + //connections + this.effectSendL.chain(this._delayNodeL, this.effectReturnL); + this.effectSendR.chain(this._delayNodeR, this.effectReturnR); + //and pass through to make the detune apparent + this.effectSendL.connect(this.effectReturnL); + this.effectSendR.connect(this.effectReturnR); + //lfo setup + this._lfoL.connect(this._delayNodeL.delayTime); + this._lfoR.connect(this._delayNodeR.delayTime); + //start the lfo + this._lfoL.start(); + this._lfoR.start(); + //have one LFO frequency control the other + this._lfoL.frequency.connect(this._lfoR.frequency); + //set the initial values + this.depth = this._depth; + this.frequency.value = options.frequency; + this.type = options.type; + this._readOnly(['frequency']); + this.spread = options.spread; + }; + Tone.extend(Tone.Chorus, Tone.StereoXFeedbackEffect); + /** + * @static + * @type {Object} + */ + Tone.Chorus.defaults = { + 'frequency': 1.5, + 'delayTime': 3.5, + 'depth': 0.7, + 'feedback': 0.1, + 'type': 'sine', + 'spread': 180 + }; + /** + * The depth of the effect. A depth of 1 makes the delayTime + * modulate between 0 and 2*delayTime (centered around the delayTime). + * @memberOf Tone.Chorus# + * @type {NormalRange} + * @name depth + */ + Object.defineProperty(Tone.Chorus.prototype, 'depth', { + get: function () { + return this._depth; + }, + set: function (depth) { + this._depth = depth; + var deviation = this._delayTime * depth; + this._lfoL.min = Math.max(this._delayTime - deviation, 0); + this._lfoL.max = this._delayTime + deviation; + this._lfoR.min = Math.max(this._delayTime - deviation, 0); + this._lfoR.max = this._delayTime + deviation; + } + }); + /** + * The delayTime in milliseconds of the chorus. A larger delayTime + * will give a more pronounced effect. Nominal range a delayTime + * is between 2 and 20ms. + * @memberOf Tone.Chorus# + * @type {Milliseconds} + * @name delayTime + */ + Object.defineProperty(Tone.Chorus.prototype, 'delayTime', { + get: function () { + return this._delayTime * 1000; + }, + set: function (delayTime) { + this._delayTime = delayTime / 1000; + this.depth = this._depth; + } + }); + /** + * The oscillator type of the LFO. + * @memberOf Tone.Chorus# + * @type {string} + * @name type + */ + Object.defineProperty(Tone.Chorus.prototype, 'type', { + get: function () { + return this._lfoL.type; + }, + set: function (type) { + this._lfoL.type = type; + this._lfoR.type = type; + } + }); + /** + * Amount of stereo spread. When set to 0, both LFO's will be panned centrally. + * When set to 180, LFO's will be panned hard left and right respectively. + * @memberOf Tone.Chorus# + * @type {Degrees} + * @name spread + */ + Object.defineProperty(Tone.Chorus.prototype, 'spread', { + get: function () { + return this._lfoR.phase - this._lfoL.phase; //180 + }, + set: function (spread) { + this._lfoL.phase = 90 - spread / 2; + this._lfoR.phase = spread / 2 + 90; + } + }); + /** + * Clean up. + * @returns {Tone.Chorus} this + */ + Tone.Chorus.prototype.dispose = function () { + Tone.StereoXFeedbackEffect.prototype.dispose.call(this); + this._lfoL.dispose(); + this._lfoL = null; + this._lfoR.dispose(); + this._lfoR = null; + this._delayNodeL.dispose(); + this._delayNodeL = null; + this._delayNodeR.dispose(); + this._delayNodeR = null; + this._writable('frequency'); + this.frequency = null; + return this; + }; + return Tone.Chorus; + }); + Module(function (Tone) { + + /** + * @class Tone.Convolver is a wrapper around the Native Web Audio + * [ConvolverNode](http://webaudio.github.io/web-audio-api/#the-convolvernode-interface). + * Convolution is useful for reverb and filter emulation. Read more about convolution reverb on + * [Wikipedia](https://en.wikipedia.org/wiki/Convolution_reverb). + * + * @constructor + * @extends {Tone.Effect} + * @param {string|Tone.Buffer|Object} [url] The URL of the impulse response or the Tone.Buffer + * contianing the impulse response. + * @param {Function} onload The callback to invoke when the url is loaded. + * @example + * //initializing the convolver with an impulse response + * var convolver = new Tone.Convolver("./path/to/ir.wav").toMaster(); + */ + Tone.Convolver = function () { + var options = this.optionsObject(arguments, [ + 'url', + 'onload' + ], Tone.Convolver.defaults); + Tone.Effect.call(this, options); + /** + * convolver node + * @type {ConvolverNode} + * @private + */ + this._convolver = this.context.createConvolver(); + /** + * the convolution buffer + * @type {Tone.Buffer} + * @private + */ + this._buffer = new Tone.Buffer(); + if (this.isString(options.url)) { + this._buffer.load(options.url, function (buffer) { + this.buffer = buffer; + options.onload(); + }.bind(this)); + } else if (options.url) { + this.buffer = options.url; + options.onload(); + } + this.connectEffect(this._convolver); + }; + Tone.extend(Tone.Convolver, Tone.Effect); + /** + * @static + * @const + * @type {Object} + */ + Tone.Convolver.defaults = { 'onload': Tone.noOp }; + /** + * The convolver's buffer + * @memberOf Tone.Convolver# + * @type {AudioBuffer} + * @name buffer + */ + Object.defineProperty(Tone.Convolver.prototype, 'buffer', { + get: function () { + return this._buffer.get(); + }, + set: function (buffer) { + this._buffer.set(buffer); + this._convolver.buffer = this._buffer.get(); + } + }); + /** + * Load an impulse response url as an audio buffer. + * Decodes the audio asynchronously and invokes + * the callback once the audio buffer loads. + * @param {string} url The url of the buffer to load. + * filetype support depends on the + * browser. + * @param {function=} callback + * @returns {Promise} + */ + Tone.Convolver.prototype.load = function (url, callback) { + return this._buffer.load(url, function (buff) { + this.buffer = buff; + if (callback) { + callback(); + } + }.bind(this)); + }; + /** + * Clean up. + * @returns {Tone.Convolver} this + */ + Tone.Convolver.prototype.dispose = function () { + Tone.Effect.prototype.dispose.call(this); + this._convolver.disconnect(); + this._convolver = null; + this._buffer.dispose(); + this._buffer = null; + return this; + }; + return Tone.Convolver; + }); + Module(function (Tone) { + + /** + * @class Tone.Distortion is a simple distortion effect using Tone.WaveShaper. + * Algorithm from [a stackoverflow answer](http://stackoverflow.com/a/22313408). + * + * @extends {Tone.Effect} + * @constructor + * @param {Number|Object} [distortion] The amount of distortion (nominal range of 0-1) + * @example + * var dist = new Tone.Distortion(0.8).toMaster(); + * var fm = new Tone.SimpleFM().connect(dist); + * //this sounds good on bass notes + * fm.triggerAttackRelease("A1", "8n"); + */ + Tone.Distortion = function () { + var options = this.optionsObject(arguments, ['distortion'], Tone.Distortion.defaults); + Tone.Effect.call(this, options); + /** + * @type {Tone.WaveShaper} + * @private + */ + this._shaper = new Tone.WaveShaper(4096); + /** + * holds the distortion amount + * @type {number} + * @private + */ + this._distortion = options.distortion; + this.connectEffect(this._shaper); + this.distortion = options.distortion; + this.oversample = options.oversample; + }; + Tone.extend(Tone.Distortion, Tone.Effect); + /** + * @static + * @const + * @type {Object} + */ + Tone.Distortion.defaults = { + 'distortion': 0.4, + 'oversample': 'none' + }; + /** + * The amount of distortion. + * @memberOf Tone.Distortion# + * @type {NormalRange} + * @name distortion + */ + Object.defineProperty(Tone.Distortion.prototype, 'distortion', { + get: function () { + return this._distortion; + }, + set: function (amount) { + this._distortion = amount; + var k = amount * 100; + var deg = Math.PI / 180; + this._shaper.setMap(function (x) { + if (Math.abs(x) < 0.001) { + //should output 0 when input is 0 + return 0; + } else { + return (3 + k) * x * 20 * deg / (Math.PI + k * Math.abs(x)); + } + }); + } + }); + /** + * The oversampling of the effect. Can either be "none", "2x" or "4x". + * @memberOf Tone.Distortion# + * @type {string} + * @name oversample + */ + Object.defineProperty(Tone.Distortion.prototype, 'oversample', { + get: function () { + return this._shaper.oversample; + }, + set: function (oversampling) { + this._shaper.oversample = oversampling; + } + }); + /** + * Clean up. + * @returns {Tone.Distortion} this + */ + Tone.Distortion.prototype.dispose = function () { + Tone.Effect.prototype.dispose.call(this); + this._shaper.dispose(); + this._shaper = null; + return this; + }; + return Tone.Distortion; + }); + Module(function (Tone) { + + /** + * @class Tone.FeedbackDelay is a DelayNode in which part of output + * signal is fed back into the delay. + * + * @constructor + * @extends {Tone.FeedbackEffect} + * @param {Time|Object} [delayTime] The delay applied to the incoming signal. + * @param {NormalRange=} feedback The amount of the effected signal which + * is fed back through the delay. + * @example + * var feedbackDelay = new Tone.FeedbackDelay("8n", 0.5).toMaster(); + * var tom = new Tone.DrumSynth({ + * "octaves" : 4, + * "pitchDecay" : 0.1 + * }).connect(feedbackDelay); + * tom.triggerAttackRelease("A2","32n"); + */ + Tone.FeedbackDelay = function () { + var options = this.optionsObject(arguments, [ + 'delayTime', + 'feedback' + ], Tone.FeedbackDelay.defaults); + Tone.FeedbackEffect.call(this, options); + /** + * the delay node + * @type {Tone.Delay} + * @private + */ + this._delayNode = new Tone.Delay(options.delayTime); + /** + * The delayTime of the DelayNode. + * @type {Time} + * @signal + */ + this.delayTime = this._delayNode.delayTime; + // connect it up + this.connectEffect(this._delayNode); + this._readOnly(['delayTime']); + }; + Tone.extend(Tone.FeedbackDelay, Tone.FeedbackEffect); + /** + * The default values. + * @const + * @static + * @type {Object} + */ + Tone.FeedbackDelay.defaults = { 'delayTime': 0.25 }; + /** + * clean up + * @returns {Tone.FeedbackDelay} this + */ + Tone.FeedbackDelay.prototype.dispose = function () { + Tone.FeedbackEffect.prototype.dispose.call(this); + this._delayNode.dispose(); + this._delayNode = null; + this._writable(['delayTime']); + this.delayTime = null; + return this; + }; + return Tone.FeedbackDelay; + }); + Module(function (Tone) { + + /** + * an array of comb filter delay values from Freeverb implementation + * @static + * @private + * @type {Array} + */ + var combFilterTunings = [ + 1557 / 44100, + 1617 / 44100, + 1491 / 44100, + 1422 / 44100, + 1277 / 44100, + 1356 / 44100, + 1188 / 44100, + 1116 / 44100 + ]; + /** + * an array of allpass filter frequency values from Freeverb implementation + * @private + * @static + * @type {Array} + */ + var allpassFilterFrequencies = [ + 225, + 556, + 441, + 341 + ]; + /** + * @class Tone.Freeverb is a reverb based on [Freeverb](https://ccrma.stanford.edu/~jos/pasp/Freeverb.html). + * Read more on reverb on [SoundOnSound](http://www.soundonsound.com/sos/may00/articles/reverb.htm). + * + * @extends {Tone.Effect} + * @constructor + * @param {NormalRange|Object} [roomSize] Correlated to the decay time. + * @param {Frequency} [dampening] The cutoff frequency of a lowpass filter as part + * of the reverb. + * @example + * var freeverb = new Tone.Freeverb().toMaster(); + * freeverb.dampening.value = 1000; + * //routing synth through the reverb + * var synth = new Tone.AMSynth().connect(freeverb); + */ + Tone.Freeverb = function () { + var options = this.optionsObject(arguments, [ + 'roomSize', + 'dampening' + ], Tone.Freeverb.defaults); + Tone.StereoEffect.call(this, options); + /** + * The roomSize value between. A larger roomSize + * will result in a longer decay. + * @type {NormalRange} + * @signal + */ + this.roomSize = new Tone.Signal(options.roomSize, Tone.Type.NormalRange); + /** + * The amount of dampening of the reverberant signal. + * @type {Frequency} + * @signal + */ + this.dampening = new Tone.Signal(options.dampening, Tone.Type.Frequency); + /** + * the comb filters + * @type {Array} + * @private + */ + this._combFilters = []; + /** + * the allpass filters on the left + * @type {Array} + * @private + */ + this._allpassFiltersL = []; + /** + * the allpass filters on the right + * @type {Array} + * @private + */ + this._allpassFiltersR = []; + //make the allpass filters on teh right + for (var l = 0; l < allpassFilterFrequencies.length; l++) { + var allpassL = this.context.createBiquadFilter(); + allpassL.type = 'allpass'; + allpassL.frequency.value = allpassFilterFrequencies[l]; + this._allpassFiltersL.push(allpassL); + } + //make the allpass filters on the left + for (var r = 0; r < allpassFilterFrequencies.length; r++) { + var allpassR = this.context.createBiquadFilter(); + allpassR.type = 'allpass'; + allpassR.frequency.value = allpassFilterFrequencies[r]; + this._allpassFiltersR.push(allpassR); + } + //make the comb filters + for (var c = 0; c < combFilterTunings.length; c++) { + var lfpf = new Tone.LowpassCombFilter(combFilterTunings[c]); + if (c < combFilterTunings.length / 2) { + this.effectSendL.chain(lfpf, this._allpassFiltersL[0]); + } else { + this.effectSendR.chain(lfpf, this._allpassFiltersR[0]); + } + this.roomSize.connect(lfpf.resonance); + this.dampening.connect(lfpf.dampening); + this._combFilters.push(lfpf); + } + //chain the allpass filters togetehr + this.connectSeries.apply(this, this._allpassFiltersL); + this.connectSeries.apply(this, this._allpassFiltersR); + this._allpassFiltersL[this._allpassFiltersL.length - 1].connect(this.effectReturnL); + this._allpassFiltersR[this._allpassFiltersR.length - 1].connect(this.effectReturnR); + this._readOnly([ + 'roomSize', + 'dampening' + ]); + }; + Tone.extend(Tone.Freeverb, Tone.StereoEffect); + /** + * @static + * @type {Object} + */ + Tone.Freeverb.defaults = { + 'roomSize': 0.7, + 'dampening': 3000 + }; + /** + * Clean up. + * @returns {Tone.Freeverb} this + */ + Tone.Freeverb.prototype.dispose = function () { + Tone.StereoEffect.prototype.dispose.call(this); + for (var al = 0; al < this._allpassFiltersL.length; al++) { + this._allpassFiltersL[al].disconnect(); + this._allpassFiltersL[al] = null; + } + this._allpassFiltersL = null; + for (var ar = 0; ar < this._allpassFiltersR.length; ar++) { + this._allpassFiltersR[ar].disconnect(); + this._allpassFiltersR[ar] = null; + } + this._allpassFiltersR = null; + for (var cf = 0; cf < this._combFilters.length; cf++) { + this._combFilters[cf].dispose(); + this._combFilters[cf] = null; + } + this._combFilters = null; + this._writable([ + 'roomSize', + 'dampening' + ]); + this.roomSize.dispose(); + this.roomSize = null; + this.dampening.dispose(); + this.dampening = null; + return this; + }; + return Tone.Freeverb; + }); + Module(function (Tone) { + + /** + * an array of the comb filter delay time values + * @private + * @static + * @type {Array} + */ + var combFilterDelayTimes = [ + 1687 / 25000, + 1601 / 25000, + 2053 / 25000, + 2251 / 25000 + ]; + /** + * the resonances of each of the comb filters + * @private + * @static + * @type {Array} + */ + var combFilterResonances = [ + 0.773, + 0.802, + 0.753, + 0.733 + ]; + /** + * the allpass filter frequencies + * @private + * @static + * @type {Array} + */ + var allpassFilterFreqs = [ + 347, + 113, + 37 + ]; + /** + * @class Tone.JCReverb is a simple [Schroeder Reverberator](https://ccrma.stanford.edu/~jos/pasp/Schroeder_Reverberators.html) + * tuned by John Chowning in 1970. + * It is made up of three allpass filters and four Tone.FeedbackCombFilter. + * + * + * @extends {Tone.Effect} + * @constructor + * @param {NormalRange|Object} [roomSize] Coorelates to the decay time. + * @example + * var reverb = new Tone.JCReverb(0.4).connect(Tone.Master); + * var delay = new Tone.FeedbackDelay(0.5); + * //connecting the synth to reverb through delay + * var synth = new Tone.DuoSynth().chain(delay, reverb); + * synth.triggerAttackRelease("A4","8n"); + */ + Tone.JCReverb = function () { + var options = this.optionsObject(arguments, ['roomSize'], Tone.JCReverb.defaults); + Tone.StereoEffect.call(this, options); + /** + * room size control values between [0,1] + * @type {NormalRange} + * @signal + */ + this.roomSize = new Tone.Signal(options.roomSize, Tone.Type.NormalRange); + /** + * scale the room size + * @type {Tone.Scale} + * @private + */ + this._scaleRoomSize = new Tone.Scale(-0.733, 0.197); + /** + * a series of allpass filters + * @type {Array} + * @private + */ + this._allpassFilters = []; + /** + * parallel feedback comb filters + * @type {Array} + * @private + */ + this._feedbackCombFilters = []; + //make the allpass filters + for (var af = 0; af < allpassFilterFreqs.length; af++) { + var allpass = this.context.createBiquadFilter(); + allpass.type = 'allpass'; + allpass.frequency.value = allpassFilterFreqs[af]; + this._allpassFilters.push(allpass); + } + //and the comb filters + for (var cf = 0; cf < combFilterDelayTimes.length; cf++) { + var fbcf = new Tone.FeedbackCombFilter(combFilterDelayTimes[cf], 0.1); + this._scaleRoomSize.connect(fbcf.resonance); + fbcf.resonance.value = combFilterResonances[cf]; + this._allpassFilters[this._allpassFilters.length - 1].connect(fbcf); + if (cf < combFilterDelayTimes.length / 2) { + fbcf.connect(this.effectReturnL); + } else { + fbcf.connect(this.effectReturnR); + } + this._feedbackCombFilters.push(fbcf); + } + //chain the allpass filters together + this.roomSize.connect(this._scaleRoomSize); + this.connectSeries.apply(this, this._allpassFilters); + this.effectSendL.connect(this._allpassFilters[0]); + this.effectSendR.connect(this._allpassFilters[0]); + this._readOnly(['roomSize']); + }; + Tone.extend(Tone.JCReverb, Tone.StereoEffect); + /** + * the default values + * @static + * @const + * @type {Object} + */ + Tone.JCReverb.defaults = { 'roomSize': 0.5 }; + /** + * Clean up. + * @returns {Tone.JCReverb} this + */ + Tone.JCReverb.prototype.dispose = function () { + Tone.StereoEffect.prototype.dispose.call(this); + for (var apf = 0; apf < this._allpassFilters.length; apf++) { + this._allpassFilters[apf].disconnect(); + this._allpassFilters[apf] = null; + } + this._allpassFilters = null; + for (var fbcf = 0; fbcf < this._feedbackCombFilters.length; fbcf++) { + this._feedbackCombFilters[fbcf].dispose(); + this._feedbackCombFilters[fbcf] = null; + } + this._feedbackCombFilters = null; + this._writable(['roomSize']); + this.roomSize.dispose(); + this.roomSize = null; + this._scaleRoomSize.dispose(); + this._scaleRoomSize = null; + return this; + }; + return Tone.JCReverb; + }); + Module(function (Tone) { + + /** + * @class Mid/Side processing separates the the 'mid' signal + * (which comes out of both the left and the right channel) + * and the 'side' (which only comes out of the the side channels) + * and effects them separately before being recombined. + * Applies a Mid/Side seperation and recombination. + * Algorithm found in [kvraudio forums](http://www.kvraudio.com/forum/viewtopic.php?t=212587). + *

+ * This is a base-class for Mid/Side Effects. + * + * @extends {Tone.Effect} + * @constructor + */ + Tone.MidSideEffect = function () { + Tone.Effect.apply(this, arguments); + /** + * The mid/side split + * @type {Tone.MidSideSplit} + * @private + */ + this._midSideSplit = new Tone.MidSideSplit(); + /** + * The mid/side merge + * @type {Tone.MidSideMerge} + * @private + */ + this._midSideMerge = new Tone.MidSideMerge(); + /** + * The mid send. Connect to mid processing + * @type {Tone.Expr} + * @private + */ + this.midSend = this._midSideSplit.mid; + /** + * The side send. Connect to side processing + * @type {Tone.Expr} + * @private + */ + this.sideSend = this._midSideSplit.side; + /** + * The mid return connection + * @type {GainNode} + * @private + */ + this.midReturn = this._midSideMerge.mid; + /** + * The side return connection + * @type {GainNode} + * @private + */ + this.sideReturn = this._midSideMerge.side; + //the connections + this.effectSend.connect(this._midSideSplit); + this._midSideMerge.connect(this.effectReturn); + }; + Tone.extend(Tone.MidSideEffect, Tone.Effect); + /** + * Clean up. + * @returns {Tone.MidSideEffect} this + */ + Tone.MidSideEffect.prototype.dispose = function () { + Tone.Effect.prototype.dispose.call(this); + this._midSideSplit.dispose(); + this._midSideSplit = null; + this._midSideMerge.dispose(); + this._midSideMerge = null; + this.midSend = null; + this.sideSend = null; + this.midReturn = null; + this.sideReturn = null; + return this; + }; + return Tone.MidSideEffect; + }); + Module(function (Tone) { + + /** + * @class Tone.Phaser is a phaser effect. Phasers work by changing the phase + * of different frequency components of an incoming signal. Read more on + * [Wikipedia](https://en.wikipedia.org/wiki/Phaser_(effect)). + * Inspiration for this phaser comes from [Tuna.js](https://github.com/Dinahmoe/tuna/). + * + * @extends {Tone.StereoEffect} + * @constructor + * @param {Frequency|Object} [frequency] The speed of the phasing. + * @param {number} [octaves] The octaves of the effect. + * @param {Frequency} [baseFrequency] The base frequency of the filters. + * @example + * var phaser = new Tone.Phaser({ + * "frequency" : 15, + * "octaves" : 5, + * "baseFrequency" : 1000 + * }).toMaster(); + * var synth = new Tone.FMSynth().connect(phaser); + * synth.triggerAttackRelease("E3", "2n"); + */ + Tone.Phaser = function () { + //set the defaults + var options = this.optionsObject(arguments, [ + 'frequency', + 'octaves', + 'baseFrequency' + ], Tone.Phaser.defaults); + Tone.StereoEffect.call(this, options); + /** + * the lfo which controls the frequency on the left side + * @type {Tone.LFO} + * @private + */ + this._lfoL = new Tone.LFO(options.frequency, 0, 1); + /** + * the lfo which controls the frequency on the right side + * @type {Tone.LFO} + * @private + */ + this._lfoR = new Tone.LFO(options.frequency, 0, 1); + this._lfoR.phase = 180; + /** + * the base modulation frequency + * @type {number} + * @private + */ + this._baseFrequency = options.baseFrequency; + /** + * the octaves of the phasing + * @type {number} + * @private + */ + this._octaves = options.octaves; + /** + * The quality factor of the filters + * @type {Positive} + * @signal + */ + this.Q = new Tone.Signal(options.Q, Tone.Type.Positive); + /** + * the array of filters for the left side + * @type {Array} + * @private + */ + this._filtersL = this._makeFilters(options.stages, this._lfoL, this.Q); + /** + * the array of filters for the left side + * @type {Array} + * @private + */ + this._filtersR = this._makeFilters(options.stages, this._lfoR, this.Q); + /** + * the frequency of the effect + * @type {Tone.Signal} + */ + this.frequency = this._lfoL.frequency; + this.frequency.value = options.frequency; + //connect them up + this.effectSendL.connect(this._filtersL[0]); + this.effectSendR.connect(this._filtersR[0]); + this._filtersL[options.stages - 1].connect(this.effectReturnL); + this._filtersR[options.stages - 1].connect(this.effectReturnR); + //control the frequency with one LFO + this._lfoL.frequency.connect(this._lfoR.frequency); + //set the options + this.baseFrequency = options.baseFrequency; + this.octaves = options.octaves; + //start the lfo + this._lfoL.start(); + this._lfoR.start(); + this._readOnly([ + 'frequency', + 'Q' + ]); + }; + Tone.extend(Tone.Phaser, Tone.StereoEffect); + /** + * defaults + * @static + * @type {object} + */ + Tone.Phaser.defaults = { + 'frequency': 0.5, + 'octaves': 3, + 'stages': 10, + 'Q': 10, + 'baseFrequency': 350 + }; + /** + * @param {number} stages + * @returns {Array} the number of filters all connected together + * @private + */ + Tone.Phaser.prototype._makeFilters = function (stages, connectToFreq, Q) { + var filters = new Array(stages); + //make all the filters + for (var i = 0; i < stages; i++) { + var filter = this.context.createBiquadFilter(); + filter.type = 'allpass'; + Q.connect(filter.Q); + connectToFreq.connect(filter.frequency); + filters[i] = filter; + } + this.connectSeries.apply(this, filters); + return filters; + }; + /** + * The number of octaves the phase goes above + * the baseFrequency + * @memberOf Tone.Phaser# + * @type {Positive} + * @name octaves + */ + Object.defineProperty(Tone.Phaser.prototype, 'octaves', { + get: function () { + return this._octaves; + }, + set: function (octaves) { + this._octaves = octaves; + var max = this._baseFrequency * Math.pow(2, octaves); + this._lfoL.max = max; + this._lfoR.max = max; + } + }); + /** + * The the base frequency of the filters. + * @memberOf Tone.Phaser# + * @type {number} + * @name baseFrequency + */ + Object.defineProperty(Tone.Phaser.prototype, 'baseFrequency', { + get: function () { + return this._baseFrequency; + }, + set: function (freq) { + this._baseFrequency = freq; + this._lfoL.min = freq; + this._lfoR.min = freq; + this.octaves = this._octaves; + } + }); + /** + * clean up + * @returns {Tone.Phaser} this + */ + Tone.Phaser.prototype.dispose = function () { + Tone.StereoEffect.prototype.dispose.call(this); + this._writable([ + 'frequency', + 'Q' + ]); + this.Q.dispose(); + this.Q = null; + this._lfoL.dispose(); + this._lfoL = null; + this._lfoR.dispose(); + this._lfoR = null; + for (var i = 0; i < this._filtersL.length; i++) { + this._filtersL[i].disconnect(); + this._filtersL[i] = null; + } + this._filtersL = null; + for (var j = 0; j < this._filtersR.length; j++) { + this._filtersR[j].disconnect(); + this._filtersR[j] = null; + } + this._filtersR = null; + this.frequency = null; + return this; + }; + return Tone.Phaser; + }); + Module(function (Tone) { + + /** + * @class Tone.PingPongDelay is a feedback delay effect where the echo is heard + * first in one channel and next in the opposite channel. In a stereo + * system these are the right and left channels. + * PingPongDelay in more simplified terms is two Tone.FeedbackDelays + * with independent delay values. Each delay is routed to one channel + * (left or right), and the channel triggered second will always + * trigger at the same interval after the first. + * + * @constructor + * @extends {Tone.StereoXFeedbackEffect} + * @param {Time|Object} [delayTime] The delayTime between consecutive echos. + * @param {NormalRange=} feedback The amount of the effected signal which + * is fed back through the delay. + * @example + * var pingPong = new Tone.PingPongDelay("4n", 0.2).toMaster(); + * var drum = new Tone.DrumSynth().connect(pingPong); + * drum.triggerAttackRelease("C4", "32n"); + */ + Tone.PingPongDelay = function () { + var options = this.optionsObject(arguments, [ + 'delayTime', + 'feedback' + ], Tone.PingPongDelay.defaults); + Tone.StereoXFeedbackEffect.call(this, options); + /** + * the delay node on the left side + * @type {Tone.Delay} + * @private + */ + this._leftDelay = new Tone.Delay(0, options.maxDelayTime); + /** + * the delay node on the right side + * @type {Tone.Delay} + * @private + */ + this._rightDelay = new Tone.Delay(0, options.maxDelayTime); + /** + * the predelay on the right side + * @type {Tone.Delay} + * @private + */ + this._rightPreDelay = new Tone.Delay(0, options.maxDelayTime); + /** + * the delay time signal + * @type {Time} + * @signal + */ + this.delayTime = new Tone.Signal(options.delayTime, Tone.Type.Time); + //connect it up + this.effectSendL.chain(this._leftDelay, this.effectReturnL); + this.effectSendR.chain(this._rightPreDelay, this._rightDelay, this.effectReturnR); + this.delayTime.fan(this._leftDelay.delayTime, this._rightDelay.delayTime, this._rightPreDelay.delayTime); + //rearranged the feedback to be after the rightPreDelay + this._feedbackLR.disconnect(); + this._feedbackLR.connect(this._rightDelay); + this._readOnly(['delayTime']); + }; + Tone.extend(Tone.PingPongDelay, Tone.StereoXFeedbackEffect); + /** + * @static + * @type {Object} + */ + Tone.PingPongDelay.defaults = { + 'delayTime': 0.25, + 'maxDelayTime': 1 + }; + /** + * Clean up. + * @returns {Tone.PingPongDelay} this + */ + Tone.PingPongDelay.prototype.dispose = function () { + Tone.StereoXFeedbackEffect.prototype.dispose.call(this); + this._leftDelay.dispose(); + this._leftDelay = null; + this._rightDelay.dispose(); + this._rightDelay = null; + this._rightPreDelay.dispose(); + this._rightPreDelay = null; + this._writable(['delayTime']); + this.delayTime.dispose(); + this.delayTime = null; + return this; + }; + return Tone.PingPongDelay; + }); + Module(function (Tone) { + + /** + * @class Tone.PitchShift does near-realtime pitch shifting to the incoming signal. + * The effect is achieved by speeding up or slowing down the delayTime + * of a DelayNode using a sawtooth wave. + * Algorithm found in [this pdf](http://dsp-book.narod.ru/soundproc.pdf). + * Additional reference by [Miller Pucket](http://msp.ucsd.edu/techniques/v0.11/book-html/node115.html). + * + * @extends {Tone.FeedbackEffect} + * @param {Interval=} pitch The interval to transpose the incoming signal by. + */ + Tone.PitchShift = function () { + var options = this.optionsObject(arguments, ['pitch'], Tone.PitchShift.defaults); + Tone.FeedbackEffect.call(this, options); + /** + * The pitch signal + * @type {Tone.Signal} + * @private + */ + this._frequency = new Tone.Signal(0); + /** + * Uses two DelayNodes to cover up the jump in + * the sawtooth wave. + * @type {DelayNode} + * @private + */ + this._delayA = new Tone.Delay(0, 1); + /** + * The first LFO. + * @type {Tone.LFO} + * @private + */ + this._lfoA = new Tone.LFO({ + 'min': 0, + 'max': 0.1, + 'type': 'sawtooth' + }).connect(this._delayA.delayTime); + /** + * The second DelayNode + * @type {DelayNode} + * @private + */ + this._delayB = new Tone.Delay(0, 1); + /** + * The first LFO. + * @type {Tone.LFO} + * @private + */ + this._lfoB = new Tone.LFO({ + 'min': 0, + 'max': 0.1, + 'type': 'sawtooth', + 'phase': 180 + }).connect(this._delayB.delayTime); + /** + * Crossfade quickly between the two delay lines + * to cover up the jump in the sawtooth wave + * @type {Tone.CrossFade} + * @private + */ + this._crossFade = new Tone.CrossFade(); + /** + * LFO which alternates between the two + * delay lines to cover up the disparity in the + * sawtooth wave. + * @type {Tone.LFO} + * @private + */ + this._crossFadeLFO = new Tone.LFO({ + 'min': 0, + 'max': 1, + 'type': 'triangle', + 'phase': 90 + }).connect(this._crossFade.fade); + /** + * The delay node + * @type {Tone.Delay} + * @private + */ + this._feedbackDelay = new Tone.Delay(options.delayTime); + /** + * The amount of delay on the input signal + * @type {Time} + * @signal + */ + this.delayTime = this._feedbackDelay.delayTime; + this._readOnly('delayTime'); + /** + * Hold the current pitch + * @type {Number} + * @private + */ + this._pitch = options.pitch; + /** + * Hold the current windowSize + * @type {Number} + * @private + */ + this._windowSize = options.windowSize; + //connect the two delay lines up + this._delayA.connect(this._crossFade.a); + this._delayB.connect(this._crossFade.b); + //connect the frequency + this._frequency.fan(this._lfoA.frequency, this._lfoB.frequency, this._crossFadeLFO.frequency); + //route the input + this.effectSend.fan(this._delayA, this._delayB); + this._crossFade.chain(this._feedbackDelay, this.effectReturn); + //start the LFOs at the same time + var now = this.now(); + this._lfoA.start(now); + this._lfoB.start(now); + this._crossFadeLFO.start(now); + //set the initial value + this.windowSize = this._windowSize; + }; + Tone.extend(Tone.PitchShift, Tone.FeedbackEffect); + /** + * default values + * @static + * @type {Object} + * @const + */ + Tone.PitchShift.defaults = { + 'pitch': 0, + 'windowSize': 0.1, + 'delayTime': 0, + 'feedback': 0 + }; + /** + * Repitch the incoming signal by some interval (measured + * in semi-tones). + * @memberOf Tone.PitchShift# + * @type {Interval} + * @name pitch + * @example + * pitchShift.pitch = -12; //down one octave + * pitchShift.pitch = 7; //up a fifth + */ + Object.defineProperty(Tone.PitchShift.prototype, 'pitch', { + get: function () { + return this._pitch; + }, + set: function (interval) { + this._pitch = interval; + var factor = 0; + if (interval < 0) { + this._lfoA.min = 0; + this._lfoA.max = this._windowSize; + this._lfoB.min = 0; + this._lfoB.max = this._windowSize; + factor = this.intervalToFrequencyRatio(interval - 1) + 1; + } else { + this._lfoA.min = this._windowSize; + this._lfoA.max = 0; + this._lfoB.min = this._windowSize; + this._lfoB.max = 0; + factor = this.intervalToFrequencyRatio(interval) - 1; + } + this._frequency.value = factor * (1.2 / this._windowSize); + } + }); + /** + * The window size corresponds roughly to the sample length in a looping sampler. + * Smaller values are desirable for a less noticeable delay time of the pitch shifted + * signal, but larger values will result in smoother pitch shifting for larger intervals. + * A nominal range of 0.03 to 0.1 is recommended. + * @memberOf Tone.PitchShift# + * @type {Time} + * @name windowSize + * @example + * pitchShift.windowSize = 0.1; + */ + Object.defineProperty(Tone.PitchShift.prototype, 'windowSize', { + get: function () { + return this._windowSize; + }, + set: function (size) { + this._windowSize = this.toSeconds(size); + this.pitch = this._pitch; + } + }); + /** + * Clean up. + * @return {Tone.PitchShift} this + */ + Tone.PitchShift.prototype.dispose = function () { + Tone.FeedbackEffect.prototype.dispose.call(this); + this._frequency.dispose(); + this._frequency = null; + this._delayA.disconnect(); + this._delayA = null; + this._delayB.disconnect(); + this._delayB = null; + this._lfoA.dispose(); + this._lfoA = null; + this._lfoB.dispose(); + this._lfoB = null; + this._crossFade.dispose(); + this._crossFade = null; + this._crossFadeLFO.dispose(); + this._crossFadeLFO = null; + this._writable('delayTime'); + this._feedbackDelay.dispose(); + this._feedbackDelay = null; + this.delayTime = null; + return this; + }; + return Tone.PitchShift; + }); + Module(function (Tone) { + + /** + * @class Base class for stereo feedback effects where the effectReturn + * is fed back into the same channel. + * + * @constructor + * @extends {Tone.FeedbackEffect} + */ + Tone.StereoFeedbackEffect = function () { + var options = this.optionsObject(arguments, ['feedback'], Tone.FeedbackEffect.defaults); + Tone.StereoEffect.call(this, options); + /** + * controls the amount of feedback + * @type {NormalRange} + * @signal + */ + this.feedback = new Tone.Signal(options.feedback, Tone.Type.NormalRange); + /** + * the left side feeback + * @type {Tone.Gain} + * @private + */ + this._feedbackL = new Tone.Gain(); + /** + * the right side feeback + * @type {Tone.Gain} + * @private + */ + this._feedbackR = new Tone.Gain(); + //connect it up + this.effectReturnL.chain(this._feedbackL, this.effectSendL); + this.effectReturnR.chain(this._feedbackR, this.effectSendR); + this.feedback.fan(this._feedbackL.gain, this._feedbackR.gain); + this._readOnly(['feedback']); + }; + Tone.extend(Tone.StereoFeedbackEffect, Tone.FeedbackEffect); + /** + * clean up + * @returns {Tone.StereoFeedbackEffect} this + */ + Tone.StereoFeedbackEffect.prototype.dispose = function () { + Tone.StereoEffect.prototype.dispose.call(this); + this._writable(['feedback']); + this.feedback.dispose(); + this.feedback = null; + this._feedbackL.dispose(); + this._feedbackL = null; + this._feedbackR.dispose(); + this._feedbackR = null; + return this; + }; + return Tone.StereoFeedbackEffect; + }); + Module(function (Tone) { + + /** + * @class Applies a width factor to the mid/side seperation. + * 0 is all mid and 1 is all side. + * Algorithm found in [kvraudio forums](http://www.kvraudio.com/forum/viewtopic.php?t=212587). + *

+ * + * Mid *= 2*(1-width)
+ * Side *= 2*width + *
+ * + * @extends {Tone.MidSideEffect} + * @constructor + * @param {NormalRange|Object} [width] The stereo width. A width of 0 is mono and 1 is stereo. 0.5 is no change. + */ + Tone.StereoWidener = function () { + var options = this.optionsObject(arguments, ['width'], Tone.StereoWidener.defaults); + Tone.MidSideEffect.call(this, options); + /** + * The width control. 0 = 100% mid. 1 = 100% side. 0.5 = no change. + * @type {NormalRange} + * @signal + */ + this.width = new Tone.Signal(options.width, Tone.Type.NormalRange); + /** + * Mid multiplier + * @type {Tone.Expr} + * @private + */ + this._midMult = new Tone.Expr('$0 * ($1 * (1 - $2))'); + /** + * Side multiplier + * @type {Tone.Expr} + * @private + */ + this._sideMult = new Tone.Expr('$0 * ($1 * $2)'); + /** + * constant output of 2 + * @type {Tone} + * @private + */ + this._two = new Tone.Signal(2); + //the mid chain + this._two.connect(this._midMult, 0, 1); + this.width.connect(this._midMult, 0, 2); + //the side chain + this._two.connect(this._sideMult, 0, 1); + this.width.connect(this._sideMult, 0, 2); + //connect it to the effect send/return + this.midSend.chain(this._midMult, this.midReturn); + this.sideSend.chain(this._sideMult, this.sideReturn); + this._readOnly(['width']); + }; + Tone.extend(Tone.StereoWidener, Tone.MidSideEffect); + /** + * the default values + * @static + * @type {Object} + */ + Tone.StereoWidener.defaults = { 'width': 0.5 }; + /** + * Clean up. + * @returns {Tone.StereoWidener} this + */ + Tone.StereoWidener.prototype.dispose = function () { + Tone.MidSideEffect.prototype.dispose.call(this); + this._writable(['width']); + this.width.dispose(); + this.width = null; + this._midMult.dispose(); + this._midMult = null; + this._sideMult.dispose(); + this._sideMult = null; + this._two.dispose(); + this._two = null; + return this; + }; + return Tone.StereoWidener; + }); + Module(function (Tone) { + + /** + * @class Tone.Tremolo modulates the amplitude of an incoming signal using a Tone.LFO. + * The type, frequency, and depth of the LFO is controllable. + * + * @extends {Tone.StereoEffect} + * @constructor + * @param {Frequency} [frequency] The rate of the effect. + * @param {NormalRange} [depth] The depth of the effect. + * @example + * //create a tremolo and start it's LFO + * var tremolo = new Tone.Tremolo(9, 0.75).toMaster().start(); + * //route an oscillator through the tremolo and start it + * var oscillator = new Tone.Oscillator().connect(tremolo).start(); + */ + Tone.Tremolo = function () { + var options = this.optionsObject(arguments, [ + 'frequency', + 'depth' + ], Tone.Tremolo.defaults); + Tone.StereoEffect.call(this, options); + /** + * The tremelo LFO in the left channel + * @type {Tone.LFO} + * @private + */ + this._lfoL = new Tone.LFO({ + 'phase': options.spread, + 'min': 1, + 'max': 0 + }); + /** + * The tremelo LFO in the left channel + * @type {Tone.LFO} + * @private + */ + this._lfoR = new Tone.LFO({ + 'phase': options.spread, + 'min': 1, + 'max': 0 + }); + /** + * Where the gain is multiplied + * @type {Tone.Gain} + * @private + */ + this._amplitudeL = new Tone.Gain(); + /** + * Where the gain is multiplied + * @type {Tone.Gain} + * @private + */ + this._amplitudeR = new Tone.Gain(); + /** + * The frequency of the tremolo. + * @type {Frequency} + * @signal + */ + this.frequency = new Tone.Signal(options.frequency, Tone.Type.Frequency); + /** + * The depth of the effect. A depth of 0, has no effect + * on the amplitude, and a depth of 1 makes the amplitude + * modulate fully between 0 and 1. + * @type {NormalRange} + * @signal + */ + this.depth = new Tone.Signal(options.depth, Tone.Type.NormalRange); + this._readOnly([ + 'frequency', + 'depth' + ]); + this.effectSendL.chain(this._amplitudeL, this.effectReturnL); + this.effectSendR.chain(this._amplitudeR, this.effectReturnR); + this._lfoL.connect(this._amplitudeL.gain); + this._lfoR.connect(this._amplitudeR.gain); + this.frequency.fan(this._lfoL.frequency, this._lfoR.frequency); + this.depth.fan(this._lfoR.amplitude, this._lfoL.amplitude); + this.type = options.type; + this.spread = options.spread; + }; + Tone.extend(Tone.Tremolo, Tone.StereoEffect); + /** + * @static + * @const + * @type {Object} + */ + Tone.Tremolo.defaults = { + 'frequency': 10, + 'type': 'sine', + 'depth': 0.5, + 'spread': 180 + }; + /** + * Start the tremolo. + * @param {Time} [time=now] When the tremolo begins. + * @returns {Tone.Tremolo} this + */ + Tone.Tremolo.prototype.start = function (time) { + this._lfoL.start(time); + this._lfoR.start(time); + return this; + }; + /** + * Stop the tremolo. + * @param {Time} [time=now] When the tremolo stops. + * @returns {Tone.Tremolo} this + */ + Tone.Tremolo.prototype.stop = function (time) { + this._lfoL.stop(time); + this._lfoR.stop(time); + return this; + }; + /** + * Sync the effect to the transport. + * @param {Time} [delay=0] Delay time before starting the effect after the + * Transport has started. + * @returns {Tone.AutoFilter} this + */ + Tone.Tremolo.prototype.sync = function (delay) { + this._lfoL.sync(delay); + this._lfoR.sync(delay); + return this; + }; + /** + * Unsync the filter from the transport + * @returns {Tone.Tremolo} this + */ + Tone.Tremolo.prototype.unsync = function () { + this._lfoL.unsync(); + this._lfoR.unsync(); + return this; + }; + /** + * The Tremolo's oscillator type. + * @memberOf Tone.Tremolo# + * @type {string} + * @name type + */ + Object.defineProperty(Tone.Tremolo.prototype, 'type', { + get: function () { + return this._lfoL.type; + }, + set: function (type) { + this._lfoL.type = type; + this._lfoR.type = type; + } + }); + /** + * Amount of stereo spread. When set to 0, both LFO's will be panned centrally. + * When set to 180, LFO's will be panned hard left and right respectively. + * @memberOf Tone.Tremolo# + * @type {Degrees} + * @name spread + */ + Object.defineProperty(Tone.Tremolo.prototype, 'spread', { + get: function () { + return this._lfoR.phase - this._lfoL.phase; //180 + }, + set: function (spread) { + this._lfoL.phase = 90 - spread / 2; + this._lfoR.phase = spread / 2 + 90; + } + }); + /** + * clean up + * @returns {Tone.Tremolo} this + */ + Tone.Tremolo.prototype.dispose = function () { + Tone.StereoEffect.prototype.dispose.call(this); + this._writable([ + 'frequency', + 'depth' + ]); + this._lfoL.dispose(); + this._lfoL = null; + this._lfoR.dispose(); + this._lfoR = null; + this._amplitudeL.dispose(); + this._amplitudeL = null; + this._amplitudeR.dispose(); + this._amplitudeR = null; + this.frequency = null; + this.depth = null; + return this; + }; + return Tone.Tremolo; + }); + Module(function (Tone) { + + /** + * @class A Vibrato effect composed of a Tone.Delay and a Tone.LFO. The LFO + * modulates the delayTime of the delay, causing the pitch to rise + * and fall. + * @extends {Tone.Effect} + * @param {Frequency} frequency The frequency of the vibrato. + * @param {NormalRange} depth The amount the pitch is modulated. + */ + Tone.Vibrato = function () { + var options = this.optionsObject(arguments, [ + 'frequency', + 'depth' + ], Tone.Vibrato.defaults); + Tone.Effect.call(this, options); + /** + * The delay node used for the vibrato effect + * @type {Tone.Delay} + * @private + */ + this._delayNode = new Tone.Delay(0, options.maxDelay); + /** + * The LFO used to control the vibrato + * @type {Tone.LFO} + * @private + */ + this._lfo = new Tone.LFO({ + 'type': options.type, + 'min': 0, + 'max': options.maxDelay, + 'frequency': options.frequency, + 'phase': -90 //offse the phase so the resting position is in the center + }).start().connect(this._delayNode.delayTime); + /** + * The frequency of the vibrato + * @type {Frequency} + * @signal + */ + this.frequency = this._lfo.frequency; + /** + * The depth of the vibrato. + * @type {NormalRange} + * @signal + */ + this.depth = this._lfo.amplitude; + this.depth.value = options.depth; + this._readOnly([ + 'frequency', + 'depth' + ]); + this.effectSend.chain(this._delayNode, this.effectReturn); + }; + Tone.extend(Tone.Vibrato, Tone.Effect); + /** + * The defaults + * @type {Object} + * @const + */ + Tone.Vibrato.defaults = { + 'maxDelay': 0.005, + 'frequency': 5, + 'depth': 0.1, + 'type': 'sine' + }; + /** + * Type of oscillator attached to the Vibrato. + * @memberOf Tone.Vibrato# + * @type {string} + * @name type + */ + Object.defineProperty(Tone.Vibrato.prototype, 'type', { + get: function () { + return this._lfo.type; + }, + set: function (type) { + this._lfo.type = type; + } + }); + /** + * Clean up. + * @returns {Tone.Vibrato} this + */ + Tone.Vibrato.prototype.dispose = function () { + Tone.Effect.prototype.dispose.call(this); + this._delayNode.dispose(); + this._delayNode = null; + this._lfo.dispose(); + this._lfo = null; + this._writable([ + 'frequency', + 'depth' + ]); + this.frequency = null; + this.depth = null; + }; + return Tone.Vibrato; + }); + Module(function (Tone) { + + /** + * @class Tone.Event abstracts away Tone.Transport.schedule and provides a schedulable + * callback for a single or repeatable events along the timeline. + * + * @extends {Tone} + * @param {function} callback The callback to invoke at the time. + * @param {*} value The value or values which should be passed to + * the callback function on invocation. + * @example + * var chord = new Tone.Event(function(time, chord){ + * //the chord as well as the exact time of the event + * //are passed in as arguments to the callback function + * }, ["D4", "E4", "F4"]); + * //start the chord at the beginning of the transport timeline + * chord.start(); + * //loop it every measure for 8 measures + * chord.loop = 8; + * chord.loopEnd = "1m"; + */ + Tone.Event = function () { + var options = this.optionsObject(arguments, [ + 'callback', + 'value' + ], Tone.Event.defaults); + /** + * Loop value + * @type {Boolean|Positive} + * @private + */ + this._loop = options.loop; + /** + * The callback to invoke. + * @type {Function} + */ + this.callback = options.callback; + /** + * The value which is passed to the + * callback function. + * @type {*} + * @private + */ + this.value = options.value; + /** + * When the note is scheduled to start. + * @type {Number} + * @private + */ + this._loopStart = this.toTicks(options.loopStart); + /** + * When the note is scheduled to start. + * @type {Number} + * @private + */ + this._loopEnd = this.toTicks(options.loopEnd); + /** + * Tracks the scheduled events + * @type {Tone.TimelineState} + * @private + */ + this._state = new Tone.TimelineState(Tone.State.Stopped); + /** + * The playback speed of the note. A speed of 1 + * is no change. + * @private + * @type {Positive} + */ + this._playbackRate = 1; + /** + * A delay time from when the event is scheduled to start + * @type {Ticks} + * @private + */ + this._startOffset = 0; + /** + * The probability that the callback will be invoked + * at the scheduled time. + * @type {NormalRange} + * @example + * //the callback will be invoked 50% of the time + * event.probability = 0.5; + */ + this.probability = options.probability; + /** + * If set to true, will apply small (+/-0.02 seconds) random variation + * to the callback time. If the value is given as a time, it will randomize + * by that amount. + * @example + * event.humanize = true; + * @type {Boolean|Time} + */ + this.humanize = options.humanize; + /** + * If mute is true, the callback won't be + * invoked. + * @type {Boolean} + */ + this.mute = options.mute; + //set the initial values + this.playbackRate = options.playbackRate; + }; + Tone.extend(Tone.Event); + /** + * The default values + * @type {Object} + * @const + */ + Tone.Event.defaults = { + 'callback': Tone.noOp, + 'loop': false, + 'loopEnd': '1m', + 'loopStart': 0, + 'playbackRate': 1, + 'value': null, + 'probability': 1, + 'mute': false, + 'humanize': false + }; + /** + * Reschedule all of the events along the timeline + * with the updated values. + * @param {Time} after Only reschedules events after the given time. + * @return {Tone.Event} this + * @private + */ + Tone.Event.prototype._rescheduleEvents = function (after) { + //if no argument is given, schedules all of the events + after = this.defaultArg(after, -1); + this._state.forEachFrom(after, function (event) { + var duration; + if (event.state === Tone.State.Started) { + if (!this.isUndef(event.id)) { + Tone.Transport.clear(event.id); + } + var startTick = event.time + Math.round(this.startOffset / this._playbackRate); + if (this._loop) { + duration = Infinity; + if (this.isNumber(this._loop)) { + duration = this._loop * this._getLoopDuration(); + } + var nextEvent = this._state.getAfter(startTick); + if (nextEvent !== null) { + duration = Math.min(duration, nextEvent.time - startTick); + } + if (duration !== Infinity) { + //schedule a stop since it's finite duration + this._state.setStateAtTime(Tone.State.Stopped, startTick + duration + 1); + duration = Tone.Time(duration, 'i'); + } + var interval = Tone.Time(this._getLoopDuration(), 'i'); + event.id = Tone.Transport.scheduleRepeat(this._tick.bind(this), interval, Tone.TransportTime(startTick, 'i'), duration); + } else { + event.id = Tone.Transport.schedule(this._tick.bind(this), startTick + 'i'); + } + } + }.bind(this)); + return this; + }; + /** + * Returns the playback state of the note, either "started" or "stopped". + * @type {String} + * @readOnly + * @memberOf Tone.Event# + * @name state + */ + Object.defineProperty(Tone.Event.prototype, 'state', { + get: function () { + return this._state.getValueAtTime(Tone.Transport.ticks); + } + }); + /** + * The start from the scheduled start time + * @type {Ticks} + * @memberOf Tone.Event# + * @name startOffset + * @private + */ + Object.defineProperty(Tone.Event.prototype, 'startOffset', { + get: function () { + return this._startOffset; + }, + set: function (offset) { + this._startOffset = offset; + } + }); + /** + * Start the note at the given time. + * @param {TimelinePosition} time When the note should start. + * @return {Tone.Event} this + */ + Tone.Event.prototype.start = function (time) { + time = this.toTicks(time); + if (this._state.getValueAtTime(time) === Tone.State.Stopped) { + this._state.add({ + 'state': Tone.State.Started, + 'time': time, + 'id': undefined + }); + this._rescheduleEvents(time); + } + return this; + }; + /** + * Stop the Event at the given time. + * @param {TimelinePosition} time When the note should stop. + * @return {Tone.Event} this + */ + Tone.Event.prototype.stop = function (time) { + this.cancel(time); + time = this.toTicks(time); + if (this._state.getValueAtTime(time) === Tone.State.Started) { + this._state.setStateAtTime(Tone.State.Stopped, time); + var previousEvent = this._state.getBefore(time); + var reschedulTime = time; + if (previousEvent !== null) { + reschedulTime = previousEvent.time; + } + this._rescheduleEvents(reschedulTime); + } + return this; + }; + /** + * Cancel all scheduled events greater than or equal to the given time + * @param {TimelinePosition} [time=0] The time after which events will be cancel. + * @return {Tone.Event} this + */ + Tone.Event.prototype.cancel = function (time) { + time = this.defaultArg(time, -Infinity); + time = this.toTicks(time); + this._state.forEachFrom(time, function (event) { + Tone.Transport.clear(event.id); + }); + this._state.cancel(time); + return this; + }; + /** + * The callback function invoker. Also + * checks if the Event is done playing + * @param {Number} time The time of the event in seconds + * @private + */ + Tone.Event.prototype._tick = function (time) { + if (!this.mute && this._state.getValueAtTime(Tone.Transport.ticks) === Tone.State.Started) { + if (this.probability < 1 && Math.random() > this.probability) { + return; + } + if (this.humanize) { + var variation = 0.02; + if (!this.isBoolean(this.humanize)) { + variation = this.toSeconds(this.humanize); + } + time += (Math.random() * 2 - 1) * variation; + } + this.callback(time, this.value); + } + }; + /** + * Get the duration of the loop. + * @return {Ticks} + * @private + */ + Tone.Event.prototype._getLoopDuration = function () { + return Math.round((this._loopEnd - this._loopStart) / this._playbackRate); + }; + /** + * If the note should loop or not + * between Tone.Event.loopStart and + * Tone.Event.loopEnd. An integer + * value corresponds to the number of + * loops the Event does after it starts. + * @memberOf Tone.Event# + * @type {Boolean|Positive} + * @name loop + */ + Object.defineProperty(Tone.Event.prototype, 'loop', { + get: function () { + return this._loop; + }, + set: function (loop) { + this._loop = loop; + this._rescheduleEvents(); + } + }); + /** + * The playback rate of the note. Defaults to 1. + * @memberOf Tone.Event# + * @type {Positive} + * @name playbackRate + * @example + * note.loop = true; + * //repeat the note twice as fast + * note.playbackRate = 2; + */ + Object.defineProperty(Tone.Event.prototype, 'playbackRate', { + get: function () { + return this._playbackRate; + }, + set: function (rate) { + this._playbackRate = rate; + this._rescheduleEvents(); + } + }); + /** + * The loopEnd point is the time the event will loop + * if Tone.Event.loop is true. + * @memberOf Tone.Event# + * @type {TransportTime} + * @name loopEnd + */ + Object.defineProperty(Tone.Event.prototype, 'loopEnd', { + get: function () { + return Tone.TransportTime(this._loopEnd, 'i').toNotation(); + }, + set: function (loopEnd) { + this._loopEnd = this.toTicks(loopEnd); + if (this._loop) { + this._rescheduleEvents(); + } + } + }); + /** + * The time when the loop should start. + * @memberOf Tone.Event# + * @type {TransportTime} + * @name loopStart + */ + Object.defineProperty(Tone.Event.prototype, 'loopStart', { + get: function () { + return Tone.TransportTime(this._loopStart, 'i').toNotation(); + }, + set: function (loopStart) { + this._loopStart = this.toTicks(loopStart); + if (this._loop) { + this._rescheduleEvents(); + } + } + }); + /** + * The current progress of the loop interval. + * Returns 0 if the event is not started yet or + * it is not set to loop. + * @memberOf Tone.Event# + * @type {NormalRange} + * @name progress + * @readOnly + */ + Object.defineProperty(Tone.Event.prototype, 'progress', { + get: function () { + if (this._loop) { + var ticks = Tone.Transport.ticks; + var lastEvent = this._state.get(ticks); + if (lastEvent !== null && lastEvent.state === Tone.State.Started) { + var loopDuration = this._getLoopDuration(); + var progress = (ticks - lastEvent.time) % loopDuration; + return progress / loopDuration; + } else { + return 0; + } + } else { + return 0; + } + } + }); + /** + * Clean up + * @return {Tone.Event} this + */ + Tone.Event.prototype.dispose = function () { + this.cancel(); + this._state.dispose(); + this._state = null; + this.callback = null; + this.value = null; + }; + return Tone.Event; + }); + Module(function (Tone) { + /** + * @class Tone.Loop creates a looped callback at the + * specified interval. The callback can be + * started, stopped and scheduled along + * the Transport's timeline. + * @example + * var loop = new Tone.Loop(function(time){ + * //triggered every eighth note. + * console.log(time); + * }, "8n").start(0); + * Tone.Transport.start(); + * @extends {Tone} + * @param {Function} callback The callback to invoke with the event. + * @param {Time} interval The time between successive callback calls. + */ + Tone.Loop = function () { + var options = this.optionsObject(arguments, [ + 'callback', + 'interval' + ], Tone.Loop.defaults); + /** + * The event which produces the callbacks + */ + this._event = new Tone.Event({ + 'callback': this._tick.bind(this), + 'loop': true, + 'loopEnd': options.interval, + 'playbackRate': options.playbackRate, + 'probability': options.probability + }); + /** + * The callback to invoke with the next event in the pattern + * @type {Function} + */ + this.callback = options.callback; + //set the iterations + this.iterations = options.iterations; + }; + Tone.extend(Tone.Loop); + /** + * The defaults + * @const + * @type {Object} + */ + Tone.Loop.defaults = { + 'interval': '4n', + 'callback': Tone.noOp, + 'playbackRate': 1, + 'iterations': Infinity, + 'probability': true, + 'mute': false + }; + /** + * Start the loop at the specified time along the Transport's + * timeline. + * @param {TimelinePosition=} time When to start the Loop. + * @return {Tone.Loop} this + */ + Tone.Loop.prototype.start = function (time) { + this._event.start(time); + return this; + }; + /** + * Stop the loop at the given time. + * @param {TimelinePosition=} time When to stop the Arpeggio + * @return {Tone.Loop} this + */ + Tone.Loop.prototype.stop = function (time) { + this._event.stop(time); + return this; + }; + /** + * Cancel all scheduled events greater than or equal to the given time + * @param {TimelinePosition} [time=0] The time after which events will be cancel. + * @return {Tone.Loop} this + */ + Tone.Loop.prototype.cancel = function (time) { + this._event.cancel(time); + return this; + }; + /** + * Internal function called when the notes should be called + * @param {Number} time The time the event occurs + * @private + */ + Tone.Loop.prototype._tick = function (time) { + this.callback(time); + }; + /** + * The state of the Loop, either started or stopped. + * @memberOf Tone.Loop# + * @type {String} + * @name state + * @readOnly + */ + Object.defineProperty(Tone.Loop.prototype, 'state', { + get: function () { + return this._event.state; + } + }); + /** + * The progress of the loop as a value between 0-1. 0, when + * the loop is stopped or done iterating. + * @memberOf Tone.Loop# + * @type {NormalRange} + * @name progress + * @readOnly + */ + Object.defineProperty(Tone.Loop.prototype, 'progress', { + get: function () { + return this._event.progress; + } + }); + /** + * The time between successive callbacks. + * @example + * loop.interval = "8n"; //loop every 8n + * @memberOf Tone.Loop# + * @type {Time} + * @name interval + */ + Object.defineProperty(Tone.Loop.prototype, 'interval', { + get: function () { + return this._event.loopEnd; + }, + set: function (interval) { + this._event.loopEnd = interval; + } + }); + /** + * The playback rate of the loop. The normal playback rate is 1 (no change). + * A `playbackRate` of 2 would be twice as fast. + * @memberOf Tone.Loop# + * @type {Time} + * @name playbackRate + */ + Object.defineProperty(Tone.Loop.prototype, 'playbackRate', { + get: function () { + return this._event.playbackRate; + }, + set: function (rate) { + this._event.playbackRate = rate; + } + }); + /** + * Random variation +/-0.01s to the scheduled time. + * Or give it a time value which it will randomize by. + * @type {Boolean|Time} + * @memberOf Tone.Loop# + * @name humanize + */ + Object.defineProperty(Tone.Loop.prototype, 'humanize', { + get: function () { + return this._event.humanize; + }, + set: function (variation) { + this._event.humanize = variation; + } + }); + /** + * The probably of the callback being invoked. + * @memberOf Tone.Loop# + * @type {NormalRange} + * @name probability + */ + Object.defineProperty(Tone.Loop.prototype, 'probability', { + get: function () { + return this._event.probability; + }, + set: function (prob) { + this._event.probability = prob; + } + }); + /** + * Muting the Loop means that no callbacks are invoked. + * @memberOf Tone.Loop# + * @type {Boolean} + * @name mute + */ + Object.defineProperty(Tone.Loop.prototype, 'mute', { + get: function () { + return this._event.mute; + }, + set: function (mute) { + this._event.mute = mute; + } + }); + /** + * The number of iterations of the loop. The default + * value is Infinity (loop forever). + * @memberOf Tone.Loop# + * @type {Positive} + * @name iterations + */ + Object.defineProperty(Tone.Loop.prototype, 'iterations', { + get: function () { + if (this._event.loop === true) { + return Infinity; + } else { + return this._event.loop; + } + return this._pattern.index; + }, + set: function (iters) { + if (iters === Infinity) { + this._event.loop = true; + } else { + this._event.loop = iters; + } + } + }); + /** + * Clean up + * @return {Tone.Loop} this + */ + Tone.Loop.prototype.dispose = function () { + this._event.dispose(); + this._event = null; + this.callback = null; + }; + return Tone.Loop; + }); + Module(function (Tone) { + + /** + * @class Tone.Part is a collection Tone.Events which can be + * started/stoped and looped as a single unit. + * + * @extends {Tone.Event} + * @param {Function} callback The callback to invoke on each event + * @param {Array} events the array of events + * @example + * var part = new Tone.Part(function(time, note){ + * //the notes given as the second element in the array + * //will be passed in as the second argument + * synth.triggerAttackRelease(note, "8n", time); + * }, [[0, "C2"], ["0:2", "C3"], ["0:3:2", "G2"]]); + * @example + * //use an array of objects as long as the object has a "time" attribute + * var part = new Tone.Part(function(time, value){ + * //the value is an object which contains both the note and the velocity + * synth.triggerAttackRelease(value.note, "8n", time, value.velocity); + * }, [{"time" : 0, "note" : "C3", "velocity": 0.9}, + * {"time" : "0:2", "note" : "C4", "velocity": 0.5} + * ]).start(0); + */ + Tone.Part = function () { + var options = this.optionsObject(arguments, [ + 'callback', + 'events' + ], Tone.Part.defaults); + /** + * If the part is looping or not + * @type {Boolean|Positive} + * @private + */ + this._loop = options.loop; + /** + * When the note is scheduled to start. + * @type {Ticks} + * @private + */ + this._loopStart = this.toTicks(options.loopStart); + /** + * When the note is scheduled to start. + * @type {Ticks} + * @private + */ + this._loopEnd = this.toTicks(options.loopEnd); + /** + * The playback rate of the part + * @type {Positive} + * @private + */ + this._playbackRate = options.playbackRate; + /** + * private holder of probability value + * @type {NormalRange} + * @private + */ + this._probability = options.probability; + /** + * the amount of variation from the + * given time. + * @type {Boolean|Time} + * @private + */ + this._humanize = options.humanize; + /** + * The start offset + * @type {Ticks} + * @private + */ + this._startOffset = 0; + /** + * Keeps track of the current state + * @type {Tone.TimelineState} + * @private + */ + this._state = new Tone.TimelineState(Tone.State.Stopped); + /** + * An array of Objects. + * @type {Array} + * @private + */ + this._events = []; + /** + * The callback to invoke at all the scheduled events. + * @type {Function} + */ + this.callback = options.callback; + /** + * If mute is true, the callback won't be + * invoked. + * @type {Boolean} + */ + this.mute = options.mute; + //add the events + var events = this.defaultArg(options.events, []); + if (!this.isUndef(options.events)) { + for (var i = 0; i < events.length; i++) { + if (Array.isArray(events[i])) { + this.add(events[i][0], events[i][1]); + } else { + this.add(events[i]); + } + } + } + }; + Tone.extend(Tone.Part, Tone.Event); + /** + * The default values + * @type {Object} + * @const + */ + Tone.Part.defaults = { + 'callback': Tone.noOp, + 'loop': false, + 'loopEnd': '1m', + 'loopStart': 0, + 'playbackRate': 1, + 'probability': 1, + 'humanize': false, + 'mute': false + }; + /** + * Start the part at the given time. + * @param {TransportTime} time When to start the part. + * @param {Time=} offset The offset from the start of the part + * to begin playing at. + * @return {Tone.Part} this + */ + Tone.Part.prototype.start = function (time, offset) { + var ticks = this.toTicks(time); + if (this._state.getValueAtTime(ticks) !== Tone.State.Started) { + if (this._loop) { + offset = this.defaultArg(offset, this._loopStart); + } else { + offset = this.defaultArg(offset, 0); + } + offset = this.toTicks(offset); + this._state.add({ + 'state': Tone.State.Started, + 'time': ticks, + 'offset': offset + }); + this._forEach(function (event) { + this._startNote(event, ticks, offset); + }); + } + return this; + }; + /** + * Start the event in the given event at the correct time given + * the ticks and offset and looping. + * @param {Tone.Event} event + * @param {Ticks} ticks + * @param {Ticks} offset + * @private + */ + Tone.Part.prototype._startNote = function (event, ticks, offset) { + ticks -= offset; + if (this._loop) { + if (event.startOffset >= this._loopStart && event.startOffset < this._loopEnd) { + if (event.startOffset < offset) { + //start it on the next loop + ticks += this._getLoopDuration(); + } + event.start(Tone.TransportTime(ticks, 'i')); + } else if (event.startOffset < this._loopStart && event.startOffset >= offset) { + event.loop = false; + event.start(Tone.TransportTime(ticks, 'i')); + } + } else { + if (event.startOffset >= offset) { + event.start(Tone.TransportTime(ticks, 'i')); + } + } + }; + /** + * The start from the scheduled start time + * @type {Ticks} + * @memberOf Tone.Part# + * @name startOffset + * @private + */ + Object.defineProperty(Tone.Part.prototype, 'startOffset', { + get: function () { + return this._startOffset; + }, + set: function (offset) { + this._startOffset = offset; + this._forEach(function (event) { + event.startOffset += this._startOffset; + }); + } + }); + /** + * Stop the part at the given time. + * @param {TimelinePosition} time When to stop the part. + * @return {Tone.Part} this + */ + Tone.Part.prototype.stop = function (time) { + var ticks = this.toTicks(time); + this._state.cancel(ticks); + this._state.setStateAtTime(Tone.State.Stopped, ticks); + this._forEach(function (event) { + event.stop(time); + }); + return this; + }; + /** + * Get/Set an Event's value at the given time. + * If a value is passed in and no event exists at + * the given time, one will be created with that value. + * If two events are at the same time, the first one will + * be returned. + * @example + * part.at("1m"); //returns the part at the first measure + * + * part.at("2m", "C2"); //set the value at "2m" to C2. + * //if an event didn't exist at that time, it will be created. + * @param {TransportTime} time The time of the event to get or set. + * @param {*=} value If a value is passed in, the value of the + * event at the given time will be set to it. + * @return {Tone.Event} the event at the time + */ + Tone.Part.prototype.at = function (time, value) { + time = Tone.TransportTime(time); + var tickTime = Tone.Time(1, 'i').toSeconds(); + for (var i = 0; i < this._events.length; i++) { + var event = this._events[i]; + if (Math.abs(time.toTicks() - event.startOffset) < tickTime) { + if (!this.isUndef(value)) { + event.value = value; + } + return event; + } + } + //if there was no event at that time, create one + if (!this.isUndef(value)) { + this.add(time, value); + //return the new event + return this._events[this._events.length - 1]; + } else { + return null; + } + }; + /** + * Add a an event to the part. + * @param {Time} time The time the note should start. + * If an object is passed in, it should + * have a 'time' attribute and the rest + * of the object will be used as the 'value'. + * @param {Tone.Event|*} value + * @returns {Tone.Part} this + * @example + * part.add("1m", "C#+11"); + */ + Tone.Part.prototype.add = function (time, value) { + //extract the parameters + if (time.hasOwnProperty('time')) { + value = time; + time = value.time; + } + time = this.toTicks(time); + var event; + if (value instanceof Tone.Event) { + event = value; + event.callback = this._tick.bind(this); + } else { + event = new Tone.Event({ + 'callback': this._tick.bind(this), + 'value': value + }); + } + //the start offset + event.startOffset = time; + //initialize the values + event.set({ + 'loopEnd': this.loopEnd, + 'loopStart': this.loopStart, + 'loop': this.loop, + 'humanize': this.humanize, + 'playbackRate': this.playbackRate, + 'probability': this.probability + }); + this._events.push(event); + //start the note if it should be played right now + this._restartEvent(event); + return this; + }; + /** + * Restart the given event + * @param {Tone.Event} event + * @private + */ + Tone.Part.prototype._restartEvent = function (event) { + this._state.forEach(function (stateEvent) { + if (stateEvent.state === Tone.State.Started) { + this._startNote(event, stateEvent.time, stateEvent.offset); + } else { + //stop the note + event.stop(Tone.TransportTime(stateEvent.time, 'i')); + } + }.bind(this)); + }; + /** + * Remove an event from the part. Will recursively iterate + * into nested parts to find the event. + * @param {Time} time The time of the event + * @param {*} value Optionally select only a specific event value + * @return {Tone.Part} this + */ + Tone.Part.prototype.remove = function (time, value) { + //extract the parameters + if (time.hasOwnProperty('time')) { + value = time; + time = value.time; + } + time = this.toTicks(time); + for (var i = this._events.length - 1; i >= 0; i--) { + var event = this._events[i]; + if (event instanceof Tone.Part) { + event.remove(time, value); + } else { + if (event.startOffset === time) { + if (this.isUndef(value) || !this.isUndef(value) && event.value === value) { + this._events.splice(i, 1); + event.dispose(); + } + } + } + } + return this; + }; + /** + * Remove all of the notes from the group. + * @return {Tone.Part} this + */ + Tone.Part.prototype.removeAll = function () { + this._forEach(function (event) { + event.dispose(); + }); + this._events = []; + return this; + }; + /** + * Cancel scheduled state change events: i.e. "start" and "stop". + * @param {TimelinePosition} after The time after which to cancel the scheduled events. + * @return {Tone.Part} this + */ + Tone.Part.prototype.cancel = function (after) { + after = this.toTicks(after); + this._forEach(function (event) { + event.cancel(after); + }); + this._state.cancel(after); + return this; + }; + /** + * Iterate over all of the events + * @param {Function} callback + * @param {Object} ctx The context + * @private + */ + Tone.Part.prototype._forEach = function (callback, ctx) { + ctx = this.defaultArg(ctx, this); + for (var i = this._events.length - 1; i >= 0; i--) { + var e = this._events[i]; + if (e instanceof Tone.Part) { + e._forEach(callback, ctx); + } else { + callback.call(ctx, e); + } + } + return this; + }; + /** + * Set the attribute of all of the events + * @param {String} attr the attribute to set + * @param {*} value The value to set it to + * @private + */ + Tone.Part.prototype._setAll = function (attr, value) { + this._forEach(function (event) { + event[attr] = value; + }); + }; + /** + * Internal tick method + * @param {Number} time The time of the event in seconds + * @private + */ + Tone.Part.prototype._tick = function (time, value) { + if (!this.mute) { + this.callback(time, value); + } + }; + /** + * Determine if the event should be currently looping + * given the loop boundries of this Part. + * @param {Tone.Event} event The event to test + * @private + */ + Tone.Part.prototype._testLoopBoundries = function (event) { + if (event.startOffset < this._loopStart || event.startOffset >= this._loopEnd) { + event.cancel(0); + } else { + //reschedule it if it's stopped + if (event.state === Tone.State.Stopped) { + this._restartEvent(event); + } + } + }; + /** + * The probability of the notes being triggered. + * @memberOf Tone.Part# + * @type {NormalRange} + * @name probability + */ + Object.defineProperty(Tone.Part.prototype, 'probability', { + get: function () { + return this._probability; + }, + set: function (prob) { + this._probability = prob; + this._setAll('probability', prob); + } + }); + /** + * If set to true, will apply small random variation + * to the callback time. If the value is given as a time, it will randomize + * by that amount. + * @example + * event.humanize = true; + * @type {Boolean|Time} + * @name humanize + */ + Object.defineProperty(Tone.Part.prototype, 'humanize', { + get: function () { + return this._humanize; + }, + set: function (variation) { + this._humanize = variation; + this._setAll('humanize', variation); + } + }); + /** + * If the part should loop or not + * between Tone.Part.loopStart and + * Tone.Part.loopEnd. An integer + * value corresponds to the number of + * loops the Part does after it starts. + * @memberOf Tone.Part# + * @type {Boolean|Positive} + * @name loop + * @example + * //loop the part 8 times + * part.loop = 8; + */ + Object.defineProperty(Tone.Part.prototype, 'loop', { + get: function () { + return this._loop; + }, + set: function (loop) { + this._loop = loop; + this._forEach(function (event) { + event._loopStart = this._loopStart; + event._loopEnd = this._loopEnd; + event.loop = loop; + this._testLoopBoundries(event); + }); + } + }); + /** + * The loopEnd point determines when it will + * loop if Tone.Part.loop is true. + * @memberOf Tone.Part# + * @type {TransportTime} + * @name loopEnd + */ + Object.defineProperty(Tone.Part.prototype, 'loopEnd', { + get: function () { + return Tone.TransportTime(this._loopEnd, 'i').toNotation(); + }, + set: function (loopEnd) { + this._loopEnd = this.toTicks(loopEnd); + if (this._loop) { + this._forEach(function (event) { + event.loopEnd = loopEnd; + this._testLoopBoundries(event); + }); + } + } + }); + /** + * The loopStart point determines when it will + * loop if Tone.Part.loop is true. + * @memberOf Tone.Part# + * @type {TransportTime} + * @name loopStart + */ + Object.defineProperty(Tone.Part.prototype, 'loopStart', { + get: function () { + return Tone.TransportTime(this._loopStart, 'i').toNotation(); + }, + set: function (loopStart) { + this._loopStart = this.toTicks(loopStart); + if (this._loop) { + this._forEach(function (event) { + event.loopStart = this.loopStart; + this._testLoopBoundries(event); + }); + } + } + }); + /** + * The playback rate of the part + * @memberOf Tone.Part# + * @type {Positive} + * @name playbackRate + */ + Object.defineProperty(Tone.Part.prototype, 'playbackRate', { + get: function () { + return this._playbackRate; + }, + set: function (rate) { + this._playbackRate = rate; + this._setAll('playbackRate', rate); + } + }); + /** + * The number of scheduled notes in the part. + * @memberOf Tone.Part# + * @type {Positive} + * @name length + * @readOnly + */ + Object.defineProperty(Tone.Part.prototype, 'length', { + get: function () { + return this._events.length; + } + }); + /** + * Clean up + * @return {Tone.Part} this + */ + Tone.Part.prototype.dispose = function () { + this.removeAll(); + this._state.dispose(); + this._state = null; + this.callback = null; + this._events = null; + return this; + }; + return Tone.Part; + }); + Module(function (Tone) { + /** + * @class Tone.Pattern arpeggiates between the given notes + * in a number of patterns. See Tone.CtrlPattern for + * a full list of patterns. + * @example + * var pattern = new Tone.Pattern(function(time, note){ + * //the order of the notes passed in depends on the pattern + * }, ["C2", "D4", "E5", "A6"], "upDown"); + * @extends {Tone.Loop} + * @param {Function} callback The callback to invoke with the + * event. + * @param {Array} values The values to arpeggiate over. + */ + Tone.Pattern = function () { + var options = this.optionsObject(arguments, [ + 'callback', + 'values', + 'pattern' + ], Tone.Pattern.defaults); + Tone.Loop.call(this, options); + /** + * The pattern manager + * @type {Tone.CtrlPattern} + * @private + */ + this._pattern = new Tone.CtrlPattern({ + 'values': options.values, + 'type': options.pattern, + 'index': options.index + }); + }; + Tone.extend(Tone.Pattern, Tone.Loop); + /** + * The defaults + * @const + * @type {Object} + */ + Tone.Pattern.defaults = { + 'pattern': Tone.CtrlPattern.Type.Up, + 'values': [] + }; + /** + * Internal function called when the notes should be called + * @param {Number} time The time the event occurs + * @private + */ + Tone.Pattern.prototype._tick = function (time) { + this.callback(time, this._pattern.value); + this._pattern.next(); + }; + /** + * The current index in the values array. + * @memberOf Tone.Pattern# + * @type {Positive} + * @name index + */ + Object.defineProperty(Tone.Pattern.prototype, 'index', { + get: function () { + return this._pattern.index; + }, + set: function (i) { + this._pattern.index = i; + } + }); + /** + * The array of events. + * @memberOf Tone.Pattern# + * @type {Array} + * @name values + */ + Object.defineProperty(Tone.Pattern.prototype, 'values', { + get: function () { + return this._pattern.values; + }, + set: function (vals) { + this._pattern.values = vals; + } + }); + /** + * The current value of the pattern. + * @memberOf Tone.Pattern# + * @type {*} + * @name value + * @readOnly + */ + Object.defineProperty(Tone.Pattern.prototype, 'value', { + get: function () { + return this._pattern.value; + } + }); + /** + * The pattern type. See Tone.CtrlPattern for the full list of patterns. + * @memberOf Tone.Pattern# + * @type {String} + * @name pattern + */ + Object.defineProperty(Tone.Pattern.prototype, 'pattern', { + get: function () { + return this._pattern.type; + }, + set: function (pattern) { + this._pattern.type = pattern; + } + }); + /** + * Clean up + * @return {Tone.Pattern} this + */ + Tone.Pattern.prototype.dispose = function () { + Tone.Loop.prototype.dispose.call(this); + this._pattern.dispose(); + this._pattern = null; + }; + return Tone.Pattern; + }); + Module(function (Tone) { + + /** + * @class A sequence is an alternate notation of a part. Instead + * of passing in an array of [time, event] pairs, pass + * in an array of events which will be spaced at the + * given subdivision. Sub-arrays will subdivide that beat + * by the number of items are in the array. + * Sequence notation inspiration from [Tidal](http://yaxu.org/tidal/) + * @param {Function} callback The callback to invoke with every note + * @param {Array} events The sequence + * @param {Time} subdivision The subdivision between which events are placed. + * @extends {Tone.Part} + * @example + * var seq = new Tone.Sequence(function(time, note){ + * console.log(note); + * //straight quater notes + * }, ["C4", "E4", "G4", "A4"], "4n"); + * @example + * var seq = new Tone.Sequence(function(time, note){ + * console.log(note); + * //subdivisions are given as subarrays + * }, ["C4", ["E4", "D4", "E4"], "G4", ["A4", "G4"]]); + */ + Tone.Sequence = function () { + var options = this.optionsObject(arguments, [ + 'callback', + 'events', + 'subdivision' + ], Tone.Sequence.defaults); + //remove the events + var events = options.events; + delete options.events; + Tone.Part.call(this, options); + /** + * The subdivison of each note + * @type {Ticks} + * @private + */ + this._subdivision = this.toTicks(options.subdivision); + //if no time was passed in, the loop end is the end of the cycle + if (this.isUndef(options.loopEnd) && !this.isUndef(events)) { + this._loopEnd = events.length * this._subdivision; + } + //defaults to looping + this._loop = true; + //add all of the events + if (!this.isUndef(events)) { + for (var i = 0; i < events.length; i++) { + this.add(i, events[i]); + } + } + }; + Tone.extend(Tone.Sequence, Tone.Part); + /** + * The default values. + * @type {Object} + */ + Tone.Sequence.defaults = { 'subdivision': '4n' }; + /** + * The subdivision of the sequence. This can only be + * set in the constructor. The subdivision is the + * interval between successive steps. + * @type {Time} + * @memberOf Tone.Sequence# + * @name subdivision + * @readOnly + */ + Object.defineProperty(Tone.Sequence.prototype, 'subdivision', { + get: function () { + return Tone.Time(this._subdivision, 'i').toNotation(); + } + }); + /** + * Get/Set an index of the sequence. If the index contains a subarray, + * a Tone.Sequence representing that sub-array will be returned. + * @example + * var sequence = new Tone.Sequence(playNote, ["E4", "C4", "F#4", ["A4", "Bb3"]]) + * sequence.at(0)// => returns "E4" + * //set a value + * sequence.at(0, "G3"); + * //get a nested sequence + * sequence.at(3).at(1)// => returns "Bb3" + * @param {Positive} index The index to get or set + * @param {*} value Optionally pass in the value to set at the given index. + */ + Tone.Sequence.prototype.at = function (index, value) { + //if the value is an array, + if (this.isArray(value)) { + //remove the current event at that index + this.remove(index); + } + //call the parent's method + return Tone.Part.prototype.at.call(this, this._indexTime(index), value); + }; + /** + * Add an event at an index, if there's already something + * at that index, overwrite it. If `value` is an array, + * it will be parsed as a subsequence. + * @param {Number} index The index to add the event to + * @param {*} value The value to add at that index + * @returns {Tone.Sequence} this + */ + Tone.Sequence.prototype.add = function (index, value) { + if (value === null) { + return this; + } + if (this.isArray(value)) { + //make a subsequence and add that to the sequence + var subSubdivision = Math.round(this._subdivision / value.length); + value = new Tone.Sequence(this._tick.bind(this), value, Tone.Time(subSubdivision, 'i')); + } + Tone.Part.prototype.add.call(this, this._indexTime(index), value); + return this; + }; + /** + * Remove a value from the sequence by index + * @param {Number} index The index of the event to remove + * @returns {Tone.Sequence} this + */ + Tone.Sequence.prototype.remove = function (index, value) { + Tone.Part.prototype.remove.call(this, this._indexTime(index), value); + return this; + }; + /** + * Get the time of the index given the Sequence's subdivision + * @param {Number} index + * @return {Time} The time of that index + * @private + */ + Tone.Sequence.prototype._indexTime = function (index) { + if (index instanceof Tone.TransportTime) { + return index; + } else { + return Tone.TransportTime(index * this._subdivision + this.startOffset, 'i'); + } + }; + /** + * Clean up. + * @return {Tone.Sequence} this + */ + Tone.Sequence.prototype.dispose = function () { + Tone.Part.prototype.dispose.call(this); + return this; + }; + return Tone.Sequence; + }); + Module(function (Tone) { + + /** + * @class Tone.PulseOscillator is a pulse oscillator with control over pulse width, + * also known as the duty cycle. At 50% duty cycle (width = 0.5) the wave is + * a square and only odd-numbered harmonics are present. At all other widths + * even-numbered harmonics are present. Read more + * [here](https://wigglewave.wordpress.com/2014/08/16/pulse-waveforms-and-harmonics/). + * + * @constructor + * @extends {Tone.Oscillator} + * @param {Frequency} [frequency] The frequency of the oscillator + * @param {NormalRange} [width] The width of the pulse + * @example + * var pulse = new Tone.PulseOscillator("E5", 0.4).toMaster().start(); + */ + Tone.PulseOscillator = function () { + var options = this.optionsObject(arguments, [ + 'frequency', + 'width' + ], Tone.Oscillator.defaults); + Tone.Source.call(this, options); + /** + * The width of the pulse. + * @type {NormalRange} + * @signal + */ + this.width = new Tone.Signal(options.width, Tone.Type.NormalRange); + /** + * gate the width amount + * @type {Tone.Gain} + * @private + */ + this._widthGate = new Tone.Gain(); + /** + * the sawtooth oscillator + * @type {Tone.Oscillator} + * @private + */ + this._sawtooth = new Tone.Oscillator({ + frequency: options.frequency, + detune: options.detune, + type: 'sawtooth', + phase: options.phase + }); + /** + * The frequency control. + * @type {Frequency} + * @signal + */ + this.frequency = this._sawtooth.frequency; + /** + * The detune in cents. + * @type {Cents} + * @signal + */ + this.detune = this._sawtooth.detune; + /** + * Threshold the signal to turn it into a square + * @type {Tone.WaveShaper} + * @private + */ + this._thresh = new Tone.WaveShaper(function (val) { + if (val < 0) { + return -1; + } else { + return 1; + } + }); + //connections + this._sawtooth.chain(this._thresh, this.output); + this.width.chain(this._widthGate, this._thresh); + this._readOnly([ + 'width', + 'frequency', + 'detune' + ]); + }; + Tone.extend(Tone.PulseOscillator, Tone.Oscillator); + /** + * The default parameters. + * @static + * @const + * @type {Object} + */ + Tone.PulseOscillator.defaults = { + 'frequency': 440, + 'detune': 0, + 'phase': 0, + 'width': 0.2 + }; + /** + * start the oscillator + * @param {Time} time + * @private + */ + Tone.PulseOscillator.prototype._start = function (time) { + time = this.toSeconds(time); + this._sawtooth.start(time); + this._widthGate.gain.setValueAtTime(1, time); + }; + /** + * stop the oscillator + * @param {Time} time + * @private + */ + Tone.PulseOscillator.prototype._stop = function (time) { + time = this.toSeconds(time); + this._sawtooth.stop(time); + //the width is still connected to the output. + //that needs to be stopped also + this._widthGate.gain.setValueAtTime(0, time); + }; + /** + * The phase of the oscillator in degrees. + * @memberOf Tone.PulseOscillator# + * @type {Degrees} + * @name phase + */ + Object.defineProperty(Tone.PulseOscillator.prototype, 'phase', { + get: function () { + return this._sawtooth.phase; + }, + set: function (phase) { + this._sawtooth.phase = phase; + } + }); + /** + * The type of the oscillator. Always returns "pulse". + * @readOnly + * @memberOf Tone.PulseOscillator# + * @type {string} + * @name type + */ + Object.defineProperty(Tone.PulseOscillator.prototype, 'type', { + get: function () { + return 'pulse'; + } + }); + /** + * The partials of the waveform. Cannot set partials for this waveform type + * @memberOf Tone.PulseOscillator# + * @type {Array} + * @name partials + * @private + */ + Object.defineProperty(Tone.PulseOscillator.prototype, 'partials', { + get: function () { + return []; + } + }); + /** + * Clean up method. + * @return {Tone.PulseOscillator} this + */ + Tone.PulseOscillator.prototype.dispose = function () { + Tone.Source.prototype.dispose.call(this); + this._sawtooth.dispose(); + this._sawtooth = null; + this._writable([ + 'width', + 'frequency', + 'detune' + ]); + this.width.dispose(); + this.width = null; + this._widthGate.dispose(); + this._widthGate = null; + this._thresh.dispose(); + this._thresh = null; + this.frequency = null; + this.detune = null; + return this; + }; + return Tone.PulseOscillator; + }); + Module(function (Tone) { + + /** + * @class Tone.PWMOscillator modulates the width of a Tone.PulseOscillator + * at the modulationFrequency. This has the effect of continuously + * changing the timbre of the oscillator by altering the harmonics + * generated. + * + * @extends {Tone.Oscillator} + * @constructor + * @param {Frequency} frequency The starting frequency of the oscillator. + * @param {Frequency} modulationFrequency The modulation frequency of the width of the pulse. + * @example + * var pwm = new Tone.PWMOscillator("Ab3", 0.3).toMaster().start(); + */ + Tone.PWMOscillator = function () { + var options = this.optionsObject(arguments, [ + 'frequency', + 'modulationFrequency' + ], Tone.PWMOscillator.defaults); + Tone.Source.call(this, options); + /** + * the pulse oscillator + * @type {Tone.PulseOscillator} + * @private + */ + this._pulse = new Tone.PulseOscillator(options.modulationFrequency); + //change the pulse oscillator type + this._pulse._sawtooth.type = 'sine'; + /** + * the modulator + * @type {Tone.Oscillator} + * @private + */ + this._modulator = new Tone.Oscillator({ + 'frequency': options.frequency, + 'detune': options.detune, + 'phase': options.phase + }); + /** + * Scale the oscillator so it doesn't go silent + * at the extreme values. + * @type {Tone.Multiply} + * @private + */ + this._scale = new Tone.Multiply(2); + /** + * The frequency control. + * @type {Frequency} + * @signal + */ + this.frequency = this._modulator.frequency; + /** + * The detune of the oscillator. + * @type {Cents} + * @signal + */ + this.detune = this._modulator.detune; + /** + * The modulation rate of the oscillator. + * @type {Frequency} + * @signal + */ + this.modulationFrequency = this._pulse.frequency; + //connections + this._modulator.chain(this._scale, this._pulse.width); + this._pulse.connect(this.output); + this._readOnly([ + 'modulationFrequency', + 'frequency', + 'detune' + ]); + }; + Tone.extend(Tone.PWMOscillator, Tone.Oscillator); + /** + * default values + * @static + * @type {Object} + * @const + */ + Tone.PWMOscillator.defaults = { + 'frequency': 440, + 'detune': 0, + 'phase': 0, + 'modulationFrequency': 0.4 + }; + /** + * start the oscillator + * @param {Time} [time=now] + * @private + */ + Tone.PWMOscillator.prototype._start = function (time) { + time = this.toSeconds(time); + this._modulator.start(time); + this._pulse.start(time); + }; + /** + * stop the oscillator + * @param {Time} time (optional) timing parameter + * @private + */ + Tone.PWMOscillator.prototype._stop = function (time) { + time = this.toSeconds(time); + this._modulator.stop(time); + this._pulse.stop(time); + }; + /** + * The type of the oscillator. Always returns "pwm". + * @readOnly + * @memberOf Tone.PWMOscillator# + * @type {string} + * @name type + */ + Object.defineProperty(Tone.PWMOscillator.prototype, 'type', { + get: function () { + return 'pwm'; + } + }); + /** + * The partials of the waveform. Cannot set partials for this waveform type + * @memberOf Tone.PWMOscillator# + * @type {Array} + * @name partials + * @private + */ + Object.defineProperty(Tone.PWMOscillator.prototype, 'partials', { + get: function () { + return []; + } + }); + /** + * The phase of the oscillator in degrees. + * @memberOf Tone.PWMOscillator# + * @type {number} + * @name phase + */ + Object.defineProperty(Tone.PWMOscillator.prototype, 'phase', { + get: function () { + return this._modulator.phase; + }, + set: function (phase) { + this._modulator.phase = phase; + } + }); + /** + * Clean up. + * @return {Tone.PWMOscillator} this + */ + Tone.PWMOscillator.prototype.dispose = function () { + Tone.Source.prototype.dispose.call(this); + this._pulse.dispose(); + this._pulse = null; + this._scale.dispose(); + this._scale = null; + this._modulator.dispose(); + this._modulator = null; + this._writable([ + 'modulationFrequency', + 'frequency', + 'detune' + ]); + this.frequency = null; + this.detune = null; + this.modulationFrequency = null; + return this; + }; + return Tone.PWMOscillator; + }); + Module(function (Tone) { + + /** + * @class Tone.FMOscillator + * + * @extends {Tone.Oscillator} + * @constructor + * @param {Frequency} frequency The starting frequency of the oscillator. + * @param {String} type The type of the carrier oscillator. + * @param {String} modulationType The type of the modulator oscillator. + * @example + * //a sine oscillator frequency-modulated by a square wave + * var fmOsc = new Tone.FMOscillator("Ab3", "sine", "square").toMaster().start(); + */ + Tone.FMOscillator = function () { + var options = this.optionsObject(arguments, [ + 'frequency', + 'type', + 'modulationType' + ], Tone.FMOscillator.defaults); + Tone.Source.call(this, options); + /** + * The carrier oscillator + * @type {Tone.Oscillator} + * @private + */ + this._carrier = new Tone.Oscillator(options.frequency, options.type); + /** + * The oscillator's frequency + * @type {Frequency} + * @signal + */ + this.frequency = new Tone.Signal(options.frequency, Tone.Type.Frequency); + /** + * The detune control signal. + * @type {Cents} + * @signal + */ + this.detune = this._carrier.detune; + this.detune.value = options.detune; + /** + * The modulation index which is in essence the depth or amount of the modulation. In other terms it is the + * ratio of the frequency of the modulating signal (mf) to the amplitude of the + * modulating signal (ma) -- as in ma/mf. + * @type {Positive} + * @signal + */ + this.modulationIndex = new Tone.Multiply(options.modulationIndex); + this.modulationIndex.units = Tone.Type.Positive; + /** + * The modulating oscillator + * @type {Tone.Oscillator} + * @private + */ + this._modulator = new Tone.Oscillator(options.frequency, options.modulationType); + /** + * Harmonicity is the frequency ratio between the carrier and the modulator oscillators. + * A harmonicity of 1 gives both oscillators the same frequency. + * Harmonicity = 2 means a change of an octave. + * @type {Positive} + * @signal + * @example + * //pitch the modulator an octave below carrier + * synth.harmonicity.value = 0.5; + */ + this.harmonicity = new Tone.Multiply(options.harmonicity); + this.harmonicity.units = Tone.Type.Positive; + /** + * the node where the modulation happens + * @type {Tone.Gain} + * @private + */ + this._modulationNode = new Tone.Gain(0); + //connections + this.frequency.connect(this._carrier.frequency); + this.frequency.chain(this.harmonicity, this._modulator.frequency); + this.frequency.chain(this.modulationIndex, this._modulationNode); + this._modulator.connect(this._modulationNode.gain); + this._modulationNode.connect(this._carrier.frequency); + this._carrier.connect(this.output); + this.detune.connect(this._modulator.detune); + this.phase = options.phase; + this._readOnly([ + 'modulationIndex', + 'frequency', + 'detune', + 'harmonicity' + ]); + }; + Tone.extend(Tone.FMOscillator, Tone.Oscillator); + /** + * default values + * @static + * @type {Object} + * @const + */ + Tone.FMOscillator.defaults = { + 'frequency': 440, + 'detune': 0, + 'phase': 0, + 'modulationIndex': 2, + 'modulationType': 'square', + 'harmonicity': 1 + }; + /** + * start the oscillator + * @param {Time} [time=now] + * @private + */ + Tone.FMOscillator.prototype._start = function (time) { + time = this.toSeconds(time); + this._modulator.start(time); + this._carrier.start(time); + }; + /** + * stop the oscillator + * @param {Time} time (optional) timing parameter + * @private + */ + Tone.FMOscillator.prototype._stop = function (time) { + time = this.toSeconds(time); + this._modulator.stop(time); + this._carrier.stop(time); + }; + /** + * The type of the carrier oscillator + * @memberOf Tone.FMOscillator# + * @type {string} + * @name type + */ + Object.defineProperty(Tone.FMOscillator.prototype, 'type', { + get: function () { + return this._carrier.type; + }, + set: function (type) { + this._carrier.type = type; + } + }); + /** + * The type of the modulator oscillator + * @memberOf Tone.FMOscillator# + * @type {String} + * @name modulationType + */ + Object.defineProperty(Tone.FMOscillator.prototype, 'modulationType', { + get: function () { + return this._modulator.type; + }, + set: function (type) { + this._modulator.type = type; + } + }); + /** + * The phase of the oscillator in degrees. + * @memberOf Tone.FMOscillator# + * @type {number} + * @name phase + */ + Object.defineProperty(Tone.FMOscillator.prototype, 'phase', { + get: function () { + return this._carrier.phase; + }, + set: function (phase) { + this._carrier.phase = phase; + this._modulator.phase = phase; + } + }); + /** + * The partials of the carrier waveform. A partial represents + * the amplitude at a harmonic. The first harmonic is the + * fundamental frequency, the second is the octave and so on + * following the harmonic series. + * Setting this value will automatically set the type to "custom". + * The value is an empty array when the type is not "custom". + * @memberOf Tone.FMOscillator# + * @type {Array} + * @name partials + * @example + * osc.partials = [1, 0.2, 0.01]; + */ + Object.defineProperty(Tone.FMOscillator.prototype, 'partials', { + get: function () { + return this._carrier.partials; + }, + set: function (partials) { + this._carrier.partials = partials; + } + }); + /** + * Clean up. + * @return {Tone.FMOscillator} this + */ + Tone.FMOscillator.prototype.dispose = function () { + Tone.Source.prototype.dispose.call(this); + this._writable([ + 'modulationIndex', + 'frequency', + 'detune', + 'harmonicity' + ]); + this.frequency.dispose(); + this.frequency = null; + this.detune = null; + this.harmonicity.dispose(); + this.harmonicity = null; + this._carrier.dispose(); + this._carrier = null; + this._modulator.dispose(); + this._modulator = null; + this._modulationNode.dispose(); + this._modulationNode = null; + this.modulationIndex.dispose(); + this.modulationIndex = null; + return this; + }; + return Tone.FMOscillator; + }); + Module(function (Tone) { + + /** + * @class Tone.AMOscillator + * + * @extends {Tone.Oscillator} + * @constructor + * @param {Frequency} frequency The starting frequency of the oscillator. + * @param {String} type The type of the carrier oscillator. + * @param {String} modulationType The type of the modulator oscillator. + * @example + * //a sine oscillator frequency-modulated by a square wave + * var fmOsc = new Tone.AMOscillator("Ab3", "sine", "square").toMaster().start(); + */ + Tone.AMOscillator = function () { + var options = this.optionsObject(arguments, [ + 'frequency', + 'type', + 'modulationType' + ], Tone.AMOscillator.defaults); + Tone.Source.call(this, options); + /** + * The carrier oscillator + * @type {Tone.Oscillator} + * @private + */ + this._carrier = new Tone.Oscillator(options.frequency, options.type); + /** + * The oscillator's frequency + * @type {Frequency} + * @signal + */ + this.frequency = this._carrier.frequency; + /** + * The detune control signal. + * @type {Cents} + * @signal + */ + this.detune = this._carrier.detune; + this.detune.value = options.detune; + /** + * The modulating oscillator + * @type {Tone.Oscillator} + * @private + */ + this._modulator = new Tone.Oscillator(options.frequency, options.modulationType); + /** + * convert the -1,1 output to 0,1 + * @type {Tone.AudioToGain} + * @private + */ + this._modulationScale = new Tone.AudioToGain(); + /** + * Harmonicity is the frequency ratio between the carrier and the modulator oscillators. + * A harmonicity of 1 gives both oscillators the same frequency. + * Harmonicity = 2 means a change of an octave. + * @type {Positive} + * @signal + * @example + * //pitch the modulator an octave below carrier + * synth.harmonicity.value = 0.5; + */ + this.harmonicity = new Tone.Multiply(options.harmonicity); + this.harmonicity.units = Tone.Type.Positive; + /** + * the node where the modulation happens + * @type {Tone.Gain} + * @private + */ + this._modulationNode = new Tone.Gain(0); + //connections + this.frequency.chain(this.harmonicity, this._modulator.frequency); + this.detune.connect(this._modulator.detune); + this._modulator.chain(this._modulationScale, this._modulationNode.gain); + this._carrier.chain(this._modulationNode, this.output); + this.phase = options.phase; + this._readOnly([ + 'frequency', + 'detune', + 'harmonicity' + ]); + }; + Tone.extend(Tone.AMOscillator, Tone.Oscillator); + /** + * default values + * @static + * @type {Object} + * @const + */ + Tone.AMOscillator.defaults = { + 'frequency': 440, + 'detune': 0, + 'phase': 0, + 'modulationType': 'square', + 'harmonicity': 1 + }; + /** + * start the oscillator + * @param {Time} [time=now] + * @private + */ + Tone.AMOscillator.prototype._start = function (time) { + time = this.toSeconds(time); + this._modulator.start(time); + this._carrier.start(time); + }; + /** + * stop the oscillator + * @param {Time} time (optional) timing parameter + * @private + */ + Tone.AMOscillator.prototype._stop = function (time) { + time = this.toSeconds(time); + this._modulator.stop(time); + this._carrier.stop(time); + }; + /** + * The type of the carrier oscillator + * @memberOf Tone.AMOscillator# + * @type {string} + * @name type + */ + Object.defineProperty(Tone.AMOscillator.prototype, 'type', { + get: function () { + return this._carrier.type; + }, + set: function (type) { + this._carrier.type = type; + } + }); + /** + * The type of the modulator oscillator + * @memberOf Tone.AMOscillator# + * @type {string} + * @name modulationType + */ + Object.defineProperty(Tone.AMOscillator.prototype, 'modulationType', { + get: function () { + return this._modulator.type; + }, + set: function (type) { + this._modulator.type = type; + } + }); + /** + * The phase of the oscillator in degrees. + * @memberOf Tone.AMOscillator# + * @type {number} + * @name phase + */ + Object.defineProperty(Tone.AMOscillator.prototype, 'phase', { + get: function () { + return this._carrier.phase; + }, + set: function (phase) { + this._carrier.phase = phase; + this._modulator.phase = phase; + } + }); + /** + * The partials of the carrier waveform. A partial represents + * the amplitude at a harmonic. The first harmonic is the + * fundamental frequency, the second is the octave and so on + * following the harmonic series. + * Setting this value will automatically set the type to "custom". + * The value is an empty array when the type is not "custom". + * @memberOf Tone.AMOscillator# + * @type {Array} + * @name partials + * @example + * osc.partials = [1, 0.2, 0.01]; + */ + Object.defineProperty(Tone.AMOscillator.prototype, 'partials', { + get: function () { + return this._carrier.partials; + }, + set: function (partials) { + this._carrier.partials = partials; + } + }); + /** + * Clean up. + * @return {Tone.AMOscillator} this + */ + Tone.AMOscillator.prototype.dispose = function () { + Tone.Source.prototype.dispose.call(this); + this._writable([ + 'frequency', + 'detune', + 'harmonicity' + ]); + this.frequency = null; + this.detune = null; + this.harmonicity.dispose(); + this.harmonicity = null; + this._carrier.dispose(); + this._carrier = null; + this._modulator.dispose(); + this._modulator = null; + this._modulationNode.dispose(); + this._modulationNode = null; + this._modulationScale.dispose(); + this._modulationScale = null; + return this; + }; + return Tone.AMOscillator; + }); + Module(function (Tone) { + + /** + * @class Tone.FatOscillator + * + * @extends {Tone.Oscillator} + * @constructor + * @param {Frequency} frequency The starting frequency of the oscillator. + * @param {String} type The type of the carrier oscillator. + * @param {String} modulationType The type of the modulator oscillator. + * @example + * //a sine oscillator frequency-modulated by a square wave + * var fmOsc = new Tone.FatOscillator("Ab3", "sine", "square").toMaster().start(); + */ + Tone.FatOscillator = function () { + var options = this.optionsObject(arguments, [ + 'frequency', + 'type', + 'spread' + ], Tone.FatOscillator.defaults); + Tone.Source.call(this, options); + /** + * The oscillator's frequency + * @type {Frequency} + * @signal + */ + this.frequency = new Tone.Signal(options.frequency, Tone.Type.Frequency); + /** + * The detune control signal. + * @type {Cents} + * @signal + */ + this.detune = new Tone.Signal(options.detune, Tone.Type.Cents); + /** + * The array of oscillators + * @type {Array} + * @private + */ + this._oscillators = []; + /** + * The total spread of the oscillators + * @type {Cents} + * @private + */ + this._spread = options.spread; + /** + * The type of the oscillator + * @type {String} + * @private + */ + this._type = options.type; + /** + * The phase of the oscillators + * @type {Degrees} + * @private + */ + this._phase = options.phase; + /** + * The partials array + * @type {Array} + * @private + */ + this._partials = this.defaultArg(options.partials, []); + //set the count initially + this.count = options.count; + this._readOnly([ + 'frequency', + 'detune' + ]); + }; + Tone.extend(Tone.FatOscillator, Tone.Oscillator); + /** + * default values + * @static + * @type {Object} + * @const + */ + Tone.FatOscillator.defaults = { + 'frequency': 440, + 'detune': 0, + 'phase': 0, + 'spread': 20, + 'count': 3, + 'type': 'sawtooth' + }; + /** + * start the oscillator + * @param {Time} [time=now] + * @private + */ + Tone.FatOscillator.prototype._start = function (time) { + time = this.toSeconds(time); + this._forEach(function (osc) { + osc.start(time); + }); + }; + /** + * stop the oscillator + * @param {Time} time (optional) timing parameter + * @private + */ + Tone.FatOscillator.prototype._stop = function (time) { + time = this.toSeconds(time); + this._forEach(function (osc) { + osc.stop(time); + }); + }; + /** + * Iterate over all of the oscillators + * @param {Function} iterator The iterator function + * @private + */ + Tone.FatOscillator.prototype._forEach = function (iterator) { + for (var i = 0; i < this._oscillators.length; i++) { + iterator.call(this, this._oscillators[i], i); + } + }; + /** + * The type of the carrier oscillator + * @memberOf Tone.FatOscillator# + * @type {string} + * @name type + */ + Object.defineProperty(Tone.FatOscillator.prototype, 'type', { + get: function () { + return this._type; + }, + set: function (type) { + this._type = type; + this._forEach(function (osc) { + osc.type = type; + }); + } + }); + /** + * The detune spread between the oscillators. If "count" is + * set to 3 oscillators and the "spread" is set to 40, + * the three oscillators would be detuned like this: [-20, 0, 20] + * for a total detune spread of 40 cents. + * @memberOf Tone.FatOscillator# + * @type {Cents} + * @name spread + */ + Object.defineProperty(Tone.FatOscillator.prototype, 'spread', { + get: function () { + return this._spread; + }, + set: function (spread) { + this._spread = spread; + if (this._oscillators.length > 1) { + var start = -spread / 2; + var step = spread / (this._oscillators.length - 1); + this._forEach(function (osc, i) { + osc.detune.value = start + step * i; + }); + } + } + }); + /** + * The number of detuned oscillators + * @memberOf Tone.FatOscillator# + * @type {Number} + * @name count + */ + Object.defineProperty(Tone.FatOscillator.prototype, 'count', { + get: function () { + return this._oscillators.length; + }, + set: function (count) { + count = Math.max(count, 1); + if (this._oscillators.length !== count) { + // var partials = this.partials; + // var type = this.type; + //dispose the previous oscillators + this._forEach(function (osc) { + osc.dispose(); + }); + this._oscillators = []; + for (var i = 0; i < count; i++) { + var osc = new Tone.Oscillator(); + if (this.type === Tone.Oscillator.Type.Custom) { + osc.partials = this._partials; + } else { + osc.type = this._type; + } + osc.phase = this._phase; + osc.volume.value = -6 - count; + this.frequency.connect(osc.frequency); + this.detune.connect(osc.detune); + osc.connect(this.output); + this._oscillators[i] = osc; + } + //set the spread + this.spread = this._spread; + if (this.state === Tone.State.Started) { + this._forEach(function (osc) { + osc.start(); + }); + } + } + } + }); + /** + * The phase of the oscillator in degrees. + * @memberOf Tone.FatOscillator# + * @type {Number} + * @name phase + */ + Object.defineProperty(Tone.FatOscillator.prototype, 'phase', { + get: function () { + return this._phase; + }, + set: function (phase) { + this._phase = phase; + this._forEach(function (osc) { + osc.phase = phase; + }); + } + }); + /** + * The partials of the carrier waveform. A partial represents + * the amplitude at a harmonic. The first harmonic is the + * fundamental frequency, the second is the octave and so on + * following the harmonic series. + * Setting this value will automatically set the type to "custom". + * The value is an empty array when the type is not "custom". + * @memberOf Tone.FatOscillator# + * @type {Array} + * @name partials + * @example + * osc.partials = [1, 0.2, 0.01]; + */ + Object.defineProperty(Tone.FatOscillator.prototype, 'partials', { + get: function () { + return this._partials; + }, + set: function (partials) { + this._partials = partials; + this._type = Tone.Oscillator.Type.Custom; + this._forEach(function (osc) { + osc.partials = partials; + }); + } + }); + /** + * Clean up. + * @return {Tone.FatOscillator} this + */ + Tone.FatOscillator.prototype.dispose = function () { + Tone.Source.prototype.dispose.call(this); + this._writable([ + 'frequency', + 'detune' + ]); + this.frequency.dispose(); + this.frequency = null; + this.detune.dispose(); + this.detune = null; + this._forEach(function (osc) { + osc.dispose(); + }); + this._oscillators = null; + this._partials = null; + return this; + }; + return Tone.FatOscillator; + }); + Module(function (Tone) { + + /** + * @class Tone.OmniOscillator aggregates Tone.Oscillator, Tone.PulseOscillator, + * Tone.PWMOscillator, Tone.FMOscillator, Tone.AMOscillator, and Tone.FatOscillator + * into one class. The oscillator class can be changed by setting the `type`. + * `omniOsc.type = "pwm"` will set it to the Tone.PWMOscillator. Prefixing + * any of the basic types ("sine", "square4", etc.) with "fm", "am", or "fat" + * will use the FMOscillator, AMOscillator or FatOscillator respectively. + * For example: `omniOsc.type = "fatsawtooth"` will create set the oscillator + * to a FatOscillator of type "sawtooth". + * + * @extends {Tone.Oscillator} + * @constructor + * @param {Frequency} frequency The initial frequency of the oscillator. + * @param {String} type The type of the oscillator. + * @example + * var omniOsc = new Tone.OmniOscillator("C#4", "pwm"); + */ + Tone.OmniOscillator = function () { + var options = this.optionsObject(arguments, [ + 'frequency', + 'type' + ], Tone.OmniOscillator.defaults); + Tone.Source.call(this, options); + /** + * The frequency control. + * @type {Frequency} + * @signal + */ + this.frequency = new Tone.Signal(options.frequency, Tone.Type.Frequency); + /** + * The detune control + * @type {Cents} + * @signal + */ + this.detune = new Tone.Signal(options.detune, Tone.Type.Cents); + /** + * the type of the oscillator source + * @type {String} + * @private + */ + this._sourceType = undefined; + /** + * the oscillator + * @type {Tone.Oscillator} + * @private + */ + this._oscillator = null; + //set the oscillator + this.type = options.type; + this._readOnly([ + 'frequency', + 'detune' + ]); + //set the options + this.set(options); + }; + Tone.extend(Tone.OmniOscillator, Tone.Oscillator); + /** + * default values + * @static + * @type {Object} + * @const + */ + Tone.OmniOscillator.defaults = { + 'frequency': 440, + 'detune': 0, + 'type': 'sine', + 'phase': 0 + }; + /** + * @enum {String} + * @private + */ + var OmniOscType = { + Pulse: 'PulseOscillator', + PWM: 'PWMOscillator', + Osc: 'Oscillator', + FM: 'FMOscillator', + AM: 'AMOscillator', + Fat: 'FatOscillator' + }; + /** + * start the oscillator + * @param {Time} [time=now] the time to start the oscillator + * @private + */ + Tone.OmniOscillator.prototype._start = function (time) { + this._oscillator.start(time); + }; + /** + * start the oscillator + * @param {Time} [time=now] the time to start the oscillator + * @private + */ + Tone.OmniOscillator.prototype._stop = function (time) { + this._oscillator.stop(time); + }; + /** + * The type of the oscillator. Can be any of the basic types: sine, square, triangle, sawtooth. Or + * prefix the basic types with "fm", "am", or "fat" to use the FMOscillator, AMOscillator or FatOscillator + * types. The oscillator could also be set to "pwm" or "pulse". All of the parameters of the + * oscillator's class are accessible when the oscillator is set to that type, but throws an error + * when it's not. + * + * @memberOf Tone.OmniOscillator# + * @type {String} + * @name type + * @example + * omniOsc.type = "pwm"; + * //modulationFrequency is parameter which is available + * //only when the type is "pwm". + * omniOsc.modulationFrequency.value = 0.5; + * @example + * //an square wave frequency modulated by a sawtooth + * omniOsc.type = "fmsquare"; + * omniOsc.modulationType = "sawtooth"; + */ + Object.defineProperty(Tone.OmniOscillator.prototype, 'type', { + get: function () { + var prefix = ''; + if (this._sourceType === OmniOscType.FM) { + prefix = 'fm'; + } else if (this._sourceType === OmniOscType.AM) { + prefix = 'am'; + } else if (this._sourceType === OmniOscType.Fat) { + prefix = 'fat'; + } + return prefix + this._oscillator.type; + }, + set: function (type) { + if (type.substr(0, 2) === 'fm') { + this._createNewOscillator(OmniOscType.FM); + this._oscillator.type = type.substr(2); + } else if (type.substr(0, 2) === 'am') { + this._createNewOscillator(OmniOscType.AM); + this._oscillator.type = type.substr(2); + } else if (type.substr(0, 3) === 'fat') { + this._createNewOscillator(OmniOscType.Fat); + this._oscillator.type = type.substr(3); + } else if (type === 'pwm') { + this._createNewOscillator(OmniOscType.PWM); + } else if (type === 'pulse') { + this._createNewOscillator(OmniOscType.Pulse); + } else { + this._createNewOscillator(OmniOscType.Osc); + this._oscillator.type = type; + } + } + }); + /** + * The partials of the waveform. A partial represents + * the amplitude at a harmonic. The first harmonic is the + * fundamental frequency, the second is the octave and so on + * following the harmonic series. + * Setting this value will automatically set the type to "custom". + * The value is an empty array when the type is not "custom". + * This is not available on "pwm" and "pulse" oscillator types. + * @memberOf Tone.OmniOscillator# + * @type {Array} + * @name partials + * @example + * osc.partials = [1, 0.2, 0.01]; + */ + Object.defineProperty(Tone.OmniOscillator.prototype, 'partials', { + get: function () { + return this._oscillator.partials; + }, + set: function (partials) { + this._oscillator.partials = partials; + } + }); + /** + * Set a member/attribute of the oscillator. + * @param {Object|String} params + * @param {number=} value + * @param {Time=} rampTime + * @returns {Tone.OmniOscillator} this + */ + Tone.OmniOscillator.prototype.set = function (params, value) { + //make sure the type is set first + if (params === 'type') { + this.type = value; + } else if (this.isObject(params) && params.hasOwnProperty('type')) { + this.type = params.type; + } + //then set the rest + Tone.prototype.set.apply(this, arguments); + return this; + }; + /** + * connect the oscillator to the frequency and detune signals + * @private + */ + Tone.OmniOscillator.prototype._createNewOscillator = function (oscType) { + if (oscType !== this._sourceType) { + this._sourceType = oscType; + var OscillatorConstructor = Tone[oscType]; + //short delay to avoid clicks on the change + var now = this.now() + this.blockTime; + if (this._oscillator !== null) { + var oldOsc = this._oscillator; + oldOsc.stop(now); + //dispose the old one + setTimeout(function () { + oldOsc.dispose(); + oldOsc = null; + }, this.blockTime * 1000); + } + this._oscillator = new OscillatorConstructor(); + this.frequency.connect(this._oscillator.frequency); + this.detune.connect(this._oscillator.detune); + this._oscillator.connect(this.output); + if (this.state === Tone.State.Started) { + this._oscillator.start(now); + } + } + }; + /** + * The phase of the oscillator in degrees. + * @memberOf Tone.OmniOscillator# + * @type {Degrees} + * @name phase + */ + Object.defineProperty(Tone.OmniOscillator.prototype, 'phase', { + get: function () { + return this._oscillator.phase; + }, + set: function (phase) { + this._oscillator.phase = phase; + } + }); + /** + * The width of the oscillator (only if the oscillator is set to "pulse") + * @memberOf Tone.OmniOscillator# + * @type {NormalRange} + * @signal + * @name width + * @example + * var omniOsc = new Tone.OmniOscillator(440, "pulse"); + * //can access the width attribute only if type === "pulse" + * omniOsc.width.value = 0.2; + */ + Object.defineProperty(Tone.OmniOscillator.prototype, 'width', { + get: function () { + if (this._sourceType === OmniOscType.Pulse) { + return this._oscillator.width; + } + } + }); + /** + * The number of detuned oscillators + * @memberOf Tone.OmniOscillator# + * @type {Number} + * @name count + */ + Object.defineProperty(Tone.OmniOscillator.prototype, 'count', { + get: function () { + if (this._sourceType === OmniOscType.Fat) { + return this._oscillator.count; + } + }, + set: function (count) { + if (this._sourceType === OmniOscType.Fat) { + this._oscillator.count = count; + } + } + }); + /** + * The detune spread between the oscillators. If "count" is + * set to 3 oscillators and the "spread" is set to 40, + * the three oscillators would be detuned like this: [-20, 0, 20] + * for a total detune spread of 40 cents. See Tone.FatOscillator + * for more info. + * @memberOf Tone.OmniOscillator# + * @type {Cents} + * @name spread + */ + Object.defineProperty(Tone.OmniOscillator.prototype, 'spread', { + get: function () { + if (this._sourceType === OmniOscType.Fat) { + return this._oscillator.spread; + } + }, + set: function (spread) { + if (this._sourceType === OmniOscType.Fat) { + this._oscillator.spread = spread; + } + } + }); + /** + * The type of the modulator oscillator. Only if the oscillator + * is set to "am" or "fm" types. see. Tone.AMOscillator or Tone.FMOscillator + * for more info. + * @memberOf Tone.OmniOscillator# + * @type {String} + * @name modulationType + */ + Object.defineProperty(Tone.OmniOscillator.prototype, 'modulationType', { + get: function () { + if (this._sourceType === OmniOscType.FM || this._sourceType === OmniOscType.AM) { + return this._oscillator.modulationType; + } + }, + set: function (mType) { + if (this._sourceType === OmniOscType.FM || this._sourceType === OmniOscType.AM) { + this._oscillator.modulationType = mType; + } + } + }); + /** + * The modulation index which is in essence the depth or amount of the modulation. In other terms it is the + * ratio of the frequency of the modulating signal (mf) to the amplitude of the + * modulating signal (ma) -- as in ma/mf. + * See Tone.FMOscillator for more info. + * @type {Positive} + * @signal + * @name modulationIndex + */ + Object.defineProperty(Tone.OmniOscillator.prototype, 'modulationIndex', { + get: function () { + if (this._sourceType === OmniOscType.FM) { + return this._oscillator.modulationIndex; + } + } + }); + /** + * Harmonicity is the frequency ratio between the carrier and the modulator oscillators. + * A harmonicity of 1 gives both oscillators the same frequency. + * Harmonicity = 2 means a change of an octave. See Tone.AMOscillator or Tone.FMOscillator + * for more info. + * @memberOf Tone.OmniOscillator# + * @signal + * @type {Positive} + * @name harmonicity + */ + Object.defineProperty(Tone.OmniOscillator.prototype, 'harmonicity', { + get: function () { + if (this._sourceType === OmniOscType.FM || this._sourceType === OmniOscType.AM) { + return this._oscillator.harmonicity; + } + } + }); + /** + * The modulationFrequency Signal of the oscillator + * (only if the oscillator type is set to pwm). See + * Tone.PWMOscillator for more info. + * @memberOf Tone.OmniOscillator# + * @type {Frequency} + * @signal + * @name modulationFrequency + * @example + * var omniOsc = new Tone.OmniOscillator(440, "pwm"); + * //can access the modulationFrequency attribute only if type === "pwm" + * omniOsc.modulationFrequency.value = 0.2; + */ + Object.defineProperty(Tone.OmniOscillator.prototype, 'modulationFrequency', { + get: function () { + if (this._sourceType === OmniOscType.PWM) { + return this._oscillator.modulationFrequency; + } + } + }); + /** + * Clean up. + * @return {Tone.OmniOscillator} this + */ + Tone.OmniOscillator.prototype.dispose = function () { + Tone.Source.prototype.dispose.call(this); + this._writable([ + 'frequency', + 'detune' + ]); + this.detune.dispose(); + this.detune = null; + this.frequency.dispose(); + this.frequency = null; + this._oscillator.dispose(); + this._oscillator = null; + this._sourceType = null; + return this; + }; + return Tone.OmniOscillator; + }); + Module(function (Tone) { + + /** + * @class Base-class for all instruments + * + * @constructor + * @extends {Tone} + */ + Tone.Instrument = function (options) { + //get the defaults + options = this.defaultArg(options, Tone.Instrument.defaults); + /** + * The output and volume triming node + * @type {Tone.Volume} + * @private + */ + this._volume = this.output = new Tone.Volume(options.volume); + /** + * The volume of the output in decibels. + * @type {Decibels} + * @signal + * @example + * source.volume.value = -6; + */ + this.volume = this._volume.volume; + this._readOnly('volume'); + }; + Tone.extend(Tone.Instrument); + /** + * the default attributes + * @type {object} + */ + Tone.Instrument.defaults = { + /** the volume of the output in decibels */ + 'volume': 0 + }; + /** + * @abstract + * @param {string|number} note the note to trigger + * @param {Time} [time=now] the time to trigger the ntoe + * @param {number} [velocity=1] the velocity to trigger the note + */ + Tone.Instrument.prototype.triggerAttack = Tone.noOp; + /** + * @abstract + * @param {Time} [time=now] when to trigger the release + */ + Tone.Instrument.prototype.triggerRelease = Tone.noOp; + /** + * Trigger the attack and then the release after the duration. + * @param {Frequency} note The note to trigger. + * @param {Time} duration How long the note should be held for before + * triggering the release. + * @param {Time} [time=now] When the note should be triggered. + * @param {NormalRange} [velocity=1] The velocity the note should be triggered at. + * @returns {Tone.Instrument} this + * @example + * //trigger "C4" for the duration of an 8th note + * synth.triggerAttackRelease("C4", "8n"); + */ + Tone.Instrument.prototype.triggerAttackRelease = function (note, duration, time, velocity) { + if (this.isUndef(time)) { + time = this.now() + this.blockTime; + } else { + time = this.toSeconds(time); + } + duration = this.toSeconds(duration); + this.triggerAttack(note, time, velocity); + this.triggerRelease(time + duration); + return this; + }; + /** + * clean up + * @returns {Tone.Instrument} this + */ + Tone.Instrument.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._volume.dispose(); + this._volume = null; + this._writable(['volume']); + this.volume = null; + return this; + }; + return Tone.Instrument; + }); + Module(function (Tone) { + + /** + * @class This is an abstract base class for other monophonic instruments to + * extend. IMPORTANT: It does not make any sound on its own and + * shouldn't be directly instantiated. + * + * @constructor + * @abstract + * @extends {Tone.Instrument} + */ + Tone.Monophonic = function (options) { + //get the defaults + options = this.defaultArg(options, Tone.Monophonic.defaults); + Tone.Instrument.call(this, options); + /** + * The glide time between notes. + * @type {Time} + */ + this.portamento = options.portamento; + }; + Tone.extend(Tone.Monophonic, Tone.Instrument); + /** + * @static + * @const + * @type {Object} + */ + Tone.Monophonic.defaults = { 'portamento': 0 }; + /** + * Trigger the attack of the note optionally with a given velocity. + * + * + * @param {Frequency} note The note to trigger. + * @param {Time} [time=now] When the note should start. + * @param {number} [velocity=1] velocity The velocity scaler + * determines how "loud" the note + * will be triggered. + * @returns {Tone.Monophonic} this + * @example + * synth.triggerAttack("C4"); + * @example + * //trigger the note a half second from now at half velocity + * synth.triggerAttack("C4", "+0.5", 0.5); + */ + Tone.Monophonic.prototype.triggerAttack = function (note, time, velocity) { + if (this.isUndef(time)) { + time = this.now() + this.blockTime; + } else { + time = this.toSeconds(time); + } + this._triggerEnvelopeAttack(time, velocity); + this.setNote(note, time); + return this; + }; + /** + * Trigger the release portion of the envelope + * @param {Time} [time=now] If no time is given, the release happens immediatly + * @returns {Tone.Monophonic} this + * @example + * synth.triggerRelease(); + */ + Tone.Monophonic.prototype.triggerRelease = function (time) { + if (this.isUndef(time)) { + time = this.now() + this.blockTime; + } else { + time = this.toSeconds(time); + } + this._triggerEnvelopeRelease(time); + return this; + }; + /** + * override this method with the actual method + * @abstract + * @private + */ + Tone.Monophonic.prototype._triggerEnvelopeAttack = function () { + }; + /** + * override this method with the actual method + * @abstract + * @private + */ + Tone.Monophonic.prototype._triggerEnvelopeRelease = function () { + }; + /** + * Set the note at the given time. If no time is given, the note + * will set immediately. + * @param {Frequency} note The note to change to. + * @param {Time} [time=now] The time when the note should be set. + * @returns {Tone.Monophonic} this + * @example + * //change to F#6 in one quarter note from now. + * synth.setNote("F#6", "+4n"); + * @example + * //change to Bb4 right now + * synth.setNote("Bb4"); + */ + Tone.Monophonic.prototype.setNote = function (note, time) { + time = this.toSeconds(time); + if (this.portamento > 0) { + var currentNote = this.frequency.value; + this.frequency.setValueAtTime(currentNote, time); + var portTime = this.toSeconds(this.portamento); + this.frequency.exponentialRampToValueAtTime(note, time + portTime); + } else { + this.frequency.setValueAtTime(note, time); + } + return this; + }; + return Tone.Monophonic; + }); + Module(function (Tone) { + + /** + * @class Tone.Synth is composed simply of a Tone.OmniOscillator + * routed through a Tone.AmplitudeEnvelope. + * + * + * @constructor + * @extends {Tone.Monophonic} + * @param {Object} [options] the options available for the synth + * see defaults below + * @example + * var synth = new Tone.Synth().toMaster(); + * synth.triggerAttackRelease("C4", "8n"); + */ + Tone.Synth = function (options) { + //get the defaults + options = this.defaultArg(options, Tone.Synth.defaults); + Tone.Monophonic.call(this, options); + /** + * The oscillator. + * @type {Tone.OmniOscillator} + */ + this.oscillator = new Tone.OmniOscillator(options.oscillator); + /** + * The frequency control. + * @type {Frequency} + * @signal + */ + this.frequency = this.oscillator.frequency; + /** + * The detune control. + * @type {Cents} + * @signal + */ + this.detune = this.oscillator.detune; + /** + * The amplitude envelope. + * @type {Tone.AmplitudeEnvelope} + */ + this.envelope = new Tone.AmplitudeEnvelope(options.envelope); + //connect the oscillators to the output + this.oscillator.chain(this.envelope, this.output); + //start the oscillators + this.oscillator.start(); + this._readOnly([ + 'oscillator', + 'frequency', + 'detune', + 'envelope' + ]); + }; + Tone.extend(Tone.Synth, Tone.Monophonic); + /** + * @const + * @static + * @type {Object} + */ + Tone.Synth.defaults = { + 'oscillator': { 'type': 'triangle' }, + 'envelope': { + 'attack': 0.005, + 'decay': 0.1, + 'sustain': 0.3, + 'release': 1 + } + }; + /** + * start the attack portion of the envelope + * @param {Time} [time=now] the time the attack should start + * @param {number} [velocity=1] the velocity of the note (0-1) + * @returns {Tone.Synth} this + * @private + */ + Tone.Synth.prototype._triggerEnvelopeAttack = function (time, velocity) { + //the envelopes + this.envelope.triggerAttack(time, velocity); + return this; + }; + /** + * start the release portion of the envelope + * @param {Time} [time=now] the time the release should start + * @returns {Tone.Synth} this + * @private + */ + Tone.Synth.prototype._triggerEnvelopeRelease = function (time) { + this.envelope.triggerRelease(time); + return this; + }; + /** + * clean up + * @returns {Tone.Synth} this + */ + Tone.Synth.prototype.dispose = function () { + Tone.Monophonic.prototype.dispose.call(this); + this._writable([ + 'oscillator', + 'frequency', + 'detune', + 'envelope' + ]); + this.oscillator.dispose(); + this.oscillator = null; + this.envelope.dispose(); + this.envelope = null; + this.frequency = null; + this.detune = null; + return this; + }; + return Tone.Synth; + }); + Module(function (Tone) { + + /** + * @class AMSynth uses the output of one Tone.Synth to modulate the + * amplitude of another Tone.Synth. The harmonicity (the ratio between + * the two signals) affects the timbre of the output signal greatly. + * Read more about Amplitude Modulation Synthesis on + * [SoundOnSound](http://www.soundonsound.com/sos/mar00/articles/synthsecrets.htm). + * + * + * @constructor + * @extends {Tone.Monophonic} + * @param {Object} [options] the options available for the synth + * see defaults below + * @example + * var synth = new Tone.AMSynth().toMaster(); + * synth.triggerAttackRelease("C4", "4n"); + */ + Tone.AMSynth = function (options) { + options = this.defaultArg(options, Tone.AMSynth.defaults); + Tone.Monophonic.call(this, options); + /** + * The carrier voice. + * @type {Tone.Synth} + * @private + */ + this._carrier = new Tone.Synth(); + this._carrier.volume.value = -10; + /** + * The carrier's oscillator + * @type {Tone.Oscillator} + */ + this.oscillator = this._carrier.oscillator; + /** + * The carrier's envelope + * @type {Tone.Oscillator} + */ + this.envelope = this._carrier.envelope.set(options.envelope); + /** + * The modulator voice. + * @type {Tone.Synth} + * @private + */ + this._modulator = new Tone.Synth(); + this._modulator.volume.value = -10; + /** + * The modulator's oscillator which is applied + * to the amplitude of the oscillator + * @type {Tone.Oscillator} + */ + this.modulation = this._modulator.oscillator.set(options.modulation); + /** + * The modulator's envelope + * @type {Tone.Oscillator} + */ + this.modulationEnvelope = this._modulator.envelope.set(options.modulationEnvelope); + /** + * The frequency. + * @type {Frequency} + * @signal + */ + this.frequency = new Tone.Signal(440, Tone.Type.Frequency); + /** + * The detune in cents + * @type {Cents} + * @signal + */ + this.detune = new Tone.Signal(options.detune, Tone.Type.Cents); + /** + * Harmonicity is the ratio between the two voices. A harmonicity of + * 1 is no change. Harmonicity = 2 means a change of an octave. + * @type {Positive} + * @signal + * @example + * //pitch voice1 an octave below voice0 + * synth.harmonicity.value = 0.5; + */ + this.harmonicity = new Tone.Multiply(options.harmonicity); + this.harmonicity.units = Tone.Type.Positive; + /** + * convert the -1,1 output to 0,1 + * @type {Tone.AudioToGain} + * @private + */ + this._modulationScale = new Tone.AudioToGain(); + /** + * the node where the modulation happens + * @type {Tone.Gain} + * @private + */ + this._modulationNode = new Tone.Gain(); + //control the two voices frequency + this.frequency.connect(this._carrier.frequency); + this.frequency.chain(this.harmonicity, this._modulator.frequency); + this.detune.fan(this._carrier.detune, this._modulator.detune); + this._modulator.chain(this._modulationScale, this._modulationNode.gain); + this._carrier.chain(this._modulationNode, this.output); + this._readOnly([ + 'frequency', + 'harmonicity', + 'oscillator', + 'envelope', + 'modulation', + 'modulationEnvelope', + 'detune' + ]); + }; + Tone.extend(Tone.AMSynth, Tone.Monophonic); + /** + * @static + * @type {Object} + */ + Tone.AMSynth.defaults = { + 'harmonicity': 3, + 'detune': 0, + 'oscillator': { 'type': 'sine' }, + 'envelope': { + 'attack': 0.01, + 'decay': 0.01, + 'sustain': 1, + 'release': 0.5 + }, + 'modulation': { 'type': 'square' }, + 'modulationEnvelope': { + 'attack': 0.5, + 'decay': 0, + 'sustain': 1, + 'release': 0.5 + } + }; + /** + * trigger the attack portion of the note + * + * @param {Time} [time=now] the time the note will occur + * @param {NormalRange} [velocity=1] the velocity of the note + * @private + * @returns {Tone.AMSynth} this + */ + Tone.AMSynth.prototype._triggerEnvelopeAttack = function (time, velocity) { + //the port glide + time = this.toSeconds(time); + //the envelopes + this.envelope.triggerAttack(time, velocity); + this.modulationEnvelope.triggerAttack(time, velocity); + return this; + }; + /** + * trigger the release portion of the note + * + * @param {Time} [time=now] the time the note will release + * @private + * @returns {Tone.AMSynth} this + */ + Tone.AMSynth.prototype._triggerEnvelopeRelease = function (time) { + this.envelope.triggerRelease(time); + this.modulationEnvelope.triggerRelease(time); + return this; + }; + /** + * clean up + * @returns {Tone.AMSynth} this + */ + Tone.AMSynth.prototype.dispose = function () { + Tone.Monophonic.prototype.dispose.call(this); + this._writable([ + 'frequency', + 'harmonicity', + 'oscillator', + 'envelope', + 'modulation', + 'modulationEnvelope', + 'detune' + ]); + this._carrier.dispose(); + this._carrier = null; + this._modulator.dispose(); + this._modulator = null; + this.frequency.dispose(); + this.frequency = null; + this.detune.dispose(); + this.detune = null; + this.harmonicity.dispose(); + this.harmonicity = null; + this._modulationScale.dispose(); + this._modulationScale = null; + this._modulationNode.dispose(); + this._modulationNode = null; + this.oscillator = null; + this.envelope = null; + this.modulationEnvelope = null; + this.modulation = null; + return this; + }; + return Tone.AMSynth; + }); + Module(function (Tone) { + + /** + * @class Tone.MonoSynth is composed of one oscillator, one filter, and two envelopes. + * The amplitude of the Tone.Oscillator and the cutoff frequency of the + * Tone.Filter are controlled by Tone.Envelopes. + * + * + * @constructor + * @extends {Tone.Monophonic} + * @param {Object} [options] the options available for the synth + * see defaults below + * @example + * var synth = new Tone.MonoSynth({ + * "oscillator" : { + * "type" : "square" + * }, + * "envelope" : { + * "attack" : 0.1 + * } + * }).toMaster(); + * synth.triggerAttackRelease("C4", "8n"); + */ + Tone.MonoSynth = function (options) { + //get the defaults + options = this.defaultArg(options, Tone.MonoSynth.defaults); + Tone.Monophonic.call(this, options); + /** + * The oscillator. + * @type {Tone.OmniOscillator} + */ + this.oscillator = new Tone.OmniOscillator(options.oscillator); + /** + * The frequency control. + * @type {Frequency} + * @signal + */ + this.frequency = this.oscillator.frequency; + /** + * The detune control. + * @type {Cents} + * @signal + */ + this.detune = this.oscillator.detune; + /** + * The filter. + * @type {Tone.Filter} + */ + this.filter = new Tone.Filter(options.filter); + /** + * The filter envelope. + * @type {Tone.FrequencyEnvelope} + */ + this.filterEnvelope = new Tone.FrequencyEnvelope(options.filterEnvelope); + /** + * The amplitude envelope. + * @type {Tone.AmplitudeEnvelope} + */ + this.envelope = new Tone.AmplitudeEnvelope(options.envelope); + //connect the oscillators to the output + this.oscillator.chain(this.filter, this.envelope, this.output); + //start the oscillators + this.oscillator.start(); + //connect the filter envelope + this.filterEnvelope.connect(this.filter.frequency); + this._readOnly([ + 'oscillator', + 'frequency', + 'detune', + 'filter', + 'filterEnvelope', + 'envelope' + ]); + }; + Tone.extend(Tone.MonoSynth, Tone.Monophonic); + /** + * @const + * @static + * @type {Object} + */ + Tone.MonoSynth.defaults = { + 'frequency': 'C4', + 'detune': 0, + 'oscillator': { 'type': 'square' }, + 'filter': { + 'Q': 6, + 'type': 'lowpass', + 'rolloff': -24 + }, + 'envelope': { + 'attack': 0.005, + 'decay': 0.1, + 'sustain': 0.9, + 'release': 1 + }, + 'filterEnvelope': { + 'attack': 0.06, + 'decay': 0.2, + 'sustain': 0.5, + 'release': 2, + 'baseFrequency': 200, + 'octaves': 7, + 'exponent': 2 + } + }; + /** + * start the attack portion of the envelope + * @param {Time} [time=now] the time the attack should start + * @param {NormalRange} [velocity=1] the velocity of the note (0-1) + * @returns {Tone.MonoSynth} this + * @private + */ + Tone.MonoSynth.prototype._triggerEnvelopeAttack = function (time, velocity) { + //the envelopes + this.envelope.triggerAttack(time, velocity); + this.filterEnvelope.triggerAttack(time); + return this; + }; + /** + * start the release portion of the envelope + * @param {Time} [time=now] the time the release should start + * @returns {Tone.MonoSynth} this + * @private + */ + Tone.MonoSynth.prototype._triggerEnvelopeRelease = function (time) { + this.envelope.triggerRelease(time); + this.filterEnvelope.triggerRelease(time); + return this; + }; + /** + * clean up + * @returns {Tone.MonoSynth} this + */ + Tone.MonoSynth.prototype.dispose = function () { + Tone.Monophonic.prototype.dispose.call(this); + this._writable([ + 'oscillator', + 'frequency', + 'detune', + 'filter', + 'filterEnvelope', + 'envelope' + ]); + this.oscillator.dispose(); + this.oscillator = null; + this.envelope.dispose(); + this.envelope = null; + this.filterEnvelope.dispose(); + this.filterEnvelope = null; + this.filter.dispose(); + this.filter = null; + this.frequency = null; + this.detune = null; + return this; + }; + return Tone.MonoSynth; + }); + Module(function (Tone) { + + /** + * @class Tone.DuoSynth is a monophonic synth composed of two + * MonoSynths run in parallel with control over the + * frequency ratio between the two voices and vibrato effect. + * + * + * @constructor + * @extends {Tone.Monophonic} + * @param {Object} [options] the options available for the synth + * see defaults below + * @example + * var duoSynth = new Tone.DuoSynth().toMaster(); + * duoSynth.triggerAttackRelease("C4", "2n"); + */ + Tone.DuoSynth = function (options) { + options = this.defaultArg(options, Tone.DuoSynth.defaults); + Tone.Monophonic.call(this, options); + /** + * the first voice + * @type {Tone.MonoSynth} + */ + this.voice0 = new Tone.MonoSynth(options.voice0); + this.voice0.volume.value = -10; + /** + * the second voice + * @type {Tone.MonoSynth} + */ + this.voice1 = new Tone.MonoSynth(options.voice1); + this.voice1.volume.value = -10; + /** + * The vibrato LFO. + * @type {Tone.LFO} + * @private + */ + this._vibrato = new Tone.LFO(options.vibratoRate, -50, 50); + this._vibrato.start(); + /** + * the vibrato frequency + * @type {Frequency} + * @signal + */ + this.vibratoRate = this._vibrato.frequency; + /** + * the vibrato gain + * @type {Tone.Gain} + * @private + */ + this._vibratoGain = new Tone.Gain(options.vibratoAmount, Tone.Type.Positive); + /** + * The amount of vibrato + * @type {Positive} + * @signal + */ + this.vibratoAmount = this._vibratoGain.gain; + /** + * the frequency control + * @type {Frequency} + * @signal + */ + this.frequency = new Tone.Signal(440, Tone.Type.Frequency); + /** + * Harmonicity is the ratio between the two voices. A harmonicity of + * 1 is no change. Harmonicity = 2 means a change of an octave. + * @type {Positive} + * @signal + * @example + * //pitch voice1 an octave below voice0 + * duoSynth.harmonicity.value = 0.5; + */ + this.harmonicity = new Tone.Multiply(options.harmonicity); + this.harmonicity.units = Tone.Type.Positive; + //control the two voices frequency + this.frequency.connect(this.voice0.frequency); + this.frequency.chain(this.harmonicity, this.voice1.frequency); + this._vibrato.connect(this._vibratoGain); + this._vibratoGain.fan(this.voice0.detune, this.voice1.detune); + this.voice0.connect(this.output); + this.voice1.connect(this.output); + this._readOnly([ + 'voice0', + 'voice1', + 'frequency', + 'vibratoAmount', + 'vibratoRate' + ]); + }; + Tone.extend(Tone.DuoSynth, Tone.Monophonic); + /** + * @static + * @type {Object} + */ + Tone.DuoSynth.defaults = { + 'vibratoAmount': 0.5, + 'vibratoRate': 5, + 'harmonicity': 1.5, + 'voice0': { + 'volume': -10, + 'portamento': 0, + 'oscillator': { 'type': 'sine' }, + 'filterEnvelope': { + 'attack': 0.01, + 'decay': 0, + 'sustain': 1, + 'release': 0.5 + }, + 'envelope': { + 'attack': 0.01, + 'decay': 0, + 'sustain': 1, + 'release': 0.5 + } + }, + 'voice1': { + 'volume': -10, + 'portamento': 0, + 'oscillator': { 'type': 'sine' }, + 'filterEnvelope': { + 'attack': 0.01, + 'decay': 0, + 'sustain': 1, + 'release': 0.5 + }, + 'envelope': { + 'attack': 0.01, + 'decay': 0, + 'sustain': 1, + 'release': 0.5 + } + } + }; + /** + * start the attack portion of the envelopes + * + * @param {Time} [time=now] the time the attack should start + * @param {NormalRange} [velocity=1] the velocity of the note (0-1) + * @returns {Tone.DuoSynth} this + * @private + */ + Tone.DuoSynth.prototype._triggerEnvelopeAttack = function (time, velocity) { + time = this.toSeconds(time); + this.voice0.envelope.triggerAttack(time, velocity); + this.voice1.envelope.triggerAttack(time, velocity); + this.voice0.filterEnvelope.triggerAttack(time); + this.voice1.filterEnvelope.triggerAttack(time); + return this; + }; + /** + * start the release portion of the envelopes + * + * @param {Time} [time=now] the time the release should start + * @returns {Tone.DuoSynth} this + * @private + */ + Tone.DuoSynth.prototype._triggerEnvelopeRelease = function (time) { + this.voice0.triggerRelease(time); + this.voice1.triggerRelease(time); + return this; + }; + /** + * clean up + * @returns {Tone.DuoSynth} this + */ + Tone.DuoSynth.prototype.dispose = function () { + Tone.Monophonic.prototype.dispose.call(this); + this._writable([ + 'voice0', + 'voice1', + 'frequency', + 'vibratoAmount', + 'vibratoRate' + ]); + this.voice0.dispose(); + this.voice0 = null; + this.voice1.dispose(); + this.voice1 = null; + this.frequency.dispose(); + this.frequency = null; + this._vibratoGain.dispose(); + this._vibratoGain = null; + this._vibrato = null; + this.harmonicity.dispose(); + this.harmonicity = null; + this.vibratoAmount.dispose(); + this.vibratoAmount = null; + this.vibratoRate = null; + return this; + }; + return Tone.DuoSynth; + }); + Module(function (Tone) { + + /** + * @class FMSynth is composed of two Tone.Synths where one Tone.Synth modulates + * the frequency of a second Tone.Synth. A lot of spectral content + * can be explored using the modulationIndex parameter. Read more about + * frequency modulation synthesis on [SoundOnSound](http://www.soundonsound.com/sos/apr00/articles/synthsecrets.htm). + * + * + * @constructor + * @extends {Tone.Monophonic} + * @param {Object} [options] the options available for the synth + * see defaults below + * @example + * var fmSynth = new Tone.FMSynth().toMaster(); + * fmSynth.triggerAttackRelease("C5", "4n"); + */ + Tone.FMSynth = function (options) { + options = this.defaultArg(options, Tone.FMSynth.defaults); + Tone.Monophonic.call(this, options); + /** + * The carrier voice. + * @type {Tone.Synth} + * @private + */ + this._carrier = new Tone.Synth(options.carrier); + this._carrier.volume.value = -10; + /** + * The carrier's oscillator + * @type {Tone.Oscillator} + */ + this.oscillator = this._carrier.oscillator; + /** + * The carrier's envelope + * @type {Tone.Oscillator} + */ + this.envelope = this._carrier.envelope.set(options.envelope); + /** + * The modulator voice. + * @type {Tone.Synth} + * @private + */ + this._modulator = new Tone.Synth(options.modulator); + this._modulator.volume.value = -10; + /** + * The modulator's oscillator which is applied + * to the amplitude of the oscillator + * @type {Tone.Oscillator} + */ + this.modulation = this._modulator.oscillator.set(options.modulation); + /** + * The modulator's envelope + * @type {Tone.Oscillator} + */ + this.modulationEnvelope = this._modulator.envelope.set(options.modulationEnvelope); + /** + * The frequency control. + * @type {Frequency} + * @signal + */ + this.frequency = new Tone.Signal(440, Tone.Type.Frequency); + /** + * The detune in cents + * @type {Cents} + * @signal + */ + this.detune = new Tone.Signal(options.detune, Tone.Type.Cents); + /** + * Harmonicity is the ratio between the two voices. A harmonicity of + * 1 is no change. Harmonicity = 2 means a change of an octave. + * @type {Positive} + * @signal + * @example + * //pitch voice1 an octave below voice0 + * synth.harmonicity.value = 0.5; + */ + this.harmonicity = new Tone.Multiply(options.harmonicity); + this.harmonicity.units = Tone.Type.Positive; + /** + * The modulation index which essentially the depth or amount of the modulation. It is the + * ratio of the frequency of the modulating signal (mf) to the amplitude of the + * modulating signal (ma) -- as in ma/mf. + * @type {Positive} + * @signal + */ + this.modulationIndex = new Tone.Multiply(options.modulationIndex); + this.modulationIndex.units = Tone.Type.Positive; + /** + * the node where the modulation happens + * @type {GainNode} + * @private + */ + this._modulationNode = new Tone.Gain(0); + //control the two voices frequency + this.frequency.connect(this._carrier.frequency); + this.frequency.chain(this.harmonicity, this._modulator.frequency); + this.frequency.chain(this.modulationIndex, this._modulationNode); + this.detune.fan(this._carrier.detune, this._modulator.detune); + this._modulator.connect(this._modulationNode.gain); + this._modulationNode.connect(this._carrier.frequency); + this._carrier.connect(this.output); + this._readOnly([ + 'frequency', + 'harmonicity', + 'modulationIndex', + 'oscillator', + 'envelope', + 'modulation', + 'modulationEnvelope', + 'detune' + ]); + }; + Tone.extend(Tone.FMSynth, Tone.Monophonic); + /** + * @static + * @type {Object} + */ + Tone.FMSynth.defaults = { + 'harmonicity': 3, + 'modulationIndex': 10, + 'detune': 0, + 'oscillator': { 'type': 'sine' }, + 'envelope': { + 'attack': 0.01, + 'decay': 0.01, + 'sustain': 1, + 'release': 0.5 + }, + 'modulation': { 'type': 'square' }, + 'modulationEnvelope': { + 'attack': 0.5, + 'decay': 0, + 'sustain': 1, + 'release': 0.5 + } + }; + /** + * trigger the attack portion of the note + * + * @param {Time} [time=now] the time the note will occur + * @param {number} [velocity=1] the velocity of the note + * @returns {Tone.FMSynth} this + * @private + */ + Tone.FMSynth.prototype._triggerEnvelopeAttack = function (time, velocity) { + time = this.toSeconds(time); + //the envelopes + this.envelope.triggerAttack(time, velocity); + this.modulationEnvelope.triggerAttack(time); + return this; + }; + /** + * trigger the release portion of the note + * + * @param {Time} [time=now] the time the note will release + * @returns {Tone.FMSynth} this + * @private + */ + Tone.FMSynth.prototype._triggerEnvelopeRelease = function (time) { + time = this.toSeconds(time); + this.envelope.triggerRelease(time); + this.modulationEnvelope.triggerRelease(time); + return this; + }; + /** + * clean up + * @returns {Tone.FMSynth} this + */ + Tone.FMSynth.prototype.dispose = function () { + Tone.Monophonic.prototype.dispose.call(this); + this._writable([ + 'frequency', + 'harmonicity', + 'modulationIndex', + 'oscillator', + 'envelope', + 'modulation', + 'modulationEnvelope', + 'detune' + ]); + this._carrier.dispose(); + this._carrier = null; + this._modulator.dispose(); + this._modulator = null; + this.frequency.dispose(); + this.frequency = null; + this.detune.dispose(); + this.detune = null; + this.modulationIndex.dispose(); + this.modulationIndex = null; + this.harmonicity.dispose(); + this.harmonicity = null; + this._modulationNode.dispose(); + this._modulationNode = null; + this.oscillator = null; + this.envelope = null; + this.modulationEnvelope = null; + this.modulation = null; + return this; + }; + return Tone.FMSynth; + }); + Module(function (Tone) { + + /** + * @class Tone.MembraneSynth makes kick and tom sounds using a single oscillator + * with an amplitude envelope and frequency ramp. A Tone.OmniOscillator + * is routed through a Tone.AmplitudeEnvelope to the output. The drum + * quality of the sound comes from the frequency envelope applied + * during during Tone.MembraneSynth.triggerAttack(note). The frequency + * envelope starts at note * .octaves and ramps to + * note over the duration of .pitchDecay. + * + * @constructor + * @extends {Tone.Instrument} + * @param {Object} [options] the options available for the synth + * see defaults below + * @example + * var synth = new Tone.MembraneSynth().toMaster(); + * synth.triggerAttackRelease("C2", "8n"); + */ + Tone.MembraneSynth = function (options) { + options = this.defaultArg(options, Tone.MembraneSynth.defaults); + Tone.Instrument.call(this, options); + /** + * The oscillator. + * @type {Tone.OmniOscillator} + */ + this.oscillator = new Tone.OmniOscillator(options.oscillator).start(); + /** + * The amplitude envelope. + * @type {Tone.AmplitudeEnvelope} + */ + this.envelope = new Tone.AmplitudeEnvelope(options.envelope); + /** + * The number of octaves the pitch envelope ramps. + * @type {Positive} + */ + this.octaves = options.octaves; + /** + * The amount of time the frequency envelope takes. + * @type {Time} + */ + this.pitchDecay = options.pitchDecay; + this.oscillator.chain(this.envelope, this.output); + this._readOnly([ + 'oscillator', + 'envelope' + ]); + }; + Tone.extend(Tone.MembraneSynth, Tone.Instrument); + /** + * @static + * @type {Object} + */ + Tone.MembraneSynth.defaults = { + 'pitchDecay': 0.05, + 'octaves': 10, + 'oscillator': { 'type': 'sine' }, + 'envelope': { + 'attack': 0.001, + 'decay': 0.4, + 'sustain': 0.01, + 'release': 1.4, + 'attackCurve': 'exponential' + } + }; + /** + * Trigger the note at the given time with the given velocity. + * + * @param {Frequency} note the note + * @param {Time} [time=now] the time, if not given is now + * @param {number} [velocity=1] velocity defaults to 1 + * @returns {Tone.MembraneSynth} this + * @example + * kick.triggerAttack(60); + */ + Tone.MembraneSynth.prototype.triggerAttack = function (note, time, velocity) { + time = this.toSeconds(time); + note = this.toFrequency(note); + var maxNote = note * this.octaves; + this.oscillator.frequency.setValueAtTime(maxNote, time); + this.oscillator.frequency.exponentialRampToValueAtTime(note, time + this.toSeconds(this.pitchDecay)); + this.envelope.triggerAttack(time, velocity); + return this; + }; + /** + * Trigger the release portion of the note. + * + * @param {Time} [time=now] the time the note will release + * @returns {Tone.MembraneSynth} this + */ + Tone.MembraneSynth.prototype.triggerRelease = function (time) { + this.envelope.triggerRelease(time); + return this; + }; + /** + * Clean up. + * @returns {Tone.MembraneSynth} this + */ + Tone.MembraneSynth.prototype.dispose = function () { + Tone.Instrument.prototype.dispose.call(this); + this._writable([ + 'oscillator', + 'envelope' + ]); + this.oscillator.dispose(); + this.oscillator = null; + this.envelope.dispose(); + this.envelope = null; + return this; + }; + return Tone.MembraneSynth; + }); + Module(function (Tone) { + /** + * Inharmonic ratio of frequencies based on the Roland TR-808 + * Taken from https://ccrma.stanford.edu/papers/tr-808-cymbal-physically-informed-circuit-bendable-digital-model + * @private + * @static + * @type {Array} + */ + var inharmRatios = [ + 1, + 1.483, + 1.932, + 2.546, + 2.63, + 3.897 + ]; + /** + * @class A highly inharmonic and spectrally complex source with a highpass filter + * and amplitude envelope which is good for making metalophone sounds. Based + * on CymbalSynth by [@polyrhythmatic](https://github.com/polyrhythmatic). + * Inspiration from [Sound on Sound](http://www.soundonsound.com/sos/jul02/articles/synthsecrets0702.asp). + * + * @constructor + * @extends {Tone.Instrument} + * @param {Object} [options] The options availble for the synth + * see defaults below + */ + Tone.MetalSynth = function (options) { + options = this.defaultArg(options, Tone.MetalSynth.defaults); + Tone.Instrument.call(this, options); + /** + * The frequency of the cymbal + * @type {Frequency} + * @signal + */ + this.frequency = new Tone.Signal(options.frequency, Tone.Type.Frequency); + /** + * The array of FMOscillators + * @type {Array} + * @private + */ + this._oscillators = []; + /** + * The frequency multipliers + * @type {Array} + * @private + */ + this._freqMultipliers = []; + /** + * The amplitude for the body + * @type {Tone.Gain} + * @private + */ + this._amplitue = new Tone.Gain(0).connect(this.output); + /** + * highpass the output + * @type {Tone.Filter} + * @private + */ + this._highpass = new Tone.Filter({ + 'type': 'highpass', + 'Q': -3.0102999566398125 + }).connect(this._amplitue); + /** + * The number of octaves the highpass + * filter frequency ramps + * @type {Number} + * @private + */ + this._octaves = options.octaves; + /** + * Scale the body envelope + * for the bandpass + * @type {Tone.Scale} + * @private + */ + this._filterFreqScaler = new Tone.Scale(options.resonance, 7000); + /** + * The envelope which is connected both to the + * amplitude and highpass filter's cutoff frequency + * @type {Tone.Envelope} + */ + this.envelope = new Tone.Envelope({ + 'attack': options.envelope.attack, + 'attackCurve': 'linear', + 'decay': options.envelope.decay, + 'sustain': 0, + 'release': options.envelope.release + }).chain(this._filterFreqScaler, this._highpass.frequency); + this.envelope.connect(this._amplitue.gain); + for (var i = 0; i < inharmRatios.length; i++) { + var osc = new Tone.FMOscillator({ + 'type': 'square', + 'modulationType': 'square', + 'harmonicity': options.harmonicity, + 'modulationIndex': options.modulationIndex + }); + osc.connect(this._highpass).start(0); + this._oscillators[i] = osc; + var mult = new Tone.Multiply(inharmRatios[i]); + this._freqMultipliers[i] = mult; + this.frequency.chain(mult, osc.frequency); + } + //set the octaves + this.octaves = options.octaves; + }; + Tone.extend(Tone.MetalSynth, Tone.Instrument); + /** + * default values + * @static + * @const + * @type {Object} + */ + Tone.MetalSynth.defaults = { + 'frequency': 200, + 'envelope': { + 'attack': 0.001, + 'decay': 1.4, + 'release': 0.2 + }, + 'harmonicity': 5.1, + 'modulationIndex': 32, + 'resonance': 4000, + 'octaves': 1.5 + }; + /** + * Trigger the attack. + * @param {Time} time When the attack should be triggered. + * @param {NormalRange=1} velocity The velocity that the envelope should be triggered at. + * @return {Tone.MetalSynth} this + */ + Tone.MetalSynth.prototype.triggerAttack = function (time, vel) { + time = this.toSeconds(time); + vel = this.defaultArg(vel, 1); + this.envelope.triggerAttack(time, vel); + return this; + }; + /** + * Trigger the release of the envelope. + * @param {Time} time When the release should be triggered. + * @return {Tone.MetalSynth} this + */ + Tone.MetalSynth.prototype.triggerRelease = function (time) { + time = this.toSeconds(time); + this.envelope.triggerRelease(time); + return this; + }; + /** + * Trigger the attack and release of the envelope after the given + * duration. + * @param {Time} duration The duration before triggering the release + * @param {Time} time When the attack should be triggered. + * @param {NormalRange=1} velocity The velocity that the envelope should be triggered at. + * @return {Tone.MetalSynth} this + */ + Tone.MetalSynth.prototype.triggerAttackRelease = function (duration, time, velocity) { + time = this.toSeconds(time); + duration = this.toSeconds(duration); + this.triggerAttack(time, velocity); + this.triggerRelease(time + duration); + return this; + }; + /** + * The modulationIndex of the oscillators which make up the source. + * see Tone.FMOscillator.modulationIndex + * @memberOf Tone.MetalSynth# + * @type {Positive} + * @name modulationIndex + */ + Object.defineProperty(Tone.MetalSynth.prototype, 'modulationIndex', { + get: function () { + return this._oscillators[0].modulationIndex.value; + }, + set: function (val) { + for (var i = 0; i < this._oscillators.length; i++) { + this._oscillators[i].modulationIndex.value = val; + } + } + }); + /** + * The harmonicity of the oscillators which make up the source. + * see Tone.FMOscillator.harmonicity + * @memberOf Tone.MetalSynth# + * @type {Positive} + * @name harmonicity + */ + Object.defineProperty(Tone.MetalSynth.prototype, 'harmonicity', { + get: function () { + return this._oscillators[0].harmonicity.value; + }, + set: function (val) { + for (var i = 0; i < this._oscillators.length; i++) { + this._oscillators[i].harmonicity.value = val; + } + } + }); + /** + * The frequency of the highpass filter attached to the envelope + * @memberOf Tone.MetalSynth# + * @type {Frequency} + * @name resonance + */ + Object.defineProperty(Tone.MetalSynth.prototype, 'resonance', { + get: function () { + return this._filterFreqScaler.min; + }, + set: function (val) { + this._filterFreqScaler.min = val; + this.octaves = this._octaves; + } + }); + /** + * The number of octaves above the "resonance" frequency + * that the filter ramps during the attack/decay envelope + * @memberOf Tone.MetalSynth# + * @type {Number} + * @name octaves + */ + Object.defineProperty(Tone.MetalSynth.prototype, 'octaves', { + get: function () { + return this._octaves; + }, + set: function (octs) { + this._octaves = octs; + this._filterFreqScaler.max = this._filterFreqScaler.min * Math.pow(2, octs); + } + }); + /** + * Clean up + * @returns {Tone.MetalSynth} this + */ + Tone.MetalSynth.prototype.dispose = function () { + Tone.Instrument.prototype.dispose.call(this); + for (var i = 0; i < this._oscillators.length; i++) { + this._oscillators[i].dispose(); + this._freqMultipliers[i].dispose(); + } + this._oscillators = null; + this._freqMultipliers = null; + this.frequency.dispose(); + this.frequency = null; + this._filterFreqScaler.dispose(); + this._filterFreqScaler = null; + this._amplitue.dispose(); + this._amplitue = null; + this.envelope.dispose(); + this.envelope = null; + this._highpass.dispose(); + this._highpass = null; + }; + return Tone.MetalSynth; + }); + Module(function (Tone) { + + /** + * @class Tone.Noise is a noise generator. It uses looped noise buffers to save on performance. + * Tone.Noise supports the noise types: "pink", "white", and "brown". Read more about + * colors of noise on [Wikipedia](https://en.wikipedia.org/wiki/Colors_of_noise). + * + * @constructor + * @extends {Tone.Source} + * @param {string} type the noise type (white|pink|brown) + * @example + * //initialize the noise and start + * var noise = new Tone.Noise("pink").start(); + * + * //make an autofilter to shape the noise + * var autoFilter = new Tone.AutoFilter({ + * "frequency" : "8m", + * "min" : 800, + * "max" : 15000 + * }).connect(Tone.Master); + * + * //connect the noise + * noise.connect(autoFilter); + * //start the autofilter LFO + * autoFilter.start() + */ + Tone.Noise = function () { + var options = this.optionsObject(arguments, ['type'], Tone.Noise.defaults); + Tone.Source.call(this, options); + /** + * @private + * @type {AudioBufferSourceNode} + */ + this._source = null; + /** + * the buffer + * @private + * @type {AudioBuffer} + */ + this._buffer = null; + /** + * The playback rate of the noise. Affects + * the "frequency" of the noise. + * @type {Positive} + * @signal + */ + this._playbackRate = options.playbackRate; + this.type = options.type; + }; + Tone.extend(Tone.Noise, Tone.Source); + /** + * the default parameters + * + * @static + * @const + * @type {Object} + */ + Tone.Noise.defaults = { + 'type': 'white', + 'playbackRate': 1 + }; + /** + * The type of the noise. Can be "white", "brown", or "pink". + * @memberOf Tone.Noise# + * @type {string} + * @name type + * @example + * noise.type = "white"; + */ + Object.defineProperty(Tone.Noise.prototype, 'type', { + get: function () { + if (this._buffer === _whiteNoise) { + return 'white'; + } else if (this._buffer === _brownNoise) { + return 'brown'; + } else if (this._buffer === _pinkNoise) { + return 'pink'; + } + }, + set: function (type) { + if (this.type !== type) { + switch (type) { + case 'white': + this._buffer = _whiteNoise; + break; + case 'pink': + this._buffer = _pinkNoise; + break; + case 'brown': + this._buffer = _brownNoise; + break; + default: + throw new TypeError('Tone.Noise: invalid type: ' + type); + } + //if it's playing, stop and restart it + if (this.state === Tone.State.Started) { + var now = this.now() + this.blockTime; + //remove the listener + this._stop(now); + this._start(now); + } + } + } + }); + /** + * The playback rate of the noise. Affects + * the "frequency" of the noise. + * @type {Positive} + * @signal + */ + Object.defineProperty(Tone.Noise.prototype, 'playbackRate', { + get: function () { + return this._playbackRate; + }, + set: function (rate) { + this._playbackRate = rate; + if (this._source) { + this._source.playbackRate.value = rate; + } + } + }); + /** + * internal start method + * + * @param {Time} time + * @private + */ + Tone.Noise.prototype._start = function (time) { + this._source = this.context.createBufferSource(); + this._source.buffer = this._buffer; + this._source.loop = true; + this._source.playbackRate.value = this._playbackRate; + this._source.connect(this.output); + this._source.start(this.toSeconds(time), Math.random() * (this._buffer.duration - 0.001)); + }; + /** + * internal stop method + * + * @param {Time} time + * @private + */ + Tone.Noise.prototype._stop = function (time) { + if (this._source) { + this._source.stop(this.toSeconds(time)); + } + }; + /** + * Clean up. + * @returns {Tone.Noise} this + */ + Tone.Noise.prototype.dispose = function () { + Tone.Source.prototype.dispose.call(this); + if (this._source !== null) { + this._source.disconnect(); + this._source = null; + } + this._buffer = null; + return this; + }; + /////////////////////////////////////////////////////////////////////////// + // THE BUFFERS + // borrowed heavily from http://noisehack.com/generate-noise-web-audio-api/ + /////////////////////////////////////////////////////////////////////////// + /** + * static noise buffers + * + * @static + * @private + * @type {AudioBuffer} + */ + var _pinkNoise = null, _brownNoise = null, _whiteNoise = null; + Tone._initAudioContext(function (audioContext) { + var sampleRate = audioContext.sampleRate; + //four seconds per buffer + var bufferLength = sampleRate * 4; + //fill the buffers + _pinkNoise = function () { + var buffer = audioContext.createBuffer(2, bufferLength, sampleRate); + for (var channelNum = 0; channelNum < buffer.numberOfChannels; channelNum++) { + var channel = buffer.getChannelData(channelNum); + var b0, b1, b2, b3, b4, b5, b6; + b0 = b1 = b2 = b3 = b4 = b5 = b6 = 0; + for (var i = 0; i < bufferLength; i++) { + var white = Math.random() * 2 - 1; + b0 = 0.99886 * b0 + white * 0.0555179; + b1 = 0.99332 * b1 + white * 0.0750759; + b2 = 0.969 * b2 + white * 0.153852; + b3 = 0.8665 * b3 + white * 0.3104856; + b4 = 0.55 * b4 + white * 0.5329522; + b5 = -0.7616 * b5 - white * 0.016898; + channel[i] = b0 + b1 + b2 + b3 + b4 + b5 + b6 + white * 0.5362; + channel[i] *= 0.11; + // (roughly) compensate for gain + b6 = white * 0.115926; + } + } + return buffer; + }(); + _brownNoise = function () { + var buffer = audioContext.createBuffer(2, bufferLength, sampleRate); + for (var channelNum = 0; channelNum < buffer.numberOfChannels; channelNum++) { + var channel = buffer.getChannelData(channelNum); + var lastOut = 0; + for (var i = 0; i < bufferLength; i++) { + var white = Math.random() * 2 - 1; + channel[i] = (lastOut + 0.02 * white) / 1.02; + lastOut = channel[i]; + channel[i] *= 3.5; // (roughly) compensate for gain + } + } + return buffer; + }(); + _whiteNoise = function () { + var buffer = audioContext.createBuffer(2, bufferLength, sampleRate); + for (var channelNum = 0; channelNum < buffer.numberOfChannels; channelNum++) { + var channel = buffer.getChannelData(channelNum); + for (var i = 0; i < bufferLength; i++) { + channel[i] = Math.random() * 2 - 1; + } + } + return buffer; + }(); + }); + return Tone.Noise; + }); + Module(function (Tone) { + + /** + * @class Tone.NoiseSynth is composed of a noise generator (Tone.Noise), one filter (Tone.Filter), + * and two envelopes (Tone.Envelop). One envelope controls the amplitude + * of the noise and the other is controls the cutoff frequency of the filter. + * + * + * @constructor + * @extends {Tone.Instrument} + * @param {Object} [options] the options available for the synth + * see defaults below + * @example + * var noiseSynth = new Tone.NoiseSynth().toMaster(); + * noiseSynth.triggerAttackRelease("8n"); + */ + Tone.NoiseSynth = function (options) { + //get the defaults + options = this.defaultArg(options, Tone.NoiseSynth.defaults); + Tone.Instrument.call(this, options); + /** + * The noise source. + * @type {Tone.Noise} + * @example + * noiseSynth.set("noise.type", "brown"); + */ + this.noise = new Tone.Noise(); + /** + * The amplitude envelope. + * @type {Tone.AmplitudeEnvelope} + */ + this.envelope = new Tone.AmplitudeEnvelope(options.envelope); + //connect the noise to the output + this.noise.chain(this.envelope, this.output); + //start the noise + this.noise.start(); + this._readOnly([ + 'noise', + 'envelope' + ]); + }; + Tone.extend(Tone.NoiseSynth, Tone.Instrument); + /** + * @const + * @static + * @type {Object} + */ + Tone.NoiseSynth.defaults = { + 'noise': { 'type': 'white' }, + 'envelope': { + 'attack': 0.005, + 'decay': 0.1, + 'sustain': 0 + } + }; + /** + * Start the attack portion of the envelopes. Unlike other + * instruments, Tone.NoiseSynth doesn't have a note. + * @param {Time} [time=now] the time the attack should start + * @param {number} [velocity=1] the velocity of the note (0-1) + * @returns {Tone.NoiseSynth} this + * @example + * noiseSynth.triggerAttack(); + */ + Tone.NoiseSynth.prototype.triggerAttack = function (time, velocity) { + //the envelopes + this.envelope.triggerAttack(time, velocity); + return this; + }; + /** + * Start the release portion of the envelopes. + * @param {Time} [time=now] the time the release should start + * @returns {Tone.NoiseSynth} this + */ + Tone.NoiseSynth.prototype.triggerRelease = function (time) { + this.envelope.triggerRelease(time); + return this; + }; + /** + * Trigger the attack and then the release. + * @param {Time} duration the duration of the note + * @param {Time} [time=now] the time of the attack + * @param {number} [velocity=1] the velocity + * @returns {Tone.NoiseSynth} this + */ + Tone.NoiseSynth.prototype.triggerAttackRelease = function (duration, time, velocity) { + time = this.toSeconds(time); + duration = this.toSeconds(duration); + this.triggerAttack(time, velocity); + this.triggerRelease(time + duration); + return this; + }; + /** + * Clean up. + * @returns {Tone.NoiseSynth} this + */ + Tone.NoiseSynth.prototype.dispose = function () { + Tone.Instrument.prototype.dispose.call(this); + this._writable([ + 'noise', + 'envelope' + ]); + this.noise.dispose(); + this.noise = null; + this.envelope.dispose(); + this.envelope = null; + return this; + }; + return Tone.NoiseSynth; + }); + Module(function (Tone) { + + /** + * @class Karplus-String string synthesis. Often out of tune. + * Will change when the AudioWorkerNode is available across + * browsers. + * + * @constructor + * @extends {Tone.Instrument} + * @param {Object} [options] see the defaults + * @example + * var plucky = new Tone.PluckSynth().toMaster(); + * plucky.triggerAttack("C4"); + */ + Tone.PluckSynth = function (options) { + options = this.defaultArg(options, Tone.PluckSynth.defaults); + Tone.Instrument.call(this, options); + /** + * @type {Tone.Noise} + * @private + */ + this._noise = new Tone.Noise('pink'); + /** + * The amount of noise at the attack. + * Nominal range of [0.1, 20] + * @type {number} + */ + this.attackNoise = options.attackNoise; + /** + * the LFCF + * @type {Tone.LowpassCombFilter} + * @private + */ + this._lfcf = new Tone.LowpassCombFilter({ + 'resonance': options.resonance, + 'dampening': options.dampening + }); + /** + * The resonance control. + * @type {NormalRange} + * @signal + */ + this.resonance = this._lfcf.resonance; + /** + * The dampening control. i.e. the lowpass filter frequency of the comb filter + * @type {Frequency} + * @signal + */ + this.dampening = this._lfcf.dampening; + //connections + this._noise.connect(this._lfcf); + this._lfcf.connect(this.output); + this._readOnly([ + 'resonance', + 'dampening' + ]); + }; + Tone.extend(Tone.PluckSynth, Tone.Instrument); + /** + * @static + * @const + * @type {Object} + */ + Tone.PluckSynth.defaults = { + 'attackNoise': 1, + 'dampening': 4000, + 'resonance': 0.9 + }; + /** + * Trigger the note. + * @param {Frequency} note The note to trigger. + * @param {Time} [time=now] When the note should be triggered. + * @returns {Tone.PluckSynth} this + */ + Tone.PluckSynth.prototype.triggerAttack = function (note, time) { + note = this.toFrequency(note); + time = this.toSeconds(time); + var delayAmount = 1 / note; + this._lfcf.delayTime.setValueAtTime(delayAmount, time); + this._noise.start(time); + this._noise.stop(time + delayAmount * this.attackNoise); + return this; + }; + /** + * Clean up. + * @returns {Tone.PluckSynth} this + */ + Tone.PluckSynth.prototype.dispose = function () { + Tone.Instrument.prototype.dispose.call(this); + this._noise.dispose(); + this._lfcf.dispose(); + this._noise = null; + this._lfcf = null; + this._writable([ + 'resonance', + 'dampening' + ]); + this.dampening = null; + this.resonance = null; + return this; + }; + return Tone.PluckSynth; + }); + Module(function (Tone) { + + /** + * @class Tone.PolySynth handles voice creation and allocation for any + * instruments passed in as the second paramter. PolySynth is + * not a synthesizer by itself, it merely manages voices of + * one of the other types of synths, allowing any of the + * monophonic synthesizers to be polyphonic. + * + * @constructor + * @extends {Tone.Instrument} + * @param {number|Object} [polyphony=4] The number of voices to create + * @param {function} [voice=Tone.Synth] The constructor of the voices + * uses Tone.Synth by default. + * @example + * //a polysynth composed of 6 Voices of Synth + * var synth = new Tone.PolySynth(6, Tone.Synth).toMaster(); + * //set the attributes using the set interface + * synth.set("detune", -1200); + * //play a chord + * synth.triggerAttackRelease(["C4", "E4", "A4"], "4n"); + */ + Tone.PolySynth = function () { + Tone.Instrument.call(this); + var options = this.optionsObject(arguments, [ + 'polyphony', + 'voice' + ], Tone.PolySynth.defaults); + options = this.defaultArg(options, Tone.Instrument.defaults); + //max polyphony + options.polyphony = Math.min(Tone.PolySynth.MAX_POLYPHONY, options.polyphony); + /** + * the array of voices + * @type {Array} + */ + this.voices = new Array(options.polyphony); + /** + * The queue of voices with data about last trigger + * and the triggered note + * @private + * @type {Array} + */ + this._triggers = new Array(options.polyphony); + /** + * The detune in cents + * @type {Cents} + * @signal + */ + this.detune = new Tone.Signal(options.detune, Tone.Type.Cents); + this._readOnly('detune'); + //create the voices + for (var i = 0; i < options.polyphony; i++) { + var v = new options.voice(arguments[2], arguments[3]); + this.voices[i] = v; + v.connect(this.output); + if (v.hasOwnProperty('detune')) { + this.detune.connect(v.detune); + } + this._triggers[i] = { + release: -1, + note: null, + voice: v + }; + } + //set the volume initially + this.volume.value = options.volume; + }; + Tone.extend(Tone.PolySynth, Tone.Instrument); + /** + * the defaults + * @const + * @static + * @type {Object} + */ + Tone.PolySynth.defaults = { + 'polyphony': 4, + 'volume': 0, + 'detune': 0, + 'voice': Tone.Synth + }; + /** + * Trigger the attack portion of the note + * @param {Frequency|Array} notes The notes to play. Accepts a single + * Frequency or an array of frequencies. + * @param {Time} [time=now] The start time of the note. + * @param {number} [velocity=1] The velocity of the note. + * @returns {Tone.PolySynth} this + * @example + * //trigger a chord immediately with a velocity of 0.2 + * poly.triggerAttack(["Ab3", "C4", "F5"], undefined, 0.2); + */ + Tone.PolySynth.prototype.triggerAttack = function (notes, time, velocity) { + if (!Array.isArray(notes)) { + notes = [notes]; + } + time = this.toSeconds(time); + for (var i = 0; i < notes.length; i++) { + var val = notes[i]; + //trigger the oldest voice + var oldest = this._triggers[0]; + var oldestIndex = 0; + for (var j = 1; j < this._triggers.length; j++) { + if (this._triggers[j].release < oldest.release) { + oldest = this._triggers[j]; + oldestIndex = j; + } + } + oldest.release = Infinity; + oldest.note = JSON.stringify(val); + oldest.voice.triggerAttack(val, time, velocity); + } + return this; + }; + /** + * Trigger the attack and release after the specified duration + * + * @param {Frequency|Array} notes The notes to play. Accepts a single + * Frequency or an array of frequencies. + * @param {Time} duration the duration of the note + * @param {Time} [time=now] if no time is given, defaults to now + * @param {number} [velocity=1] the velocity of the attack (0-1) + * @returns {Tone.PolySynth} this + * @example + * //trigger a chord for a duration of a half note + * poly.triggerAttackRelease(["Eb3", "G4", "C5"], "2n"); + * @example + * //can pass in an array of durations as well + * poly.triggerAttackRelease(["Eb3", "G4", "C5"], ["2n", "4n", "4n"]); + */ + Tone.PolySynth.prototype.triggerAttackRelease = function (notes, duration, time, velocity) { + time = this.toSeconds(time); + this.triggerAttack(notes, time, velocity); + if (this.isArray(duration) && this.isArray(notes)) { + for (var i = 0; i < notes.length; i++) { + var d = duration[Math.min(i, duration.length - 1)]; + this.triggerRelease(notes[i], time + this.toSeconds(d)); + } + } else { + this.triggerRelease(notes, time + this.toSeconds(duration)); + } + return this; + }; + /** + * Trigger the release of the note. Unlike monophonic instruments, + * a note (or array of notes) needs to be passed in as the first argument. + * @param {Frequency|Array} notes The notes to play. Accepts a single + * Frequency or an array of frequencies. + * @param {Time} [time=now] When the release will be triggered. + * @returns {Tone.PolySynth} this + * @example + * poly.triggerRelease(["Ab3", "C4", "F5"], "+2n"); + */ + Tone.PolySynth.prototype.triggerRelease = function (notes, time) { + if (!Array.isArray(notes)) { + notes = [notes]; + } + time = this.toSeconds(time); + for (var i = 0; i < notes.length; i++) { + //get the voice + var stringified = JSON.stringify(notes[i]); + for (var v = 0; v < this._triggers.length; v++) { + var desc = this._triggers[v]; + if (desc.note === stringified && desc.release > time) { + desc.voice.triggerRelease(time); + desc.release = time; + } + } + } + return this; + }; + /** + * Set a member/attribute of the voices. + * @param {Object|string} params + * @param {number=} value + * @param {Time=} rampTime + * @returns {Tone.PolySynth} this + * @example + * poly.set({ + * "filter" : { + * "type" : "highpass" + * }, + * "envelope" : { + * "attack" : 0.25 + * } + * }); + */ + Tone.PolySynth.prototype.set = function (params, value, rampTime) { + for (var i = 0; i < this.voices.length; i++) { + this.voices[i].set(params, value, rampTime); + } + return this; + }; + /** + * Get the synth's attributes. Given no arguments get + * will return all available object properties and their corresponding + * values. Pass in a single attribute to retrieve or an array + * of attributes. The attribute strings can also include a "." + * to access deeper properties. + * @param {Array=} params the parameters to get, otherwise will return + * all available. + */ + Tone.PolySynth.prototype.get = function (params) { + return this.voices[0].get(params); + }; + /** + * Trigger the release portion of all the currently active voices. + * @param {Time} [time=now] When the notes should be released. + * @return {Tone.PolySynth} this + */ + Tone.PolySynth.prototype.releaseAll = function (time) { + time = this.toSeconds(time); + for (var i = 0; i < this._triggers.length; i++) { + var desc = this._triggers[i]; + if (desc.release > time) { + desc.release = time; + desc.voice.triggerRelease(time); + } + } + return this; + }; + /** + * Clean up. + * @returns {Tone.PolySynth} this + */ + Tone.PolySynth.prototype.dispose = function () { + Tone.Instrument.prototype.dispose.call(this); + for (var i = 0; i < this.voices.length; i++) { + this.voices[i].dispose(); + this.voices[i] = null; + } + this._writable('detune'); + this.detune.dispose(); + this.detune = null; + this.voices = null; + this._triggers = null; + return this; + }; + /** + * The maximum number of notes that can be allocated + * to a polysynth. + * @type {Number} + * @static + */ + Tone.PolySynth.MAX_POLYPHONY = 20; + return Tone.PolySynth; + }); + Module(function (Tone) { + + /** + * @class Tone.Player is an audio file player with start, loop, and stop functions. + * + * @constructor + * @extends {Tone.Source} + * @param {string|AudioBuffer} url Either the AudioBuffer or the url from + * which to load the AudioBuffer + * @param {function=} onload The function to invoke when the buffer is loaded. + * Recommended to use Tone.Buffer.on('load') instead. + * @example + * var player = new Tone.Player("./path/to/sample.mp3").toMaster(); + * //play as soon as the buffer is loaded + * player.autostart = true; + */ + Tone.Player = function (url) { + var options; + if (url instanceof Tone.Buffer) { + url = url.get(); + options = Tone.Player.defaults; + } else { + options = this.optionsObject(arguments, [ + 'url', + 'onload' + ], Tone.Player.defaults); + } + Tone.Source.call(this, options); + /** + * @private + * @type {AudioBufferSourceNode} + */ + this._source = null; + /** + * If the file should play as soon + * as the buffer is loaded. + * @type {boolean} + * @example + * //will play as soon as it's loaded + * var player = new Tone.Player({ + * "url" : "./path/to/sample.mp3", + * "autostart" : true, + * }).toMaster(); + */ + this.autostart = options.autostart; + /** + * the buffer + * @private + * @type {Tone.Buffer} + */ + this._buffer = new Tone.Buffer({ + 'url': options.url, + 'onload': this._onload.bind(this, options.onload), + 'reverse': options.reverse + }); + if (url instanceof AudioBuffer) { + this._buffer.set(url); + } + /** + * if the buffer should loop once it's over + * @type {boolean} + * @private + */ + this._loop = options.loop; + /** + * if 'loop' is true, the loop will start at this position + * @type {Time} + * @private + */ + this._loopStart = options.loopStart; + /** + * if 'loop' is true, the loop will end at this position + * @type {Time} + * @private + */ + this._loopEnd = options.loopEnd; + /** + * the playback rate + * @private + * @type {number} + */ + this._playbackRate = options.playbackRate; + /** + * Enabling retrigger will allow a player to be restarted + * before the the previous 'start' is done playing. Otherwise, + * successive calls to Tone.Player.start will only start + * the sample if it had played all the way through. + * @type {boolean} + */ + this.retrigger = options.retrigger; + }; + Tone.extend(Tone.Player, Tone.Source); + /** + * the default parameters + * @static + * @const + * @type {Object} + */ + Tone.Player.defaults = { + 'onload': Tone.noOp, + 'playbackRate': 1, + 'loop': false, + 'autostart': false, + 'loopStart': 0, + 'loopEnd': 0, + 'retrigger': false, + 'reverse': false + }; + /** + * Load the audio file as an audio buffer. + * Decodes the audio asynchronously and invokes + * the callback once the audio buffer loads. + * Note: this does not need to be called if a url + * was passed in to the constructor. Only use this + * if you want to manually load a new url. + * @param {string} url The url of the buffer to load. + * Filetype support depends on the + * browser. + * @param {function=} callback The function to invoke once + * the sample is loaded. + * @returns {Promise} + */ + Tone.Player.prototype.load = function (url, callback) { + return this._buffer.load(url, this._onload.bind(this, callback)); + }; + /** + * Internal callback when the buffer is loaded. + * @private + */ + Tone.Player.prototype._onload = function (callback) { + callback = this.defaultArg(callback, Tone.noOp); + callback(this); + if (this.autostart) { + this.start(); + } + }; + /** + * Play the buffer at the given startTime. Optionally add an offset + * and/or duration which will play the buffer from a position + * within the buffer for the given duration. + * + * @param {Time} [startTime=now] When the player should start. + * @param {Time} [offset=0] The offset from the beginning of the sample + * to start at. + * @param {Time=} duration How long the sample should play. If no duration + * is given, it will default to the full length + * of the sample (minus any offset) + * @returns {Tone.Player} this + * @memberOf Tone.Player# + * @method start + * @name start + */ + /** + * Internal start method + * @private + */ + Tone.Player.prototype._start = function (startTime, offset, duration) { + if (this._buffer.loaded) { + //if it's a loop the default offset is the loopstart point + if (this._loop) { + offset = this.defaultArg(offset, this._loopStart); + } else { + //otherwise the default offset is 0 + offset = this.defaultArg(offset, 0); + } + offset = this.toSeconds(offset); + //make sure it has a positive duration + duration = this.defaultArg(duration, Math.max(this._buffer.duration - offset, 0)); + duration = this.toSeconds(duration); + //the values in seconds + startTime = this.toSeconds(startTime); + //make the source + this._source = this.context.createBufferSource(); + this._source.buffer = this._buffer.get(); + //set the looping properties + if (this._loop) { + this._source.loop = this._loop; + this._source.loopStart = this.toSeconds(this._loopStart); + this._source.loopEnd = this.toSeconds(this._loopEnd); + } else { + //if it's not looping, set the state change at the end of the sample + this._state.setStateAtTime(Tone.State.Stopped, startTime + duration); + } + //and other properties + this._source.playbackRate.value = this._playbackRate; + this._source.connect(this.output); + //start it + if (this._loop) { + //modify the offset if it's greater than the loop time + var loopEnd = this._source.loopEnd || this._buffer.duration; + var loopStart = this._source.loopStart; + var loopDuration = loopEnd - loopStart; + if (offset > loopEnd) { + //move the offset back + while (offset > loopEnd) { + offset -= loopDuration; + } + } + this._source.start(startTime, offset); + } else { + this._source.start(startTime, offset, duration); + } + } else { + throw Error('Tone.Player: tried to start Player before the buffer was loaded'); + } + return this; + }; + /** + * Stop playback. + * @private + * @param {Time} [time=now] + * @returns {Tone.Player} this + */ + Tone.Player.prototype._stop = function (time) { + if (this._source) { + this._source.stop(this.toSeconds(time)); + this._source = null; + } + return this; + }; + /** + * Seek to a specific time in the player's buffer. If the + * source is no longer playing at that time, it will stop. + * If you seek to a time that + * @param {Time} offset The time to seek to. + * @param {Time=} time The time for the seek event to occur. + * @return {Tone.Player} this + * @example + * source.start(0.2); + * source.stop(0.4); + */ + Tone.Player.prototype.seek = function (offset, time) { + time = this.toSeconds(time); + if (this._state.getValueAtTime(time) === Tone.State.Started) { + offset = this.toSeconds(offset); + // if it's currently playing, stop it + this._stop(time); + //restart it at the given time + this._start(time, offset); + } + return this; + }; + /** + * Set the loop start and end. Will only loop if loop is + * set to true. + * @param {Time} loopStart The loop end time + * @param {Time} loopEnd The loop end time + * @returns {Tone.Player} this + * @example + * //loop 0.1 seconds of the file. + * player.setLoopPoints(0.2, 0.3); + * player.loop = true; + */ + Tone.Player.prototype.setLoopPoints = function (loopStart, loopEnd) { + this.loopStart = loopStart; + this.loopEnd = loopEnd; + return this; + }; + /** + * If loop is true, the loop will start at this position. + * @memberOf Tone.Player# + * @type {Time} + * @name loopStart + */ + Object.defineProperty(Tone.Player.prototype, 'loopStart', { + get: function () { + return this._loopStart; + }, + set: function (loopStart) { + this._loopStart = loopStart; + if (this._source) { + this._source.loopStart = this.toSeconds(loopStart); + } + } + }); + /** + * If loop is true, the loop will end at this position. + * @memberOf Tone.Player# + * @type {Time} + * @name loopEnd + */ + Object.defineProperty(Tone.Player.prototype, 'loopEnd', { + get: function () { + return this._loopEnd; + }, + set: function (loopEnd) { + this._loopEnd = loopEnd; + if (this._source) { + this._source.loopEnd = this.toSeconds(loopEnd); + } + } + }); + /** + * The audio buffer belonging to the player. + * @memberOf Tone.Player# + * @type {Tone.Buffer} + * @name buffer + */ + Object.defineProperty(Tone.Player.prototype, 'buffer', { + get: function () { + return this._buffer; + }, + set: function (buffer) { + this._buffer.set(buffer); + } + }); + /** + * If the buffer should loop once it's over. + * @memberOf Tone.Player# + * @type {boolean} + * @name loop + */ + Object.defineProperty(Tone.Player.prototype, 'loop', { + get: function () { + return this._loop; + }, + set: function (loop) { + this._loop = loop; + if (this._source) { + this._source.loop = loop; + } + } + }); + /** + * The playback speed. 1 is normal speed. This is not a signal because + * Safari and iOS currently don't support playbackRate as a signal. + * @memberOf Tone.Player# + * @type {number} + * @name playbackRate + */ + Object.defineProperty(Tone.Player.prototype, 'playbackRate', { + get: function () { + return this._playbackRate; + }, + set: function (rate) { + this._playbackRate = rate; + if (this._source) { + this._source.playbackRate.value = rate; + } + } + }); + /** + * The direction the buffer should play in + * @memberOf Tone.Player# + * @type {boolean} + * @name reverse + */ + Object.defineProperty(Tone.Player.prototype, 'reverse', { + get: function () { + return this._buffer.reverse; + }, + set: function (rev) { + this._buffer.reverse = rev; + } + }); + /** + * Dispose and disconnect. + * @return {Tone.Player} this + */ + Tone.Player.prototype.dispose = function () { + Tone.Source.prototype.dispose.call(this); + if (this._source !== null) { + this._source.disconnect(); + this._source = null; + } + this._buffer.dispose(); + this._buffer = null; + return this; + }; + return Tone.Player; + }); + Module(function (Tone) { + + /** + * @class Sampler wraps Tone.Player in an AmplitudeEnvelope. + * + * @constructor + * @extends {Tone.Instrument} + * @param {String} url the url of the audio file + * @param {Function=} onload The callback to invoke when the sample is loaded. + * @example + * var sampler = new Sampler("./audio/casio/A1.mp3", function(){ + * //repitch the sample down a half step + * sampler.triggerAttack(-1); + * }).toMaster(); + */ + Tone.Sampler = function () { + var options = this.optionsObject(arguments, [ + 'url', + 'onload' + ], Tone.Sampler.defaults); + Tone.Instrument.call(this, options); + /** + * The sample player. + * @type {Tone.Player} + */ + this.player = new Tone.Player(options.url, options.onload); + this.player.retrigger = true; + /** + * The amplitude envelope. + * @type {Tone.AmplitudeEnvelope} + */ + this.envelope = new Tone.AmplitudeEnvelope(options.envelope); + this.player.chain(this.envelope, this.output); + this._readOnly([ + 'player', + 'envelope' + ]); + this.loop = options.loop; + this.reverse = options.reverse; + }; + Tone.extend(Tone.Sampler, Tone.Instrument); + /** + * the default parameters + * @static + */ + Tone.Sampler.defaults = { + 'onload': Tone.noOp, + 'loop': false, + 'reverse': false, + 'envelope': { + 'attack': 0.001, + 'decay': 0, + 'sustain': 1, + 'release': 0.1 + } + }; + /** + * Trigger the start of the sample. + * @param {Interval} [pitch=0] The amount the sample should + * be repitched. + * @param {Time} [time=now] The time when the sample should start + * @param {NormalRange} [velocity=1] The velocity of the note + * @returns {Tone.Sampler} this + * @example + * sampler.triggerAttack(0, "+0.1", 0.5); + */ + Tone.Sampler.prototype.triggerAttack = function (pitch, time, velocity) { + time = this.toSeconds(time); + pitch = this.defaultArg(pitch, 0); + this.player.playbackRate = this.intervalToFrequencyRatio(pitch); + this.player.start(time); + this.envelope.triggerAttack(time, velocity); + return this; + }; + /** + * Start the release portion of the sample. Will stop the sample once the + * envelope has fully released. + * + * @param {Time} [time=now] The time when the note should release + * @returns {Tone.Sampler} this + * @example + * sampler.triggerRelease(); + */ + Tone.Sampler.prototype.triggerRelease = function (time) { + time = this.toSeconds(time); + this.envelope.triggerRelease(time); + this.player.stop(this.toSeconds(this.envelope.release) + time); + return this; + }; + /** + * Trigger the attack and then the release after the duration. + * @param {Interval} interval The interval in half-steps that the + * sample should be pitch shifted. + * @param {Time} duration How long the note should be held for before + * triggering the release. + * @param {Time} [time=now] When the note should be triggered. + * @param {NormalRange} [velocity=1] The velocity the note should be triggered at. + * @returns {Tone.Sampler} this + * @example + * //trigger the unpitched note for the duration of an 8th note + * synth.triggerAttackRelease(0, "8n"); + * @memberOf Tone.Sampler# + * @name triggerAttackRelease + * @method triggerAttackRelease + */ + /** + * If the output sample should loop or not. + * @memberOf Tone.Sampler# + * @type {number|string} + * @name loop + */ + Object.defineProperty(Tone.Sampler.prototype, 'loop', { + get: function () { + return this.player.loop; + }, + set: function (loop) { + this.player.loop = loop; + } + }); + /** + * The direction the buffer should play in + * @memberOf Tone.Sampler# + * @type {boolean} + * @name reverse + */ + Object.defineProperty(Tone.Sampler.prototype, 'reverse', { + get: function () { + return this.player.reverse; + }, + set: function (rev) { + this.player.reverse = rev; + } + }); + /** + * The buffer to play. + * @memberOf Tone.Sampler# + * @type {Tone.Buffer} + * @name buffer + */ + Object.defineProperty(Tone.Sampler.prototype, 'buffer', { + get: function () { + return this.player.buffer; + }, + set: function (buff) { + this.player.buffer = buff; + } + }); + /** + * Clean up. + * @returns {Tone.Sampler} this + */ + Tone.Sampler.prototype.dispose = function () { + Tone.Instrument.prototype.dispose.call(this); + this._writable([ + 'player', + 'envelope' + ]); + this.player.dispose(); + this.player = null; + this.envelope.dispose(); + this.envelope = null; + return this; + }; + return Tone.Sampler; + }); + Module(function (Tone) { + + /** + * @class Maps a NormalRange [0, 1] to an AudioRange [-1, 1]. + * See also Tone.AudioToGain. + * + * @extends {Tone.SignalBase} + * @constructor + * @example + * var g2a = new Tone.GainToAudio(); + */ + Tone.GainToAudio = function () { + /** + * @type {WaveShaperNode} + * @private + */ + this._norm = this.input = this.output = new Tone.WaveShaper(function (x) { + return Math.abs(x) * 2 - 1; + }); + }; + Tone.extend(Tone.GainToAudio, Tone.SignalBase); + /** + * clean up + * @returns {Tone.GainToAudio} this + */ + Tone.GainToAudio.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._norm.dispose(); + this._norm = null; + return this; + }; + return Tone.GainToAudio; + }); + Module(function (Tone) { + + /** + * @class Normalize takes an input min and max and maps it linearly to NormalRange [0,1] + * + * @extends {Tone.SignalBase} + * @constructor + * @param {number} inputMin the min input value + * @param {number} inputMax the max input value + * @example + * var norm = new Tone.Normalize(2, 4); + * var sig = new Tone.Signal(3).connect(norm); + * //output of norm is 0.5. + */ + Tone.Normalize = function (inputMin, inputMax) { + /** + * the min input value + * @type {number} + * @private + */ + this._inputMin = this.defaultArg(inputMin, 0); + /** + * the max input value + * @type {number} + * @private + */ + this._inputMax = this.defaultArg(inputMax, 1); + /** + * subtract the min from the input + * @type {Tone.Add} + * @private + */ + this._sub = this.input = new Tone.Add(0); + /** + * divide by the difference between the input and output + * @type {Tone.Multiply} + * @private + */ + this._div = this.output = new Tone.Multiply(1); + this._sub.connect(this._div); + this._setRange(); + }; + Tone.extend(Tone.Normalize, Tone.SignalBase); + /** + * The minimum value the input signal will reach. + * @memberOf Tone.Normalize# + * @type {number} + * @name min + */ + Object.defineProperty(Tone.Normalize.prototype, 'min', { + get: function () { + return this._inputMin; + }, + set: function (min) { + this._inputMin = min; + this._setRange(); + } + }); + /** + * The maximum value the input signal will reach. + * @memberOf Tone.Normalize# + * @type {number} + * @name max + */ + Object.defineProperty(Tone.Normalize.prototype, 'max', { + get: function () { + return this._inputMax; + }, + set: function (max) { + this._inputMax = max; + this._setRange(); + } + }); + /** + * set the values + * @private + */ + Tone.Normalize.prototype._setRange = function () { + this._sub.value = -this._inputMin; + this._div.value = 1 / (this._inputMax - this._inputMin); + }; + /** + * clean up + * @returns {Tone.Normalize} this + */ + Tone.Normalize.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._sub.dispose(); + this._sub = null; + this._div.dispose(); + this._div = null; + return this; + }; + return Tone.Normalize; + }); + Module(function (Tone) { + /** + * @class Wrapper around the native BufferSourceNode. + * @param {AudioBuffer|Tone.Buffer} buffer The buffer to play + * @param {Function} onended The callback to invoke when the + * buffer is done playing. + */ + Tone.BufferSource = function () { + var options = this.optionsObject(arguments, [ + 'buffer', + 'onended' + ], Tone.BufferSource.defaults); + /** + * The callback to invoke after the + * buffer source is done playing. + * @type {Function} + */ + this.onended = options.onended; + /** + * The time that the buffer was started. + * @type {Number} + * @private + */ + this._startTime = -1; + /** + * The time that the buffer is scheduled to stop. + * @type {Number} + * @private + */ + this._stopTime = -1; + /** + * The gain node which envelopes the BufferSource + * @type {Tone.Gain} + * @private + */ + this._gainNode = this.output = new Tone.Gain(); + /** + * The buffer source + * @type {AudioBufferSourceNode} + * @private + */ + this._source = this.context.createBufferSource(); + this._source.connect(this._gainNode); + /** + * The playbackRate of the buffer + * @type {Positive} + * @signal + */ + this.playbackRate = new Tone.Param(this._source.playbackRate, Tone.Type.Positive); + /** + * The fadeIn time of the amplitude envelope. + * @type {Time} + */ + this.fadeIn = options.fadeIn; + /** + * The fadeOut time of the amplitude envelope. + * @type {Time} + */ + this.fadeOut = options.fadeOut; + /** + * The value that the buffer ramps to + * @type {Gain} + * @private + */ + this._gain = 1; + /** + * The onended timeout + * @type {Number} + * @private + */ + this._onendedTimeout = -1; + //set the buffer initially + if (!this.isUndef(options.buffer)) { + this.buffer = options.buffer; + } + this.loop = options.loop; + }; + Tone.extend(Tone.BufferSource); + /** + * The defaults + * @const + * @type {Object} + */ + Tone.BufferSource.defaults = { + 'onended': Tone.noOp, + 'fadeIn': 0, + 'fadeOut': 0 + }; + /** + * Returns the playback state of the source, either "started" or "stopped". + * @type {Tone.State} + * @readOnly + * @memberOf Tone.BufferSource# + * @name state + */ + Object.defineProperty(Tone.BufferSource.prototype, 'state', { + get: function () { + var now = this.now(); + if (this._startTime !== -1 && now >= this._startTime && now < this._stopTime) { + return Tone.State.Started; + } else { + return Tone.State.Stopped; + } + } + }); + /** + * Start the buffer + * @param {Time} [startTime=now] When the player should start. + * @param {Time} [offset=0] The offset from the beginning of the sample + * to start at. + * @param {Time=} duration How long the sample should play. If no duration + * is given, it will default to the full length + * of the sample (minus any offset) + * @param {Gain} [gain=1] The gain to play the buffer back at. + * @param {Time=} fadeInTime The optional fadeIn ramp time. + * @return {Tone.BufferSource} this + */ + Tone.BufferSource.prototype.start = function (time, offset, duration, gain, fadeInTime) { + if (this._startTime !== -1) { + throw new Error('Tone.BufferSource: can only be started once.'); + } + if (this.buffer) { + time = this.toSeconds(time); + //if it's a loop the default offset is the loopstart point + if (this.loop) { + offset = this.defaultArg(offset, this.loopStart); + } else { + //otherwise the default offset is 0 + offset = this.defaultArg(offset, 0); + } + offset = this.toSeconds(offset); + //the values in seconds + time = this.toSeconds(time); + this._source.start(time, offset); + gain = this.defaultArg(gain, 1); + this._gain = gain; + //the fadeIn time + if (this.isUndef(fadeInTime)) { + fadeInTime = this.toSeconds(this.fadeIn); + } else { + fadeInTime = this.toSeconds(fadeInTime); + } + if (fadeInTime > 0) { + this._gainNode.gain.setValueAtTime(0, time); + this._gainNode.gain.linearRampToValueAtTime(this._gain, time + fadeInTime); + } else { + this._gainNode.gain.setValueAtTime(gain, time); + } + this._startTime = time + fadeInTime; + if (!this.isUndef(duration)) { + duration = this.defaultArg(duration, this.buffer.duration - offset); + duration = this.toSeconds(duration); + this.stop(time + duration + fadeInTime, fadeInTime); + } + } + return this; + }; + /** + * Stop the buffer. Optionally add a ramp time to fade the + * buffer out. + * @param {Time=} time The time the buffer should stop. + * @param {Time=} fadeOutTime How long the gain should fade out for + * @return {Tone.BufferSource} this + */ + Tone.BufferSource.prototype.stop = function (time, fadeOutTime) { + if (this.buffer) { + time = this.toSeconds(time); + //the fadeOut time + if (this.isUndef(fadeOutTime)) { + fadeOutTime = this.toSeconds(this.fadeOut); + } else { + fadeOutTime = this.toSeconds(fadeOutTime); + } + this._stopTime = time + fadeOutTime; + //cancel the end curve + this._gainNode.gain.cancelScheduledValues(this._startTime + this.sampleTime); + //set a new one + if (fadeOutTime > 0) { + this._gainNode.gain.setValueAtTime(this._gain, time); + this._gainNode.gain.linearRampToValueAtTime(0, time + fadeOutTime); + time += fadeOutTime; + } else { + this._gainNode.gain.setValueAtTime(0, time); + } + // fix for safari bug and old FF + if (!this.isNumber(this._source.playbackState) || this._source.playbackState === 2) { + this._source.stop(time); + } + clearTimeout(this._onendedTimeout); + this._onendedTimeout = setTimeout(this._onended.bind(this), (this._stopTime - this.now()) * 1000); + } + return this; + }; + /** + * Internal callback when the buffer is ended. + * Invokes `onended` and disposes the node. + * @private + */ + Tone.BufferSource.prototype._onended = function () { + this.onended(this); + this.dispose(); + }; + /** + * If loop is true, the loop will start at this position. + * @memberOf Tone.BufferSource# + * @type {Time} + * @name loopStart + */ + Object.defineProperty(Tone.BufferSource.prototype, 'loopStart', { + get: function () { + return this._source.loopStart; + }, + set: function (loopStart) { + this._source.loopStart = this.toSeconds(loopStart); + } + }); + /** + * If loop is true, the loop will end at this position. + * @memberOf Tone.BufferSource# + * @type {Time} + * @name loopEnd + */ + Object.defineProperty(Tone.BufferSource.prototype, 'loopEnd', { + get: function () { + return this._source.loopEnd; + }, + set: function (loopEnd) { + this._source.loopEnd = this.toSeconds(loopEnd); + } + }); + /** + * The audio buffer belonging to the player. + * @memberOf Tone.BufferSource# + * @type {AudioBuffer} + * @name buffer + */ + Object.defineProperty(Tone.BufferSource.prototype, 'buffer', { + get: function () { + if (this._source) { + return this._source.buffer; + } else { + return null; + } + }, + set: function (buffer) { + if (buffer instanceof Tone.Buffer) { + this._source.buffer = buffer.get(); + } else { + this._source.buffer = buffer; + } + } + }); + /** + * If the buffer should loop once it's over. + * @memberOf Tone.BufferSource# + * @type {boolean} + * @name loop + */ + Object.defineProperty(Tone.BufferSource.prototype, 'loop', { + get: function () { + return this._source.loop; + }, + set: function (loop) { + this._source.loop = loop; + } + }); + /** + * Clean up. + * @return {Tone.BufferSource} this + */ + Tone.BufferSource.prototype.dispose = function () { + this.onended = null; + if (this._source) { + this._source.disconnect(); + this._source = null; + } + if (this._gainNode) { + this._gainNode.dispose(); + this._gainNode = null; + } + this._startTime = -1; + this.playbackRate = null; + this.output = null; + clearTimeout(this._onendedTimeout); + return this; + }; + return Tone.BufferSource; + }); + Module(function (Tone) { + /** + * @class Tone.MultiPlayer is well suited for one-shots, multi-sampled instruments + * or any time you need to play a bunch of audio buffers. + * @param {Object|Array|Tone.Buffers} buffers The buffers which are available + * to the MultiPlayer + * @param {Function} onload The callback to invoke when all of the buffers are loaded. + * @extends {Tone} + * @example + * var multiPlayer = new MultiPlayer({ + * "kick" : "path/to/kick.mp3", + * "snare" : "path/to/snare.mp3", + * }, function(){ + * multiPlayer.start("kick"); + * }); + * @example + * //can also store the values in an array + * var multiPlayer = new MultiPlayer(["path/to/kick.mp3", "path/to/snare.mp3"], + * function(){ + * //if an array is passed in, the samples are referenced to by index + * multiPlayer.start(1); + * }); + */ + Tone.MultiPlayer = function () { + var options = this.optionsObject(arguments, [ + 'urls', + 'onload' + ], Tone.MultiPlayer.defaults); + if (options.urls instanceof Tone.Buffers) { + /** + * All the buffers belonging to the player. + * @type {Tone.Buffers} + */ + this.buffers = options.urls; + } else { + this.buffers = new Tone.Buffers(options.urls, options.onload); + } + /** + * Keeps track of the currently playing sources. + * @type {Object} + * @private + */ + this._activeSources = {}; + /** + * The fade in envelope which is applied + * to the beginning of the BufferSource + * @type {Time} + */ + this.fadeIn = options.fadeIn; + /** + * The fade out envelope which is applied + * to the end of the BufferSource + * @type {Time} + */ + this.fadeOut = options.fadeOut; + /** + * The output volume node + * @type {Tone.Volume} + * @private + */ + this._volume = this.output = new Tone.Volume(options.volume); + /** + * The volume of the output in decibels. + * @type {Decibels} + * @signal + * @example + * source.volume.value = -6; + */ + this.volume = this._volume.volume; + this._readOnly('volume'); + //make the output explicitly stereo + this._volume.output.output.channelCount = 2; + this._volume.output.output.channelCountMode = 'explicit'; + //mute initially + this.mute = options.mute; + }; + Tone.extend(Tone.MultiPlayer, Tone.Source); + /** + * The defaults + * @type {Object} + */ + Tone.MultiPlayer.defaults = { + 'onload': Tone.noOp, + 'fadeIn': 0, + 'fadeOut': 0 + }; + /** + * Make the source from the buffername + * @param {String} bufferName + * @return {Tone.BufferSource} + * @private + */ + Tone.MultiPlayer.prototype._makeSource = function (bufferName) { + var buffer; + if (this.isString(bufferName) || this.isNumber(bufferName)) { + buffer = this.buffers.get(bufferName).get(); + } else if (bufferName instanceof Tone.Buffer) { + buffer = bufferName.get(); + } else if (bufferName instanceof AudioBuffer) { + buffer = bufferName; + } + var source = new Tone.BufferSource(buffer).connect(this.output); + if (!this._activeSources.hasOwnProperty(bufferName)) { + this._activeSources[bufferName] = []; + } + this._activeSources[bufferName].push(source); + return source; + }; + /** + * Start a buffer by name. The `start` method allows a number of options + * to be passed in such as offset, interval, and gain. This is good for multi-sampled + * instruments and sound sprites where samples are repitched played back at different velocities. + * @param {String} bufferName The name of the buffer to start. + * @param {Time} time When to start the buffer. + * @param {Time} [offset=0] The offset into the buffer to play from. + * @param {Time=} duration How long to play the buffer for. + * @param {Interval} [pitch=0] The interval to repitch the buffer. + * @param {Gain} [gain=1] The gain to play the sample at. + * @return {Tone.MultiPlayer} this + */ + Tone.MultiPlayer.prototype.start = function (bufferName, time, offset, duration, pitch, gain) { + time = this.toSeconds(time); + var source = this._makeSource(bufferName); + source.start(time, offset, duration, this.defaultArg(gain, 1), this.fadeIn); + if (duration) { + source.stop(time + this.toSeconds(duration), this.fadeOut); + } + pitch = this.defaultArg(pitch, 0); + source.playbackRate.value = this.intervalToFrequencyRatio(pitch); + return this; + }; + /** + * Start a looping buffer by name. Similar to `start`, but the buffer + * is looped instead of played straight through. Can still be stopped with `stop`. + * @param {String} bufferName The name of the buffer to start. + * @param {Time} time When to start the buffer. + * @param {Time} [offset=0] The offset into the buffer to play from. + * @param {Time=} loopStart The start of the loop. + * @param {Time=} loopEnd The end of the loop. + * @param {Interval} [pitch=0] The interval to repitch the buffer. + * @param {Gain} [gain=1] The gain to play the sample at. + * @return {Tone.MultiPlayer} this + */ + Tone.MultiPlayer.prototype.startLoop = function (bufferName, time, offset, loopStart, loopEnd, pitch, gain) { + time = this.toSeconds(time); + var source = this._makeSource(bufferName); + source.loop = true; + source.loopStart = this.toSeconds(this.defaultArg(loopStart, 0)); + source.loopEnd = this.toSeconds(this.defaultArg(loopEnd, 0)); + source.start(time, offset, undefined, this.defaultArg(gain, 1), this.fadeIn); + pitch = this.defaultArg(pitch, 0); + source.playbackRate.value = this.intervalToFrequencyRatio(pitch); + return this; + }; + /** + * Stop the first played instance of the buffer name. + * @param {String} bufferName The buffer to stop. + * @param {Time=} time When to stop the buffer + * @return {Tone.MultiPlayer} this + */ + Tone.MultiPlayer.prototype.stop = function (bufferName, time) { + if (this._activeSources[bufferName] && this._activeSources[bufferName].length) { + time = this.toSeconds(time); + this._activeSources[bufferName].shift().stop(time, this.fadeOut); + } else { + throw new Error('Tone.MultiPlayer: cannot stop a buffer that hasn\'t been started or is already stopped'); + } + return this; + }; + /** + * Stop all currently playing buffers at the given time. + * @param {Time=} time When to stop the buffers. + * @return {Tone.MultiPlayer} this + */ + Tone.MultiPlayer.prototype.stopAll = function (time) { + time = this.toSeconds(time); + for (var bufferName in this._activeSources) { + var sources = this._activeSources[bufferName]; + for (var i = 0; i < sources.length; i++) { + sources[i].stop(time); + } + } + return this; + }; + /** + * Add another buffer to the available buffers. + * @param {String} name The name to that the buffer is refered + * to in start/stop methods. + * @param {String|Tone.Buffer} url The url of the buffer to load + * or the buffer. + * @param {Function} callback The function to invoke after the buffer is loaded. + */ + Tone.MultiPlayer.prototype.add = function (name, url, callback) { + this.buffers.add(name, url, callback); + return this; + }; + /** + * Returns the playback state of the source. "started" + * if there are any buffers playing. "stopped" otherwise. + * @type {Tone.State} + * @readOnly + * @memberOf Tone.MultiPlayer# + * @name state + */ + Object.defineProperty(Tone.MultiPlayer.prototype, 'state', { + get: function () { + return this._activeSources.length > 0 ? Tone.State.Started : Tone.State.Stopped; + } + }); + /** + * Mute the output. + * @memberOf Tone.MultiPlayer# + * @type {boolean} + * @name mute + * @example + * //mute the output + * source.mute = true; + */ + Object.defineProperty(Tone.MultiPlayer.prototype, 'mute', { + get: function () { + return this._volume.mute; + }, + set: function (mute) { + this._volume.mute = mute; + } + }); + /** + * Clean up. + * @return {Tone.MultiPlayer} this + */ + Tone.MultiPlayer.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this._volume.dispose(); + this._volume = null; + this._writable('volume'); + this.volume = null; + for (var bufferName in this._activeSources) { + this._activeSources[bufferName].forEach(function (source) { + source.dispose(); + }); + } + this.buffers.dispose(); + this.buffers = null; + this._activeSources = null; + return this; + }; + return Tone.MultiPlayer; + }); + Module(function (Tone) { + /** + * @class Tone.GrainPlayer implements [granular synthesis](https://en.wikipedia.org/wiki/Granular_synthesis). + * Granular Synthesis enables you to adjust pitch and playback rate independently. The grainSize is the + * amount of time each small chunk of audio is played for and the overlap is the + * amount of crossfading transition time between successive grains. + * @extends {Tone} + * @param {String|Tone.Buffer} url The url to load, or the Tone.Buffer to play. + * @param {Function=} callback The callback to invoke after the url is loaded. + */ + Tone.GrainPlayer = function () { + var options = this.optionsObject(arguments, [ + 'url', + 'onload' + ], Tone.GrainPlayer.defaults); + Tone.Source.call(this); + /** + * The audio buffer belonging to the player. + * @type {Tone.Buffer} + */ + this.buffer = new Tone.Buffer(options.url, options.onload); + /** + * Plays the buffer with a small envelope + * @type {Tone.MultiPlayer} + * @private + */ + this._player = this.output = new Tone.MultiPlayer(); + /** + * Create a repeating tick to schedule + * the grains. + * @type {Tone.Clock} + * @private + */ + this._clock = new Tone.Clock(this._tick.bind(this), 1); + /** + * @type {Number} + * @private + */ + this._loopStart = 0; + /** + * @type {Number} + * @private + */ + this._loopEnd = 0; + /** + * @type {Number} + * @private + */ + this._playbackRate = options.playbackRate; + /** + * @type {Number} + * @private + */ + this._grainSize = options.grainSize; + /** + * @private + * @type {Number} + */ + this._overlap = options.overlap; + /** + * Adjust the pitch independently of the playbackRate. + * @type {Cents} + */ + this.detune = options.detune; + /** + * The amount of time randomly added + * or subtracted from the grain's offset + * @type {Time} + */ + this.drift = options.drift; + //setup + this.overlap = options.overlap; + this.loop = options.loop; + this.playbackRate = options.playbackRate; + this.grainSize = options.grainSize; + this.loopStart = options.loopStart; + this.loopEnd = options.loopEnd; + this.reverse = options.reverse; + }; + Tone.extend(Tone.GrainPlayer, Tone.Source); + /** + * the default parameters + * @static + * @const + * @type {Object} + */ + Tone.GrainPlayer.defaults = { + 'onload': Tone.noOp, + 'overlap': 0.1, + 'grainSize': 0.2, + 'drift': 0, + 'playbackRate': 1, + 'detune': 0, + 'loop': false, + 'loopStart': 0, + 'loopEnd': 0, + 'reverse': false + }; + /** + * Play the buffer at the given startTime. Optionally add an offset + * from the start of the buffer to play from. + * + * @param {Time} [startTime=now] When the player should start. + * @param {Time} [offset=0] The offset from the beginning of the sample + * to start at. + * @return {Tone.GrainPlayer} this + */ + /** + * Internal start method + * @param {Time} time + * @param {Time} offset + * @private + */ + Tone.GrainPlayer.prototype._start = function (time, offset) { + offset = this.defaultArg(offset, 0); + offset = this.toSeconds(offset); + time = this.toSeconds(time); + this._offset = offset; + this._clock.start(time); + }; + /** + * Internal start method + * @param {Time} time + * @private + */ + Tone.GrainPlayer.prototype._stop = function (time) { + this._clock.stop(time); + this._player.stop(this.buffer, time); + this._offset = 0; + }; + /** + * Invoked on each clock tick. scheduled a new + * grain at this time. + * @param {Time} time + * @private + */ + Tone.GrainPlayer.prototype._tick = function (time) { + var bufferDuration = this.buffer.duration; + if (this.loop && this._loopEnd > 0) { + bufferDuration = this._loopEnd; + } + var drift = (Math.random() * 2 - 1) * this.drift; + var offset = this._offset - this._overlap + drift; + var detune = this.detune / 100; + var originalFadeIn = this._player.fadeIn; + if (this.loop && this._offset > bufferDuration) { + //play the end + var endSegmentDuration = this._offset - bufferDuration; + this._player.start(this.buffer, time, offset, endSegmentDuration + this._overlap, detune); + //and play the beginning + offset = this._offset % bufferDuration; + this._offset = this._loopStart; + this._player.fadeIn = 0; + this._player.start(this.buffer, time + endSegmentDuration, this._offset, offset + this._overlap, detune); + } else if (this._offset > bufferDuration) { + //set the state to stopped. + this.stop(time); + } else { + if (offset < 0) { + this._player.fadeIn = Math.max(this._player.fadeIn + offset, 0); + offset = 0; + } + this._player.start(this.buffer, time, offset, this.grainSize + this._overlap, detune); + } + this._player.fadeIn = originalFadeIn; + //increment the offset + var duration = this._clock._nextTick - time; + this._offset += duration * this._playbackRate; + }; + /** + * Jump to a specific time and play it. + * @param {Time} offset The offset to jump to. + * @param {Time=} time When to make the jump. + * @return {[type]} [description] + */ + Tone.GrainPlayer.prototype.scrub = function (offset, time) { + this._offset = this.toSeconds(offset); + this._tick(this.toSeconds(time)); + return this; + }; + /** + * The playback rate of the sample + * @memberOf Tone.GrainPlayer# + * @type {Positive} + * @name playbackRate + */ + Object.defineProperty(Tone.GrainPlayer.prototype, 'playbackRate', { + get: function () { + return this._playbackRate; + }, + set: function (rate) { + this._playbackRate = rate; + this.grainSize = this._grainSize; + } + }); + /** + * The loop start time. + * @memberOf Tone.GrainPlayer# + * @type {Time} + * @name loopStart + */ + Object.defineProperty(Tone.GrainPlayer.prototype, 'loopStart', { + get: function () { + return this._loopStart; + }, + set: function (time) { + this._loopStart = this.toSeconds(time); + } + }); + /** + * The loop end time. + * @memberOf Tone.GrainPlayer# + * @type {Time} + * @name loopEnd + */ + Object.defineProperty(Tone.GrainPlayer.prototype, 'loopEnd', { + get: function () { + return this._loopEnd; + }, + set: function (time) { + this._loopEnd = this.toSeconds(time); + } + }); + /** + * The direction the buffer should play in + * @memberOf Tone.GrainPlayer# + * @type {boolean} + * @name reverse + */ + Object.defineProperty(Tone.GrainPlayer.prototype, 'reverse', { + get: function () { + return this.buffer.reverse; + }, + set: function (rev) { + this.buffer.reverse = rev; + } + }); + /** + * The size of each chunk of audio that the + * buffer is chopped into and played back at. + * @memberOf Tone.GrainPlayer# + * @type {Time} + * @name grainSize + */ + Object.defineProperty(Tone.GrainPlayer.prototype, 'grainSize', { + get: function () { + return this._grainSize; + }, + set: function (size) { + this._grainSize = this.toSeconds(size); + this._clock.frequency.value = this._playbackRate / this._grainSize; + } + }); + /** + * This is the duration of the cross-fade between + * sucessive grains. + * @memberOf Tone.GrainPlayer# + * @type {Time} + * @name overlap + */ + Object.defineProperty(Tone.GrainPlayer.prototype, 'overlap', { + get: function () { + return this._overlap; + }, + set: function (time) { + time = this.toSeconds(time); + this._overlap = time; + if (this._overlap < 0) { + this._player.fadeIn = 0.01; + this._player.fadeOut = 0.01; + } else { + this._player.fadeIn = time; + this._player.fadeOut = time; + } + } + }); + /** + * Clean up + * @return {Tone.GrainPlayer} this + */ + Tone.GrainPlayer.prototype.dispose = function () { + Tone.Source.prototype.dispose.call(this); + this.buffer.dispose(); + this.buffer = null; + this._player.dispose(); + this._player = null; + this._clock.dispose(); + this._clock = null; + return this; + }; + return Tone.GrainPlayer; + }); + Module(function (Tone) { + + /** + * @class Tone.UserMedia uses MediaDevices.getUserMedia to open up + * and external microphone or audio input. Check + * [MediaDevices API Support](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia) + * to see which browsers are supported. Access to an external input + * is limited to secure (HTTPS) connections. + * + * @constructor + * @extends {Tone} + * @param {Decibels=} volume The level of the input + * @example + * //list the inputs and open the third one + * var motu = new Tone.UserMedia(); + * + * //opening the input asks the user to activate their mic + * motu.open().then(function(){ + * //opening is activates the microphone + * //starting lets audio through + * motu.start(10); + * }); + */ + Tone.UserMedia = function () { + var options = this.optionsObject(arguments, ['volume'], Tone.UserMedia.defaults); + /** + * The MediaStreamNode + * @type {MediaStreamAudioSourceNode} + * @private + */ + this._mediaStream = null; + /** + * The media stream created by getUserMedia. + * @type {LocalMediaStream} + * @private + */ + this._stream = null; + /** + * The open device + * @type {MediaDeviceInfo} + * @private + */ + this._device = null; + /** + * The output volume node + * @type {Tone.Volume} + * @private + */ + this._volume = this.output = new Tone.Volume(options.volume); + /** + * The volume of the output in decibels. + * @type {Decibels} + * @signal + * @example + * input.volume.value = -6; + */ + this.volume = this._volume.volume; + this._readOnly('volume'); + this.mute = options.mute; + }; + Tone.extend(Tone.UserMedia); + /** + * the default parameters + * @type {Object} + */ + Tone.UserMedia.defaults = { + 'volume': 0, + 'mute': false + }; + /** + * Open the media stream. If a string is passed in, it is assumed + * to be the label or id of the stream, if a number is passed in, + * it is the input number of the stream. + * @param {String|Number} [labelOrId="default"] The label or id of the audio input media device. + * With no argument, the default stream is opened. + * @return {Promise} The promise is resolved when the stream is open. + */ + Tone.UserMedia.prototype.open = function (labelOrId) { + labelOrId = this.defaultArg(labelOrId, 'default'); + return this.enumerateDevices().then(function (devices) { + var device; + if (this.isNumber(labelOrId)) { + device = devices[labelOrId]; + } else { + device = devices.find(function (device) { + return device.label === labelOrId || device.deviceId === labelOrId; + }); + if (!device) { + //otherwise just take the first one + device = devices[0]; + } + } + //didn't find a matching device + if (!device) { + throw new Error('Tone.UserMedia: no matching audio inputs.'); + } + this._device = device; + //do getUserMedia + var constraints = { + audio: { + 'deviceId': device.deviceId, + 'echoCancellation': false, + 'sampleRate': this.context.sampleRate + } + }; + return navigator.mediaDevices.getUserMedia(constraints).then(function (stream) { + //start a new source only if the previous one is closed + if (!this._stream) { + this._stream = stream; + //Wrap a MediaStreamSourceNode around the live input stream. + this._mediaStream = this.context.createMediaStreamSource(stream); + //Connect the MediaStreamSourceNode to a gate gain node + this._mediaStream.connect(this.output); + } + return this; + }.bind(this)); + }.bind(this)); + }; + /** + * Close the media stream + * @return {Tone.UserMedia} this + */ + Tone.UserMedia.prototype.close = function () { + if (this._stream) { + this._stream.getAudioTracks().forEach(function (track) { + track.stop(); + }); + this._stream = null; + //remove the old media stream + this._mediaStream.disconnect(); + this._mediaStream = null; + } + this._device = null; + return this; + }; + /** + * Returns a promise which resolves with the list of audio input devices available. + * @return {Promise} The promise that is resolved with the devices + * @example + * extInput.enumerateDevices().then(function(devices){ + * console.log(devices) + * }) + */ + Tone.UserMedia.prototype.enumerateDevices = function () { + return navigator.mediaDevices.enumerateDevices().then(function (devices) { + return devices.filter(function (device) { + return device.kind === 'audioinput'; + }); + }); + }; + /** + * Returns the playback state of the source, "started" when the microphone is open + * and "stopped" when the mic is closed. + * @type {Tone.State} + * @readOnly + * @memberOf Tone.UserMedia# + * @name state + */ + Object.defineProperty(Tone.UserMedia.prototype, 'state', { + get: function () { + return this._stream && this._stream.active ? Tone.State.Started : Tone.State.Stopped; + } + }); + /** + * Returns an identifier for the represented device that is + * persisted across sessions. It is un-guessable by other applications and + * unique to the origin of the calling application. It is reset when the + * user clears cookies (for Private Browsing, a different identifier is + * used that is not persisted across sessions). Returns undefined when the + * device is not open. + * @type {String} + * @readOnly + * @memberOf Tone.UserMedia# + * @name deviceId + */ + Object.defineProperty(Tone.UserMedia.prototype, 'deviceId', { + get: function () { + if (this._device) { + return this._device.deviceId; + } + } + }); + /** + * Returns a group identifier. Two devices have the + * same group identifier if they belong to the same physical device. + * Returns undefined when the device is not open. + * @type {String} + * @readOnly + * @memberOf Tone.UserMedia# + * @name groupId + */ + Object.defineProperty(Tone.UserMedia.prototype, 'groupId', { + get: function () { + if (this._device) { + return this._device.groupId; + } + } + }); + /** + * Returns a label describing this device (for example "Built-in Microphone"). + * Returns undefined when the device is not open or label is not available + * because of permissions. + * @type {String} + * @readOnly + * @memberOf Tone.UserMedia# + * @name groupId + */ + Object.defineProperty(Tone.UserMedia.prototype, 'label', { + get: function () { + if (this._device) { + return this._device.label; + } + } + }); + /** + * Mute the output. + * @memberOf Tone.UserMedia# + * @type {boolean} + * @name mute + * @example + * //mute the output + * userMedia.mute = true; + */ + Object.defineProperty(Tone.UserMedia.prototype, 'mute', { + get: function () { + return this._volume.mute; + }, + set: function (mute) { + this._volume.mute = mute; + } + }); + /** + * Clean up. + * @return {Tone.UserMedia} this + */ + Tone.UserMedia.prototype.dispose = function () { + Tone.prototype.dispose.call(this); + this.close(); + this._writable('volume'); + this._volume.dispose(); + this._volume = null; + this.volume = null; + return this; + }; + /** + * If getUserMedia is supported by the browser. + * @type {Boolean} + * @memberOf Tone.UserMedia# + * @name supported + * @static + * @readOnly + */ + Object.defineProperty(Tone.UserMedia, 'supported', { + get: function () { + return !Tone.prototype.isUndef(navigator.mediaDevices) && Tone.prototype.isFunction(navigator.mediaDevices.getUserMedia); + } + }); + return Tone.UserMedia; + }); + + return Tone; +})); ADDED public/nexus-js/example/link.html Index: public/nexus-js/example/link.html ================================================================== --- public/nexus-js/example/link.html +++ public/nexus-js/example/link.html @@ -0,0 +1,26 @@ + + + + + + Musician's Toolkit + + + + + +
+
+   +
+ + + ADDED public/nexus-js/example/media/D-sharp.mp3 Index: public/nexus-js/example/media/D-sharp.mp3 ================================================================== --- public/nexus-js/example/media/D-sharp.mp3 +++ public/nexus-js/example/media/D-sharp.mp3 cannot compute difference between binary files ADDED public/nexus-js/example/media/piano-f3.mp3 Index: public/nexus-js/example/media/piano-f3.mp3 ================================================================== --- public/nexus-js/example/media/piano-f3.mp3 +++ public/nexus-js/example/media/piano-f3.mp3 cannot compute difference between binary files ADDED public/nexus-js/example/misc-testing.html Index: public/nexus-js/example/misc-testing.html ================================================================== --- public/nexus-js/example/misc-testing.html +++ public/nexus-js/example/misc-testing.html @@ -0,0 +1,53 @@ + + + + + + Musician's Toolkit + + + + + + + + + +
+ Testing Sandbox +
+ +
+ + + + + + + ADDED public/nexus-js/example/sizing.html Index: public/nexus-js/example/sizing.html ================================================================== --- public/nexus-js/example/sizing.html +++ public/nexus-js/example/sizing.html @@ -0,0 +1,40 @@ + + + + + + Musician's Toolkit + + + + + + + + +
+ Testing Sandbox +
+ +
+ + + + + + ADDED public/nexus-js/example/tilt.html Index: public/nexus-js/example/tilt.html ================================================================== --- public/nexus-js/example/tilt.html +++ public/nexus-js/example/tilt.html @@ -0,0 +1,57 @@ + + + + + + Musician's Toolkit + + + + + + + + +
+ NexusUI Tilt Test +
+ + + +
~
+
~
+
~
+ + + + + ADDED public/nexus-js/example/toggle.html Index: public/nexus-js/example/toggle.html ================================================================== --- public/nexus-js/example/toggle.html +++ public/nexus-js/example/toggle.html @@ -0,0 +1,42 @@ + + + + + + Musician's Toolkit + + + + + + + + +
+ Toggle Test +
+ + + + + + + + ADDED public/nexus-js/favicon.png Index: public/nexus-js/favicon.png ================================================================== --- public/nexus-js/favicon.png +++ public/nexus-js/favicon.png cannot compute difference between binary files ADDED public/nexus-js/index.html Index: public/nexus-js/index.html ================================================================== --- public/nexus-js/index.html +++ public/nexus-js/index.html @@ -0,0 +1,356 @@ + + + + + + Nexus Web Audio Interfaces + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +

NexusUI

+

Web Audio Interfaces


+
+ +
+
+
+
+
+
+
+
+ +
+ + + +
+ + +
+ +

+ NexusUI is a collection of HTML5 interfaces and Javascript helper functions to assist with building web audio instruments in the browser. +

+ +

+ In addition to interfaces, it offers a few helper methods for tuning and timing. + It does not provide any sound-making capabilities –– for that, check out the Web Audio API or web audio libraries such as Tone.js, WebPD, or Gibber. +

+ + + +
+ +
+ +
+ + Example
+ +
+ + + + + +
+
+ + + + + + + +

+ HTML + +
<div id="power"><div>
+<div id="gain"><div>
+ +

+ JS + +
// Create interfaces
+var power = new Nexus.Toggle("#power");
+var gain = new Nexus.Slider("#gain");
+
+// Create a sound source
+var volume = new Tone.Volume(-Infinity).toMaster();
+var synth = new Tone.Oscillator(300,"sine").connect(volume);
+
+// Listen for interface events
+power.on('change',function(v) {
+	v ? synth.start() : synth.stop();
+});
+
+gain.on('change',function(v) {
+	volume.volume.rampTo(v,.1)
+});
+gain.min = -100;
+gain.max = 0;
+gain.value = -30;
+ + + +
+ +
+ +
+ +
+ + Support

+ NexusUI is an open-source project which is maintained in my spare time. If you enjoy NexusUI, please considering supporting its continued development and keeping it open-source.

+
+ + + + + +
+ +
+ + +
+ + + +
+ +
©
+ experimental music & digital media @ louisiana state univeristy 2013-2016
+ ben taylor 2017-2019 + +
+ + + + + + + + + + + + + ADDED public/nexus-js/index.js Index: public/nexus-js/index.js ================================================================== --- public/nexus-js/index.js +++ public/nexus-js/index.js @@ -0,0 +1,5 @@ +'use strict'; + +import NexusUI from './lib/main'; + +export default NexusUI; ADDED public/nexus-js/lib/components/buttontemplate.js Index: public/nexus-js/lib/components/buttontemplate.js ================================================================== --- public/nexus-js/lib/components/buttontemplate.js +++ public/nexus-js/lib/components/buttontemplate.js @@ -0,0 +1,222 @@ +'use strict'; + +let svg = require('../util/svg'); +let math = require('../util/math'); +let ToggleModel = require('../models/toggle'); +let Interface = require('../core/interface'); + +/** +Button Template +*/ + +export default class ButtonTemplate extends Interface { + + constructor(args,options,defaults) { + + super(args,options,defaults); + + this.mode = this.settings.mode || 'button'; + + this.position = { + x: 0, + y: 0 + }; + + this._state = new ToggleModel(this.settings.state); + + } + + buildInterface() { + this.pad = svg.create('circle'); + this.pad.setAttribute('fill', '#d18'); + this.pad.setAttribute('stroke', '#d18'); + this.pad.setAttribute('stroke-width', 4); + + this.element.appendChild(this.pad); + + this.interactionTarget = this.pad; + + this.sizeInterface(); + } + + sizeInterface() { + this.pad.setAttribute('cx',this.width/2); + this.pad.setAttribute('cy',this.height/2); + this.pad.setAttribute('r', Math.min(this.width,this.height) / 2 - 2); + } + + render() { + if (!this.state) { + this.pad.setAttribute('fill', this.colors.fill); + this.pad.setAttribute('stroke', this.colors.mediumLight); + } else { + this.pad.setAttribute('fill', this.colors.accent); + this.pad.setAttribute('stroke', this.colors.accent); + } + } + + down(paintbrush) { + switch (this.mode) { + case 'impulse': + this.turnOn(); + if (this.timeout) { + clearTimeout(this.timeout); + } + this.timeout = setTimeout(this.turnOff.bind(this),30); + // this.emit('change',this.state); + break; + case 'button': + this.turnOn(); + // this.emit('change',this.state); + break; + case 'aftertouch': + this.position = { + x: math.clip(this.mouse.x / this.width,0,1), + y: math.clip(1-this.mouse.y / this.height,0,1) + }; + this.turnOn(); + // this.emit('change',{ + // state: this.state, + // x: this.position.x, + // y: this.position.y, + // }); + break; + case 'toggle': + this.flip(paintbrush); + // this.emit('change',this.state); + break; + } + + } + + bend(mouse) { + if (this.mode==='aftertouch') { + this.mouse = mouse || this.mouse; + this.position = { + x: math.clip(this.mouse.x / this.width,0,1), + y: math.clip(1 - this.mouse.y / this.height,0,1) + }; + this.emit('change',{ + state: this.state, + x: this.position.x, + y: this.position.y, + }); + this.render(); + } + } + + up() { + switch (this.mode) { + case 'button': + this.turnOff(); + // this.emit('change',this.state); + break; + case 'aftertouch': + this.turnOff(); + this.position = { + x: math.clip(this.mouse.x / this.width,0,1), + y: math.clip(1 - this.mouse.y / this.height,0,1) + }; + // this.emit('change',{ + // state: this.state, + // x: this.position.x, + // y: this.position.y, + // }); + break; + } + } + + /* overwritable interaction handlers */ + + click() { + this.down(); + } + move() { + this.bend(); + } + release() { + this.up(); + } + + /** + Whether the button is on (pressed) or off (not pressed) + @type {boolean} + @example button.state = true; + */ + get state() { + return this._state.state; + } + set state(value) { + this._state.flip(value); + if (this.mode==='aftertouch') { + this.emit('change',{ + state: this.state, + x: this.position.x, + y: this.position.y, + }); + } else { + this.emit('change',this.state); + } + this.render(); + } + + /** + Change the button to its alternate state (off=>on, on=>off), or flip it to a specified state. + @param value {boolean} (Optional) State to flip to. + @example button.flip(); + */ + flip(value) { + this._state.flip(value); + if (this.mode==='aftertouch') { + this.emit('change',{ + state: this.state, + x: this.position.x, + y: this.position.y, + }); + } else { + this.emit('change',this.state); + } + this.render(); + } + + /** + Turn the button's state to true. + @example button.turnOn(); + */ + turnOn(emitting) { + this._state.on(); + if (emitting!==false) { + if (this.mode==='aftertouch') { + this.emit('change',{ + state: this.state, + x: this.position.x, + y: this.position.y, + }); + } else { + this.emit('change',this.state); + } + } + this.render(); + } + + /** + Turn the button's state to false. + @example button.turnOff(); + */ + turnOff(emitting) { + this._state.off(); + if (emitting!==false) { + if (this.mode==='aftertouch') { + this.emit('change',{ + state: this.state, + x: this.position.x, + y: this.position.y, + }); + } else { + this.emit('change',this.state); + } + } + this.render(); + } + +} ADDED public/nexus-js/lib/components/rangeslider.js Index: public/nexus-js/lib/components/rangeslider.js ================================================================== --- public/nexus-js/lib/components/rangeslider.js +++ public/nexus-js/lib/components/rangeslider.js @@ -0,0 +1,223 @@ +'use strict'; + +let svg = require('../util/svg'); +let RangeModel = require('../models/range'); +let math = require('../util/math'); + +import Interface from '../core/interface'; +import * as Interaction from '../util/interaction'; + +export default class RangeSlider extends Interface { + + constructor() { + + let options = []; + + let defaults = { + 'size': [100,30], + 'mode': 'select' + }; + + super(arguments,options,defaults); + + this.min = this.settings.min; + this.max = this.settings.max; + this.step = this.settings.step; + this.mode = this.settings.mode; + + this.range = new RangeModel(this.min,this.max,this.step); + + if (this.mode==='drag') { + this.position = { + center: new Interaction.Handle('relative','horizontal',[0,this.width],[this.height,0]), + size: new Interaction.Handle('relative','vertical',[0,this.width],[this.height,0]) + }; + this.position.size.sensitivity = 0.2; + } else if (this.mode==='select') { + this.position = { + center: new Interaction.Handle('relative','horizontal',[0,this.width],[this.height,0]), + start: new Interaction.Handle('relative','horizontal',[0,this.width],[this.height,0]), + end: new Interaction.Handle('relative','horizontal',[0,this.width],[this.height,0]) + // size: new Interaction.Handle('relative','vertical',[0,this.width],[this.height,0]) + }; + } + + this.init(); + return this; + } + + buildFrame() { + this.element = svg.create('svg'); + this.element.setAttribute('x',0); + this.element.setAttribute('y',0); + this.parent.appendChild(this.element); + } + + buildInterface() { + + this.dummy = svg.create('rect'); + this.dummy.setAttribute('width', '100%'); + this.dummy.setAttribute('height', '100%'); + this.dummy.setAttribute('x',0); + this.dummy.setAttribute('y',0); + this.dummy.setAttribute('fill','none'); + + this.element.appendChild(this.dummy); + + this.ref = svg.create('g'); + this.ref.setAttribute('width', '100%'); + this.ref.setAttribute('height', '100%'); + this.ref.setAttribute('x',0); + this.ref.setAttribute('y',0); + this.ref.setAttribute('fill','none'); + + this.element.appendChild(this.ref); + + this.bar = svg.create('rect'); + this.bar.setAttribute('x',0); + this.bar.setAttribute('y',0); + this.bar.setAttribute('stroke-width','0'); + this.bar.setAttribute('fill-opacity','0.4'); + + this.arrowL = svg.create('rect'); + this.arrowL.setAttribute('x',0); + this.arrowL.setAttribute('y',0); + this.arrowL.setAttribute('fill-opacity','0.7'); + + this.arrowL.addEventListener('mousedown', (e) => { + e.preventDefault(); + e.stopPropagation(); + }); + + this.arrowR = svg.create('rect'); + this.arrowR.setAttribute('fill-opacity','0.7'); + + this.arrowR.addEventListener('mousedown', (e) => { + e.preventDefault(); + e.stopPropagation(); + }); + + this.ref.appendChild(this.arrowL); + this.ref.appendChild(this.arrowR); + this.ref.appendChild(this.bar); + + this.resize(); + + } + + colorInterface() { + this.bar.setAttribute('fill',this.colors.accent); + this.bar.setAttribute('stroke',this.colors.accent); + this.arrowL.setAttribute('fill',this.colors.accent); + this.arrowR.setAttribute('fill',this.colors.accent); + } + + resize(w,h) { + this.width = w || this.width; + this.height = h || this.height; + this.element.setAttribute('width',this.width); + this.element.setAttribute('height',this.height); + this.bar.setAttribute('width', (this.range.end.normalized - this.range.start.normalized) * this.width ); + this.bar.setAttribute('height',this.height); + this.arrowL.setAttribute('width', 3); + this.arrowL.setAttribute('height',this.height); + this.arrowR.setAttribute('width', 3); + this.arrowR.setAttribute('height',this.height); + this.arrowR.setAttribute('x',this.bar.getAttribute('width')); + this.arrowR.setAttribute('y',0); + if (this.mode==='drag') { + this.position.center.resize([0,this.width],[this.height,0]); + this.position.size.resize([0,this.width],[this.height,0]); + } else if (this.mode==='select') { + this.position.center.resize([0,this.width],[this.height,0]); + this.position.start.resize([0,this.width],[this.height,0]); + this.position.end.resize([0,this.width],[this.height,0]); + } + this.render(); + } + + render() { + this.ref.setAttribute('transform', 'translate(' + this.range.start.normalized * this.width + ', 0)'); + this.bar.setAttribute('width', (this.range.end.normalized - this.range.start.normalized) * this.width ); + this.arrowR.setAttribute('x',this.bar.getAttribute('width') - 3); + } + + click() { + this.hasMoved = false; + console.log('slider clicked'); + + if (this.mode==='drag') { + this.position.center.anchor = this.mouse; + this.position.size.anchor = this.mouse; + } else if (this.mode==='select') { + this.position.center.anchor = this.mouse; + } + //this.range.center = math.scale(this.mouse.x,0,this.width,this.min,this.max); + this.render(); + } + + move() { + if(this.clicked){ + this.hasMoved = true; + if (this.mode==='drag') { + + this.position.center.update( this.mouse ); + this.range.center = math.scale(this.position.center.value,0,1,this.min,this.max); + //this.range.center = math.scale(this.mouse.x,0,this.width,this.min,this.max); + + this.position.size.update( this.mouse ); + this.range.size = math.scale(this.position.size.value,0,1,this.min,this.max); + + this.render(); + } + else if (this.mode==='select') { + this.position.center.update( this.mouse ); + this.range.center = math.scale(this.position.center.value,0,1,this.min,this.max); + this.render(); + } + } + } + + release() { + if (!this.hasMoved) { + this.destroy(); + } + this.render(); + } + + get start() { + return this.range.start.value; + } + + set start(value) { + // console.log("start is being set to", value); + this.range.start.value = value; + this.updatePosition(); + } + + get end() { + return this.range.end.value; + } + + set end(value ) { + // console.log("end is being set to", value); + this.range.end.value = value; + this.updatePosition(); + } + + updatePosition() { + // console.log("updatePosition is being set"); + let start = this.range.start.normalized; + // console.log("updatePosition start", start); + let end = this.range.end.normalized; + // console.log("updatePosition end", end); + let center = (end+start)/2; + let size = end - start; + + // console.log("updatePosition center", center); + // console.log("updatePosition size", size); + this.position.center.update(center); + this.position.size.update(size); + } + +} ADDED public/nexus-js/lib/components/slidertemplate.js Index: public/nexus-js/lib/components/slidertemplate.js ================================================================== --- public/nexus-js/lib/components/slidertemplate.js +++ public/nexus-js/lib/components/slidertemplate.js @@ -0,0 +1,248 @@ +'use strict'; + +let svg = require('../util/svg'); +let Interface = require('../core/interface'); +let Step = require('../models/step'); +import * as Interaction from '../util/interaction'; + +export default class SliderTemplate extends Interface { + + constructor(args,options,defaults) { + + super(args,options,defaults); + + this.orientation = this.settings.orientation; + + // this.mode = this.settings.mode; + + this.hasKnob = this.settings.hasKnob; + + // this.step should eventually be get/set + // updating it will update the _value step model + // this.step = this.settings.step; // float + + this._value = new Step(this.settings.scale[0], this.settings.scale[1], this.settings.step, this.settings.value); + + this.init(); + + this.position = new Interaction.Handle(this.settings.mode,this.orientation,[0,this.width],[this.height,0]); + this.position.value = this._value.normalized; + + this.value = this._value.value; + + this.emit('change',this.value); + + } + + buildInterface() { + + this.bar = svg.create('rect'); + this.fillbar = svg.create('rect'); + this.knob = svg.create('circle'); + + this.element.appendChild(this.bar); + this.element.appendChild(this.fillbar); + this.element.appendChild(this.knob); + + this.sizeInterface(); + + + + } + + sizeInterface() { + + + if (!this.settings.orientation) { + if (this.width < this.height) { + this.orientation = 'vertical'; + } else { + this.orientation = 'horizontal'; + } + } + + let x, y, w, h, barOffset, cornerRadius; + this.knobData = { + level: 0, + r: 0 + }; + + if (this.orientation === 'vertical') { + this.thickness = this.width / 2; + x = this.width/2; + y = 0; + w = this.thickness; + h = this.height; + this.knobData.r = this.thickness * 0.8; + this.knobData.level = h-this.normalized*h; + barOffset = 'translate('+this.thickness*(-1)/2+',0)'; + cornerRadius = w/2; + } else { + this.thickness = this.height / 2; + x = 0; + y = this.height/2; + w = this.width; + h = this.thickness; + this.knobData.r = this.thickness * 0.8; + this.knobData.level = this.normalized*w; + barOffset = 'translate(0,'+this.thickness*(-1)/2+')'; + cornerRadius = h/2; + } + + this.bar.setAttribute('x',x); + this.bar.setAttribute('y',y); + this.bar.setAttribute('transform',barOffset); + this.bar.setAttribute('rx',cornerRadius); // corner radius + this.bar.setAttribute('ry',cornerRadius); + this.bar.setAttribute('width',w); + this.bar.setAttribute('height',h); + + if (this.orientation === 'vertical') { + this.fillbar.setAttribute('x',x); + this.fillbar.setAttribute('y',this.knobData.level); + this.fillbar.setAttribute('width',w); + this.fillbar.setAttribute('height',h-this.knobData.level); + } else { + this.fillbar.setAttribute('x',0); + this.fillbar.setAttribute('y',y); + this.fillbar.setAttribute('width',this.knobData.level); + this.fillbar.setAttribute('height',h); + } + this.fillbar.setAttribute('transform',barOffset); + this.fillbar.setAttribute('rx',cornerRadius); + this.fillbar.setAttribute('ry',cornerRadius); + + if (this.orientation === 'vertical') { + this.knob.setAttribute('cx',x); + this.knob.setAttribute('cy',this.knobData.level); + } else { + this.knob.setAttribute('cx',this.knobData.level); + this.knob.setAttribute('cy',y); + } + this.knob.setAttribute('r',this.knobData.r); + + + if (this.position) { + this.position.resize([0,this.width],[this.height,0]); + } + + } + + colorInterface() { + + this.bar.setAttribute('fill', this.colors.fill); + this.fillbar.setAttribute('fill', this.colors.accent); + this.knob.setAttribute('fill', this.colors.accent); + if (!this.hasKnob) { + this.knob.setAttribute('fill','none'); + } + + } + + render() { + if (!this.clicked) { + this.knobData.r = this.thickness*0.75; + } + this.knob.setAttribute('r',this.knobData.r); + + if (this.orientation === 'vertical') { + this.knobData.level = this._value.normalized*this.height; + this.knob.setAttribute('cy',this.height - this.knobData.level); + this.fillbar.setAttribute('y',this.height - this.knobData.level); + this.fillbar.setAttribute('height',this.knobData.level); + } else { + this.knobData.level = this._value.normalized*this.width; + this.knob.setAttribute('cx',this.knobData.level); + this.fillbar.setAttribute('x',0); + this.fillbar.setAttribute('width',this.knobData.level); + } + } + + down() { + this.clicked = true; + this.knobData.r = this.thickness*0.9; + this.position.anchor = this.mouse; + this.slide(); + } + + slide() { + if (this.clicked) { + this.position.update(this.mouse); + this.value = this._value.updateNormal( this.position.value ); + this.emit('change',this.value); + } + } + + up() { + this.clicked = false; + this.render(); + } + + get normalized() { + return this._value.normalized; + } + + /** + The slider's current value. If set manually, will update the interface and trigger the output event. + @type {number} + @example slider.value = 10; + */ + get value() { + return this._value.value; + } + set value(v) { + this._value.update(v); + this.position.value = this._value.normalized; + this.render(); + } + + /** + Lower limit of the sliders's output range + @type {number} + @example slider.min = 1000; + */ + get min() { + return this._value.min; + } + set min(v) { + this._value.min = v; + } + + /** + Upper limit of the slider's output range + @type {number} + @example slider.max = 1000; + */ + get max() { + return this._value.max; + } + set max(v) { + this._value.max = v; + } + + /** + The increment that the slider's value changes by. + @type {number} + @example slider.step = 5; + */ + get step() { + return this._value.step; + } + set step(v) { + this._value.step = v; + } + + /** + Absolute mode (slider's value jumps to mouse click position) or relative mode (mouse drag changes value relative to its current position). Default: "relative". + @type {string} + @example slider.mode = "relative"; + */ + get mode() { + return this.position.mode; + } + set mode(v) { + this.position.mode = v; + } + + +} ADDED public/nexus-js/lib/core/interface.js Index: public/nexus-js/lib/core/interface.js ================================================================== --- public/nexus-js/lib/core/interface.js +++ public/nexus-js/lib/core/interface.js @@ -0,0 +1,306 @@ +'use strict'; + +let svg = require('../util/svg'); +let dom = require('../util/dom'); +let util = require('../util/util'); +let touch = require('../util/touch'); +const EventEmitter = require('events'); + +import { colors } from '../main'; + +/** +Interface +*/ +export default class Interface extends EventEmitter { + + constructor(args,options,defaults) { + super(); + this.type = this.constructor.name; + this.settings = this.parseSettings(args,options,defaults); + this.mouse = {}; + this.wait = false; + this.colors = {}; + let defaultColors = colors(); // jshint ignore:line + this.colors.accent = defaultColors.accent; + this.colors.fill = defaultColors.fill; + this.colors.light = defaultColors.light; + this.colors.dark = defaultColors.dark; + this.colors.mediumLight = defaultColors.mediumLight; + this.colors.mediumDark = defaultColors.mediumDark; + } + + parseSettings(args,options,defaults) { + + options.unshift('target'); + defaults.defaultSize = defaults.size.splice(0,2); + defaults.size = false; + + let settings = { + 'target': document.body, + 'colors': {}, // should inherit from a colors module, + 'snapWithParent': true, + 'event': function() {}, + 'component': false + }; + + for (let key in defaults) { + settings[key] = defaults[key]; + } + + for (let i=0; i=1) { + // grab the first option -- i.e. 'target' + let key = options.splice(0,1)[0]; + settings[key] = setting; + } + } + + /* handle common settings */ + + // target + this.parent = dom.parseElement(settings.target); + + // nexus-ui attribute + if (this.parent && this.parent instanceof HTMLElement && !settings.component) { + if (!this.parent.hasAttribute('nexus-ui')) { + this.parent.setAttribute('nexus-ui',''); + } + } + + // size + + if (settings.size && Array.isArray(settings.size) && settings.snapWithParent) { + this.width = settings.size[0]; + this.height = settings.size[1]; + this.parent.style.width = this.width + 'px'; + this.parent.style.height = this.height + 'px'; + } else if (settings.snapWithParent && !settings.component) { + + this.width = parseFloat(window.getComputedStyle(this.parent, null).getPropertyValue('width').replace('px','')); + this.height = parseFloat(window.getComputedStyle(this.parent, null).getPropertyValue('height').replace('px','')); + + if (this.width==5000) { + this.width = settings.defaultSize[0]; + this.parent.style.width = this.parent.width = this.width + 'px'; + } + if (this.height==5000) { + this.height = settings.defaultSize[1]; + this.parent.style.height = this.parent.height = this.height + 'px'; + } + + } else { + settings.size = settings.defaultSize; + this.width = settings.size[0]; + this.height = settings.size[1]; + } + + // event + if (settings.event) { + this.event = this.on('change', settings.event); + } else { + this.event = false; + } + + return settings; + + } + + init() { + this.buildFrame(); + this.buildInterface(); + this.sizeInterface(); + this.attachListeners(); + this.colorInterface(); + this.finalTouches(); + } + + buildFrame() { + this.element = svg.create('svg'); + this.element.setAttribute('width',this.width); + this.element.setAttribute('height',this.height); + this.parent.appendChild(this.element); + } + + buildInterface() {} + sizeInterface() {} + colorInterface() {} + + attachListeners() { + + this.interactionTarget = this.interactionTarget || this.element; + + // Setup interaction + if (touch.exists) { + this.interactionTarget.addEventListener('touchstart', evt => this.preTouch(evt)); + this.interactionTarget.addEventListener('touchmove', evt => this.preTouchMove(evt)); + this.interactionTarget.addEventListener('touchend', evt => this.preTouchRelease(evt)); + } + this.boundPreMove = evt => this.preMove(evt); + this.boundPreRelease = evt => this.preRelease(evt); + this.interactionTarget.addEventListener('mousedown', evt => this.preClick(evt)); + } + + finalTouches() { + this.element.style.cursor = 'pointer'; + } + + preClick(e) { + // 10000 getComputedStyle calls takes 100 ms. + // .:. one takes about .01ms + if (this.element instanceof HTMLElement) { + this.width = window.getComputedStyle(this.element, null).getPropertyValue('width').replace('px',''); + } + // 10000 getComputedStyle calls takes 40 ms. + // .:. one takes about .004ms + this.offset = dom.findPosition(this.element); + this.mouse = dom.locateMouse(e,this.offset); + this.clicked = true; + this.click(); + this.moveEvent = document.addEventListener('mousemove', this.boundPreMove); + this.releaseEvent = document.addEventListener('mouseup', this.boundPreRelease); + this.emit('click'); + e.preventDefault(); + e.stopPropagation(); + } + + preMove(e) { + if (!this.wait) { + this.mouse = dom.locateMouse(e,this.offset); + this.move(); + this.wait = true; + setTimeout(() => { this.wait = false; },25); + } + e.preventDefault(); + e.stopPropagation(); + } + + preRelease(e) { + this.mouse = dom.locateMouse(e,this.offset); + this.clicked = false; + this.release(); + this.emit('release'); + document.removeEventListener('mousemove',this.boundPreMove); + document.removeEventListener('mouseup',this.boundPreRelease); + e.preventDefault(); + e.stopPropagation(); + } + + click() { + + } + + move() { + + } + + release() { + + } + + + /* touch */ + + preTouch(e) { + if (this.element instanceof HTMLElement) { + this.width = window.getComputedStyle(this.element, null).getPropertyValue('width').replace('px',''); + } + this.offset = dom.findPosition(this.element); + this.mouse = dom.locateTouch(e,this.offset); + this.clicked = true; + this.touch(e); + this.emit('click'); + e.preventDefault(); + e.stopPropagation(); + } + + preTouchMove(e) { + if (this.clicked) { + this.mouse = dom.locateTouch(e,this.offset); + this.touchMove(); + e.preventDefault(); + e.stopPropagation(); + } + } + + preTouchRelease(e) { + this.mouse = dom.locateTouch(e, this.offset); + this.clicked = false; + this.touchRelease(); + this.emit('release'); + e.preventDefault(); + e.stopPropagation(); + } + + touch() { + this.click(); + } + + touchMove() { + this.move(); + } + + touchRelease() { + this.release(); + } + + /** + * Resize the interface + * @param width {number} New width in pixels + * @param height {number} New height in pixels + * + * @example + * button.resize(100,100); + */ + resize(width,height) { + this.width = width; + this.height = height; + this.parent.style.width = this.width+'px'; + this.parent.style.height = this.height+'px'; + this.element.setAttribute('width',this.width); + this.element.setAttribute('height',this.height); + this.sizeInterface(); + } + + empty() { + while (this.element.lastChild) { + this.element.removeChild(this.element.lastChild); + } + } + + /** + * Remove the interface from the page and cancel its event listener(s). + * + * @example + * button.destroy(); + */ + destroy() { + this.empty(); + this.parent.removeChild(this.element); + this.removeAllListeners(); + if (this.instrument) { + delete this.instrument[this.id]; + } + this.customDestroy(); + } + + customDestroy() { + + } + + colorize(type,color) { + this.colors[type] = color; + this.colorInterface(); + } + +} ADDED public/nexus-js/lib/core/rack.js Index: public/nexus-js/lib/core/rack.js ================================================================== --- public/nexus-js/lib/core/rack.js +++ public/nexus-js/lib/core/rack.js @@ -0,0 +1,177 @@ +/* +Main concept: +synth = new Nexus.Rack('elementID'); + +Transform all elements inside the div +synth.elementID will hold the first slider interface + +2) In future, potentially writing a rack that is re-usable? +Could also take JSON + +new Nexus.Rack('#target',{ + pre: () => { + create some divs here, or some audio code + }, + interface: { + slider1: Nexus.add.slider({ + top:10, + left:10, + width:50, + height:100, + min: 0, + max: 100, + step: 1 + }), + wave1: Nexus.add.waveform({ + file: './path/to/file.mp3', + width:500, + height:100, + mode: 'range' + }) + }, + init: () => { + // some audio init code goes here... + } +}); + +*/ + +import * as transform from '../util/transform'; +import dom from '../util/dom'; + +import { colors } from '../main'; + +export default class Rack { + + constructor(target, settings) { + + this.meta = {}; + this.meta.target = target; + this.meta.parent = dom.parseElement(target); // should be a generic function for parsing a 'target' argument that checks for string/DOM/jQUERY + this.meta.colors = {}; + + if (settings) { + this.meta.attribute = settings.attribute || 'nexus-ui'; + this.meta.title = settings.name || false; + this.meta.open = settings.open || false; + } else { + this.meta.attribute = 'nexus-ui'; + this.meta.title = false; + this.meta.open = false; + } + + let defaultColors = colors(); // jshint ignore:line + this.meta.colors.accent = defaultColors.accent; + this.meta.colors.fill = defaultColors.fill; + this.meta.colors.light = defaultColors.light; + this.meta.colors.dark = defaultColors.dark; + this.meta.colors.mediumLight = defaultColors.mediumLight; + this.meta.colors.mediumDark = defaultColors.mediumDark; + this.buildInterface(); + this.colorInterface(); + } + + buildInterface() { + this.meta.parent.style.boxSizing = 'border-box'; + this.meta.parent.style.userSelect = 'none'; + this.meta.parent.style.mozUserSelect = 'none'; + this.meta.parent.style.webkitUserSelect = 'none'; + + this.meta.contents = document.createElement('div'); + + while (this.meta.parent.childNodes.length > 0) { + this.meta.contents.appendChild(this.meta.parent.childNodes[0]); + } + + this.meta.contents.style.padding = '0px'; + this.meta.contents.style.boxSizing = 'border-box'; + + if (this.meta.title) { + this.meta.titleBar = document.createElement('div'); + this.meta.titleBar.innerHTML = this.meta.title; + this.meta.titleBar.style.fontFamily = 'arial'; + this.meta.titleBar.style.position = 'relative'; + this.meta.titleBar.style.color = '#888'; + this.meta.titleBar.style.padding = '7px'; + this.meta.titleBar.style.fontSize = '12px'; + + this.meta.button = document.createElement('div'); + this.meta.button.style.position = 'absolute'; + this.meta.button.style.top = '5px' ; + this.meta.button.style.right = '5px' ; + this.meta.button.innerHTML = '-'; + this.meta.button.style.padding = '0px 5px 2px'; + this.meta.button.style.lineHeight = '12px'; + this.meta.button.style.fontSize = '15px'; + + this.meta.button.style.cursor = 'pointer'; + + this.meta.button.addEventListener('mouseover', () => { + this.meta.button.style.backgroundColor = this.meta.colors.mediumDark; + }); + this.meta.button.addEventListener('mouseleave', () => { + this.meta.button.style.backgroundColor = this.meta.colors.mediumLight; + }); + this.meta.button.addEventListener('click', () => { + if (this.meta.open) { + this.hide(); + } else { + this.show(); + } + }); + + + this.meta.titleBar.appendChild(this.meta.button); + + this.meta.parent.appendChild(this.meta.titleBar); + } + this.meta.parent.appendChild(this.meta.contents); + + // var width = this.meta.parent.style.width = getComputedStyle(this.meta.parent).getPropertyValue('width'); +// this.meta.parent.style.width = width; + + let ui = transform.section(this.meta.target, this.meta.attribute); + for (var key in ui) { + this[key] = ui[key]; + } + } + + colorInterface() { + if (this.meta.title) { + this.meta.button.style.backgroundColor = this.meta.colors.mediumLight; + this.meta.button.style.border = 'solid 0px '+this.meta.colors.fill; + this.meta.parent.style.border = 'solid 1px '+this.meta.colors.mediumLight; + this.meta.parent.style.backgroundColor = this.meta.colors.light; + this.meta.titleBar.style.backgroundColor = this.meta.colors.fill; + } + } + + show() { + this.meta.contents.style.display = 'block'; + this.meta.open = true; + } + + hide() { + this.meta.contents.style.display = 'none'; + this.meta.open = false; + } + + colorize(type,color) { + for (var key in this) { + if (this[key].colorize) { + this[key].colorize(type,color); + } + } + this.meta.colors[type] = color; + this.colorInterface(); + } + + empty() { + for (var key in this) { + if (this[key].destroy) { + this[key].destroy(); + } + } + } + +} ADDED public/nexus-js/lib/interfaces/button.js Index: public/nexus-js/lib/interfaces/button.js ================================================================== --- public/nexus-js/lib/interfaces/button.js +++ public/nexus-js/lib/interfaces/button.js @@ -0,0 +1,120 @@ +'use strict'; + +let svg = require('../util/svg'); +let ButtonTemplate = require('../components/buttontemplate'); + +/** +* Button +* +* @description Circular button with optional aftertouch. +* +* @demo +* +* @example +* var button = new Nexus.Button('#target') +* +* @example +* var button = new Nexus.Button('#target',{ +* 'size': [80,80], +* 'mode': 'aftertouch', +* 'state': false +* }) +* +* @output +* change +* Fires any time the interface's value changes.
+* In button mode, toggle mode, and impulse mode, the output data is a boolean describing the state of the button.
+* In aftertouch mode, the output data is an object containing x (0-1) and y (0-1) positions of aftertouch. +* +* @outputexample +* button.on('change',function(v) { +* // v is the value of the button +* console.log(v); +* }) +* +*/ + +export default class Button extends ButtonTemplate { + + constructor() { + + let options = ['mode']; + + + let defaults = { + 'size': [80,80], + 'mode': 'aftertouch', // button, aftertouch, impulse, toggle + 'state': false + }; + + super(arguments,options,defaults); + + + /** + * Interaction mode: supports "button", "aftertouch", "impulse", or "toggle" + * @type {string} + * @example button.mode = 'toggle'; + */ + this.mode = this.settings.mode; + + this.init(); + this.render(); + + } + + buildInterface() { + this.pad = svg.create('circle'); + this.element.appendChild(this.pad); + + this.interactionTarget = this.pad; + + // only used if in 'aftertouch' mode + this.defs = svg.create('defs'); + this.element.appendChild(this.defs); + + this.gradient = svg.radialGradient(this.defs,2); + + this.gradient.stops[0].setAttribute('offset', '30%'); + + this.gradient.stops[1].setAttribute('offset', '100%'); + + } + + sizeInterface() { + + this.pad.setAttribute('cx',this.width/2); + this.pad.setAttribute('cy',this.height/2); + this.pad.setAttribute('r', Math.min(this.width,this.height) / 2 - this.width/40); + this.pad.setAttribute('stroke-width', this.width/20); + } + + colorInterface() { + + this.gradient.stops[0].setAttribute('stop-color', this.colors.accent); + this.gradient.stops[1].setAttribute('stop-color', this.colors.fill); + this.render(); + } + + /* + * Update the visual interface using its current state + * + * @example + * button.render(); + */ + render() { + if (!this.state) { + this.pad.setAttribute('fill', this.colors.fill); + this.pad.setAttribute('stroke', this.colors.mediumLight); + } else { + if (this.mode==='aftertouch') { + this.pad.setAttribute('stroke', 'url(#'+this.gradient.id+')'); + this.gradient.element.setAttribute('cx', (this.position.x*100)+'%'); + this.gradient.element.setAttribute('cy', ((1-this.position.y)*100)+'%'); + } else { + this.pad.setAttribute('stroke', this.colors.accent); + } + this.pad.setAttribute('fill', this.colors.accent); + } + } + +} ADDED public/nexus-js/lib/interfaces/dial.js Index: public/nexus-js/lib/interfaces/dial.js ================================================================== --- public/nexus-js/lib/interfaces/dial.js +++ public/nexus-js/lib/interfaces/dial.js @@ -0,0 +1,379 @@ +'use strict'; + +let svg = require('../util/svg'); +let math = require('../util/math'); +let Interface = require('../core/interface'); +let Step = require('../models/step'); +import * as Interaction from '../util/interaction'; + +/** +* Dial +* +* +* @description Dial with radial or linear interaction. +* +* @demo +* +* @example +* var dial = new Nexus.Dial('#target') +* +* @example +* var dial = new Nexus.Dial('#target',{ +* 'size': [75,75], +* 'interaction': 'radial', // "radial", "vertical", or "horizontal" +* 'mode': 'relative', // "absolute" or "relative" +* 'min': 0, +* 'max': 1, +* 'step': 0, +* 'value': 0 +* }) +* +* @output +* change +* Fires any time the interface's value changes.
+* The event data is the number value of the interface. +* +* @outputexample +* dial.on('change',function(v) { +* console.log(v); +* }) +* +* @tutorial +* Dial +* ygGMxq +* +*/ + +export default class Dial extends Interface { + + constructor() { + + let options = ['min','max','value']; + + let defaults = { + 'size': [75,75], + 'interaction': 'radial', // radial, vertical, horizontal + 'mode': 'relative', // absolute, relative + 'min': 0, + 'max': 1, + 'step': 0, + 'value': 0 + }; + + super(arguments,options,defaults); + + this.interaction = this.settings.interaction; + + this._value = new Step(this.settings.min, this.settings.max, this.settings.step, this.settings.value); + + this.position = new Interaction.Handle(this.settings.mode,this.interaction,[0,this.width],[this.height,0]); + + this.init(); + + this.value = this._value.value; + + this.position.value = this._value.normalized; + + this.previousAngle = false; + + this.emit('change',this.value); + + } + + buildInterface() { + + this.background = svg.create('circle'); + this.screw = svg.create('circle'); + this.handle = svg.create('path'); + this.handle2 = svg.create('path'); + this.handleFill = svg.create('path'); + this.handle2Fill = svg.create('path'); + this.handleLine = svg.create('path'); + + this.element.appendChild(this.background); + this.element.appendChild(this.handle); + this.element.appendChild(this.handle2); + this.element.appendChild(this.handleFill); + this.element.appendChild(this.handle2Fill); + this.element.appendChild(this.handleLine); + this.element.appendChild(this.screw); + + } + + + sizeInterface() { + + this.position.resize([0,this.width],[this.height,0]); + + let center = { + x: this.width/2, + y: this.height/2 + }; + + let diameter = Math.min(this.width,this.height); + + this.background.setAttribute('cx', center.x); + this.background.setAttribute('cy', center.y); + this.background.setAttribute('r', diameter/2-diameter/40); + + this.screw.setAttribute('cx', center.x); + this.screw.setAttribute('cy', center.y); + this.screw.setAttribute('r', diameter/12); + + let value = this.value; + + let handlePoints = { + start: Math.PI*1.5, + end: math.clip( math.scale(value,0,0.5,Math.PI*1.5,Math.PI*0.5) , Math.PI*0.5, Math.PI*1.5 ) + }; + let handle2Points = { + start: Math.PI*2.5, + end: math.clip( math.scale(value,0.5,1,Math.PI*2.5,Math.PI*1.5) , Math.PI*1.5, Math.PI*2.5 ) + }; + + let handlePath = svg.arc(center.x, center.y, diameter/2-diameter/40, handlePoints.start, handlePoints.end); + let handle2Path = svg.arc(center.x, center.y, diameter/2-diameter/40, handle2Points.start, handle2Points.end); + + this.handle.setAttribute('d',handlePath); + this.handle.setAttribute('stroke-width', diameter/20); + this.handle.setAttribute('fill', 'none'); + + this.handle2.setAttribute('d',handle2Path); + this.handle2.setAttribute('stroke-width', diameter/20); + this.handle2.setAttribute('fill', 'none'); + + handlePath += ' L '+center.x+' '+center.y; + + this.handleFill.setAttribute('d',handlePath); + this.handleFill.setAttribute('fill-opacity', '0.3'); + + handle2Path += ' L '+center.x+' '+center.y; + + this.handle2Fill.setAttribute('d',handle2Path); + this.handle2Fill.setAttribute('fill-opacity', '0.3'); + + let arcEndingA; + if (value < 0.5) { + arcEndingA = handlePoints.end; + } else { + arcEndingA = handle2Points.end; + } + + let arcEndingX = center.x + Math.cos(arcEndingA) * (diameter/2); + let arcEndingY = center.y + Math.sin(arcEndingA) * (diameter/2) * -1; + + this.handleLine.setAttribute('d','M '+center.x+' '+center.y+' L '+arcEndingX+' '+arcEndingY); + this.handleLine.setAttribute('stroke-width', diameter/20); + + } + + colorInterface() { + this.background.setAttribute('fill', this.colors.fill); + this.screw.setAttribute('fill', this.colors.accent); + this.handle.setAttribute('stroke', this.colors.accent); + this.handle2.setAttribute('stroke', this.colors.accent); + this.handleFill.setAttribute('fill', this.colors.accent); + this.handle2Fill.setAttribute('fill', this.colors.accent); + this.handleLine.setAttribute('stroke', this.colors.accent); + + } + + render() { + let value = this._value.normalized; + + let center = { + x: this.width/2, + y: this.height/2 + }; + + let diameter = Math.min(this.width,this.height); + + let handlePoints = { + start: Math.PI*1.5, + end: math.clip( math.scale(value,0,0.5,Math.PI*1.5,Math.PI*0.5) , Math.PI*0.5, Math.PI*1.5 ) + }; + let handle2Points = { + start: Math.PI *2.5, + end: math.clip( math.scale(value,0.5,1,Math.PI*2.5,Math.PI*1.5) , Math.PI*1.5, Math.PI*2.5 ) + }; + + let handlePath = svg.arc(center.x, center.y, diameter/2-diameter/40, handlePoints.start, handlePoints.end); + let handle2Path = svg.arc(center.x, center.y, diameter/2-diameter/40, handle2Points.start, handle2Points.end); + + this.handle.setAttribute('d',handlePath); + this.handle2.setAttribute('d',handle2Path); + + + handlePath += ' L '+center.x+' '+center.y; + + this.handleFill.setAttribute('d',handlePath); + + handle2Path += ' L '+center.x+' '+center.y; + + this.handle2Fill.setAttribute('d',handle2Path); + + let arcEndingA; + if (value <= 0.5) { + arcEndingA = handlePoints.end; + } else { + arcEndingA = handle2Points.end; + } + + let arcEndingX = center.x + Math.cos(arcEndingA) * (diameter/2); + let arcEndingY = center.y + Math.sin(arcEndingA) * (diameter/2) * -1; + + this.handleLine.setAttribute('d','M '+center.x+' '+center.y+' L '+arcEndingX+' '+arcEndingY); + + } + + + click() { + if (this.mode==='relative') { + this.previousAngle = false; + } + this.position.anchor = this.mouse; + this.position.value = this._value.normalized; + this.move(); + } + + move() { + if (this.clicked) { + + this.position.update(this.mouse); + + let angle = this.position.value*Math.PI*2; + + if (angle < 0 ) { angle += (Math.PI*2); } + + if (this.mode === 'relative') { + if (this.previousAngle !== false && Math.abs(this.previousAngle - angle) > 2) { + if (this.previousAngle > 3) { + angle = Math.PI*2; + } else { + angle = 0; + } + } + } /* else { + if (this.previousAngle !== false && Math.abs(this.previousAngle - angle) > 2) { + if (this.previousAngle > 3) { + angle = Math.PI*2; + } else { + angle = 0; + } + } + } */ + this.previousAngle = angle; + + let realValue = angle / (Math.PI*2); + + this.value = this._value.updateNormal( realValue ); + + if (this.mode === 'relative') { + this.position.value = realValue; + } + + this.emit('change',this._value.value); + + this.render(); + + } + } + + release() { + } + + /* + Dial's value. When set, it will automatically be adjust to fit min/max/step settings of the interface. + @type {number} + @example dial.value = 10; + + get value() { + return this._value.value; + } + + set value(value) { + this._value.update(value); + this.emit('change',this.value); + this.render(); + } +*/ + + /** + Dial's value. When set, it will automatically be adjust to fit min/max/step settings of the interface. + @type {number} + @example dial.value = 10; + */ + get value() { + return this._value.value; + } + set value(v) { + this._value.update(v); + this.position.value = this._value.normalized; + this.emit('change',this._value.value); + this.render(); + } + + /** + Lower limit of the dial's output range + @type {number} + @example dial.min = 1000; + */ + get min() { + return this._value.min; + } + set min(v) { + this._value.min = v; + } + + /** + Upper limit of the dial's output range + @type {number} + @example dial.max = 1000; + */ + get max() { + return this._value.max; + } + set max(v) { + this._value.max = v; + } + + /** + The increment that the dial's value changes by. + @type {number} + @example dial.step = 5; + */ + get step() { + return this._value.step; + } + set step(v) { + this._value.step = v; + } + + /** + Absolute mode (dial's value jumps to mouse click position) or relative mode (mouse drag changes value relative to its current position). Default: "relative". + @type {string} + @example dial.mode = "relative"; + */ + get mode() { + return this.position.mode; + } + set mode(v) { + this.position.mode = v; + } + + + /** + Normalized value of the dial. + @type {number} + @example dial.normalized = 0.5; + */ + get normalized() { + return this._value.normalized; + } + + set normalized(v) { + this._value.updateNormal(v); + this.emit('change',this.value); + } + +} ADDED public/nexus-js/lib/interfaces/index.js Index: public/nexus-js/lib/interfaces/index.js ================================================================== --- public/nexus-js/lib/interfaces/index.js +++ public/nexus-js/lib/interfaces/index.js @@ -0,0 +1,23 @@ +export default { + Position: require('./position'), + Slider: require('./slider'), + Toggle: require('./toggle'), +/* Range: require('./rangeslider'), + Waveform: require('./waveform'), */ + Button: require('./button'), + TextButton: require('./textbutton'), + RadioButton: require('./radiobutton'), + Number: require('./number'), + Select: require('./select'), + Dial: require('./dial'), + Piano: require('./piano'), + Sequencer: require('./sequencer'), + Pan2D: require('./pan2d'), + Tilt: require('./tilt'), + Multislider: require('./multislider'), + Pan: require('./pan'), + Envelope: require('./envelope'), + Spectrogram: require('./spectrogram'), + Meter: require('./meter'), + Oscilloscope: require('./oscilloscope') +}; ADDED public/nexus-js/lib/interfaces/meter.js Index: public/nexus-js/lib/interfaces/meter.js ================================================================== --- public/nexus-js/lib/interfaces/meter.js +++ public/nexus-js/lib/interfaces/meter.js @@ -0,0 +1,181 @@ +'use strict'; + +let dom = require('../util/dom'); +let math = require('../util/math'); +let Interface = require('../core/interface'); + +/** + * Meter + * + * @description Stereo decibel meter + * + * @demo + * + * @example + * var meter = new Nexus.Meter('#target') + * meter.connect(myWebAudioNode) + * + * @example + * var meter = new Nexus.Meter('#target', { + * size: [75,75] + * }) + * meter.connect(myWebAudioNode) + * + * @output + *   + * No events + * + */ + +export default class Meter extends Interface { + constructor() { + let options = []; + + let defaults = { + size: [30, 100] + }; + + super(arguments, options, defaults); + + this.channels = 2; + this.splitter = null; + this.analysers = []; + this.bufferLength = 0; + this.dataArray = null; + this.active = false; + this.source = null; + this.db = -Infinity; + + this.init(); + + this.meterWidth = this.canvas.element.width / this.channels; + + this.render(); + } + + buildFrame() { + this.canvas = new dom.SmartCanvas(this.parent); + this.element = this.canvas.element; + } + + sizeInterface() { + this.canvas.resize(this.width, this.height); + } + + colorInterface() { + this.canvas.element.style.backgroundColor = this.colors.fill; + } + + render() { + if (this.active) { + requestAnimationFrame(this.render.bind(this)); + } + + this.canvas.context.fillStyle = this.colors.fill; + this.canvas.context.fillRect( + 0, + 0, + this.canvas.element.width, + this.canvas.element.height + ); + + for (let i = 0; i < this.analysers.length; i++) { + if (this.source) { + this.analysers[i].getFloatTimeDomainData(this.dataArray); + + let rms = 0; + + for (let i = 0; i < this.dataArray.length; i++) { + rms += this.dataArray[i] * this.dataArray[i]; + } + + rms = Math.sqrt(rms / this.dataArray.length); + + this.db = 20 * Math.log10(rms); + } else if (this.db > -200 && this.db !== -Infinity) { + this.db -= 1; + } else { + this.db = -Infinity; + } + + //console.log(db) + + if (this.db > -70) { + let linear = math.normalize(this.db, -70, 5); + let exp = linear * linear; + let y = math.scale(exp, 0, 1, this.element.height, 0); + + this.canvas.context.fillStyle = this.colors.accent; + this.canvas.context.fillRect( + this.meterWidth * i, + y, + this.meterWidth, + this.canvas.element.height - y + ); + + //console.log("rendering...") + } + } + } + + /** + Equivalent to "patching in" an audio node to visualize. + @param node {AudioNode} The audio node to visualize + @param channels {number} (optional) The number of channels in the source node to watch. If not specified, the interface will look for a .channelCount property on the input node. If it does not exist, the interface will default to 1 channel. + @example meter.connect( Tone.Master, 2 ); + */ + connect(node, channels) { + if (this.source) { + this.disconnect(); + } + + this.channels = channels || node.channelCount || 2; + + this.splitter = node.context.createChannelSplitter(this.channels); + + this.analysers = []; + for (let i = 0; i < this.channels; i++) { + const analyser = node.context.createAnalyser(); + analyser.fftSize = 1024; + analyser.smoothingTimeConstant = 1; + this.splitter.connect(analyser, i); + this.analysers.push(analyser); + } + this.bufferLength = this.analysers[0].frequencyBinCount; + this.dataArray = new Float32Array(this.bufferLength); + + this.active = true; + + this.meterWidth = this.canvas.element.width / this.channels; + + this.source = node; + this.source.connect(this.splitter); + + this.render(); + } + + /** + Stop visualizing the source node and disconnect it. + */ + disconnect() { + if (this.source) { + this.source.disconnect(this.splitter); + } + + this.splitter = null; + this.analysers = []; + this.bufferLength = 0; + this.dataArray = null; + this.active = false; + this.source = null; + } + + click() { + this.active = !this.active && this.source; + this.render(); + } + + customDestroy() { + this.active = false; + } +} ADDED public/nexus-js/lib/interfaces/multislider.js Index: public/nexus-js/lib/interfaces/multislider.js ================================================================== --- public/nexus-js/lib/interfaces/multislider.js +++ public/nexus-js/lib/interfaces/multislider.js @@ -0,0 +1,443 @@ +'use strict'; + +let math = require('../util/math'); +let svg = require('../util/svg'); +let Interface = require('../core/interface'); + +/** + * Multislider + * + * @description Multislider + * + * @demo + * + * @example + * var multislider = new Nexus.Multislider('#target') + * + * @example + * var multislider = new Nexus.Multislider('#target',{ + * 'size': [200,100], + * 'numberOfSliders': 5, + * 'min': 0, + * 'max': 1, + * 'step': 0, + * 'candycane': 3, + * 'values': [0.9,0.8,0.7,0.6,0.5,0.4,0.3,0.2,0.1], + * 'smoothing': 0, + * 'mode': 'bar' // 'bar' or 'line' + *}) + * + * @output + * change + * Fires any time the interface's value changes.
+ * The event data is an object containing index and value properties + * + * @outputexample + * multislider.on('change',function(v) { + * console.log(v); + * }) + * + */ + +export default class Multislider extends Interface { + constructor() { + let options = ['value']; + + let defaults = { + size: [200, 100], + numberOfSliders: 5, + min: 0, + max: 1, + step: 0, + candycane: 3, + values: [0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1], + smoothing: 0, + mode: 'bar' // 'bar', 'line' + }; + + super(arguments, options, defaults); + + this._numberOfSliders = this.settings.numberOfSliders; + this._min = this.settings.min; + this._max = this.settings.max; + this._step = this.settings.step; + + this._mode = this.settings.mode; + + /** + The current values of the slider. NOTE: Use this only to get the current values. Setting this array will not update the multislider. To set the multislider's values, use setSlider() or setAllSliders() + @type {Array} + */ + const vs = this.settings.values; + this.values = vs.length > this._numberOfSliders ? vs.slice(0, this._numberOfSliders) : vs.concat(Array(this._numberOfSliders - vs.length).fill(0)); + + this.candycane = this.settings.candycane; + + this.sliderWidth = this.width / this.values.length; + + /** + Applies a simple low-pass filter to the multislider as it is interacted with. A smoothing of 0 will be no smoothing. A smoothing of 1 will smooth 1 slider on each side of the interaction. A smoothing of 2 will smooth 2 sliders on each side, and so on. + @type {Number} + */ + this.smoothing = this.settings.smoothing; + + this.init(); + this.render(); + } + + buildInterface() { + if (this._mode == 'line') { + this.line = svg.create('polyline'); + this.line.setAttribute('stroke-width', 2); + this.line.setAttribute('fill', 'none'); + + this.element.appendChild(this.line); + + this.fill = svg.create('polyline'); + this.fill.setAttribute('fill-opacity', '0.2'); + + this.element.appendChild(this.fill); + + this.nodes = []; + + this.values.forEach( + function(value, index) { + let node = svg.create('circle'); + + node.setAttribute('cx', this.getX(index)); + node.setAttribute('cy', this.getY(value)); + + this.element.appendChild(node); + this.nodes.push(node); + }.bind(this) + ); + } else { + this.bars = []; + this.caps = []; + + this.values.forEach( + function(value, index) { + let bar = svg.create('rect'); + + let x = this.getBarX(index); + let y = this.getY(value); + + bar.setAttribute('x', x - 0.1); + bar.setAttribute('y', y); + bar.setAttribute('width', this.sliderWidth + 0.2); + bar.setAttribute('height', this.height); + bar.setAttribute( + 'opacity', + 1 - ((index % this.candycane) + 1) / (this.candycane + 1) + ); + + this.element.appendChild(bar); + this.bars.push(bar); + + let cap = svg.create('rect'); + + cap.setAttribute('x', x - 0.1); + cap.setAttribute('y', y); + cap.setAttribute('width', this.sliderWidth + 0.2); + cap.setAttribute('height', 5); + + this.element.appendChild(cap); + this.caps.push(cap); + }.bind(this) + ); + } + } + + getBarX(index) { + return this.getX(index) - this.sliderWidth / 2; + } + + getX(index) { + //return Math.floor( index * this.sliderWidth + this.sliderWidth/2 ); + return index * this.sliderWidth + this.sliderWidth / 2; + } + + getY(value) { + return math.scale(value, this._min, this._max, this.height, 0); //(1 - value) * this.height; + } + + getValueFromY(y) { + let scaleAdjusted = math.scale(y, this.height, 0, this._min, this._max); + return this.adjustValueToStep(scaleAdjusted); + } + + getIndexFromX(x) { + return math.clip( + Math.floor((x / this.width) * this.values.length), + 0, + this.values.length - 1 + ); + } + + adjustValueToStep(value) { + if (!this._step) { + return value; + } + let offset = value % this._step; + value = value - (value % this._step); + if (offset > this._step / 2) { + value += this._step; + } + return value; + } + + adjustAllValues() { + this.values.forEach( + function(value, index) { + value = this.adjustValueToStep(value); + this.values[index] = math.clip(value, this._min, this._max); + }.bind(this) + ); + } + + getNormalizedValues() { + this.normalizedValues = []; + this.values.forEach( + function(value) { + this.normalizedValues.push( + math.scale(value, this._min, this._max, 0, 1) + ); + }.bind(this) + ); + } + + colorInterface() { + this.element.style.backgroundColor = this.colors.fill; + + if (this._mode == 'line') { + this.line.setAttribute('stroke', this.colors.accent); + this.fill.setAttribute('fill', this.colors.accent); + this.nodes.forEach(node => { + node.setAttribute('fill', this.colors.accent); + }); + } else { + this.bars.forEach(bar => { + bar.setAttribute('fill', this.colors.accent); + }); + this.caps.forEach(cap => { + cap.setAttribute('fill', this.colors.accent); + }); + } + } + + sizeInterface() { + this.sliderWidth = this.width / this.values.length; + + if (this._mode == 'line') { + this.nodes.forEach( + function(node) { + let r = ~~(Math.min(this.width, this.height) / 50) + 2; + r = Math.min(this.sliderWidth, r); + node.setAttribute('r', r); + }.bind(this) + ); + } + + this.render(); + } + + render() { + if (this._mode == 'line') { + let data = '0 ' + this.getY(this.values[0]) + ', '; + + this.values.forEach((value, index) => { + let x = this.getX(index); + let y = this.getY(value); + data += x + ' ' + y + ', '; + this.nodes[index].setAttribute('cx', this.getX(index)); + this.nodes[index].setAttribute('cy', this.getY(value)); + }); + + data += this.width + ' ' + this.getY(this.values[this.values.length - 1]); + + this.line.setAttribute('points', data); + + // fill data + // add bottom corners + + data += ', ' + this.width + ' ' + this.height + ', '; + data += '0 ' + this.height; + + this.fill.setAttribute('points', data); + } else { + this.values.forEach((value, index) => { + this.bars[index].setAttribute('y', this.getY(value)); + this.caps[index].setAttribute('y', this.getY(value)); + }); + } + } + + click() { + this.hasMoved = false; + this.previousSlider = false; + this.move(); + } + + move() { + if (this.clicked) { + this.mouse.x = math.clip(this.mouse.x, 0, this.width); + this.mouse.y = math.clip(this.mouse.y, 0, this.height); + this.hasMoved = true; + + this.selectedSlider = this.getIndexFromX(this.mouse.x); + + this.values[this.selectedSlider] = this.getValueFromY(this.mouse.y); + + /* handle interpolation for in-between sliders */ + + if (this.previousSlider !== false) { + let distance = Math.abs(this.previousSlider - this.selectedSlider); + if (distance > 1) { + let low = Math.min(this.previousSlider, this.selectedSlider); + let high = Math.max(this.previousSlider, this.selectedSlider); + let lowValue = this.values[low]; + let highValue = this.values[high]; + for (let i = low; i < high; i++) { + this.values[i] = math.interp( + (i - low) / distance, + lowValue, + highValue + ); + this.values[i] = this.adjustValueToStep(this.values[i]); + } + } + } + + if (this.smoothing > 0) { + for (var i = 1; i <= this.smoothing; i++) { + let downCenter = this.selectedSlider - i; + let upCenter = this.selectedSlider + i; + + if (downCenter >= 1) { + let downLowerNeighbor = downCenter - 1 >= 0 ? downCenter - 1 : 0; + let downUpperNeighbor = downCenter + 1; + this.values[downCenter] = + (this.values[downLowerNeighbor] + + this.values[downUpperNeighbor]) / + 2; + this.values[downCenter] = this.adjustValueToStep( + this.values[downCenter] + ); + } + + if (upCenter < this.values.length - 1) { + let upLowerNeighbor = upCenter - 1; + let upUpperNeighbor = upCenter + 1 < this.values.length ? upCenter + 1 : this.values.length - 1; + this.values[upCenter] = + (this.values[upLowerNeighbor] + this.values[upUpperNeighbor]) / 2; + this.values[upCenter] = this.adjustValueToStep( + this.values[upCenter] + ); + } + } + } + + this.previousSlider = this.selectedSlider; + + this.emit('change', this.values); + this.render(); + } + } + + // would be a cool API call to have for later... + scan() {} + + update(index, value) { + this.values[index] = this.adjustValueToStep(value); + this.emit('change', { + index: index, + value: value + }); + } + + /** + Get the number of sliders + @type {Number} + */ + get numberOfSliders() { + return this.values.length; + } + + /** + Lower limit of the multislider's output range + @type {number} + @example multislider.min = 1000; + */ + get min() { + return this._min; + } + set min(v) { + this._min = v; + this.adjustAllValues(); + this.render(); + } + + /** + Upper limit of the multislider's output range + @type {number} + @example multislider.max = 1000; + */ + get max() { + return this._max; + } + set max(v) { + this._max = v; + this.adjustAllValues(); + this.render(); + } + + /** + The increment that the multislider's value changes by. + @type {number} + @example multislider.step = 5; + */ + get step() { + return this._step; + } + set step(v) { + this._step = v; + this.adjustAllValues(); + this.render(); + } + + /** + Set the value of an individual slider + @param index {number} Slider index + @param value {number} New slider value + @example + // Set the first slider to value 0.5 + multislider.setSlider(0,0.5) + */ + setSlider(index, value) { + this.values[index] = this.adjustValueToStep(value); + this.values[index] = math.clip(this.values[index], this._min, this._max); + this.emit('change', { + index: index, + value: value + }); + } + + /** + Set the value of all sliders at once. If the size of the input array does not match the current number of sliders, the value array will repeat until all sliders have been set. I.e. an input array of length 1 will set all sliders to that value. + @param values {Array} All slider values + @example + multislider.setAllSliders([0.2,0.3,0.4,0.5,0.6]) + */ + setAllSliders(values) { + let previousLength = this.values.length; + let newLength = values.length; + this.values = values; + this.adjustAllValues(); + if (previousLength != newLength) { + this.empty(); + this.buildInterface(); + this.colorInterface(); + } + this.sizeInterface(); + } +} ADDED public/nexus-js/lib/interfaces/number.js Index: public/nexus-js/lib/interfaces/number.js ================================================================== --- public/nexus-js/lib/interfaces/number.js +++ public/nexus-js/lib/interfaces/number.js @@ -0,0 +1,262 @@ +'use strict'; + +let Interface = require('../core/interface'); +let Step = require('../models/step'); +let math = require('../util/math'); +let util = require('../util/util'); + +/** +* Number +* +* @description Number interface which is controllable by dragging or typing. +* +* @demo +* +* @example +* var number = new Nexus.Number('#target') +* +* @example +* var number = new Nexus.Number('#target',{ +* 'size': [60,30], +* 'value': 0, +* 'min': 0, +* 'max': 20000, +* 'step': 1 +* }) +* +* @output +* change +* Fires any time the interface's value changes.
+* The event data is the number value of the interface. +* +* @outputexample +* number.on('change',function(v) { +* console.log(v); +* }) +* +* +*/ + + +export default class Number extends Interface { + + constructor() { + + let options = ['value']; + + let defaults = { + 'size': [60,30], + 'value': 0, + 'min': 0, + 'max': 20000, + 'step': 1 + }; + + super(arguments,options,defaults); + + this._value = new Step(this.settings.min,this.settings.max,this.settings.step,this.settings.value); + + /* + Default: 2. How many decimal places to clip the number's visual rendering to. This does not affect number's actual value output -- for that, set the step property to .01, .1, or 1. + @type {number} + @example number.decimalPlaces = 2; + */ + this.decimalPlaces = 2; + this.actual = 0; + + this.max = this._value.max; + + this.min = this._value.min; + + this.step = this._value.step; + + this.init(); + this.render(); + + } + + buildFrame() { + this.element = document.createElement('input'); + this.element.type = 'text'; + + this.element.addEventListener('blur', function () { + this.element.style.backgroundColor = this.colors.fill; + this.element.style.color = this.colors.dark; + if (this.element.value !== this.value) { + this.value = parseFloat(this.element.value); + this.render(); + } + }.bind(this)); + + util.setInputFilter(this.element, function(value) { + return /^-?\d*\.?\d*$/.test(value); }); + + this.element.addEventListener('keydown', function (e) { + if (e.which===13) { + this.element.blur(); + this.value = this.element.value; + this.emit('change',this.value); + this.render(); + } + }.bind(this), true); + + this.parent.appendChild(this.element); + + } + + sizeInterface() { + + this._minDimension = Math.min(this.width,this.height); + + let styles = 'width: ' + this.width + 'px;'; + styles += 'height: ' + this.height + 'px;'; + styles += 'background-color: #e7e7e7;'; + styles += 'color: #333;'; + styles += 'font-family: arial;'; + styles += 'font-weight: 500;'; + styles += 'font-size:' + this._minDimension/2 + 'px;'; + // styles += 'highlight: #d18;'; + styles += 'border: none;'; + styles += 'outline: none;'; + styles += 'padding: '+this._minDimension/4+'px '+this._minDimension/4+'px;'; + styles += 'box-sizing: border-box;'; + styles += 'userSelect: text;'; + styles += 'mozUserSelect: text;'; + styles += 'webkitUserSelect: text;'; + this.element.style.cssText += styles; + + // to add eventually + // var css = '#'+this.elementID+'::selection{ background-color: transparent }'; + + this.element.value = this.value; + + } + + colorInterface() { + this.element.style.backgroundColor = this.colors.fill; + this.element.style.color = this.colors.dark; + } + + render() { + + this.element.value = math.prune(this.value,this.decimalPlaces); + + } + + click() { + this.hasMoved = false; + this.element.readOnly = true; + this.actual = this.value; + this.initial = { y: this.mouse.y }; + this.changeFactor = math.invert( this.mouse.x / this.width ); + } + + move() { + this.hasMoved = true; + if (this.clicked) { + + let newvalue = this.actual - (this.mouse.y - this.initial.y) * ( math.clip( this.max-this.min, 0, 1000 ) / 200 ) * Math.pow(this.changeFactor,2); + this.value = newvalue; + + this.render(); + if (this._value.changed) { + this.emit('change',this.value); + } + + } + } + + release() { + if (!this.hasMoved) { + this.element.readOnly = false; + this.element.focus(); + this.element.setSelectionRange(0, this.element.value.length); + this.element.style.backgroundColor = this.colors.accent; + this.element.style.color = this.colors.light; + } else { + document.body.focus(); + } + } + + /** + Connect this number interface to a dial or slider + @param {Interface} element Element to connect to. + @example number.link(slider) + */ + link(destination) { + this.min = destination.min; + this.max = destination.max; + this.step = destination.step; + destination.on('change',(v) => { + this.passiveUpdate(v); + }); + this.on('change',(v) => { + destination.value = v; + }); + this.value = destination.value; + /* return { + listener1: listener1, + listener2: listener2, + destroy: () => { + listener1.remove() (or similar) + listener2.remove() (or similar) + } + } */ + } + + passiveUpdate(v) { + this._value.update(v); + this.render(); + } + + /** + The interface's current value. If set manually, will update the interface and trigger the output event. + @type {number} + @example number.value = 10; + */ + get value() { + return this._value.value; + } + set value(v) { + this._value.update(v); + this.emit('change',this.value); + this.render(); + } + + /** + Lower limit of the number's output range + @type {number} + @example number.min = 1000; + */ + get min() { + return this._value.min; + } + set min(v) { + this._value.min = v; + } + + /** + Upper limit of the number's output range + @type {number} + @example number.max = 1000; + */ + get max() { + return this._value.max; + } + set max(v) { + this._value.max = v; + } + + /** + The increment that the number's value changes by. + @type {number} + @example number.step = 5; + */ + get step() { + return this._value.step; + } + set step(v) { + this._value.step = v; + } + +} ADDED public/nexus-js/lib/interfaces/oscilloscope.js Index: public/nexus-js/lib/interfaces/oscilloscope.js ================================================================== --- public/nexus-js/lib/interfaces/oscilloscope.js +++ public/nexus-js/lib/interfaces/oscilloscope.js @@ -0,0 +1,162 @@ +'use strict'; + +let dom = require('../util/dom'); +let Interface = require('../core/interface'); + +/** + * Oscilloscope + * + * @description Visualizes a waveform's stream of values. + * + * @demo + * + * @example + * var oscilloscope = new Nexus.Oscilloscope('#target') + * oscilloscope.connect(myWebAudioNode) + * + * @example + * var oscilloscope = new Nexus.Oscilloscope('#target',{ + * 'size': [300,150] + * }) + * oscilloscope.connect(myWebAudioNode) + * + * @output + *   + * No events + * + */ + +export default class Oscilloscope extends Interface { + constructor() { + let options = []; + + let defaults = { + size: [300, 150] + }; + + super(arguments, options, defaults); + + this.analyser = null; + this.bufferLength = 0; + this.dataArray = null; + + this.active = false; + + this.source = null; + + this.init(); + + this.render(); + } + + buildFrame() { + this.canvas = new dom.SmartCanvas(this.parent); + this.element = this.canvas.element; + } + + sizeInterface() { + this.canvas.resize(this.width, this.height); + } + + colorInterface() { + this.canvas.element.style.backgroundColor = this.colors.fill; + } + + render() { + if (this.active) { + requestAnimationFrame(this.render.bind(this)); + } + + if (this.analyser) { + this.analyser.getByteTimeDomainData(this.dataArray); + } + + this.canvas.context.fillStyle = this.colors.fill; + this.canvas.context.fillRect( + 0, + 0, + this.canvas.element.width, + this.canvas.element.height + ); + + this.canvas.context.lineWidth = ~~(this.height / 100 + 2); + this.canvas.context.strokeStyle = this.colors.accent; + + this.canvas.context.beginPath(); + + if (this.source) { + var sliceWidth = (this.canvas.element.width * 1.0) / this.bufferLength; + var x = 0; + + for (var i = 0; i < this.bufferLength; i++) { + var v = this.dataArray[i] / 128.0; + var y = (v * this.canvas.element.height) / 2; + + if (i === 0) { + this.canvas.context.moveTo(x, y); + } else { + this.canvas.context.lineTo(x, y); + } + + x += sliceWidth; + } + } else { + this.canvas.context.moveTo(0, this.canvas.element.height / 2); + this.canvas.context.lineTo( + this.canvas.element.width, + this.canvas.element.height / 2 + ); + } + + this.canvas.context.stroke(); + } + + /** + Equivalent to "patching in" an audio node to visualize. + @param node {AudioNode} The audio node to visualize + @example oscilloscope.connect( Tone.Master ); + */ + + connect(node) { + if (this.source) { + this.disconnect(); + } + + this.analyser = node.context.createAnalyser(); + this.analyser.fftSize = 2048; + this.bufferLength = this.analyser.frequencyBinCount; + this.dataArray = new Uint8Array(this.bufferLength); + this.analyser.getByteTimeDomainData(this.dataArray); + + this.active = true; + + this.source = node; + this.source.connect(this.analyser); + + this.render(); + } + + /** + Stop visualizing the source node and disconnect it. + */ + disconnect() { + if (this.source) { + this.source.disconnect(this.analyser); + } + + this.analyser = null; + this.bufferLength = 0; + this.dataArray = null; + this.active = false; + this.source = null; + } + + click() { + this.active = !this.active && this.source; + this.render(); + } + + customDestroy() { + this.active = false; + } +} ADDED public/nexus-js/lib/interfaces/pan.js Index: public/nexus-js/lib/interfaces/pan.js ================================================================== --- public/nexus-js/lib/interfaces/pan.js +++ public/nexus-js/lib/interfaces/pan.js @@ -0,0 +1,217 @@ +'use strict'; + +let svg = require('../util/svg'); +let math = require('../util/math'); +let Interface = require('../core/interface'); +let Step = require('../models/step'); +import * as Interaction from '../util/interaction'; + +/** +* Pan +* +* @description Stereo crossfader. +* +* @demo +* +* @example +* var pan = new Nexus.Pan('#target') +* +* @output +* change +* Fires any time the interface's value changes.
+* The event data is an object containing the interface's value (-1 to 1), as well as L and R amplitude values (0-1) for left and right speakers, calculated by a square-root crossfade algorithm. +* +* @outputexample +* pan.on('change',function(v) { +* console.log(v); +* }) +* +* +*/ + +export default class Pan extends Interface { + + constructor() { + + let options = ['scale','value']; + + let defaults = { + 'size': [120,20], + 'orientation': 'horizontal', + 'mode': 'relative', + 'scale': [-1,1], + 'step': 0, + 'value': 0, + 'hasKnob': true + }; + + super(arguments,options,defaults); + + this.orientation = this.settings.orientation; + + this.mode = this.settings.mode; + + this.hasKnob = this.settings.hasKnob; + + // this.step should eventually be get/set + // updating it will update the _value step model + this.step = this.settings.step; // float + + this._value = new Step(this.settings.scale[0], this.settings.scale[1], this.settings.step, this.settings.value); + + this.init(); + + this.position = new Interaction.Handle(this.mode,this.orientation,[0,this.width],[this.height,0]); + this.position.value = this._value.normalized; + + this.value = this._value.value; + + this.emit('change',this.value); + + } + + buildInterface() { + + this.bar = svg.create('rect'); + this.knob = svg.create('circle'); + + this.element.appendChild(this.bar); + this.element.appendChild(this.knob); + + } + + sizeInterface() { + + if (this.position) { + this.position.resize([0,this.width],[this.height,0]); + } + + if (this.width < this.height) { + this.orientation = 'vertical'; + } else { + this.orientation = 'horizontal'; + } + + let x, y, w, h, barOffset, cornerRadius; + this.knobData = { + level: 0, + r: 0 + }; + + if (this.orientation === 'vertical') { + this.thickness = this.width / 2; + x = this.width/2; + y = 0; + w = this.thickness; + h = this.height; + this.knobData.r = this.thickness * 0.8; + this.knobData.level = h-this.knobData.r-this.normalized*(h-this.knobData.r*2); + barOffset = 'translate('+this.thickness*(-1)/2+',0)'; + cornerRadius = w/2; + } else { + this.thickness = this.height / 2; + x = 0; + y = this.height/2; + w = this.width; + h = this.thickness; + this.knobData.r = this.thickness * 0.8; + this.knobData.level = this.normalized*(w-this.knobData.r*2)+this.knobData.r; + barOffset = 'translate(0,'+this.thickness*(-1)/2+')'; + cornerRadius = h/2; + } + + this.bar.setAttribute('x',x); + this.bar.setAttribute('y',y); + this.bar.setAttribute('transform',barOffset); + this.bar.setAttribute('rx',cornerRadius); // corner radius + this.bar.setAttribute('ry',cornerRadius); + this.bar.setAttribute('width',w); + this.bar.setAttribute('height',h); + + if (this.orientation === 'vertical') { + this.knob.setAttribute('cx',x); + this.knob.setAttribute('cy',this.knobData.level); + } else { + this.knob.setAttribute('cx',this.knobData.level); + this.knob.setAttribute('cy',y); + } + this.knob.setAttribute('r',this.knobData.r); + + } + + colorInterface() { + + this.bar.setAttribute('fill', this.colors.fill); + this.knob.setAttribute('fill', this.colors.accent); + + if (!this.hasKnob) { + this.knob.setAttribute('fill','transparent'); + } + + } + + render() { + if (!this.clicked) { + this.knobData.r = this.thickness*0.75; + } + this.knob.setAttribute('r',this.knobData.r); + + if (this.orientation === 'vertical') { + this.knobData.level = this.knobData.r+this._value.normalized*(this.height-this.knobData.r*2); + this.knob.setAttribute('cy',this.height - this.knobData.level); + } else { + this.knobData.level = this._value.normalized*(this.width-this.knobData.r*2)+this.knobData.r; + this.knob.setAttribute('cx',this.knobData.level); + } + } + + + click() { + this.knobData.r = this.thickness*0.9; + this.position.anchor = this.mouse; + this.move(); + } + + move() { + if (this.clicked) { + this.position.update(this.mouse); + + this.value = this._value.updateNormal( this.position.value ); + + this.emit('change',{ + value: this.value, + L: Math.pow( math.scale(this.value,-1,1,1,0), 2), + R: Math.pow( math.scale(this.value,-1,1,0,1), 2) + }); + + } + } + + release() { + this.render(); + } + + /** + The position of crossfader, from -1 (left) to 1 (right). Setting this value updates the interface and triggers the output event. + @type {number} + */ + get value() { + return this._value.value; + } + + set value(value) { + this._value.update(value); + this.position.value = this._value.normalized; + this.emit('change',{ + value: this.value, + L: Math.pow( math.scale(this.value,-1,1,1,0), 2), + R: Math.pow( math.scale(this.value,-1,1,0,1), 2) + }); + this.render(); + } + + get normalized() { + return this._value.normalized; + } + +} ADDED public/nexus-js/lib/interfaces/pan2d.js Index: public/nexus-js/lib/interfaces/pan2d.js ================================================================== --- public/nexus-js/lib/interfaces/pan2d.js +++ public/nexus-js/lib/interfaces/pan2d.js @@ -0,0 +1,275 @@ +'use strict'; + +let svg = require('../util/svg'); +let math = require('../util/math'); +let Interface = require('../core/interface'); +let Step = require('../models/step'); +import * as Interaction from '../util/interaction'; + +/** +* Pan2D +* +* @description Interface for moving a sound around an array of speakers. Speaker locations can be customized. The interface calculates the closeness of the sound source to each speaker and returns that distance as a numeric value. +* +* @demo +* +* @example +* var pan2d = new Nexus.Pan2d('#target') +* +* @example +* var pan2d = new Nexus.Pan2D('#target',{ +* 'size': [200,200], +* 'range': 0.5, // detection radius of each speaker +* 'mode': 'absolute', // 'absolute' or 'relative' sound movement +* 'speakers': [ // the speaker [x,y] positions +* [0.5,0.2], +* [0.75,0.25], +* [0.8,0.5], +* [0.75,0.75], +* [0.5,0.8], +* [0.25,0.75] +* [0.2,0.5], +* [0.25,0.25] +* ] +* }) +* +* @output +* change +* Fires any time the "source" node's position changes.
+* The event data is an array of the amplitudes (0-1), representing the level of each speaker (as calculated by its distance to the audio source). +* +* @outputexample +* pan2d.on('change',function(v) { +* console.log(v); +* }) +* +*/ + +export default class Pan2D extends Interface { + + constructor() { + + let options = ['range']; + + let defaults = { + 'size': [200,200], + 'range': 0.5, + 'mode': 'absolute', + 'speakers': [ + [0.5,0.2], + [0.75,0.25], + [0.8,0.5], + [0.75,0.75], + [0.5,0.8], + [0.25,0.75], + [0.2,0.5], + [0.25,0.25] + ] + }; + + super(arguments,options,defaults); + + this.value = { + x: new Step(0,1,0,0.5), + y: new Step(0,1,0,0.5) + }; + + /** + Absolute or relative mouse interaction. In "absolute" mode, the source node will jump to your mouse position on mouse click. In "relative" mode, it does not. + */ + this.mode = this.settings.mode; + + this.position = { + x: new Interaction.Handle(this.mode,'horizontal',[0,this.width],[this.height,0]), + y: new Interaction.Handle(this.mode,'vertical',[0,this.width],[this.height,0]) + }; + this.position.x.value = this.value.x.normalized; + this.position.y.value = this.value.y.normalized; + + /** + An array of speaker locations. Update this with .moveSpeaker() or .moveAllSpeakers() + */ + this.speakers = this.settings.speakers; + + /** + Rewrite: The maximum distance from a speaker that the source node can be for it to be heard from that speaker. A low range (0.1) will result in speakers only playing when the sound is very close it. Default is 0.5 (half of the interface). + */ + this.range = this.settings.range; + + /** + The current levels for each speaker. This is calculated when a source node or speaker node is moved through interaction or programatically. + */ + this.levels = []; + + this.init(); + + this.calculateLevels(); + this.render(); + + } + + buildInterface() { + + this.knob = svg.create('circle'); + + + this.element.appendChild(this.knob); + + + // add speakers + this.speakerElements = []; + + for (let i=0;i { + let distance = math.distance(s[0]*this.width,s[1]*this.height,this.position.x.value*this.width,(1-this.position.y.value)*this.height); + let level = math.clip(1-distance/(this.range*this.width),0,1); + this.levels.push(level); + this.speakerElements[i].setAttribute('fill-opacity', level); + }); + } + + /** + Move the audio source node and trigger the output event. + @param x {number} New x location, normalized 0-1 + @param y {number} New y location, normalized 0-1 + */ + moveSource(x,y) { + let location = { + x: x*this.width, + y: y*this.height + }; + this.position.x.update(location); + this.position.y.update(location); + this.calculateLevels(); + this.emit('change',this.levels); + this.render(); + } + + /** + Move a speaker node and trigger the output event. + @param index {number} Index of the speaker to move + @param x {number} New x location, normalized 0-1 + @param y {number} New y location, normalized 0-1 + */ + moveSpeaker(index,x,y) { + + this.speakers[index] = [x,y]; + this.speakerElements[index].setAttribute('cx', x*this.width); + this.speakerElements[index].setAttribute('cy', y*this.height); + this.calculateLevels(); + this.emit('change',this.levels); + this.render(); + + } + + /** + Set all speaker locations + @param locations {Array} Array of speaker locations. Each item in the array should be an array of normalized x and y coordinates. + + setSpeakers(locations) { + + } + */ + +} ADDED public/nexus-js/lib/interfaces/piano.js Index: public/nexus-js/lib/interfaces/piano.js ================================================================== --- public/nexus-js/lib/interfaces/piano.js +++ public/nexus-js/lib/interfaces/piano.js @@ -0,0 +1,434 @@ +'use strict'; + +let svg = require('../util/svg'); +let Interface = require('../core/interface'); +let ButtonTemplate = require('../components/buttontemplate'); +let touch = require('../util/touch'); + +class PianoKey extends ButtonTemplate { + + constructor() { + + let options = ['value','note','color']; + + let defaults = { + 'size': [80,80], + 'target': false, + 'mode': 'button', + 'value': 0 + }; + + super(arguments,options,defaults); + + this.note = this.settings.note; + this.color = this.settings.color; + + this.colors = { + 'w': '#fff', + 'b': '#666', + }; + + this.init(); + this.render(); + + } + + buildFrame() { + this.element = svg.create('svg'); + this.element.setAttribute('width',this.width); + this.element.setAttribute('height',this.height); + this.parent.appendChild(this.element); + } + + buildInterface() { + + this.pad = svg.create('rect'); + + this.element.appendChild(this.pad); + + this.interactionTarget = this.pad; + + /* events */ + + if (!touch.exists) { + + this.click = () => { + // console.log('click'); + this.piano.interacting = true; + this.piano.paintbrush = !this.state; + this.down(this.piano.paintbrush); + }; + + this.pad.addEventListener('mouseover', () => { + if (this.piano.interacting) { + // console.log('mouseover'); + this.down(this.piano.paintbrush); + } + }); + + + this.move = () => { + if (this.piano.interacting) { + // console.log('move'); + this.bend(); + } + }; + + + this.release = () => { + this.piano.interacting = false; + // console.log('release'); + // this.up(); + }; + this.pad.addEventListener('mouseup', () => { + if (this.piano.interacting) { + // console.log('mouseup'); + this.up(); + } + }); + this.pad.addEventListener('mouseout', () => { + if (this.piano.interacting) { + // console.log('mouseout'); + this.up(); + } + }); + + } + + } + + sizeInterface() { + + //let radius = Math.min(this.width,this.height) / 5; + let radius = 0; + + this.pad.setAttribute('x',0.5); + this.pad.setAttribute('y',0.5); + if (this.width > 2) { + this.pad.setAttribute('width', this.width - 1); + } else { + this.pad.setAttribute('width', this.width); + } + if (this.height > 2) { + this.pad.setAttribute('height', this.height); + } else { + this.pad.setAttribute('height', this.height); + } + this.pad.setAttribute('rx', radius); + this.pad.setAttribute('ry', radius); + + } + + render() { + if (!this.state) { + this.pad.setAttribute('fill', this.colors[this.color]); + } else { + this.pad.setAttribute('fill', this.colors.accent); + } + } + +} + +/** +* Piano +* +* @description Piano keyboard interface +* +* @demo
+* +* @example +* var piano = new Nexus.Piano('#target') +* +* @example +* var piano = new Nexus.Piano('#target',{ +* 'size': [500,125], +* 'mode': 'button', // 'button', 'toggle', or 'impulse' +* 'lowNote': 24, +* 'highNote': 60 +* }) +* +* @output +* change +* Fires any time a new key is pressed or released
+* The event data is an object containing note and state properties. +* +* @outputexample +* piano.on('change',function(v) { +* console.log(v); +* }) +* +*/ + +export default class Piano extends Interface { + + constructor() { + + let options = ['value']; + + let defaults = { + 'size': [500,125], + 'lowNote': 24, + 'highNote': 60, + 'mode': 'button' + }; + + super(arguments,options,defaults); + + this.keyPattern = ['w','b','w','b','w','w','b','w','b','w','b','w']; + + this.paintbrush = false; + + this.mode = this.settings.mode; + + this.range = { + low: this.settings.lowNote, + high: this.settings.highNote + }; + + this.range.size = this.range.high - this.range.low + 1; + + this.keys = []; + + this.toggleTo = false; + + this.init(); + this.render(); + + } + + buildFrame() { + this.element = document.createElement('div'); + this.element.style.position = 'relative'; + this.element.style.borderRadius = '0px'; + this.element.style.display = 'block'; + this.element.style.width = '100%'; + this.element.style.height = '100%'; + this.parent.appendChild(this.element); + } + + buildInterface() { + + this.keys = []; + + for (let i=0;i {}; + key.click = key.move = key.release = () => {}; + key.preTouch = key.preTouchMove = key.preTouchRelease = () => {}; + key.touch = key.touchMove = key.touchRelease = () => {}; + } + + this.keys.push(key); + this.element.appendChild(container); + + } + if (touch.exists) { + this.addTouchListeners(); + } + + } + + sizeInterface() { + + let keyX = 0; + + let keyPositions = []; + + for (let i=0;i= this.range.high) { + keyX += 1; + } else if (this.keyPattern[scaleIndex] === 'w' && this.keyPattern[nextScaleIndex] === 'w') { + keyX += 1; + } else { + keyX += 0.5; + } + } + let keysWide = keyX; + + + // let padding = this.width / 120; + let padding = 1; + let buttonWidth = (this.width-padding*2) / keysWide; + let buttonHeight = (this.height-padding*2) / 2; + + for (let i=0;i {}; + this.click = this.move = this.release = () => {}; + this.preTouch = this.preTouchMove = this.preTouchRelease = () => {}; + this.touch = this.touchMove = this.touchRelease = () => {}; + + const allActiveTouches = {}; + const keys = this.keys; + + function cloneTouch(touch) { + return { identifier: touch.identifier, clientX: touch.clientX, clientY: touch.clientY }; + } + + function updateKeyState() { + const allActiveKeys = {}; + + // Check/set "key-down" status for all keys that are currently touched. + Object.keys(allActiveTouches).forEach(id => { + const touch = allActiveTouches[id]; + const el = document.elementFromPoint(touch.clientX, touch.clientY); + let key = el ? keys[el.index] : null; + if (key) { + allActiveKeys[el.index] = id; + if (!key.state) { + key.down(); + } + } else { + delete allActiveTouches[id]; + } + }); + + // Set "key-up" status for all keys that are untouched. + keys.forEach(key => { + if (key.state && !allActiveKeys[key.pad.index]) { + key.up(); + } + }); + } + + function handleTouchStartAndMove(e) { + e.preventDefault(); + e.stopPropagation(); + for (let i = 0; i < e.changedTouches.length; i++){ + const touch = e.changedTouches[i]; + allActiveTouches[touch.identifier] = cloneTouch(touch); + } + updateKeyState(); + } + + function handleTouchEnd(e) { + e.preventDefault(); + e.stopPropagation(); + for (let i = 0; i < e.changedTouches.length; i++){ + const touch = e.changedTouches[i]; + delete allActiveTouches[touch.identifier]; + } + updateKeyState(); + } + + this.element.addEventListener('touchstart', handleTouchStartAndMove); + this.element.addEventListener('touchmove', handleTouchStartAndMove); + this.element.addEventListener('touchend', handleTouchEnd); + } + + /** + Define the pitch range (lowest and highest note) of the piano keyboard. + @param low {number} MIDI note value of the lowest note on the keyboard + @param high {number} MIDI note value of the highest note on the keyboard + */ + setRange(low,high) { + this.range.low = low; + this.range.high = high; + this.empty(); + this.buildInterface(); + } + + /** + Turn a key on or off using its MIDI note value; + @param note {number} MIDI note value of the key to change + @param on {boolean} Whether the note should turn on or off + */ + toggleKey(note, on) { + this.keys[note-this.range.low].flip(on); + } + + /** + Turn a key on or off using its key index on the piano interface. + @param index {number} Index of the key to change + @param on {boolean} Whether the note should turn on or off + */ + toggleIndex(index, on) { + this.keys[index].flip(on); + } + +} ADDED public/nexus-js/lib/interfaces/position.js Index: public/nexus-js/lib/interfaces/position.js ================================================================== --- public/nexus-js/lib/interfaces/position.js +++ public/nexus-js/lib/interfaces/position.js @@ -0,0 +1,301 @@ + +'use strict'; + +let svg = require('../util/svg'); +let Interface = require('../core/interface'); +let Step = require('../models/step'); +import * as Interaction from '../util/interaction'; + +/** +* Position +* +* @description Two-dimensional touch slider. +* +* @demo +* +* @example +* var position = new Nexus.Position('#target') +* +* @example +* var position = new Nexus.Position('#target',{ +* 'size': [200,200], +* 'mode': 'absolute', // "absolute" or "relative" +* 'x': 0.5, // initial x value +* 'minX': 0, +* 'maxX': 1, +* 'stepX': 0, +* 'y': 0.5, // initial y value +* 'minY': 0, +* 'maxY': 1, +* 'stepY': 0 +* }) +* +* @output +* change +* Fires any time the interface's value changes.
+* The event data is an object with x and y properties containing the x and y values of the interface. +* +* @outputexample +* position.on('change',function(v) { +* console.log(v); +* }) +* +* +*/ + +export default class Position extends Interface { + + constructor() { + + let options = ['value']; + + let defaults = { + 'size': [200,200], + 'mode': 'absolute', + 'minX': 0, + 'maxX': 1, + 'stepX': 0, + 'x': 0.5, + 'minY': 0, + 'maxY': 1, + 'stepY': 0, + 'y': 0.5 + }; + + super(arguments,options,defaults); + + + this._x = new Step( this.settings.minX, this.settings.maxX, this.settings.stepX, this.settings.x ); + this._y = new Step( this.settings.minY, this.settings.maxY, this.settings.stepY, this.settings.y ); + + this.position = { + x: new Interaction.Handle(this.settings.mode,'horizontal',[0,this.width],[this.height,0]), + y: new Interaction.Handle(this.settings.mode,'vertical',[0,this.width],[this.height,0]) + }; + this.position.x.value = this._x.normalized; + this.position.y.value = this._y.normalized; + + this.init(); + this.render(); + + } + + buildInterface() { + + this.knob = svg.create('circle'); + this.element.appendChild(this.knob); + + } + + sizeInterface() { + + this.position.x.resize([0,this.width],[this.height,0]); + this.position.y.resize([0,this.width],[this.height,0]); + + this._minDimension = Math.min(this.width,this.height); + + this.knobRadius = { + off: ~~(this._minDimension/100) * 5 + 5, + }; + this.knobRadius.on = this.knobRadius.off * 2; + + this.knob.setAttribute('cx',this.width/2); + this.knob.setAttribute('cy',this.height/2); + this.knob.setAttribute('r',this.knobRadius.off); + } + + colorInterface() { + this.element.style.backgroundColor = this.colors.fill; + this.knob.setAttribute('fill', this.colors.accent); + } + + render() { + if (this.clicked) { + // this.knobRadius = 30; + this.knob.setAttribute('r',this.knobRadius.on); + } else { + // this.knobRadius = 15; + this.knob.setAttribute('r',this.knobRadius.off); + } + + this.knobCoordinates = { + x: this._x.normalized * this.width, + y: this.height - this._y.normalized * this.height + }; + + this.knob.setAttribute('cx',this.knobCoordinates.x); + this.knob.setAttribute('cy',this.knobCoordinates.y); + } + + + click() { + this.position.x.anchor = this.mouse; + this.position.y.anchor = this.mouse; + this.move(); + } + + move() { + if (this.clicked) { + this.position.x.update(this.mouse); + this.position.y.update(this.mouse); + this._x.updateNormal( this.position.x.value ); + this._y.updateNormal( this.position.y.value ); + this.emit('change',{ + x: this._x.value, + y: this._y.value + }); + this.render(); + } + } + + release() { + this.render(); + } + + /** + * The interface's x value. When set, it will automatically adjust to fit min/max/step settings of the interface. + * @type {object} + * @example position.x = 0.5; + */ + + get x() { + return this._x.value; + } + + set x(value) { + this._x.update(value); + this.emit('change',{ + x: this._x.value, + y: this._y.value + }); + this.render(); + } + + /** + * The interface's y values. When set, it will automatically adjust to fit min/max/step settings of the interface. + * @type {object} + * @example position.x = 0.5; + */ + + get y() { + return this._y.value; + } + + set y(value) { + this._y.update(value); + this.emit('change',{ + x: this._x.value, + y: this._y.value + }); + this.render(); + } + + + + get normalized() { + return { + x: this._x.normalized, + y: this._y.normalized + }; + } + + /** + * The lower limit of value on the x axis + * @type {object} + */ + get minX() { + return this._x.min; + } + + set minX(v) { + this._x.min = v; + this.render(); + } + + /** + * The lower limit of value on the y axis + * @type {object} + */ + get minY() { + return this._y.min; + } + + set minY(v) { + this._y.min = v; + this.render(); + } + + + /** + * The upper limit of value on the x axis + * @type {object} + */ + get maxX() { + return this._x.max; + } + + set maxX(v) { + this._x.max = v; + this.render(); + } + + + /** + * The upper limit of value on the y axis + * @type {object} + */ + get maxY() { + return this._y.max; + } + + set maxY(v) { + this._y.max = v; + this.render(); + } + + + /** + * The incremental step of values on the x axis + * @type {object} + */ + get stepX() { + return this._x.step; + } + + set stepX(v) { + this._x.step = v; + this.render(); + } + + + /** + * The incremental step of values on the y axis + * @type {object} + */ + get stepY() { + return this._y.step; + } + + set stepY(v) { + this._y.step = v; + this.render(); + } + + + /** + Absolute mode (position's value jumps to mouse click position) or relative mode (mouse drag changes value relative to its current position). Default: "absolute". + @type {string} + @example position.mode = "relative"; + */ + get mode() { + return this.position.x.mode; + } + set mode(v) { + this.position.x.mode = v; + this.position.y.mode = v; + } + + + + +} ADDED public/nexus-js/lib/interfaces/radiobutton.js Index: public/nexus-js/lib/interfaces/radiobutton.js ================================================================== --- public/nexus-js/lib/interfaces/radiobutton.js +++ public/nexus-js/lib/interfaces/radiobutton.js @@ -0,0 +1,164 @@ +'use strict'; + +//let svg = require('../util/svg'); +let Interface = require('../core/interface'); +let Button = require('../interfaces/button'); + +/** + * RadioButton + * + * @description An array of buttons. By default, selecting one button will deselect all other buttons, but this can be customized using the API below. + * + * @demo
+ * + * @example + * var radiobutton = new Nexus.RadioButton('#target') + * + * @example + * var radiobutton = new Nexus.RadioButton('#target',{ + * 'size': [120,25], + * 'numberOfButtons': 4, + * 'active': -1 + * }) + * + * @output + * change + * Fires any time the interface's value changes.
+ * The event data an integer, the index of the button that is currently on. If no button is selected, the value will be -1. + * + * @outputexample + * radiobutton.on('change',function(v) { + * console.log(v); + * }) + * + */ + +export default class RadioButton extends Interface { + constructor() { + let options = ['value']; + + let defaults = { + size: [120, 25], + numberOfButtons: 4, + active: -1 + }; + + super(arguments, options, defaults); + + this.buttons = []; + this._numberOfButtons = this.settings.numberOfButtons; + this.active = this.settings.active; + + this.init(); + this.render(); + } + + buildFrame() { + this.element = document.createElement('div'); + this.parent.appendChild(this.element); + } + + buildInterface() { + for (let i = 0; i < this._numberOfButtons; i++) { + let container = document.createElement('span'); + + let button = new Button( + container, + { + mode: 'toggle', + component: true + }, + this.update.bind(this, i) + ); + + this.buttons.push(button); + this.element.appendChild(container); + } + } + + sizeInterface() { + let orientation; + if (this.width > this.height) { + orientation = 'horizontal'; + } else { + orientation = 'vertical'; + } + + let buttonWidth = + this.width / (orientation === 'vertical' ? 1 : this._numberOfButtons); + let buttonHeight = + this.height / (orientation === 'vertical' ? this._numberOfButtons : 1); + + for (let i = 0; i < this._numberOfButtons; i++) { + this.buttons[i].resize(buttonWidth, buttonHeight); + } + } + + colorInterface() { + for (let i = 0; i < this._numberOfButtons; i++) { + this.buttons[i].colors = this.colors; + this.buttons[i].render(); + } + } + + update(index) { + if (this.buttons[index].state) { + this.select(index); + } else { + this.deselect(); + } + // this.render(); + } + + render() { + for (let i = 0; i < this.buttons.length; i++) { + if (i === this.active) { + this.buttons[i].turnOn(false); + } else { + this.buttons[i].turnOff(false); + } + } + } + + /** + Select one button and deselect all other buttons. + @param index {number} The index of the button to select + */ + select(index) { + if (index >= 0 && index < this.buttons.length) { + this.active = index; + this.emit('change', this.active); + this.render(); + } + } + + /** + Deselect all buttons. + */ + deselect() { + this.active = -1; + this.emit('change', this.active); + this.render(); + } + + get numberOfButtons() { + return this._numberOfButtons; + } + + /** + * Update how many buttons are in the interface + * @param {number} buttons How many buttons are in the interface + */ + set numberOfButtons(buttons) { + this._numberOfButtons = buttons; + for (let i = 0; i < this.buttons.length; i++) { + this.buttons[i].destroy(); + } + this.buttons = []; + // for (let i=0;i +* +* @example +* var select = new Nexus.Select('#target') +* +* @example +* var select = new Nexus.Select('#target',{ +* 'size': [100,30], +* 'options': ['default','options'] +* }) +* +* @output +* change +* Fires any time the interface's value changes.
+* The event data is an object containing the text value of the selected option, as well as the numeric index of the selection. +* +* @outputexample +* select.on('change',function(v) { +* console.log(v); +* }) +* +* +*/ + + +export default class Select extends Interface { + + constructor() { + + let options = ['value']; + + let defaults = { + 'size': [100,30], + 'options': ['default','options'] + }; + + super(arguments,options,defaults); + + this._selectedIndex = -1; + this._value = false; + + this._options = this.settings.options; + + this.init(); + this.render(); + + } + + buildFrame() { + this.element = document.createElement('select'); + this.element.style.fontSize = this.height/2+'px'; + this.element.style.outline = 'none'; + this.element.style.highlight = 'none'; + this.element.style.width = this.width+'px'; + this.element.style.height = this.height+'px'; + + this.boundRender = this.render.bind(this); + + this.element.addEventListener('change', this.boundRender); + + this.parent.appendChild(this.element); + + } + + attachListeners() { + + } + + buildInterface() { + + this.defineOptions(); + + } + + colorInterface() { + this.element.style.backgroundColor = this.colors.fill; + this.element.style.color = this.colors.dark; + this.element.style.border = 'solid 0px '+this.colors.mediumLight; + } + + render() { + + this._value = this.element.options[this.element.selectedIndex].text; + this._selectedIndex = this.element.selectedIndex; + this.emit('change',{ + value: this._value, + index: this._selectedIndex + }); + + } + + click() { + + } + + move() { + + } + + release() { + + } + + /** + * Update the list of options. This removes all existing options and creates a new list of options. + * @param {array} options New array of options + */ + + defineOptions(options) { + + /* function removeOptions(selectbox) + { + var i; + for(i = selectbox.options.length - 1 ; i >= 0 ; i--) + { + selectbox.remove(i); + } + } + //using the function: + removeOptions(document.getElementById("mySelectObject")); */ + + + if (options) { + this._options = options; + } + + for(let i=this.element.options.length-1; i >= 0; i--) { + this.element.remove(i); + } + + for(let i=0;i { + this.matrix.interacting = true; + this.matrix.paintbrush = !this.state; + this.down(this.matrix.paintbrush); + }; + this.pad.addEventListener('mouseover', () => { + if (this.matrix.interacting) { + this.down(this.matrix.paintbrush); + } + }); + + this.move = () => {}; + this.pad.addEventListener('mousemove', e => { + if (this.matrix.interacting) { + if (!this.offset) { + this.offset = dom.findPosition(this.element); + } + this.mouse = dom.locateMouse(e, this.offset); + this.bend(); + } + }); + + this.release = () => { + this.matrix.interacting = false; + }; + this.pad.addEventListener('mouseup', () => { + if (this.matrix.interacting) { + this.up(); + } + }); + this.pad.addEventListener('mouseout', () => { + if (this.matrix.interacting) { + this.up(); + } + }); + } + } + + sizeInterface() { + this.pad.setAttribute('x', this.paddingColumn / 2); + this.pad.setAttribute('y', this.paddingRow / 2); + if (this.width > 2) { + this.pad.setAttribute('width', this.width - this.paddingColumn); + } else { + this.pad.setAttribute('width', this.width); + } + if (this.height > 2) { + this.pad.setAttribute('height', this.height - this.paddingRow); + } else { + this.pad.setAttribute('height', this.height); + } + this.pad.setAttribute('fill', this.matrix.colors.fill); + } + + render() { + if (!this.state) { + this.pad.setAttribute('fill', this.matrix.colors.fill); + } else { + this.pad.setAttribute('fill', this.matrix.colors.accent); + } + } +} + +/** + * Sequencer + * + * @description Grid of buttons with built-in step sequencer. + * + * @demo
+ * + * @example + * var sequencer = new Nexus.Sequencer('#target') + * + * @example + * var sequencer = new Nexus.Sequencer('#target',{ + * 'size': [400,200], + * 'mode': 'toggle', + * 'rows': 5, + * 'columns': 10, + * 'paddingRow': 10, + * 'paddingColumn': 20 + *}) + * + * @output + * change + * Fires whenever a value is received. For example, when clicking a cell from off to on.
+ * The event data is an object containing row (number), column (number), and state (boolean) properties. + * + * @outputexample + * sequencer.on('change',function(v) { + * console.log(v); + * }) + * + * @output + * step + * Fires any time the sequencer steps to the next column, in sequece mode.
+ * The event data is an array containing all values in the column, bottom row first. + * + * @outputexample + * sequencer.on('step',function(v) { + * console.log(v); + * }) + */ + +export default class Sequencer extends Interface { + constructor() { + let options = ['value']; + + let defaults = { + size: [400, 200], + mode: 'toggle', + rows: 5, + columns: 10 + }; + + super(arguments, options, defaults); + + this.active = -1; + + /** + * Button interaction mode: see Button + * @type {string} + * @example button.mode = 'toggle'; + */ + this.mode = this.settings.mode; + + /** + * The interval object which controls timing and sequence scheduling. + * @type {interval} + */ + this.interval = new Interval(200, function() {}, false); // jshint ignore:line + + /** + * A Matrix model containing methods for manipulating the sequencer's array of values. To learn how to manipulate the matrix, read about the matrix model. + * @type {matrix} + */ + this.matrix = new MatrixModel(this.settings.rows, this.settings.columns); + this.matrix.ui = this; + + /** + * A Counter model which the sequencer steps through. For example, you could use this model to step through the sequencer in reverse, randomly, or in a drunk walk. + * @type {counter} + */ + this.stepper = new CounterModel(0, this.columns); + + this.paddingRow = this.settings.paddingRow; + this.paddingColumn = this.settings.paddingColumn; + + this.init(); + } + + buildFrame() { + this.element = document.createElement('div'); + this.element.style.position = 'relative'; + this.element.style.display = 'block'; + this.element.style.width = '100%'; + this.element.style.height = '100%'; + this.parent.appendChild(this.element); + if (touch.exists) { + this.addTouchListeners(); + } + } + + buildInterface() { + this.cells = []; + for (let i = 0; i < this.matrix.length; i++) { + let location = this.matrix.locate(i); + // returns {row,col} + + let container = document.createElement('span'); + container.style.position = 'absolute'; + + let cell = new MatrixCell( + container, + { + component: true, + index: i, + row: location.row, + column: location.column, + mode: this.mode, + matrix: this, + paddingRow: this.paddingRow, + paddingColumn: this.paddingColumn + }, + this.keyChange.bind(this, i) + ); + + // cell.matrix = this; + if (touch.exists) { + cell.pad.index = i; + cell.preClick = cell.preMove = cell.preRelease = () => {}; + cell.click = cell.move = cell.release = () => {}; + cell.preTouch = cell.preTouchMove = cell.preTouchRelease = () => {}; + cell.touch = cell.touchMove = cell.touchRelease = () => {}; + } + + this.cells.push(cell); + this.element.appendChild(container); + } + this.sizeInterface(); + } + + sizeInterface() { + let cellWidth = this.width / this.columns; + let cellHeight = this.height / this.rows; + + for (let i = 0; i < this.cells.length; i++) { + let container = this.cells[i].parent; + container.style.left = this.cells[i].column * cellWidth + 'px'; + container.style.top = this.cells[i].row * cellHeight + 'px'; + this.cells[i].resize(cellWidth, cellHeight); + } + } + + colorInterface() { + for (var i = 0; i < this.cells.length; i++) { + this.cells[i].render(); + } + } + + update() { + // console.log("updating...") + //on = on || false; + this.matrix.iterate((r, c, i) => { + // console.log(this.matrix.pattern[r][c], this.cells[i].state); + if (this.matrix.pattern[r][c] !== this.cells[i].state) { + if (this.matrix.pattern[r][c] > 0) { + this.cells[i].turnOn(); + } else { + this.cells[i].turnOff(); + } + } + }); + } + + // update => cell.turnOn => cell.emit => keyChange (seq.emit) => matrix.set.cell => update + // + // interaction => keyChange => matrix.set.cell => update => cell.turnOn + // => emit + // + // set.cell => update => needs to emit. + + keyChange(note, on) { + // emit data for any key turning on/off + // i is the note index + // v is whether it is on or off + let cell = this.matrix.locate(note); + // this.matrix.set.cell(cell.column,cell.row,on); + this.matrix.pattern[cell.row][cell.column] = on; + var data = { + row: cell.row, + column: cell.column, + state: on + }; + this.emit('change', data); + } + + render() { + if (this.stepper.value >= 0) { + this.matrix.iterate((r, c, i) => { + if (c === this.stepper.value) { + this.cells[i].pad.setAttribute('stroke', this.colors.mediumLight); + this.cells[i].pad.setAttribute('stroke-width', '1'); + this.cells[i].pad.setAttribute('stroke-opacity', '1'); + } else { + this.cells[i].pad.setAttribute('stroke', 'none'); + } + }); + } + } + + /** + * Start sequencing + * @param {number} ms Beat tempo in milliseconds + */ + start(ms) { + this.interval.event = this.next.bind(this); + if (ms) { + this.interval.ms(ms); + } + this.interval.start(); + } + + /** + Stop sequencing + */ + stop() { + this.interval.stop(); + } + + /** + Manually jump to the next column and trigger the 'change' event. The "next" column is determined by your mode of sequencing. + */ + next() { + this.stepper.next(); + this.emit('step', this.matrix.column(this.stepper.value).reverse()); + this.render(); + } + + addTouchListeners() { + this.preClick = this.preMove = this.preRelease = () => {}; + this.click = this.move = this.release = () => {}; + this.preTouch = this.preTouchMove = this.preTouchRelease = () => {}; + this.touch = this.touchMove = this.touchRelease = () => {}; + + this.currentElement = false; + + this.element.addEventListener('touchstart', e => { + let element = document.elementFromPoint( + e.targetTouches[0].clientX, + e.targetTouches[0].clientY + ); + let cell = this.cells[element.index]; + this.paintbrush = !cell.state; + cell.down(this.paintbrush); + this.currentElement = element.index; + e.preventDefault(); + e.stopPropagation(); + }); + + this.element.addEventListener('touchmove', e => { + let element = document.elementFromPoint( + e.targetTouches[0].clientX, + e.targetTouches[0].clientY + ); + let cell = this.cells[element.index]; + if (element.index !== this.currentElement) { + if (this.currentElement >= 0) { + let pastCell = this.cells[this.currentElement]; + pastCell.up(); + } + cell.down(this.paintbrush); + } else { + cell.bend(); + } + this.currentElement = element.index; + e.preventDefault(); + e.stopPropagation(); + }); + + this.element.addEventListener('touchend', e => { + // no touches to calculate because none remaining + let cell = this.cells[this.currentElement]; + cell.up(); + this.interacting = false; + this.currentElement = false; + e.preventDefault(); + e.stopPropagation(); + }); + } + + /** + Number of rows in the sequencer + @type {number} + */ + get rows() { + return this.matrix.rows; + } + + set rows(v) { + this.matrix.rows = v; + this.empty(); + this.buildInterface(); + this.update(); + } + + /** + Number of columns in the sequencer + @type {number} + */ + get columns() { + return this.matrix.columns; + } + + set columns(v) { + this.matrix.columns = v; + this.stepper.max = v; + this.empty(); + this.buildInterface(); + this.update(); + } +} ADDED public/nexus-js/lib/interfaces/slider.js Index: public/nexus-js/lib/interfaces/slider.js ================================================================== --- public/nexus-js/lib/interfaces/slider.js +++ public/nexus-js/lib/interfaces/slider.js @@ -0,0 +1,277 @@ +'use strict'; + +let svg = require('../util/svg'); +let Interface = require('../core/interface'); +let Step = require('../models/step'); +import * as Interaction from '../util/interaction'; + +/** +* Slider +* +* @description Horizontal or vertical slider with settable interaction modes. +* +* @demo +* +* @example +* var slider = new Nexus.Slider('#target') +* +* @example +* var slider = new Nexus.Slider('#target',{ +* 'size': [120,20], +* 'mode': 'relative', // 'relative' or 'absolute' +* 'min': 0, +* 'max': 1, +* 'step': 0, +* 'value': 0 +* }) +* +* @output +* change +* Fires when the interface's value changes.
+* Event data: number The number value of the interface. +* +* @outputexample +* slider.on('change',function(v) { +* console.log(v); +* }) +* +* +*/ + +export default class Slider extends Interface { + + constructor() { + + let options = ['min','max','value']; + + let defaults = { + 'size': [120,20], + 'mode': 'relative', // 'relative' or 'absolute' + 'min': 0, + 'max': 1, + 'step': 0, + 'value': 0 + }; + + super(arguments,options,defaults); + + this.orientation = 'vertical'; // This will change automatically to 'horizontal'if the interface is wider than it is tall. + + this._value = new Step(this.settings.min, this.settings.max, this.settings.step, this.settings.value); + + this.position = new Interaction.Handle(this.settings.mode,this.orientation,[0,this.width],[this.height,0]); + this.position.value = this._value.normalized; + + this.init(); + + this.position.direction = this.orientation; + + this.emit('change',this.value); + + } + + buildInterface() { + + this.bar = svg.create('rect'); + this.fillbar = svg.create('rect'); + this.knob = svg.create('circle'); + + this.element.appendChild(this.bar); + this.element.appendChild(this.fillbar); + this.element.appendChild(this.knob); + + } + + sizeInterface() { + + if (this.width < this.height) { + this.orientation = 'vertical'; + this.position.direction = 'vertical'; + } else { + this.orientation = 'horizontal'; + this.position.direction = 'horizontal'; + } + + if (this.position) { + this.position.resize([0,this.width],[this.height,0]); + } + + let x, y, w, h, barOffset, cornerRadius; + this.knobData = { + level: 0, + r: 0 + }; + + if (this.orientation === 'vertical') { + this.thickness = this.width / 2; + x = this.width/2; + y = 0; + w = this.thickness; + h = this.height; + this.knobData.r = this.thickness * 0.8; + this.knobData.level = h-this.knobData.r-this.normalized*(h-this.knobData.r*2); + barOffset = 'translate('+this.thickness*(-1)/2+',0)'; + cornerRadius = w/2; + } else { + this.thickness = this.height / 2; + x = 0; + y = this.height/2; + w = this.width; + h = this.thickness; + this.knobData.r = this.thickness * 0.8; + this.knobData.level = this.normalized*(w-this.knobData.r*2)+this.knobData.r; + barOffset = 'translate(0,'+this.thickness*(-1)/2+')'; + cornerRadius = h/2; + } + + this.bar.setAttribute('x',x); + this.bar.setAttribute('y',y); + this.bar.setAttribute('transform',barOffset); + this.bar.setAttribute('rx',cornerRadius); // corner radius + this.bar.setAttribute('ry',cornerRadius); + this.bar.setAttribute('width',w); + this.bar.setAttribute('height',h); + + if (this.orientation === 'vertical') { + this.fillbar.setAttribute('x',x); + this.fillbar.setAttribute('y',this.knobData.level); + this.fillbar.setAttribute('width',w); + this.fillbar.setAttribute('height',h-this.knobData.level); + } else { + this.fillbar.setAttribute('x',0); + this.fillbar.setAttribute('y',y); + this.fillbar.setAttribute('width',this.knobData.level); + this.fillbar.setAttribute('height',h); + } + this.fillbar.setAttribute('transform',barOffset); + this.fillbar.setAttribute('rx',cornerRadius); + this.fillbar.setAttribute('ry',cornerRadius); + + if (this.orientation === 'vertical') { + this.knob.setAttribute('cx',x); + this.knob.setAttribute('cy',this.knobData.level); + } else { + this.knob.setAttribute('cx',this.knobData.level); + this.knob.setAttribute('cy',y); + } + this.knob.setAttribute('r',this.knobData.r); + + } + + colorInterface() { + this.bar.setAttribute('fill', this.colors.fill); + this.fillbar.setAttribute('fill', this.colors.accent); + this.knob.setAttribute('fill', this.colors.accent); + } + + + render() { + if (!this.clicked) { + this.knobData.r = this.thickness*0.75; + } + this.knob.setAttribute('r',this.knobData.r); + + if (this.orientation === 'vertical') { + this.knobData.level = this.knobData.r+this._value.normalized*(this.height-this.knobData.r*2); + this.knob.setAttribute('cy',this.height - this.knobData.level); + this.fillbar.setAttribute('y',this.height - this.knobData.level); + this.fillbar.setAttribute('height',this.knobData.level); + } else { + this.knobData.level = this._value.normalized*(this.width-this.knobData.r*2)+this.knobData.r; + this.knob.setAttribute('cx',this.knobData.level); + this.fillbar.setAttribute('x',0); + this.fillbar.setAttribute('width',this.knobData.level); + } + } + + + click() { + this.knobData.r = this.thickness*0.9; + this.position.anchor = this.mouse; + this.move(); + } + + move() { + if (this.clicked) { + this.position.update(this.mouse); + this._value.updateNormal( this.position.value ); + this.emit('change',this._value.value); + this.render(); + + } + } + + release() { + this.render(); + } + + get normalized() { + return this._value.normalized; + } + + /** + The slider's current value. If set manually, will update the interface and trigger the output event. + @type {number} + @example slider.value = 10; + */ + get value() { + return this._value.value; + } + set value(v) { + this._value.update(v); + this.position.value = this._value.normalized; + this.emit('change',this._value.value); + this.render(); + } + + /** + Lower limit of the sliders's output range + @type {number} + @example slider.min = 1000; + */ + get min() { + return this._value.min; + } + set min(v) { + this._value.min = v; + } + + /** + Upper limit of the slider's output range + @type {number} + @example slider.max = 1000; + */ + get max() { + return this._value.max; + } + set max(v) { + this._value.max = v; + } + + /** + The increment that the slider's value changes by. + @type {number} + @example slider.step = 5; + */ + get step() { + return this._value.step; + } + set step(v) { + this._value.step = v; + } + + /** + Absolute mode (slider's value jumps to mouse click position) or relative mode (mouse drag changes value relative to its current position). Default: "relative". + @type {string} + @example slider.mode = "relative"; + */ + get mode() { + return this.position.mode; + } + set mode(v) { + this.position.mode = v; + } + + + +} ADDED public/nexus-js/lib/interfaces/spectrogram.js Index: public/nexus-js/lib/interfaces/spectrogram.js ================================================================== --- public/nexus-js/lib/interfaces/spectrogram.js +++ public/nexus-js/lib/interfaces/spectrogram.js @@ -0,0 +1,154 @@ +'use strict'; + +let dom = require('../util/dom'); +let Interface = require('../core/interface'); + +/** + * Spectrogram + * + * @description Audio spectrum visualization + * + * @demo + * + * @example + * var spectrogram = new Nexus.Spectrogram('#target') + * spectrogram.connect(myWebAudioNode) + * + * @example + * var spectrogram = new Nexus.Spectrogram('#target',{ + * 'size': [300,150] + * }) + * spectrogram.connect(myWebAudioNode) + * + * @output + *   + * No events + * + */ + +export default class Spectrogram extends Interface { + constructor() { + let options = []; + + let defaults = { + size: [300, 150] + }; + + super(arguments, options, defaults); + + this.analyser = null; + this.bufferLength = 0; + this.dataArray = null; + this.active = false; + this.source = null; + + this.init(); + } + + buildFrame() { + this.canvas = new dom.SmartCanvas(this.parent); + this.element = this.canvas.element; + } + + sizeInterface() { + this.canvas.resize(this.width, this.height); + } + + colorInterface() { + this.canvas.element.style.backgroundColor = this.colors.fill; + } + + render() { + if (this.active) { + requestAnimationFrame(this.render.bind(this)); + } + + if (this.analyser) { + this.analyser.getByteFrequencyData(this.dataArray); + } + + this.canvas.context.fillStyle = this.colors.fill; + this.canvas.context.fillRect( + 0, + 0, + this.canvas.element.width, + this.canvas.element.height + ); + + if (this.source && this.dataArray) { + //console.log(this.dataArray); + + let barWidth = this.canvas.element.width / this.bufferLength; + let barHeight; + let x = 0; + + let definition = this.canvas.element.width / 50; + + for (let i = 0; i < this.bufferLength; i = i + definition) { + barHeight = Math.max.apply( + null, + this.dataArray.subarray(i, i + definition) + ); + barHeight /= 255; + barHeight *= this.canvas.element.height; + + this.canvas.context.fillStyle = this.colors.accent; + this.canvas.context.fillRect( + x, + this.canvas.element.height - barHeight, + barWidth * definition, + barHeight + ); + + x += barWidth * definition; + } + } + } + + /** + Equivalent to "patching in" an audio node to visualize. + @param node {AudioNode} The audio node to visualize + @example spectrogram.connect( Tone.Master ); + */ + connect(node) { + if (this.source) { + this.disconnect(); + } + + this.analyser = node.context.createAnalyser(); + this.analyser.fftSize = 2048; + this.bufferLength = this.analyser.frequencyBinCount; + this.dataArray = new Uint8Array(this.bufferLength); + + this.active = true; + + this.source = node; + this.source.connect(this.analyser); + + this.render(); + } + + /** + Stop visualizing the source node and disconnect it. + */ + disconnect() { + if (this.source) { + this.source.disconnect(this.analyser); + } + + this.analyser = null; + this.bufferLength = 0; + this.dataArray = null; + this.active = false; + this.source = null; + } + + click() { + this.active = !this.active && this.source; + this.render(); + } + + customDestroy() { + this.active = false; + } +} ADDED public/nexus-js/lib/interfaces/textbutton.js Index: public/nexus-js/lib/interfaces/textbutton.js ================================================================== --- public/nexus-js/lib/interfaces/textbutton.js +++ public/nexus-js/lib/interfaces/textbutton.js @@ -0,0 +1,154 @@ +'use strict'; + +let ButtonTemplate = require('../components/buttontemplate'); + +/** +* TextButton +* +* @description Text button +* +* @demo +* +* @example +* var textbutton = new Nexus.TextButton('#target') +* +* @example +* var textbutton = new Nexus.TextButton('#target',{ +* 'size': [150,50], +* 'state': false, +* 'text': 'Play', +* 'alternateText': 'Stop' +* }) +* +* @output +* change +* Fires any time the interface's value changes.
+* The event data is a string of the text on the button at the moment it was clicked. +* +* @outputexample +* textbutton.on('change',function(v) { +* console.log(v); +* }) +* +*/ + +export default class TextButton extends ButtonTemplate { + + constructor() { + + let options = ['value']; + + let defaults = { + 'size': [150,50], + 'state': false, + 'text': 'Play' + }; + + super(arguments,options,defaults); + + this._text = this.settings.text; + + if(this.settings.alternate){ //TODO: Remove this conditional in a breaking-changes release + this.settings.alternateText = this.settings.alternate; + console.warn("'alternate' initiator is deprecated. Use 'alternateText' instead."); + } + this._alternateText = this.settings.alternateText; + this.mode = (this.settings.alternateText) ? 'toggle' : 'button'; + this.init(); + this.render(); + + this.state = this.settings.state; + + } + + buildFrame() { + + this.element = document.createElement('div'); + this.parent.appendChild(this.element); + + this.textElement = document.createElement('div'); + this.textElement.innerHTML = this._text; + this.element.appendChild(this.textElement); + } + + buildInterface() { + + } + + colorInterface() { + this.element.style.color = this.colors.dark; + this.render(); + } + + sizeInterface() { + let textsize = this.height/3; + let textsize2 = (this.width / (this._text.length + 2) ); + textsize = Math.min(textsize,textsize2); + if (this.alternateText) { + let textsize3 = (this.width / (this.alternateText.length + 2) ); + textsize = Math.min(textsize,textsize3); + } + let styles = 'width: ' + this.width + 'px;'; + styles += 'height: ' + this.height + 'px;'; + styles += 'padding: '+(this.height-textsize)/2+'px 0px;'; + styles += 'box-sizing: border-box;'; + styles += 'text-align: center;'; + styles += 'font-family: inherit;'; + styles += 'font-weight: 700;'; + styles += 'opacity: 1;'; + styles += 'font-size:' + textsize + 'px;'; + this.textElement.style.cssText = styles; + this.render(); + } + + render() { + if (!this.state) { + this.element.style.backgroundColor = this.colors.fill; + this.textElement.style.color = this.colors.dark; + this.textElement.innerHTML = this._text; + } else { + this.element.style.backgroundColor = this.colors.accent; + this.textElement.style.color = this.colors.fill; + if (this.alternateText) { + this.textElement.innerHTML = this._alternateText; + } else { + this.textElement.innerHTML = this._text; + } + } + } + + /** + The text to display when the button is in its "on" state. If set, this puts the button in "toggle" mode. + @type {String} + */ + get alternateText() { + return this._alternateText; + } + + set alternateText(text) { + if (text) { + this.mode = 'toggle'; + } else { + this.mode = 'button'; + } + this._alternateText = text; + this.render(); + } + + + /** + The text to display. (If .alternateText exists, then this .text will only be displayed when the button is in its "off" state.) + @type {String} + */ + get text() { + return this._text; + } + + set text(text) { + this._text = text; + this.sizeInterface(); + this.render(); + } + + +} ADDED public/nexus-js/lib/interfaces/tilt.js Index: public/nexus-js/lib/interfaces/tilt.js ================================================================== --- public/nexus-js/lib/interfaces/tilt.js +++ public/nexus-js/lib/interfaces/tilt.js @@ -0,0 +1,309 @@ +'use strict'; + +let math = require('../util/math'); +let svg = require('../util/svg'); +let Interface = require('../core/interface'); + +/** +* Tilt +* +* @description Device tilt sensor with 2 or 3 axes (depending on your device and browser). +* +* @demo +* +* @example +* var tilt = new Nexus.Tilt('#target') +* +* @output +* change +* Fires at a regular interval, as long as this interface is active (see the interface's .active property)
+* The event data is an object containing x (number) and y (number) properties which represent the current tilt state of the device. +* +* @outputexample +* tilt.on('change',function(v) { +* console.log(v); +* }) +* +* +*/ + +export default class Tilt extends Interface { + + constructor() { + + let options = ['value']; + + let defaults = { + 'size': [80,80] + }; + + super(arguments,options,defaults); + + this._active = true; + + this.init(); + + // add event listener for device orientation + + this.boundUpdate = this.update.bind(this); + // this.boundMozTilt = this.mozTilt.bind(this) + + if (window.DeviceOrientationEvent) { + this.orientationListener = window.addEventListener('deviceorientation', this.boundUpdate, false); + } else { + this._active = false; + this.colorInterface(); + } + + + + /*else if (window.OrientationEvent) { + // window.addEventListener('MozOrientation', this.boundMozTilt, false); + } else { + console.log('Not supported on your device or browser.'); + } */ + + + } + + + buildInterface() { + + this.title = svg.create('text'); + this.circleX = svg.create('circle'); + this.circleY = svg.create('circle'); + this.circleZ = svg.create('circle'); + + this.barX = svg.create('path'); + this.barY = svg.create('path'); + this.barZ = svg.create('path'); + + this.barX2 = svg.create('path'); + this.barY2 = svg.create('path'); + this.barZ2 = svg.create('path'); + + this.barX.setAttribute('opacity','0.8'); + this.barY.setAttribute('opacity','0.8'); + this.barZ.setAttribute('opacity','0.8'); + this.barX2.setAttribute('opacity','0.8'); + this.barY2.setAttribute('opacity','0.8'); + this.barZ2.setAttribute('opacity','0.8'); + + this.circleX.setAttribute('cx',this.width*3/12); + this.circleX.setAttribute('cy',this.height*3/4); + this.circleX.setAttribute('r',this.height/10); + this.circleX.setAttribute('opacity','0.4'); + + this.circleY.setAttribute('cx',this.width*6/12); + this.circleY.setAttribute('cy',this.height*3/4); + this.circleY.setAttribute('r',this.height/10); + this.circleY.setAttribute('opacity','0.4'); + + this.circleZ.setAttribute('cx',this.width*9/12); + this.circleZ.setAttribute('cy',this.height*3/4); + this.circleZ.setAttribute('r',this.height/10); + this.circleZ.setAttribute('opacity','0.4'); + + + this.barX.setAttribute('stroke-width',Math.round(this.height/30)); + this.barY.setAttribute('stroke-width',Math.round(this.height/30)); + this.barZ.setAttribute('stroke-width',Math.round(this.height/30)); + + this.barX.setAttribute('fill', 'none'); + this.barY.setAttribute('fill', 'none'); + this.barZ.setAttribute('fill', 'none'); + + this.barX2.setAttribute('stroke-width',Math.round(this.height/30)); + this.barY2.setAttribute('stroke-width',Math.round(this.height/30)); + this.barZ2.setAttribute('stroke-width',Math.round(this.height/30)); + + this.barX2.setAttribute('fill', 'none'); + this.barY2.setAttribute('fill', 'none'); + this.barZ2.setAttribute('fill', 'none'); + + + this.title.setAttribute('x',this.width/2); + this.title.setAttribute('y',this.height/3+7); + this.title.setAttribute('font-size','15px'); + this.title.setAttribute('font-weight','bold'); + this.title.setAttribute('letter-spacing','2px'); + this.title.setAttribute('opacity','0.7'); + this.title.setAttribute('text-anchor','middle'); + this.title.textContent = 'TILT'; + + + this.element.appendChild(this.circleX); + this.element.appendChild(this.circleY); + this.element.appendChild(this.circleZ); + + this.element.appendChild(this.barX); + this.element.appendChild(this.barY); + this.element.appendChild(this.barZ); + + this.element.appendChild(this.barX2); + this.element.appendChild(this.barY2); + this.element.appendChild(this.barZ2); + + this.element.appendChild(this.title); + + } + + colorInterface() { + + if (this._active) { + this.element.style.backgroundColor = this.colors.accent; + this.circleX.setAttribute('fill',this.colors.light); + this.circleY.setAttribute('fill',this.colors.light); + this.circleZ.setAttribute('fill',this.colors.light); + this.circleX.setAttribute('stroke',this.colors.light); + this.circleY.setAttribute('stroke',this.colors.light); + this.circleZ.setAttribute('stroke',this.colors.light); + this.barX.setAttribute('stroke',this.colors.light); + this.barY.setAttribute('stroke',this.colors.light); + this.barZ.setAttribute('stroke',this.colors.light); + this.barX2.setAttribute('stroke',this.colors.light); + this.barY2.setAttribute('stroke',this.colors.light); + this.barZ2.setAttribute('stroke',this.colors.light); + this.title.setAttribute('fill',this.colors.light); + } else { + this.element.style.backgroundColor = this.colors.fill; + this.circleX.setAttribute('fill',this.colors.mediumLight); + this.circleY.setAttribute('fill',this.colors.mediumLight); + this.circleZ.setAttribute('fill',this.colors.mediumLight); + this.circleX.setAttribute('stroke',this.colors.mediumLight); + this.circleY.setAttribute('stroke',this.colors.mediumLight); + this.circleZ.setAttribute('stroke',this.colors.mediumLight); + this.barX.setAttribute('stroke',this.colors.mediumLight); + this.barY.setAttribute('stroke',this.colors.mediumLight); + this.barZ.setAttribute('stroke',this.colors.mediumLight); + this.barX2.setAttribute('stroke',this.colors.mediumLight); + this.barY2.setAttribute('stroke',this.colors.mediumLight); + this.barZ2.setAttribute('stroke',this.colors.mediumLight); + this.title.setAttribute('fill',this.colors.mediumLight); + } + + } + + update(v) { + if (this._active){ + + let y = v.beta; + let x = v.gamma; + let z = v.alpha; + + // take the original -90 to 90 scale and normalize it 0-1 + x = math.scale(x,-90,90,0,1); + y = math.scale(y,-90,90,0,1); + z = math.scale(z,0,360,0,1); + + + let handlePoints = { + start: Math.PI*1.5, + end: math.clip( math.scale(x,0,0.5,Math.PI*1.5,Math.PI*0.5) , Math.PI*0.5, Math.PI*1.5 ) + }; + let handle2Points = { + start: Math.PI*2.5, + end: math.clip( math.scale(x,0.5,1,Math.PI*2.5,Math.PI*1.5) , Math.PI*1.5, Math.PI*2.5 ) + }; + + let handlePath = svg.arc(this.circleX.cx.baseVal.value, this.circleX.cy.baseVal.value, this.circleX.r.baseVal.value, handlePoints.start, handlePoints.end); + let handle2Path = svg.arc(this.circleX.cx.baseVal.value, this.circleX.cy.baseVal.value, this.circleX.r.baseVal.value, handle2Points.start, handle2Points.end); + + this.barX.setAttribute('d', handlePath); + this.barX2.setAttribute('d', handle2Path); + + + + + + handlePoints = { + start: Math.PI*1.5, + end: math.clip( math.scale(y,0,0.5,Math.PI*1.5,Math.PI*0.5) , Math.PI*0.5, Math.PI*1.5 ) + }; + handle2Points = { + start: Math.PI*2.5, + end: math.clip( math.scale(y,0.5,1,Math.PI*2.5,Math.PI*1.5) , Math.PI*1.5, Math.PI*2.5 ) + }; + + handlePath = svg.arc(this.circleY.cx.baseVal.value, this.circleY.cy.baseVal.value, this.circleY.r.baseVal.value, handlePoints.start, handlePoints.end); + handle2Path = svg.arc(this.circleY.cx.baseVal.value, this.circleY.cy.baseVal.value, this.circleY.r.baseVal.value, handle2Points.start, handle2Points.end); + + this.barY.setAttribute('d', handlePath); + this.barY2.setAttribute('d', handle2Path); + + + + + + + handlePoints = { + start: Math.PI*1.5, + end: math.clip( math.scale(z,0,0.5,Math.PI*1.5,Math.PI*0.5) , Math.PI*0.5, Math.PI*1.5 ) + }; + handle2Points = { + start: Math.PI*2.5, + end: math.clip( math.scale(z,0.5,1,Math.PI*2.5,Math.PI*1.5) , Math.PI*1.5, Math.PI*2.5 ) + }; + + handlePath = svg.arc(this.circleZ.cx.baseVal.value, this.circleZ.cy.baseVal.value, this.circleZ.r.baseVal.value, handlePoints.start, handlePoints.end); + handle2Path = svg.arc(this.circleZ.cx.baseVal.value, this.circleZ.cy.baseVal.value, this.circleZ.r.baseVal.value, handle2Points.start, handle2Points.end); + + this.barZ.setAttribute('d', handlePath); + this.barZ2.setAttribute('d', handle2Path); + + + /* + + let pointsX = { + start: 0, + end: math.scale( x, 0, 1, 0, Math.PI*2 ) + }; + + // console.log(this.circleX.cx.baseVal.value); + + let pathX = svg.arc(this.circleX.cx.baseVal.value, this.circleX.cy.baseVal.value, this.circleX.r.baseVal.value*2, pointsX.start, pointsX.end); + + this.barX.setAttribute('d',pathX); */ + + //this.textH.textContent = math.prune(x,2); + //this.textV.textContent = math.prune(y,2); + // + // this.circleX.setAttribute('opacity',x); + // this.circleY.setAttribute('opacity',y); + // this.circleZ.setAttribute('opacity',z); + + this.emit('change', { + x: x, + y: y, + z: z + }); + + } + + } + + click() { + if (window.DeviceOrientationEvent) { + this.active = !this.active; + } + } + + /** + Whether the interface is on (emitting values) or off (paused & not emitting values). Setting this property will update it. + @type {boolean} + */ + + get active() { + return this._active; + } + + set active(on) { + this._active = on; + this.colorInterface(); + } + + customDestroy() { + window.removeEventListener('deviceorientation', this.boundUpdate, false); + } + +} ADDED public/nexus-js/lib/interfaces/toggle.js Index: public/nexus-js/lib/interfaces/toggle.js ================================================================== --- public/nexus-js/lib/interfaces/toggle.js +++ public/nexus-js/lib/interfaces/toggle.js @@ -0,0 +1,131 @@ +'use strict'; + +let svg = require('../util/svg'); +let ToggleModel = require('../models/toggle'); +let Interface = require('../core/interface'); + +/** +* Toggle +* +* @description Binary switch +* +* @demo +* +* @example +* var toggle = new Nexus.Toggle('#target') +* +* @example +* var toggle = new Nexus.Toggle('#target',{ +* 'size': [40,20], +* 'state': false +* }) +* +* @output +* change +* Fires any time the interface's value changes.
+* Parameter: The boolean state of the interface. +* +* @outputexample +* toggle.on('change',function(v) { +* console.log(v); +* }) +* +* +*/ +export default class Toggle extends Interface { + + constructor() { + + let options = ['value']; + + let defaults = { + 'size': [40,20], + 'target': false, + 'state': false + }; + + super(arguments,options,defaults); + + this._state = new ToggleModel(this.settings.state); + + this.init(); + + } + + buildInterface() { + + this.bar = svg.create('rect'); + this.knob = svg.create('circle'); + this.element.appendChild(this.bar); + this.element.appendChild(this.knob); + + } + + sizeInterface() { + + if (this.height < this.width/2) { + this.knobSize = this.height/2; + } else { + this.knobSize = this.width/4; + } + + this.bar.setAttribute('x',this.width/2 - this.knobSize*1.5); + this.bar.setAttribute('y',this.height/2 - this.knobSize/2); + this.bar.setAttribute('rx',this.knobSize/2); + this.bar.setAttribute('ry',this.knobSize/2); + this.bar.setAttribute('width',this.knobSize*3); + this.bar.setAttribute('height',this.knobSize); + + this.knob.setAttribute('cx',this.width/2 - this.knobSize); + this.knob.setAttribute('cy',this.height/2); + this.knob.setAttribute('r',this.knobSize); + + } + + colorInterface() { + this.knob.setAttribute('fill', this.colors.accent); + this.render(); + } + + render() { + if (!this.state) { + this.knob.setAttribute('cx',this.width/2 - this.knobSize); + this.bar.setAttribute('fill', this.colors.fill); + } else { + this.knob.setAttribute('cx',this.width/2 + this.knobSize); + this.bar.setAttribute('fill', this.colors.accent); + } + } + + click() { + this.flip(); + this.render(); + this.emit('change',this.state); + } + + /** + Whether the toggle is currently on or off. Setting this property will update the toggle interface and trigger the output event. + @type {boolean} + @example toggle.state = false; + */ + get state() { + return this._state.state; + } + set state(value) { + this._state.flip(value); + this.emit('change',this.state); + this.render(); + } + + + /** + * Switch the toggle state to its opposite state + * @example + * toggle.flip(); + */ + flip() { + this._state.flip(); + this.render(); + } + +} ADDED public/nexus-js/lib/main.js Index: public/nexus-js/lib/main.js ================================================================== --- public/nexus-js/lib/main.js +++ public/nexus-js/lib/main.js @@ -0,0 +1,118 @@ +'use strict'; + +import Interfaces from './interfaces/'; +import math from './util/math'; +import Rack from './core/rack'; +import Tune from './tuning/tuning'; +import * as Transform from './util/transform'; + +let Counter = require('./models/counter'); +let Radio = require('./models/radio'); +let Drunk = require('./models/drunk'); +let Sequence = require('./models/sequence'); +let Matrix = require('./models/matrix'); + +import WAAClock from 'waaclock'; +import Interval from './time/interval'; + + +/** +NexusUI => created as Nexus +*/ + +class NexusUI { + + constructor(context) { + + for (let key in Interfaces) { + this[key] = Interfaces[key]; + } + + for (let key in math) { + this[key] = math[key]; + } + + let Core = { + 'Rack': Rack + }; + + let Models = { + 'Counter': Counter, + 'Radio': Radio, + 'Drunk': Drunk, + 'Sequence': Sequence, + 'Matrix': Matrix + }; + + for (let key in Models) { + this[key] = Models[key]; + } + + for (let key in Core) { + this[key] = Core[key]; + } + + let DefaultContext = window.AudioContext || window.webkitAudioContext; + this._context = context || new DefaultContext(); + + this.tune = new Tune(); + this.note = this.tune.note.bind(this.tune); + + this.clock = new WAAClock(this._context); + this.clock.start(); + this.Interval = Interval; + + this.colors = { + accent: '#2bb', + fill: '#eee', + light: '#fff', + dark: '#333', + mediumLight: '#ccc', + mediumDark: '#666' + }; + + this.transform = Transform; + this.add = Transform.add; + + + this.Add = {}; + for (let key in Interfaces) { + this.Add[key] = Transform.add.bind(this,key); + } + + /* create default component size as 1st style element in document */ + var defaultStyleNode = document.createElement('style'); + defaultStyleNode.type = 'text/css'; + defaultStyleNode.innerHTML = '[nexus-ui]{height:5000px;width:5000px}'; + var h = document.head; + h.insertBefore(defaultStyleNode, h.firstElementChild); + } + + get context() { + return this._context; + } + + set context(ctx) { + this.clock.stop(); + this._context = ctx; + this.clock = new WAAClock(this.context); + this.clock.start(); + } + + + +} + +let Nexus = new NexusUI(); + +export function colors() { + return Nexus.colors; +} +export function context() { + return Nexus.context; +} +export function clock() { + return Nexus.clock; +} + +export default Nexus; ADDED public/nexus-js/lib/models/counter.js Index: public/nexus-js/lib/models/counter.js ================================================================== --- public/nexus-js/lib/models/counter.js +++ public/nexus-js/lib/models/counter.js @@ -0,0 +1,80 @@ +'use strict'; + +import math from '../util/math'; +import Drunk from './drunk'; + +export default class Counter { + + constructor(min=0, max=10, mode='up', value=false) { + this.min = min; + this.max = max; + this.value = value; + this.mode = mode; + this.drunkWalk = new Drunk(this.min, this.max); + if (this.value!==false) { + this.next = this[this._mode]; + } else { + this.next = this.first; + } + } + + set mode(mode) { + if (!(mode === 'up' || mode === 'down' || mode === 'random' || mode === 'drunk')) { + console.error('The only modes currently allowed are: up, down, random, drunk'); + return; + } + this._mode = mode; + if (this.value) { + this.next = this[this._mode]; + } + } + + get mode() { + return this._mode; + } + + first() { + if (this.value!==false) { + this.next = this[this._mode]; + return this.next(); + } + this.startValues = { + 'up': this.min, + 'down': this.max, + 'drunk': ~~math.average(this.min,this.max), + 'random': math.ri(this.min,this.max) + }; + this.value = this.startValues[this._mode]; + this.next = this[this._mode]; + return this.value; + } + + up() { + this.value++; + if (this.value >= this.max) { + this.value = this.min; + } + return this.value; + } + + down() { + this.value--; + if (this.value < this.min) { + this.value = this.max; + } + return this.value; + } + + random() { + this.value = math.ri(this.min, this.max); + return this.value; + } + + drunk() { + this.drunkWalk.min = this.min; + this.drunkWalk.max = this.max; + this.drunkWalk.value = this.value; + this.value = this.drunkWalk.next(); + return this.value; + } +} ADDED public/nexus-js/lib/models/drunk.js Index: public/nexus-js/lib/models/drunk.js ================================================================== --- public/nexus-js/lib/models/drunk.js +++ public/nexus-js/lib/models/drunk.js @@ -0,0 +1,34 @@ +'use strict'; + +import math from '../util/math'; + +export default class Drunk { + + constructor(min=0, max=9, value=0, increment=1, loop=false) { + this.min = min; + this.max = max; + this.value = value; + this.increment = increment; + this.loop = loop; + } + + next() { + this.value += math.pick(-1 * this.increment, this.increment); + if (this.value > this.max) { + if (this.loop) { + this.value = this.min; + } else { + this.value = this.max - this.increment; + } + } + + if (this.value < this.min) { + if (this.loop) { + this.value = this.max; + } else { + this.value = this.min + this.increment; + } + } + return this.value; + } +} ADDED public/nexus-js/lib/models/matrix.js Index: public/nexus-js/lib/models/matrix.js ================================================================== --- public/nexus-js/lib/models/matrix.js +++ public/nexus-js/lib/models/matrix.js @@ -0,0 +1,277 @@ +'use strict'; + +import math from '../util/math'; +import Sequence from '../models/sequence'; + +// For the tutorial, looking at + +//Pattern section: +// .create(), .rows, .columns, +// .pattern, .length, .formatAsText(), .log(), +// .locate(i), .indexOf(c,r) +// row(), column() (returns contents of row or colum) + +//Control section: +// toggle x3 +// set x4 +// rotate x3 +// populate x3 +// erase x3 + + +// should some version of this have a float value for each cell? +// could be like a mirror .pattern that has values. by default, everything is 1, but could be set... +// not a good way to do that on interface, but as a model it would be nice... +// for .formatAsText(), could multiply by 100 and floor, so each cell is an int from 0 to 9 + +export default class Matrix { + + constructor(rows,columns) { + // should also have ability to create using an existing matrix (2d array) + this.pattern = []; + this.create(rows,columns); + + this.toggle = { + cell: (column, row) => { + this.pattern[row][column] = !this.pattern[row][column]; // math.invert(this.pattern[row][column]); + if (this.ui) { this.ui.update(); } + return this.pattern[row][column]; + }, + all: () => { + this.iterate((r,c) => { this.toggle.cell(c,r); }); + if (this.ui) { this.ui.update(); } + }, + row: (row) => { + for (let i=0; i { + for (let i=0; i { + this.pattern[row][column] = value; + if (this.ui) { this.ui.update(); } + }, + all: (values) => { + // set the whole matrix using a 2d array as input + // this should also resize the array? + this.pattern = values; + if (this.ui) { this.ui.update(); } + }, + row: (row,values) => { + // set a row using an array as input + this.pattern[row] = values; + if (this.ui) { this.ui.update(); } + }, + column: (column,values) => { + // set a column using an array as input + this.pattern.forEach((row,i) => { + this.pattern[i][column] = values[i]; + }); + if (this.ui) { this.ui.update(); } + } + }; + + this.rotate = { + //should eventually do (amountX, amountY) here + // could just use a loop and this.rotate.row(i,amountX); + all: (amount) => { + if (!amount && amount!==0) { + amount = 1; + } + amount %= this.pattern[0].length; + if (amount < 0) { + amount = this.pattern[0].length + amount; + } + for (let i=0; i { + if (!amount && amount!==0) { + amount = 1; + } + amount %= this.pattern[0].length; + if (amount < 0) { + amount = this.pattern[0].length + amount; + } + let cut = this.pattern[row].splice( this.pattern[row].length - amount, amount ); + this.pattern[row] = cut.concat( this.pattern[row] ); + if (this.ui) { this.ui.update(); } + }, + column: (column, amount) => { + if (!amount && amount!==0) { + amount = 1; + } + amount %= this.pattern.length; + if (amount < 0) { + amount = this.pattern.length + amount; + } + let proxy = []; + this.pattern.forEach((row) => { + proxy.push( row[column] ); + }); + let cut = proxy.splice( proxy.length - amount, amount ); + proxy = cut.concat( proxy ); + this.pattern.forEach((row,i) => { + row[column] = proxy[i]; + }); + if (this.ui) { this.ui.update(); } + } + }; + + // the idea behind populate is to be able to set a whole row or column to 0 or 1 + // IF the value is a float, such as 0.7, then it would become a probability + // so populate(0.7) would give each cell a 70% chance of being 1 + this.populate = { + all: (odds) => { + let oddsSequence = new Sequence(odds); + this.iterate((r,c) => { + this.pattern[r][c] = math.coin(oddsSequence.next()); + }); + // This could be used so that each row has same odds pattern, even if row length is not divisibly by sequence length. + //,() => { + // odds.pos = -1; + // } + if (this.ui) { this.ui.update(); } + }, + row: (row=0,odds=1) => { + let oddsSequence = new Sequence(odds); + this.pattern[row].forEach((cell,i) => { + this.pattern[row][i] = math.coin(oddsSequence.next()); + }); + if (this.ui) { this.ui.update(); } + }, + column: (column=0,odds=1) => { + let oddsSequence = new Sequence(odds); + this.pattern.forEach((row,i) => { + this.pattern[i][column] = math.coin(oddsSequence.next()); + }); + if (this.ui) { this.ui.update(); } + } + }; + + // essentiall populate(0) so i'm not sure if this is necessary but is nice + this.erase = { + all: () => { + this.set.all(0); + }, + row: (row) => { + this.set.row(row,0); + }, + column: (column) => { + this.set.column(column,0); + } + }; + + // end constructor + } + + + create(rows,columns) { + this.pattern = []; + for ( let row=0; row < rows; row++ ) { + let arr = new Array(columns); + this.pattern.push(arr); + } + this.iterate((r,c) => { this.pattern[r][c] = false; }); + } + + iterate(f, f2) { + let i = 0; + for ( let row=0; row < this.rows; row++ ) { + if (f2) { f2(row); } + for ( let column=0; column < this.columns; column++ ) { + f(row,column,i); + i++; + } + } + } + + formatAsText() { + let patternString = ''; + this.iterate( + (r,c) => { patternString += (this.pattern[r][c] ? 1 : 0) + ' '; }, + () => { patternString += '\n'; } + ); + return patternString; + } + + log() { + console.log(this.formatAsText()); + } + + update(pattern) { + this.pattern = pattern || this.pattern; + } + + get length() { + return this.rows*this.columns; + } + + locate(index) { + // returns row and column of cell by index + return { + row: ~~( index / this.columns ), + column: index % this.columns + }; + } + + indexOf(row,column) { + return column + row * this.columns; + // returns index of cell by row and column + } + + row(row) { + let data = []; + for (let i=0; i { + if (previous[r] && previous[r][c]) { + this.pattern[r][c] = previous[r][c]; + } + }); + } + + get columns() { + return this.pattern[0].length; + } + set columns(v) { + let previous = this.pattern.slice(0); + this.create(this.rows,v); + this.iterate((r,c) => { + if (previous[r] && previous[r][c]) { + this.pattern[r][c] = previous[r][c]; + } + }); + } + +} ADDED public/nexus-js/lib/models/radio.js Index: public/nexus-js/lib/models/radio.js ================================================================== --- public/nexus-js/lib/models/radio.js +++ public/nexus-js/lib/models/radio.js @@ -0,0 +1,82 @@ +'use strict'; + +//Disable jshint warning concerning trailing regular params +/*jshint -W138 */ + +export default class Radio { + //if non-existent buttons are switched, they are ignored + + constructor(length = 3, ...onVals) { + //each optional 'onVals' argument switches on that value in the Radio if it exists + //In the example below, a 3-button radio is created, index 0 is switched on, index 1 is switched on then then attempted again producing an warning, and the final argument produces a warning because the index value does not exist. + //Example: + //` radio = new Radio(3, 0, 1, 1, 3); + //… [1,1,0] + + if (length < 0) { length = 1; } + + this.length = length; + this.onVals = onVals; + this.array = new Array(length).fill(0); + + if (onVals.length > 0) { + this.on(...onVals); + } + } + + select(value) { + this.array.fill(0); + this.array[value] = 1; + return this.array; + } + + flip(...values) { + //flips the specified values. if no value is specified, flips all buttons + let a = this.array; + if (values.length > 0) { + values.forEach(function(v) { + if (v > a.length - 1) { + console.warn('Warning: AnonRadio[' + v + '] does not exist'); + } else { + a[v] = (a[v] ? 0 : 1); + } + }); + } else { + a.forEach(function(v, i, arr) { + arr[i] = (v ? 0 : 1); + }); + } + return a; + } + + on(...values) { + //switch on the specified values. if no value specified, flips on all buttons + let a = this.array; + if (values.length > 0) { + values.forEach(function(v) { + if (v > a.length - 1) { + console.warn('Warning: AnonRadio[' + v + '] exceeds size of object'); + } else { + if (a[v] === 1) { console.warn('Warning: AnonRadio[' + v + '] was already on.'); } + a[v] = 1; + } + }); + } else { + a.fill(1); + } + return a; + } + + off(...values) { + //switch off the specified values. if no value specified, flips off all buttons + let a = this.array; + if (values.length > 0) { + values.forEach(function(v) { + a[v] = 0; + }); + } else { + a.fill(0); + } + return a; + } +} ADDED public/nexus-js/lib/models/range.js Index: public/nexus-js/lib/models/range.js ================================================================== --- public/nexus-js/lib/models/range.js +++ public/nexus-js/lib/models/range.js @@ -0,0 +1,84 @@ +'use strict'; + +import Step from './step'; + +/** + Creates an abstract model of a steppable range slider with start and end values which are constricted by a minimum, maximum, and step size. + @param {number} [min=0] minimum + @param {number} [max=1] maximum + @param {number} [step=0] + @returns {Object} Step +*/ + +export default class Range { + + constructor(min = 0,max = 1,step = false) { + + /** + {number} Minimum value of the range + */ + this.min = min; + + /** + {number} Maximum value of the range + */ + this.max = max; + + /** + {Step} Start value of the range selection + */ + this.start = new Step(min,max,step); + + /** + {Step} End value of the range selection + */ + this.end = new Step(min,max,step); + } + + /** + {number} Center of the range selection + */ + get center() { + return this.start.value + (this.end.value - this.start.value)/2; + } + + set center(value) { + let size = this.end.value-this.start.value; + console.log('===='); + console.log(this.start.value); + console.log(this.end.value); + this.start.update( value - size/2 ); + this.end.update( this.start.value + size ); + } + + /** + {number} Size of the range selection + */ + get size() { + return this.end.value - this.start.value; + } + + set size(size) { + let center = this.center; + this.start.update(center - size/2); + // Ensure that the range slsection _is_ the size desired, even if it changes the center. + this.end.update(this.start.value + size); + //this.end.update(center + size/2); + } + + + /** + Move the range selection + @param {number} start New start value of the range selection + @param {number} end New end value of the range selection + */ + move(start,end) { + if (start) { + this.start.update(start); + } + if (end) { + this.end.update(end); + } + } + +} ADDED public/nexus-js/lib/models/sequence.js Index: public/nexus-js/lib/models/sequence.js ================================================================== --- public/nexus-js/lib/models/sequence.js +++ public/nexus-js/lib/models/sequence.js @@ -0,0 +1,98 @@ +'use strict'; + +import math from '../util/math'; +import Drunk from './drunk'; + +export default class Sequence { + + constructor(sequence = [0,10,20,30], mode='up', position=false) { + this.values = sequence; + if (!Array.isArray(this.values)) { + this.values = [this.values]; + } + this._mode = mode; + this.position = position; + + this.drunkWalk = new Drunk(0, this.values.length - 1); + + this.startValues = { + 'up': 0, + 'down': this.values.length - 1, + 'drunk': ~~(this.values.length/2), + 'random': math.ri(this.values.length) + }; + + if (this.position!==false) { + this.next = this[this._mode]; + } else { + this.next = this.first; + } + + + } + + get mode() { + return this._mode; + } + + set mode(mode) { + if (!(mode === 'up' || mode === 'down' || mode === 'random' || mode === 'drunk')) { + console.error('The only modes currently allowed are: up, down, random, drunk'); + return; + } + this._mode = mode; + if (this.position) { + this.next = this[this._mode]; + } + } + + get value() { + return this.values[this.position]; + } + + set value(v) { + this.position = this.values.indexOf(v); + } + + first() { + if (this.position!==false) { + this.next = this[this._mode]; + return this.next(); + } + this.position = this.startValues[this._mode]; + this.next = this[this._mode]; + return this.value; + } + + up() { + this.position++; + this.position %= this.values.length; + return this.value; + } + + down() { + this.position--; + if (this.position < 0) { + this.position = (this.position + this.values.length) % this.values.length; + } + return this.value; + } + + random() { + this.position = math.ri(0, this.values.length); + return this.value; + } + + drunk() { + this.drunkWalk.max = this.values.length; + this.drunkWalk.value = this.position; + this.position = this.drunkWalk.next(); + return this.value; + } + + /* future methods + .group(start,stop) -- outputs a group of n items from the list, with wrapping + .loop(start,stop) -- confines sequencing to a subset of the values + (could even have a distinction between .originalValues and the array of values being used) + */ +} ADDED public/nexus-js/lib/models/step.js Index: public/nexus-js/lib/models/step.js ================================================================== --- public/nexus-js/lib/models/step.js +++ public/nexus-js/lib/models/step.js @@ -0,0 +1,66 @@ +'use strict'; + +let math = require('../util/math'); + +/** + Creates a steppable value with minimum, maximum, and step size. This is used in many interfaces to constrict their values to certain ranges. + @param {number} [min=0] minimum + @param {number} [max=1] maximum + @param {number} [step=0] + @param {number} [value=0] initial value + @returns {Object} Step +*/ + +export default class Step { + + constructor(min = 0,max = 1,step = 0,value = 0) { + //Object.assign(this,{min,max,step}); + //Cannot use Object.assign because not supported in Safari. + //I would expect for Babel to take care of this but it is not. + this.min = min; + this.max = max; + this.step = step; + this.value = value; + this.changed = false; + this.oldValue = false; + this.update(this.value); + } + + /** + Update with a new value. The value will be auto-adjusted to fit the min/max/step. + @param {number} value + */ + + update(value) { + if (this.step) { + // this.value = math.clip(Math.round(value / (this.step)) * this.step, this.min,this.max); + this.value = math.clip(Math.round((value-this.min) / (this.step)) * this.step + this.min, this.min,this.max); + } else { + this.value = math.clip(value,this.min,this.max); + } + if (this.oldValue !== this.value) { + this.oldValue = this.value; + this.changed = true; + } else { + this.changed = false; + } + return this.value; + } + + /** + Update with a normalized value 0-1. + @param {number} value + */ + updateNormal(value) { + this.value = math.scale(value,0,1,this.min,this.max); + return this.update(this.value); + } + + /** + Get a normalized version of this.value . Not settable. + */ + get normalized() { + return math.normalize(this.value,this.min,this.max); + } + +} ADDED public/nexus-js/lib/models/toggle.js Index: public/nexus-js/lib/models/toggle.js ================================================================== --- public/nexus-js/lib/models/toggle.js +++ public/nexus-js/lib/models/toggle.js @@ -0,0 +1,25 @@ +'use strict'; + +export default class Toggle { + + constructor(state) { + this.state = state || false; + } + + flip(state) { + if (state || state === false) { + this.state = state; + } else { + this.state = !this.state; + } + } + + on() { + this.state = true; + } + + off() { + this.state = false; + } + +} ADDED public/nexus-js/lib/time/interval.js Index: public/nexus-js/lib/time/interval.js ================================================================== --- public/nexus-js/lib/time/interval.js +++ public/nexus-js/lib/time/interval.js @@ -0,0 +1,51 @@ +'use strict'; + +import { clock } from '../main'; + +export default class Interval { + + constructor(rate,func,on) { + + this.rate = rate; + this.on = on; + this.clock = clock(); // jshint ignore:line + + this.pattern = [1]; + this.index = 0; + + this.event = func ? func : function() { }; + + if (this.on) { + this.start(); + } + + } + + _event(e) { + // if (this.pattern[this.index%this.pattern.length]) { + this.event(e); + // } + this.index++; + } + + stop() { + this.on = false; + this.interval.clear(); + } + + start() { + this.on = true; + this.interval = this.clock.callbackAtTime(this._event.bind(this), this.clock.context.currentTime).repeat(this.rate/1000).tolerance({early: 0.1, late:1}); + } + + ms(newrate) { + if (this.on) { + var ratio = newrate/this.rate; + this.rate = newrate; + this.clock.timeStretch(this.clock.context.currentTime, [this.interval], ratio); + } else { + this.rate = newrate; + } + } + +} ADDED public/nexus-js/lib/tuning/tuning.js Index: public/nexus-js/lib/tuning/tuning.js ================================================================== --- public/nexus-js/lib/tuning/tuning.js +++ public/nexus-js/lib/tuning/tuning.js @@ -0,0 +1,173 @@ +'use strict'; + +import math from '../util/math'; + +export default class Tune { + constructor() { + // the scale as ratios + this.scale = []; + + // i/o modes + this.mode = { + output: 'frequency', + input: 'step' + }; + + // ET major + this.etmajor = [ + 261.62558, + 293.664764, + 329.627563, + 349.228241, + 391.995422, + 440, + 493.883301, + 523.25116 + ]; + + // Root frequency. + this.root = math.mtof(60); // * Math.pow(2,(60-69)/12); + + // default is a major scale + this.createScale(0, 2, 4, 5, 7, 9, 11); + } + + /* Return data in the mode you are in (freq, ratio, or midi) */ + note(input, octave) { + let newvalue; + + if (this.mode.output === 'frequency') { + newvalue = this.frequency(input, octave); + } else if (this.mode.output === 'ratio') { + newvalue = this.ratio(input, octave); + } else if (this.mode.output === 'MIDI') { + newvalue = this.MIDI(input, octave); + } else { + newvalue = this.frequency(input, octave); + } + + return newvalue; + } + + /* Return freq data */ + frequency(stepIn, octaveIn) { + if (this.mode.input === 'midi' || this.mode.input === 'MIDI') { + this.stepIn += 60; + } + + // what octave is our input + let octave = Math.floor(stepIn / this.scale.length); + + if (octaveIn) { + octave += octaveIn; + } + + // which scale degree (0 - scale length) is our input + let scaleDegree = stepIn % this.scale.length; + + while (scaleDegree < 0) { + scaleDegree += this.scale.length; + } + + let ratio = this.scale[scaleDegree]; + + let freq = this.root * ratio; + + freq = freq * Math.pow(2, octave); + + // truncate irrational numbers + freq = Math.floor(freq * 100000000000) / 100000000000; + + return freq; + } + + /* Force return ratio data */ + + ratio(stepIn, octaveIn) { + if (this.mode.input === 'midi' || this.mode.input === 'MIDI') { + this.stepIn += 60; + } + + // what octave is our input + let octave = Math.floor(stepIn / this.scale.length); + + if (octaveIn) { + octave += octaveIn; + } + + // which scale degree (0 - scale length) is our input + let scaleDegree = stepIn % this.scale.length; + + // what ratio is our input to our key + let ratio = Math.pow(2, octave) * this.scale[scaleDegree]; + + ratio = Math.floor(ratio * 100000000000) / 100000000000; + + return ratio; + } + + /* Force return adjusted MIDI data */ + + MIDI(stepIn, octaveIn) { + let newvalue = this.frequency(stepIn, octaveIn); + + let n = 69 + (12 * Math.log(newvalue / 440)) / Math.log(2); + + n = Math.floor(n * 1000000000) / 1000000000; + + return n; + } + + createScale() { + let newScale = []; + for (let i = 0; i < arguments.length; i++) { + newScale.push(math.mtof(60 + arguments[i])); + } + this.loadScaleFromFrequencies(newScale); + } + + createJIScale() { + this.scale = []; + for (let i = 0; i < arguments.length; i++) { + this.scale.push(arguments[i]); + } + } + + loadScaleFromFrequencies(freqs) { + this.scale = []; + for (let i = 0; i < freqs.length; i++) { + this.scale.push(freqs[i] / freqs[0]); + } + } + + /* Load a new scale */ + + loadScale(name) { + /* load the scale */ + let freqs = this.scales[name].frequencies; + this.loadScaleFromFrequencies(freqs); + } + + /* Search the names of tunings + Returns an array of names of tunings */ + + search(letters) { + let possible = []; + for (let key in this.scales) { + if (key.toLowerCase().indexOf(letters.toLowerCase()) !== -1) { + possible.push(key); + } + } + return possible; + } + + /* Return a collection of notes as an array */ + + chord(midis) { + let output = []; + for (let i = 0; i < midis.length; i++) { + output.push(this.note(midis[i])); + } + return output; + } +} ADDED public/nexus-js/lib/util/cssparse.js Index: public/nexus-js/lib/util/cssparse.js ================================================================== --- public/nexus-js/lib/util/cssparse.js +++ public/nexus-js/lib/util/cssparse.js @@ -0,0 +1,160 @@ +'use strict'; + + +// polyfill window.getMatchedCSSRules() in FireFox 6+ +//if (typeof window.getMatchedCSSRules !== 'function') { + var ELEMENT_RE = /[\w-]+/g, + ID_RE = /#[\w-]+/g, + CLASS_RE = /\.[\w-]+/g, + ATTR_RE = /\[[^\]]+\]/g, + // :not() pseudo-class does not add to specificity, but its content does as if it was outside it + PSEUDO_CLASSES_RE = /\:(?!not)[\w-]+(\(.*\))?/g, + PSEUDO_ELEMENTS_RE = /\:\:?(after|before|first-letter|first-line|selection)/g; + // convert an array-like object to array + function toArray(list) { + return [].slice.call(list); + } + + // handles extraction of `cssRules` as an `Array` from a stylesheet or something that behaves the same + function getSheetRules(stylesheet) { + var sheet_media = stylesheet.media && stylesheet.media.mediaText; + // if this sheet is disabled skip it + if ( stylesheet.disabled ) return []; + // if this sheet's media is specified and doesn't match the viewport then skip it + if ( sheet_media && sheet_media.length && ! window.matchMedia(sheet_media).matches ) return []; + // get the style rules of this sheet + return toArray(stylesheet.cssRules); + } + + function _find(string, re) { + var matches = string.match(re); + return matches ? matches.length : 0; + } + + // Find correct matchesSelector impl + function matchesSelector(el, selector) { + var matcher = el.matchesSelector || el.mozMatchesSelector || + el.webkitMatchesSelector || el.oMatchesSelector || el.msMatchesSelector; + + selector = '*'; + console.log(selector); + console.log(matcher); + var result = el.webkitMatchesSelector('*'); + //return matcher(selector); + return result; + } + + // calculates the specificity of a given `selector` + function calculateScore(selector) { + var score = [0,0,0], + parts = selector.split(' '), + part, match; + //TODO: clean the ':not' part since the last ELEMENT_RE will pick it up + while (part = parts.shift(), typeof part == 'string') { + // find all pseudo-elements + match = _find(part, PSEUDO_ELEMENTS_RE); + score[2] += match; + // and remove them + part = part.replace(PSEUDO_ELEMENTS_RE, ''); + // find all pseudo-classes + match = _find(part, PSEUDO_CLASSES_RE); + score[1] += match; + // and remove them + part = part.replace(PSEUDO_CLASSES_RE, ''); + // find all attributes + match = _find(part, ATTR_RE); + score[1] += match; + // and remove them + part = part.replace(ATTR_RE, ''); + // find all IDs + match = _find(part, ID_RE); + score[0] += match; + // and remove them + part = part.replace(ID_RE, ''); + // find all classes + match = _find(part, CLASS_RE); + score[1] += match; + // and remove them + part = part.replace(CLASS_RE, ''); + // find all elements + score[2] += _find(part, ELEMENT_RE); + } + return parseInt(score.join(''), 10); + } + + // returns the heights possible specificity score an element can get from a give rule's selectorText + function getSpecificityScore(element, selector_text) { + var selectors = selector_text.split(','), + selector, score, result = 0; + selector = selectors.shift(); + while (selector) { + if (matchesSelector(element, selector)) { + score = calculateScore(selector); + result = score > result ? score : result; + } + selector = selectors.shift(); + } + return result; + } + + function sortBySpecificity(element, rules) { + // comparing function that sorts CSSStyleRules according to specificity of their `selectorText` + function compareSpecificity (a, b) { + return getSpecificityScore(element, b.selectorText) - getSpecificityScore(element, a.selectorText); + } + + return rules.sort(compareSpecificity); + } + + //TODO: not supporting 2nd argument for selecting pseudo elements + //TODO: not supporting 3rd argument for checking author style sheets only + var getCSSRules = function(element) { + var style_sheets, sheet, /* sheet_media, */ + rules, rule, + result = []; + // get stylesheets and convert to a regular Array + style_sheets = toArray(window.document.styleSheets); + + // assuming the browser hands us stylesheets in order of appearance + // we iterate them from the beginning to follow proper cascade order + sheet = style_sheets.shift(); + while (sheet) { + // get the style rules of this sheet + rules = getSheetRules(sheet); + // loop the rules in order of appearance + rule = rules.shift(); + while (rule) { + // if this is an @import rule + if (rule.styleSheet) { + // insert the imported stylesheet's rules at the beginning of this stylesheet's rules + rules = getSheetRules(rule.styleSheet).concat(rules); + // and skip this rule + continue; + } + // if there's no stylesheet attribute BUT there IS a media attribute it's a media rule + else if (rule.media) { + // insert the contained rules of this media rule to the beginning of this stylesheet's rules + rules = getSheetRules(rule).concat(rules); + // and skip it + continue; + } + + // check if this element matches this rule's selector + if (matchesSelector(element, rule.selectorText)) { + // push the rule to the results set + result.push(rule); + } + rule = rules.shift(); + } + sheet = style_sheets.shift(); + } + // sort according to specificity + return sortBySpecificity(element, result); + }; +// } + + +exports.parseSize = function(element) { + let rules = getCSSRules(element); + console.log(rules); +}; ADDED public/nexus-js/lib/util/dom.js Index: public/nexus-js/lib/util/dom.js ================================================================== --- public/nexus-js/lib/util/dom.js +++ public/nexus-js/lib/util/dom.js @@ -0,0 +1,49 @@ +'use strict'; + +exports.findPosition = (el) => { + let viewportOffset = el.getBoundingClientRect(); + let top = viewportOffset.top + window.scrollY; + let left = viewportOffset.left + window.scrollX; + return {top,left}; +}; + +exports.parseElement = (parent) => { + if (typeof parent === 'string') { + parent = document.getElementById(parent.replace('#','')); + } + + if (parent instanceof HTMLElement || parent instanceof SVGElement){ + return parent; + } else { + return 'No valid parent argument'; + } +}; + +exports.locateMouse = (e,offset) => { + return { + x: e.pageX - offset.left, + y: e.pageY - offset.top + }; +}; + +exports.locateTouch = (e,offset) => { + return { + x: e.targetTouches.length ? e.targetTouches[0].pageX - offset.left : false, + y: e.targetTouches.length ? e.targetTouches[0].pageY - offset.top : false + }; +}; + +exports.SmartCanvas = function(parent) { + + this.element = document.createElement('canvas'); + this.context = this.element.getContext('2d'); + parent.appendChild(this.element); + + this.resize = (w,h) => { + this.element.width = w*2; + this.element.height = h*2; + this.element.style.width = w+'px'; + this.element.style.height = h+'px'; + }; + +}; ADDED public/nexus-js/lib/util/interaction.js Index: public/nexus-js/lib/util/interaction.js ================================================================== --- public/nexus-js/lib/util/interaction.js +++ public/nexus-js/lib/util/interaction.js @@ -0,0 +1,182 @@ +'use strict'; + +import math from '../util/math'; +import ToggleModel from '../models/toggle'; + + +/* +how to use : + +dial.interaction = new Handle('radial','relative',this.width,this.height); +// dial.interaction.mode = 'relative' +// dial.interaction.direction = 'radial' + +on click: +dial.interaction.anchor = this.mouse; + +on move: +dial.interaction.update(this.mouse); + +console.log( dial.interaction.value ); should be a normalized value. + +*/ + +/* + absolute/relative are property: mode + radial/vertical/horizontal/2d are property: direction + + plan : + + if relative -- + NO on click, get value offset between current value and click value. + NO on move, use click value - offset + INSTEAD + use delta -- bc vertical motion on dial is impossible otherwise + also allow to set sensitivity + +*/ + +export class Handle { + + constructor(mode='absolute',direction='vertical',xbound=[0,100],ybound=[0,100]) { + this.mode = mode; + this.direction = direction; + this.previous = 0; + this.value = 0; + this.sensitivity = 1; + this.resize(xbound,ybound); + } + + resize(xbound,ybound) { + this.boundary = { + min: { + x: xbound[0], + y: ybound[0] + }, + max: { + x: xbound[1], + y: ybound[1] + }, + center: { + x: (xbound[1] - xbound[0])/2 + xbound[0], + y: (ybound[1] - ybound[0])/2 + ybound[0] + } + }; + } + + set anchor(mouse) { + this._anchor = this.convertPositionToValue(mouse); + } + + get anchor() { + return this._anchor; + } + + + update(mouse) { + if (this.mode==='relative') { + let increment = this.convertPositionToValue(mouse) - this.anchor; + if (Math.abs(increment) > 0.5) { increment = 0; } + this.anchor = mouse; + this.value = this.value + increment * this.sensitivity; + } else { + this.value = this.convertPositionToValue(mouse); + } + this.value = math.clip(this.value,0,1); + } + + convertPositionToValue(current) { + switch(this.direction) { + case 'radial': + let position = math.toPolar(current.x - this.boundary.center.x, current.y - this.boundary.center.y); + position = position.angle / (Math.PI*2); + position = ((position - 0.25) + 1) % 1; + return position; + case 'vertical': + return math.scale(current.y,this.boundary.min.y,this.boundary.max.y,0,1); + case 'horizontal': + return math.scale(current.x,this.boundary.min.x,this.boundary.max.x,0,1); + } + } + +} + + +export class Button { + + constructor(mode='button') { + this.mode = mode; + this.state = new ToggleModel(); + this.paintbrush = false; + } + + click() { + switch (this.mode) { + case 'impulse': + this.state.on(); + if (this.timeout) { + clearTimeout(this.timeout); + } + this.timeout = setTimeout(this.state.off.bind(this),30); + this.emit('change',this.state); + break; + case 'button': + this.turnOn(); + this.emit('change',this.state); + break; + case 'aftertouch': + this.position = { + x: math.clip(this.mouse.x / this.width,0,1), + y: math.clip(1 - this.mouse.y / this.height,0,1) + }; + this.turnOn(); + this.emit('change',{ + state: this.state, + x: this.position.x, + y: this.position.y, + }); + break; + case 'toggle': + this.flip(); + this.emit('change',this.state); + break; + } + + } + + move() { + if (this.mode==='aftertouch') { + this.position = { + x: math.clip(this.mouse.x / this.width,0,1), + y: math.clip(1 - this.mouse.y / this.height,0,1) + }; + this.emit('change',{ + state: this.state, + x: this.position.x, + y: this.position.y, + }); + this.render(); + } + } + + release() { + switch (this.mode) { + case 'button': + this.turnOff(); + this.emit('change',this.state); + break; + case 'aftertouch': + this.turnOff(); + this.position = { + x: this.mouse.x / this.width, + y: 1 - this.mouse.y / this.height + }; + this.emit('change',{ + state: this.state, + x: this.position.x, + y: this.position.y, + }); + break; + } + } +} ADDED public/nexus-js/lib/util/math.js Index: public/nexus-js/lib/util/math.js ================================================================== --- public/nexus-js/lib/util/math.js +++ public/nexus-js/lib/util/math.js @@ -0,0 +1,222 @@ +'use strict'; + +/** + * Limit a number to within a minimum and maximum + * @param {number} value Input value + * @param {number} min Lower limit + * @param {number} max Upper limit + * @return {number} The input value constrained within the lower and upper limits + * @example + * Nexus.clip(11,0,10) // returns 10 + * Nexus.clip(-1,0,10) // returns 0 + * Nexus.clip(5,0,10) // returns 5 + */ + +exports.clip = (value,min,max) => { + return Math.min(Math.max(value,min),max); +}; + +exports.normalize = (value,min,max) => { + return ( (value-min) / (max-min) ); +}; + +/** + * Scale a value from one range to another range. + * @param {number} inNum Input value + * @param {number} inMin Input range minimum + * @param {number} inMax Input range maximum + * @param {number} outMin Output range minimum + * @param {number} outMax Output range maximum + * @return {number} The input value scaled to its new range + * @example + * Nexus.scale(0.5,0,1,0,10) // returns 5 + * Nexus.scale(0.9,0,1,1,0) // returns 0.1 + */ +exports.scale = (inNum, inMin, inMax, outMin, outMax) => { + if (inMin === inMax) { + return outMin; + } + return (((inNum - inMin) * (outMax - outMin)) / (inMax - inMin)) + outMin; +}; + +exports.toPolar = (x,y) => { + var r = Math.sqrt(x*x + y*y); + + var theta = Math.atan2(y,x); + if (theta < 0) { + theta = theta + (2 * Math.PI); + } + return {radius: r, angle: theta}; +}; + +exports.toCartesian = function(radius, angle){ + var cos = Math.cos(angle); + var sin = Math.sin(angle); + return {x: radius*cos, y: radius*sin*-1}; +}; +/* +exports.polarToCartesian(centerX, centerY, radius, angleInDegrees) { + var angleInRadians = (angleInDegrees-90) * Math.PI / 180.0; + + return { + x: centerX + (radius * Math.cos(angleInRadians)), + y: centerY + (radius * Math.sin(angleInRadians)) + }; +} */ + + + +exports.prune = function(data, scale) { + return parseFloat(data.toFixed(scale)); +}; + +exports.invert = function (inNum) { + return exports.scale(inNum, 1, 0, 0, 1); +}; + +/** + * Convert a MIDi note number to a frequency value in equal temperament. + * @param {number} midi MIDI note value + * @return {number} Frequence value + * @example + * Nexus.mtof(60) // returns the frequency number of Middle C + */ +exports.mtof = function(midi) { + return Math.pow(2, ((midi-69)/12)) * 440; +}; + +/** + * Interpolate between two numbers + * @param {number} loc Interpolation index (0-1) + * @param {number} min Lower value + * @param {number} max Upper value + * @return {number} Interpolated value + * @example + * Nexus.interp(0.5,2,4) // returns 3 + * Nexus.interp(0.1,0,10) // returns 1 + */ +exports.interp = function(loc,min,max) { + return loc * (max - min) + min; +}; + +/** + * Return a random choice from a list of arguments + * @return {various} One random argument + * @example + * Nexus.pick(1,2,3,4) // returns 1, 2, 3, or 4 + * Nexus.pick(function1,function2) // returns either function1 or function2 + */ +exports.pick = function() { + return arguments[~~(Math.random()*arguments.length)]; +}; + +/** + * Returns an octave multiplier for frequency values + * @param {number} num Relative octave number (e.g. -1 for one octave down, 1 for one octave up) + * @return {number} Octave multiplier + * @example + * Nexus.octave(-1) // returns 0.5 + * Nexus.octave(0) // returns 1 + * Nexus.octave(1) // returns 2 + * Nexus.octave(2) // returns 4 + */ +exports.octave = function(num) { + return Math.pow(2,num); +}; + +/** + * Random integer generator. If no second argument is given, will return random integer from 0 to bound1. + * @param {number} bound1 Minimum random value + * @param {number} bound2 Maximum random value + * @return {number} Random integer between lower and upper boundary + * @example + * Nexus.ri(10) // returns random int from 0 to 10 + * Nexus.ri(20,2000) // returns random int from 20 to 2000 + */ +exports.ri = function(bound1,bound2) { + if (!bound2) { + bound2 = bound1; + bound1 = 0; + } + var low = Math.min(bound1,bound2); + var high = Math.max(bound1,bound2); + return Math.floor(Math.random()*(high-low)+low); +}; + +/** + * Random float number generator. If no second argument is given, will return random float from 0 to bound1. + * @param {number} bound1 Minimum random value + * @param {number} bound2 Maximum random value + * @return {number} Random float between lower and upper boundary + * @example + * Nexus.rf(1) // returns random float from 0 to 1 + * Nexus.rf(1,2) // returns random float from 1 to 2 + */ +exports.rf = function(bound1,bound2) { + if (!bound2) { + bound2 = bound1; + bound1 = 0; + } + var low = Math.min(bound1,bound2); + var high = Math.max(bound1,bound2); + return Math.random()*(high-low)+low; +}; + + +exports.cycle = function(input,min,max) { + input++; + if (input >= max) { + input = min; + } + return input; +}; + +/** + * Average an array of numbers + * @param {Array} data Array of numbers to average + * @return {number} Average of the input data + * @example + * Nexus.average([0,2,4,6,8,10]) // returns 5 + */ +exports.average = function(data) { + let total = 0; + for (var i=0;i { + return document.createElementNS('http://www.w3.org/2000/svg', type); + }, + + arc: (x, y, radius, startAngle, endAngle) => { + + var start = math.toCartesian(radius, endAngle); + var end = math.toCartesian(radius, startAngle); + + var largeArcFlag = endAngle - startAngle <= 180 ? '0' : '1'; + + var d = [ + 'M', start.x+x, start.y+y, + 'A', radius, radius, 0, largeArcFlag, 0, end.x+x, end.y+y + ].join(' '); + + return d; + }, + + radialGradient: (defs,numberOfStops) => { + + let id = 'gradient' + math.ri(100000000000); + let stops = []; + + let gradient = document.createElementNS('http://www.w3.org/2000/svg', 'radialGradient'); + gradient.setAttribute('id', id); + gradient.setAttribute('cx', '50%'); + gradient.setAttribute('cy', '50%'); + gradient.setAttribute('r', '50%'); + + defs.appendChild(gradient); + + for (let i=0;i { + let type = widget.type; + if (interfaceIDs[type]) { + interfaceIDs[type]++; + } else { + interfaceIDs[type] = 1; + } + return ( type + interfaceIDs[type] ); +}; + +let element = (element,type,options) => { + options = options || {}; + for (let i = 0; i < element.attributes.length; i++){ + let att = element.attributes[i]; + // try { + // options[att.nodeName] = eval(att.nodeValue); + // } catch(e) { + options[att.nodeName] = att.nodeValue; + // } + } + type = type[0].toUpperCase() + type.slice(1); + let widget = new Interfaces[type](element,options); + widget.id = element.id; + return widget; +}; + + +let section = (parent,keyword) => { + + keyword = keyword || 'nexus-ui'; + + let interfaceIDs = {}; + + let container = dom.parseElement(parent); + + let ui = {}; + + let htmlElements = container.getElementsByTagName('*'); + let elements = []; + for (let i=0; i { + let target = document.createElement('div'); + options = options || {}; + if (parent) { + parent = dom.parseElement(parent); + } else { + parent = document.body; + } + parent.appendChild(target); + options.target = target; + if (options.size) { + target.style.width = options.size[0] + 'px'; + target.style.height = options.size[1] + 'px'; + } + return element(target,type,options); +}; + +export { element }; +export { section }; +export { add }; ADDED public/nexus-js/lib/util/util.js Index: public/nexus-js/lib/util/util.js ================================================================== --- public/nexus-js/lib/util/util.js +++ public/nexus-js/lib/util/util.js @@ -0,0 +1,29 @@ +'use strict'; + +exports.isObject = (obj) => { + if (typeof obj === 'object' && !Array.isArray(obj) && obj !== null && obj instanceof SVGElement === false && obj instanceof HTMLElement === false ) { + return true; + } else { + return false; + } +}; + +// Restricts input for the given textbox to the given inputFilter function +// cf https://stackoverflow.com/a/469362 +exports.setInputFilter = (textbox, inputFilter) => { + ["input", "keydown", "keyup", "mousedown", "mouseup", "select", "contextmenu", "drop"].forEach(function(event) { + textbox.addEventListener(event, function() { + if (inputFilter(this.value)) { + this.oldValue = this.value; + this.oldSelectionStart = this.selectionStart; + this.oldSelectionEnd = this.selectionEnd; + } else if (this.hasOwnProperty("oldValue")) { + this.value = this.oldValue; + this.setSelectionRange(this.oldSelectionStart, this.oldSelectionEnd); + } else { + this.value = ""; + } + }); + }); +}; + ADDED public/nexus-js/package-lock.json Index: public/nexus-js/package-lock.json ================================================================== --- public/nexus-js/package-lock.json +++ public/nexus-js/package-lock.json @@ -0,0 +1,9393 @@ +{ + "name": "nexusui", + "version": "2.1.6", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", + "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", + "dev": true + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", + "dev": true + }, + "@types/minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-aaI6OtKcrwCX8G7aWbNh7i8GOfY=", + "dev": true + }, + "@types/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", + "dev": true + }, + "JSONStream": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.2.tgz", + "integrity": "sha1-wQI3G27Dp887hHygDCC7D85Mbeo=", + "dev": true, + "requires": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + } + }, + "acorn": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.2.1.tgz", + "integrity": "sha512-jG0u7c4Ly+3QkkW18V+NRDN+4bWHdln30NL1ZL2AvFZZmQe/BfopYCtghCKKVBUSetZ4QKcyA0pY6/4Gw8Pv8w==", + "dev": true + }, + "acorn-babel": { + "version": "0.11.1-38", + "resolved": "https://registry.npmjs.org/acorn-babel/-/acorn-babel-0.11.1-38.tgz", + "integrity": "sha1-bPewwHkaEaBe9gIL8G7zSzAIZ2g=", + "dev": true + }, + "add-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz", + "integrity": "sha1-anmQQ3ynNtXhKI25K9MmbV9csqo=", + "dev": true + }, + "align-text": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", + "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", + "dev": true, + "requires": { + "kind-of": "^3.0.2", + "longest": "^1.0.1", + "repeat-string": "^1.5.2" + } + }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "dev": true + }, + "ansi-html": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", + "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=", + "dev": true + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "anymatch": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", + "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "dev": true, + "requires": { + "micromatch": "^2.1.5", + "normalize-path": "^2.0.0" + }, + "dependencies": { + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dev": true, + "requires": { + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.2", + "expand-brackets": "^0.1.4", + "extglob": "^0.3.1", + "filename-regex": "^2.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.1", + "kind-of": "^3.0.2", + "normalize-path": "^2.0.1", + "object.omit": "^2.0.0", + "parse-glob": "^3.0.4", + "regex-cache": "^0.4.2" + } + } + } + }, + "append-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz", + "integrity": "sha1-2CIM9GYIFSXv6lBhTz3mUU36WPE=", + "dev": true, + "requires": { + "buffer-equal": "^1.0.0" + } + }, + "argparse": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", + "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dev": true, + "requires": { + "arr-flatten": "^1.0.1" + } + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true + }, + "array-ify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", + "integrity": "sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4=", + "dev": true + }, + "array-iterate": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-iterate/-/array-iterate-1.1.1.tgz", + "integrity": "sha1-hlv3+K851rCYLGCQKRSsdrwBCPY=", + "dev": true + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "dev": true + }, + "arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "dev": true + }, + "assert": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", + "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", + "dev": true, + "requires": { + "util": "0.10.3" + } + }, + "ast-types": { + "version": "0.7.8", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.7.8.tgz", + "integrity": "sha1-kC0uDWDQcb3NRtwRXhgJ7RHBOKk=", + "dev": true + }, + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + }, + "async-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", + "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", + "dev": true + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + }, + "dependencies": { + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + } + } + }, + "babel-core": { + "version": "4.7.16", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-4.7.16.tgz", + "integrity": "sha1-vQBvEBGwdn9N81+Dwo5+p2Hw740=", + "dev": true, + "requires": { + "acorn-babel": "0.11.1-38", + "ast-types": "~0.7.0", + "chalk": "^1.0.0", + "commander": "^2.6.0", + "convert-source-map": "^0.5.0", + "core-js": "^0.6.1", + "debug": "^2.1.1", + "detect-indent": "^3.0.0", + "estraverse": "^1.9.1", + "esutils": "^1.1.6", + "fs-readdir-recursive": "^0.1.0", + "globals": "^6.2.0", + "is-integer": "^1.0.4", + "js-tokens": "1.0.0", + "leven": "^1.0.1", + "line-numbers": "0.2.0", + "lodash": "^3.2.0", + "output-file-sync": "^1.1.0", + "path-is-absolute": "^1.0.0", + "private": "^0.1.6", + "regenerator-babel": "0.8.13-2", + "regexpu": "^1.1.2", + "repeating": "^1.1.2", + "shebang-regex": "^1.0.0", + "slash": "^1.0.0", + "source-map": "^0.4.0", + "source-map-support": "^0.2.9", + "to-fast-properties": "^1.0.0", + "trim-right": "^1.0.0" + } + }, + "babel-generator": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.0.tgz", + "integrity": "sha1-rBriAHC3n248odMmlhMFN3TyDcU=", + "dev": true, + "requires": { + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "detect-indent": "^4.0.0", + "jsesc": "^1.3.0", + "lodash": "^4.17.4", + "source-map": "^0.5.6", + "trim-right": "^1.0.1" + }, + "dependencies": { + "detect-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", + "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", + "dev": true, + "requires": { + "repeating": "^2.0.0" + } + }, + "jsesc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", + "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", + "dev": true + }, + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", + "dev": true + }, + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "dev": true, + "requires": { + "is-finite": "^1.0.0" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "babel-helper-bindify-decorators": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz", + "integrity": "sha1-FMGeXxQte0fxmlJDHlKxzLxAozA=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-builder-binary-assignment-operator-visitor": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", + "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=", + "dev": true, + "requires": { + "babel-helper-explode-assignable-expression": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-builder-react-jsx": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.26.0.tgz", + "integrity": "sha1-Of+DE7dci2Xc7/HzHTg+D/KkCKA=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "esutils": "^2.0.2" + }, + "dependencies": { + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + } + } + }, + "babel-helper-call-delegate": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", + "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", + "dev": true, + "requires": { + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-define-map": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", + "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=", + "dev": true, + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + }, + "dependencies": { + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", + "dev": true + } + } + }, + "babel-helper-explode-assignable-expression": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", + "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-explode-class": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz", + "integrity": "sha1-fcKjkQ3uAHBW4eMdZAztPVTqqes=", + "dev": true, + "requires": { + "babel-helper-bindify-decorators": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", + "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", + "dev": true, + "requires": { + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-get-function-arity": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", + "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-hoist-variables": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", + "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-optimise-call-expression": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", + "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-regex": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz", + "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + }, + "dependencies": { + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", + "dev": true + } + } + }, + "babel-helper-remap-async-to-generator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", + "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=", + "dev": true, + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-replace-supers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", + "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", + "dev": true, + "requires": { + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helpers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", + "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-jest": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-4.0.0.tgz", + "integrity": "sha1-0ERtuFNdDzOFNaGKL0I4TedFoQ0=", + "dev": true, + "requires": { + "babel-core": "^4.0.0" + } + }, + "babel-loader": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-4.3.0.tgz", + "integrity": "sha1-44orp+iyZgmQ6/C883vC+hfXhl8=", + "dev": true, + "requires": { + "babel-core": "^4.7.16", + "loader-utils": "^0.2.5" + } + }, + "babel-messages": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", + "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-check-es2015-constants": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", + "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-syntax-async-functions": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", + "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=", + "dev": true + }, + "babel-plugin-syntax-async-generators": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz", + "integrity": "sha1-a8lj67FuzLrmuStZbrfzXDQqi5o=", + "dev": true + }, + "babel-plugin-syntax-class-constructor-call": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-constructor-call/-/babel-plugin-syntax-class-constructor-call-6.18.0.tgz", + "integrity": "sha1-nLnTn+Q8hgC+yBRkVt3L1OGnZBY=", + "dev": true + }, + "babel-plugin-syntax-class-properties": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz", + "integrity": "sha1-1+sjt5oxf4VDlixQW4J8fWysJ94=", + "dev": true + }, + "babel-plugin-syntax-decorators": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz", + "integrity": "sha1-MSVjtNvePMgGzuPkFszurd0RrAs=", + "dev": true + }, + "babel-plugin-syntax-do-expressions": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-do-expressions/-/babel-plugin-syntax-do-expressions-6.13.0.tgz", + "integrity": "sha1-V0d1YTmqJtOQ0JQQsDdEugfkeW0=", + "dev": true + }, + "babel-plugin-syntax-dynamic-import": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz", + "integrity": "sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo=", + "dev": true + }, + "babel-plugin-syntax-exponentiation-operator": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", + "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=", + "dev": true + }, + "babel-plugin-syntax-export-extensions": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-export-extensions/-/babel-plugin-syntax-export-extensions-6.13.0.tgz", + "integrity": "sha1-cKFITw+QiaToStRLrDU8lbmxJyE=", + "dev": true + }, + "babel-plugin-syntax-flow": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz", + "integrity": "sha1-TDqyCiryaqIM0lmVw5jE63AxDI0=", + "dev": true + }, + "babel-plugin-syntax-function-bind": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-function-bind/-/babel-plugin-syntax-function-bind-6.13.0.tgz", + "integrity": "sha1-SMSV8Xe98xqYHnMvVa3AvdJgH0Y=", + "dev": true + }, + "babel-plugin-syntax-jsx": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", + "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=", + "dev": true + }, + "babel-plugin-syntax-object-rest-spread": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", + "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=", + "dev": true + }, + "babel-plugin-syntax-trailing-function-commas": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", + "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=", + "dev": true + }, + "babel-plugin-system-import-transformer": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-system-import-transformer/-/babel-plugin-system-import-transformer-3.1.0.tgz", + "integrity": "sha1-038Mro5h7zkGAggzHZMbXmMNfF8=", + "dev": true, + "requires": { + "babel-plugin-syntax-dynamic-import": "^6.18.0" + } + }, + "babel-plugin-transform-async-generator-functions": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz", + "integrity": "sha1-8FiQAUX9PpkHpt3yjaWfIVJYpds=", + "dev": true, + "requires": { + "babel-helper-remap-async-to-generator": "^6.24.1", + "babel-plugin-syntax-async-generators": "^6.5.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-async-to-generator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", + "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=", + "dev": true, + "requires": { + "babel-helper-remap-async-to-generator": "^6.24.1", + "babel-plugin-syntax-async-functions": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-class-constructor-call": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-constructor-call/-/babel-plugin-transform-class-constructor-call-6.24.1.tgz", + "integrity": "sha1-gNwoVQWsBn3LjWxl4vbxGrd2Xvk=", + "dev": true, + "requires": { + "babel-plugin-syntax-class-constructor-call": "^6.18.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-class-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz", + "integrity": "sha1-anl2PqYdM9NvN7YRqp3vgagbRqw=", + "dev": true, + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-plugin-syntax-class-properties": "^6.8.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-decorators": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz", + "integrity": "sha1-eIAT2PjGtSIr33s0Q5Df13Vp4k0=", + "dev": true, + "requires": { + "babel-helper-explode-class": "^6.24.1", + "babel-plugin-syntax-decorators": "^6.13.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-decorators-legacy": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-decorators-legacy/-/babel-plugin-transform-decorators-legacy-1.3.4.tgz", + "integrity": "sha1-dBtY9sW86eYCfgiC2cmU8E82aSU=", + "dev": true, + "requires": { + "babel-plugin-syntax-decorators": "^6.1.18", + "babel-runtime": "^6.2.0", + "babel-template": "^6.3.0" + } + }, + "babel-plugin-transform-do-expressions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-do-expressions/-/babel-plugin-transform-do-expressions-6.22.0.tgz", + "integrity": "sha1-KMyvkoEtlJws0SgfaQyP3EaK6bs=", + "dev": true, + "requires": { + "babel-plugin-syntax-do-expressions": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-arrow-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", + "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-block-scoped-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", + "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-block-scoping": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", + "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + }, + "dependencies": { + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", + "dev": true + } + } + }, + "babel-plugin-transform-es2015-classes": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", + "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", + "dev": true, + "requires": { + "babel-helper-define-map": "^6.24.1", + "babel-helper-function-name": "^6.24.1", + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-helper-replace-supers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-computed-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", + "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-destructuring": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", + "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-duplicate-keys": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", + "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-for-of": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", + "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", + "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", + "dev": true, + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", + "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-modules-amd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", + "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", + "dev": true, + "requires": { + "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-modules-commonjs": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz", + "integrity": "sha1-DYOUApt9xqvhqX7xgeAHWN0uXYo=", + "dev": true, + "requires": { + "babel-plugin-transform-strict-mode": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-types": "^6.26.0" + } + }, + "babel-plugin-transform-es2015-modules-systemjs": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", + "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", + "dev": true, + "requires": { + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-modules-umd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", + "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", + "dev": true, + "requires": { + "babel-plugin-transform-es2015-modules-amd": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-object-super": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", + "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", + "dev": true, + "requires": { + "babel-helper-replace-supers": "^6.24.1", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-parameters": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", + "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", + "dev": true, + "requires": { + "babel-helper-call-delegate": "^6.24.1", + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-shorthand-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", + "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-spread": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", + "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-sticky-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", + "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", + "dev": true, + "requires": { + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-template-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", + "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-typeof-symbol": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", + "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-unicode-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", + "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", + "dev": true, + "requires": { + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "regexpu-core": "^2.0.0" + } + }, + "babel-plugin-transform-exponentiation-operator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", + "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", + "dev": true, + "requires": { + "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", + "babel-plugin-syntax-exponentiation-operator": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-export-extensions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-export-extensions/-/babel-plugin-transform-export-extensions-6.22.0.tgz", + "integrity": "sha1-U3OLR+deghhYnuqUbLvTkQm75lM=", + "dev": true, + "requires": { + "babel-plugin-syntax-export-extensions": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-flow-strip-types": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz", + "integrity": "sha1-hMtnKTXUNxT9wyvOhFaNh0Qc988=", + "dev": true, + "requires": { + "babel-plugin-syntax-flow": "^6.18.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-function-bind": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-function-bind/-/babel-plugin-transform-function-bind-6.22.0.tgz", + "integrity": "sha1-xvuOlqwpajELjPjqQBRiQH3fapc=", + "dev": true, + "requires": { + "babel-plugin-syntax-function-bind": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-object-rest-spread": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", + "integrity": "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY=", + "dev": true, + "requires": { + "babel-plugin-syntax-object-rest-spread": "^6.8.0", + "babel-runtime": "^6.26.0" + } + }, + "babel-plugin-transform-react-display-name": { + "version": "6.25.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.25.0.tgz", + "integrity": "sha1-Z+K/Hx6ck6sI25Z5LgU5K/LMKNE=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-react-jsx": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.24.1.tgz", + "integrity": "sha1-hAoCjn30YN/DotKfDA2R9jduZqM=", + "dev": true, + "requires": { + "babel-helper-builder-react-jsx": "^6.24.1", + "babel-plugin-syntax-jsx": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-react-jsx-self": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx-self/-/babel-plugin-transform-react-jsx-self-6.22.0.tgz", + "integrity": "sha1-322AqdomEqEh5t3XVYvL7PBuY24=", + "dev": true, + "requires": { + "babel-plugin-syntax-jsx": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-react-jsx-source": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx-source/-/babel-plugin-transform-react-jsx-source-6.22.0.tgz", + "integrity": "sha1-ZqwSFT9c0tF7PBkmj0vwGX9E7NY=", + "dev": true, + "requires": { + "babel-plugin-syntax-jsx": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-regenerator": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", + "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=", + "dev": true, + "requires": { + "regenerator-transform": "^0.10.0" + } + }, + "babel-plugin-transform-strict-mode": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", + "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-preset-env": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.6.1.tgz", + "integrity": "sha512-W6VIyA6Ch9ePMI7VptNn2wBM6dbG0eSz25HEiL40nQXCsXGTGZSTZu1Iap+cj3Q0S5a7T9+529l/5Bkvd+afNA==", + "dev": true, + "requires": { + "babel-plugin-check-es2015-constants": "^6.22.0", + "babel-plugin-syntax-trailing-function-commas": "^6.22.0", + "babel-plugin-transform-async-to-generator": "^6.22.0", + "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoping": "^6.23.0", + "babel-plugin-transform-es2015-classes": "^6.23.0", + "babel-plugin-transform-es2015-computed-properties": "^6.22.0", + "babel-plugin-transform-es2015-destructuring": "^6.23.0", + "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0", + "babel-plugin-transform-es2015-for-of": "^6.23.0", + "babel-plugin-transform-es2015-function-name": "^6.22.0", + "babel-plugin-transform-es2015-literals": "^6.22.0", + "babel-plugin-transform-es2015-modules-amd": "^6.22.0", + "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", + "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0", + "babel-plugin-transform-es2015-modules-umd": "^6.23.0", + "babel-plugin-transform-es2015-object-super": "^6.22.0", + "babel-plugin-transform-es2015-parameters": "^6.23.0", + "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0", + "babel-plugin-transform-es2015-spread": "^6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "^6.22.0", + "babel-plugin-transform-es2015-template-literals": "^6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0", + "babel-plugin-transform-es2015-unicode-regex": "^6.22.0", + "babel-plugin-transform-exponentiation-operator": "^6.22.0", + "babel-plugin-transform-regenerator": "^6.22.0", + "browserslist": "^2.1.2", + "invariant": "^2.2.2", + "semver": "^5.3.0" + } + }, + "babel-preset-flow": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-preset-flow/-/babel-preset-flow-6.23.0.tgz", + "integrity": "sha1-5xIYiHCFrpoktb5Baa/7WZgWxJ0=", + "dev": true, + "requires": { + "babel-plugin-transform-flow-strip-types": "^6.22.0" + } + }, + "babel-preset-react": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-react/-/babel-preset-react-6.24.1.tgz", + "integrity": "sha1-umnfrqRfw+xjm2pOzqbhdwLJE4A=", + "dev": true, + "requires": { + "babel-plugin-syntax-jsx": "^6.3.13", + "babel-plugin-transform-react-display-name": "^6.23.0", + "babel-plugin-transform-react-jsx": "^6.24.1", + "babel-plugin-transform-react-jsx-self": "^6.22.0", + "babel-plugin-transform-react-jsx-source": "^6.22.0", + "babel-preset-flow": "^6.23.0" + } + }, + "babel-preset-stage-0": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-stage-0/-/babel-preset-stage-0-6.24.1.tgz", + "integrity": "sha1-VkLRUEL5E4TX5a+LyIsduVsDnmo=", + "dev": true, + "requires": { + "babel-plugin-transform-do-expressions": "^6.22.0", + "babel-plugin-transform-function-bind": "^6.22.0", + "babel-preset-stage-1": "^6.24.1" + } + }, + "babel-preset-stage-1": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-stage-1/-/babel-preset-stage-1-6.24.1.tgz", + "integrity": "sha1-dpLNfc1oSZB+auSgqFWJz7niv7A=", + "dev": true, + "requires": { + "babel-plugin-transform-class-constructor-call": "^6.24.1", + "babel-plugin-transform-export-extensions": "^6.22.0", + "babel-preset-stage-2": "^6.24.1" + } + }, + "babel-preset-stage-2": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz", + "integrity": "sha1-2eKWD7PXEYfw5k7sYrwHdnIZvcE=", + "dev": true, + "requires": { + "babel-plugin-syntax-dynamic-import": "^6.18.0", + "babel-plugin-transform-class-properties": "^6.24.1", + "babel-plugin-transform-decorators": "^6.24.1", + "babel-preset-stage-3": "^6.24.1" + } + }, + "babel-preset-stage-3": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz", + "integrity": "sha1-g2raCp56f6N8sTj7kyb4eTSkg5U=", + "dev": true, + "requires": { + "babel-plugin-syntax-trailing-function-commas": "^6.22.0", + "babel-plugin-transform-async-generator-functions": "^6.24.1", + "babel-plugin-transform-async-to-generator": "^6.24.1", + "babel-plugin-transform-exponentiation-operator": "^6.24.1", + "babel-plugin-transform-object-rest-spread": "^6.22.0" + } + }, + "babel-register": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", + "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", + "dev": true, + "requires": { + "babel-core": "^6.26.0", + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "home-or-tmp": "^2.0.0", + "lodash": "^4.17.4", + "mkdirp": "^0.5.1", + "source-map-support": "^0.4.15" + }, + "dependencies": { + "babel-core": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.0.tgz", + "integrity": "sha1-rzL3izGm/O8RnIew/Y2XU/A6C7g=", + "dev": true, + "requires": { + "babel-code-frame": "^6.26.0", + "babel-generator": "^6.26.0", + "babel-helpers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-register": "^6.26.0", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "convert-source-map": "^1.5.0", + "debug": "^2.6.8", + "json5": "^0.5.1", + "lodash": "^4.17.4", + "minimatch": "^3.0.4", + "path-is-absolute": "^1.0.1", + "private": "^0.1.7", + "slash": "^1.0.0", + "source-map": "^0.5.6" + } + }, + "convert-source-map": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz", + "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=", + "dev": true + }, + "core-js": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.3.tgz", + "integrity": "sha1-isw4NFgk8W2DZbfJtCWRaOjtYD4=", + "dev": true + }, + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-support": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", + "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", + "dev": true, + "requires": { + "source-map": "^0.5.6" + } + } + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "dev": true, + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + }, + "dependencies": { + "core-js": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.3.tgz", + "integrity": "sha1-isw4NFgk8W2DZbfJtCWRaOjtYD4=", + "dev": true + } + } + }, + "babel-template": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", + "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "lodash": "^4.17.4" + }, + "dependencies": { + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", + "dev": true + } + } + }, + "babel-traverse": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", + "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", + "dev": true, + "requires": { + "babel-code-frame": "^6.26.0", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "debug": "^2.6.8", + "globals": "^9.18.0", + "invariant": "^2.2.2", + "lodash": "^4.17.4" + }, + "dependencies": { + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "dev": true + }, + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", + "dev": true + } + } + }, + "babel-types": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" + }, + "dependencies": { + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", + "dev": true + } + } + }, + "babelify": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/babelify/-/babelify-5.0.5.tgz", + "integrity": "sha1-MyLk4NVTVm/ac3gZVU/VIbXw6Yg=", + "dev": true, + "requires": { + "babel-core": "^4.0.0", + "lodash": "^3.0.0", + "through": "2.3.4" + }, + "dependencies": { + "through": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.4.tgz", + "integrity": "sha1-SV5A6Nio6uvHwnXqiMK4/BTFZFU=", + "dev": true + } + } + }, + "babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", + "dev": true + }, + "bail": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.2.tgz", + "integrity": "sha1-99bBcxYwqfnw1NNe0fli4gdKF2Q=", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "base64-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.1.tgz", + "integrity": "sha512-dwVUVIXsBZXwTuwnXI9RK8sBmgq09NDHzyR9SAph9eqk76gKK2JSQmZARC2zRC81JC2QTtxD0ARU5qTS25gIGw==", + "dev": true + }, + "big.js": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", + "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==", + "dev": true + }, + "binary-extensions": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", + "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=", + "dev": true + }, + "body": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/body/-/body-5.1.0.tgz", + "integrity": "sha1-5LoM5BCkaTYyM2dgnstOZVMSUGk=", + "dev": true, + "requires": { + "continuable-cache": "^0.3.1", + "error": "^7.0.0", + "raw-body": "~1.1.0", + "safe-json-parse": "~1.0.1" + } + }, + "brace-expansion": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", + "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "dev": true, + "requires": { + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" + } + }, + "browser-resolve": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.2.tgz", + "integrity": "sha1-j/CbCixCFxihBRwmCzLkj0QpOM4=", + "dev": true, + "requires": { + "resolve": "1.1.7" + }, + "dependencies": { + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + } + } + }, + "browserify-aes": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-0.4.0.tgz", + "integrity": "sha1-BnFJtmjfMcS1hTPgLQHoBthgjiw=", + "dev": true, + "requires": { + "inherits": "^2.0.1" + } + }, + "browserify-zlib": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz", + "integrity": "sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=", + "dev": true, + "requires": { + "pako": "~0.2.0" + } + }, + "browserslist": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.10.0.tgz", + "integrity": "sha512-WyvzSLsuAVPOjbljXnyeWl14Ae+ukAT8MUuagKVzIDvwBxl4UAwD1xqtyQs2eWYPGUKMeC3Ol62goqYuKqTTcw==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30000780", + "electron-to-chromium": "^1.3.28" + } + }, + "buffer": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", + "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "buffer-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz", + "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=", + "dev": true + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "buffer-shims": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", + "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=", + "dev": true + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "dev": true + }, + "bytes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-1.0.0.tgz", + "integrity": "sha1-NWnt6Lo0MV+rmcPpLLBMciDeH6g=", + "dev": true + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + } + } + }, + "caniuse-lite": { + "version": "1.0.30000783", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000783.tgz", + "integrity": "sha1-m1SZ+xtQPSNF0SqmuGEoUvQnb/0=", + "dev": true + }, + "ccount": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.0.2.tgz", + "integrity": "sha1-U7ai+BW7d7nChx97mnLDol8djok=", + "dev": true + }, + "center-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", + "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", + "dev": true, + "requires": { + "align-text": "^0.1.3", + "lazy-cache": "^1.0.3" + }, + "dependencies": { + "lazy-cache": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", + "dev": true + } + } + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "character-entities": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.1.tgz", + "integrity": "sha1-92hxvl72bdt/j440eOzDdMJ9bco=", + "dev": true + }, + "character-entities-html4": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-1.1.1.tgz", + "integrity": "sha1-NZoqSg9+KdPcKsmb2+Ie45Q46lA=", + "dev": true + }, + "character-entities-legacy": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.1.tgz", + "integrity": "sha1-9Ad53xoQGHK7UQo9KV4fzPFHIC8=", + "dev": true + }, + "character-reference-invalid": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.1.tgz", + "integrity": "sha1-lCg191Dk7GGjCOYMLvjMEBEgLvw=", + "dev": true + }, + "chokidar": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", + "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", + "dev": true, + "requires": { + "anymatch": "^1.3.0", + "async-each": "^1.0.0", + "fsevents": "^1.0.0", + "glob-parent": "^2.0.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^2.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0" + } + }, + "class-utils": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.5.tgz", + "integrity": "sha1-F+eTEDdQ+WJ7IXbqNM/RtWWQPIA=", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "lazy-cache": "^2.0.2", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "cli": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/cli/-/cli-0.4.3.tgz", + "integrity": "sha1-5oGcjV+qlX9k+Y9mqFBiaMHR8X0=", + "dev": true, + "requires": { + "glob": ">= 3.1.4" + } + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + } + }, + "clone": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz", + "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs=", + "dev": true + }, + "clone-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", + "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=", + "dev": true + }, + "clone-stats": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", + "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", + "dev": true + }, + "cloneable-readable": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.0.0.tgz", + "integrity": "sha1-pikNQT8hemEjL5XkWP84QYz7ARc=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "process-nextick-args": "^1.0.6", + "through2": "^2.0.1" + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "collapse-white-space": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.3.tgz", + "integrity": "sha1-S5BvZw5aljqHt2sOFolkM0G2Ajw=", + "dev": true + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color-convert": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", + "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", + "dev": true, + "requires": { + "color-name": "^1.1.1" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "color-ops": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/color-ops/-/color-ops-2.0.0.tgz", + "integrity": "sha1-OkiiMjTpq1l9OqxK+j/3xTpW3cQ=", + "dev": true + }, + "colors": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", + "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", + "dev": true + }, + "comma-separated-tokens": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.4.tgz", + "integrity": "sha1-cgg+WNSkYvAYZvZhf02Yo807ikY=", + "dev": true, + "requires": { + "trim": "0.0.1" + } + }, + "commander": { + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.12.2.tgz", + "integrity": "sha512-BFnaq5ZOGcDN7FlrtBT4xxkgIToalIIxwjxLWVJ8bGTpe1LroqMiqQXdA7ygc7CRvaYS+9zfPGFnJqFSayx+AA==", + "dev": true + }, + "commoner": { + "version": "0.10.8", + "resolved": "https://registry.npmjs.org/commoner/-/commoner-0.10.8.tgz", + "integrity": "sha1-NPw2cs0kOT6LtH5wyqApOBH08sU=", + "dev": true, + "requires": { + "commander": "^2.5.0", + "detective": "^4.3.1", + "glob": "^5.0.15", + "graceful-fs": "^4.1.2", + "iconv-lite": "^0.4.5", + "mkdirp": "^0.5.0", + "private": "^0.1.6", + "q": "^1.1.2", + "recast": "^0.11.17" + } + }, + "compare-func": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-1.3.4.tgz", + "integrity": "sha512-sq2sWtrqKPkEXAC8tEJA1+BqAH9GbFkGBtUOqrUX57VSfwp8xyktctk+uLoRy5eccTdxzDcVIztlYDpKs3Jv1Q==", + "dev": true, + "requires": { + "array-ify": "^1.0.0", + "dot-prop": "^3.0.0" + } + }, + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", + "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "console-browserify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", + "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", + "dev": true, + "requires": { + "date-now": "^0.1.4" + } + }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "dev": true + }, + "continuable-cache": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/continuable-cache/-/continuable-cache-0.3.1.tgz", + "integrity": "sha1-vXJ6f67XfnH/OYWskzUakSczrQ8=", + "dev": true + }, + "conventional-changelog": { + "version": "3.1.21", + "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-3.1.21.tgz", + "integrity": "sha512-ZGecVZPEo3aC75VVE4nu85589dDhpMyqfqgUM5Myq6wfKWiNqhDJLSDMsc8qKXshZoY7dqs1hR0H/15kI/G2jQ==", + "dev": true, + "requires": { + "conventional-changelog-angular": "^5.0.10", + "conventional-changelog-atom": "^2.0.7", + "conventional-changelog-codemirror": "^2.0.7", + "conventional-changelog-conventionalcommits": "^4.3.0", + "conventional-changelog-core": "^4.1.7", + "conventional-changelog-ember": "^2.0.8", + "conventional-changelog-eslint": "^3.0.8", + "conventional-changelog-express": "^2.0.5", + "conventional-changelog-jquery": "^3.0.10", + "conventional-changelog-jshint": "^2.0.7", + "conventional-changelog-preset-loader": "^2.3.4" + } + }, + "conventional-changelog-angular": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.10.tgz", + "integrity": "sha512-k7RPPRs0vp8+BtPsM9uDxRl6KcgqtCJmzRD1wRtgqmhQ96g8ifBGo9O/TZBG23jqlXS/rg8BKRDELxfnQQGiaA==", + "dev": true, + "requires": { + "compare-func": "^1.3.1", + "q": "^1.5.1" + } + }, + "conventional-changelog-atom": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/conventional-changelog-atom/-/conventional-changelog-atom-2.0.7.tgz", + "integrity": "sha512-7dOREZwzB+tCEMjRTDfen0OHwd7vPUdmU0llTy1eloZgtOP4iSLVzYIQqfmdRZEty+3w5Jz+AbhfTJKoKw1JeQ==", + "dev": true, + "requires": { + "q": "^1.5.1" + } + }, + "conventional-changelog-codemirror": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/conventional-changelog-codemirror/-/conventional-changelog-codemirror-2.0.7.tgz", + "integrity": "sha512-Oralk1kiagn3Gb5cR5BffenWjVu59t/viE6UMD/mQa1hISMPkMYhJIqX+CMeA1zXgVBO+YHQhhokEj99GP5xcg==", + "dev": true, + "requires": { + "q": "^1.5.1" + } + }, + "conventional-changelog-config-spec": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-config-spec/-/conventional-changelog-config-spec-2.1.0.tgz", + "integrity": "sha512-IpVePh16EbbB02V+UA+HQnnPIohgXvJRxHcS5+Uwk4AT5LjzCZJm5sp/yqs5C6KZJ1jMsV4paEV13BN1pvDuxQ==", + "dev": true + }, + "conventional-changelog-conventionalcommits": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.3.0.tgz", + "integrity": "sha512-oYHydvZKU+bS8LnGqTMlNrrd7769EsuEHKy4fh1oMdvvDi7fem8U+nvfresJ1IDB8K00Mn4LpiA/lR+7Gs6rgg==", + "dev": true, + "requires": { + "compare-func": "^1.3.1", + "lodash": "^4.17.15", + "q": "^1.5.1" + }, + "dependencies": { + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + } + } + }, + "conventional-changelog-core": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-4.1.7.tgz", + "integrity": "sha512-UBvSrQR2RdKbSQKh7RhueiiY4ZAIOW3+CSWdtKOwRv+KxIMNFKm1rOcGBFx0eA8AKhGkkmmacoTWJTqyz7Q0VA==", + "dev": true, + "requires": { + "add-stream": "^1.0.0", + "conventional-changelog-writer": "^4.0.16", + "conventional-commits-parser": "^3.1.0", + "dateformat": "^3.0.0", + "get-pkg-repo": "^1.0.0", + "git-raw-commits": "2.0.0", + "git-remote-origin-url": "^2.0.0", + "git-semver-tags": "^4.0.0", + "lodash": "^4.17.15", + "normalize-package-data": "^2.3.5", + "q": "^1.5.1", + "read-pkg": "^3.0.0", + "read-pkg-up": "^3.0.0", + "shelljs": "^0.8.3", + "through2": "^3.0.0" + }, + "dependencies": { + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + }, + "shelljs": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz", + "integrity": "sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==", + "dev": true, + "requires": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + } + }, + "through2": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", + "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", + "dev": true, + "requires": { + "inherits": "^2.0.4", + "readable-stream": "2 || 3" + }, + "dependencies": { + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + } + } + } + } + }, + "conventional-changelog-ember": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/conventional-changelog-ember/-/conventional-changelog-ember-2.0.8.tgz", + "integrity": "sha512-JEMEcUAMg4Q9yxD341OgWlESQ4gLqMWMXIWWUqoQU8yvTJlKnrvcui3wk9JvnZQyONwM2g1MKRZuAjKxr8hAXA==", + "dev": true, + "requires": { + "q": "^1.5.1" + } + }, + "conventional-changelog-eslint": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/conventional-changelog-eslint/-/conventional-changelog-eslint-3.0.8.tgz", + "integrity": "sha512-5rTRltgWG7TpU1PqgKHMA/2ivjhrB+E+S7OCTvj0zM/QGg4vmnVH67Vq/EzvSNYtejhWC+OwzvDrLk3tqPry8A==", + "dev": true, + "requires": { + "q": "^1.5.1" + } + }, + "conventional-changelog-express": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/conventional-changelog-express/-/conventional-changelog-express-2.0.5.tgz", + "integrity": "sha512-pW2hsjKG+xNx/Qjof8wYlAX/P61hT5gQ/2rZ2NsTpG+PgV7Rc8RCfITvC/zN9K8fj0QmV6dWmUefCteD9baEAw==", + "dev": true, + "requires": { + "q": "^1.5.1" + } + }, + "conventional-changelog-jquery": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/conventional-changelog-jquery/-/conventional-changelog-jquery-3.0.10.tgz", + "integrity": "sha512-QCW6wF8QgPkq2ruPaxc83jZxoWQxLkt/pNxIDn/oYjMiVgrtqNdd7lWe3vsl0hw5ENHNf/ejXuzDHk6suKsRpg==", + "dev": true, + "requires": { + "q": "^1.5.1" + } + }, + "conventional-changelog-jshint": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/conventional-changelog-jshint/-/conventional-changelog-jshint-2.0.7.tgz", + "integrity": "sha512-qHA8rmwUnLiIxANJbz650+NVzqDIwNtc0TcpIa0+uekbmKHttidvQ1dGximU3vEDdoJVKFgR3TXFqYuZmYy9ZQ==", + "dev": true, + "requires": { + "compare-func": "^1.3.1", + "q": "^1.5.1" + } + }, + "conventional-changelog-preset-loader": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.3.4.tgz", + "integrity": "sha512-GEKRWkrSAZeTq5+YjUZOYxdHq+ci4dNwHvpaBC3+ENalzFWuCWa9EZXSuZBpkr72sMdKB+1fyDV4takK1Lf58g==", + "dev": true + }, + "conventional-changelog-writer": { + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-4.0.16.tgz", + "integrity": "sha512-jmU1sDJDZpm/dkuFxBeRXvyNcJQeKhGtVcFFkwTphUAzyYWcwz2j36Wcv+Mv2hU3tpvLMkysOPXJTLO55AUrYQ==", + "dev": true, + "requires": { + "compare-func": "^1.3.1", + "conventional-commits-filter": "^2.0.6", + "dateformat": "^3.0.0", + "handlebars": "^4.7.6", + "json-stringify-safe": "^5.0.1", + "lodash": "^4.17.15", + "meow": "^7.0.0", + "semver": "^6.0.0", + "split": "^1.0.0", + "through2": "^3.0.0" + }, + "dependencies": { + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "through2": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", + "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", + "dev": true, + "requires": { + "inherits": "^2.0.4", + "readable-stream": "2 || 3" + } + } + } + }, + "conventional-commits-filter": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.6.tgz", + "integrity": "sha512-4g+sw8+KA50/Qwzfr0hL5k5NWxqtrOVw4DDk3/h6L85a9Gz0/Eqp3oP+CWCNfesBvZZZEFHF7OTEbRe+yYSyKw==", + "dev": true, + "requires": { + "lodash.ismatch": "^4.4.0", + "modify-values": "^1.0.0" + } + }, + "conventional-commits-parser": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.1.0.tgz", + "integrity": "sha512-RSo5S0WIwXZiRxUGTPuYFbqvrR4vpJ1BDdTlthFgvHt5kEdnd1+pdvwWphWn57/oIl4V72NMmOocFqqJ8mFFhA==", + "dev": true, + "requires": { + "JSONStream": "^1.0.4", + "is-text-path": "^1.0.1", + "lodash": "^4.17.15", + "meow": "^7.0.0", + "split2": "^2.0.0", + "through2": "^3.0.0", + "trim-off-newlines": "^1.0.0" + }, + "dependencies": { + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + }, + "through2": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", + "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", + "dev": true, + "requires": { + "inherits": "^2.0.4", + "readable-stream": "2 || 3" + } + } + } + }, + "conventional-recommended-bump": { + "version": "6.0.9", + "resolved": "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-6.0.9.tgz", + "integrity": "sha512-DpRmW1k8CpRrcsXHOPGgHgOd4BMGiq2gtXAveGM8B9pSd9b4r4WKnqp1Fd0vkDtk8l973mIk8KKKUYnKRr9SFw==", + "dev": true, + "requires": { + "concat-stream": "^2.0.0", + "conventional-changelog-preset-loader": "^2.3.4", + "conventional-commits-filter": "^2.0.6", + "conventional-commits-parser": "^3.1.0", + "git-raw-commits": "2.0.0", + "git-semver-tags": "^4.0.0", + "meow": "^7.0.0", + "q": "^1.5.1" + }, + "dependencies": { + "concat-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.0.2", + "typedarray": "^0.0.6" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + } + } + }, + "convert-source-map": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-0.5.1.tgz", + "integrity": "sha1-vrgPOyLeBf1FkUEPSUvOvmNKBX4=", + "dev": true + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, + "core-js": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-0.6.1.tgz", + "integrity": "sha1-G0lwhz6BAb+MQ1rwlfqpAk9Lm1g=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "crypto-browserify": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.3.0.tgz", + "integrity": "sha1-ufx1u0oO1h3PHNXa6W6zDJw+UGw=", + "dev": true, + "requires": { + "browserify-aes": "0.4.0", + "pbkdf2-compat": "2.0.1", + "ripemd160": "0.2.0", + "sha.js": "2.2.6" + } + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dev": true, + "requires": { + "array-find-index": "^1.0.1" + } + }, + "dargs": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/dargs/-/dargs-4.1.0.tgz", + "integrity": "sha1-A6nbtLXC8Tm/FK5T8LiipqhvThc=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "date-now": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", + "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", + "dev": true + }, + "dateformat": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", + "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decamelize-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", + "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", + "dev": true, + "requires": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "dependencies": { + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + } + } + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, + "define-properties": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", + "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", + "dev": true, + "requires": { + "foreach": "^2.0.5", + "object-keys": "^1.0.8" + } + }, + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", + "dev": true + }, + "detab": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/detab/-/detab-2.0.1.tgz", + "integrity": "sha512-/hhdqdQc5thGrqzjyO/pz76lDZ5GSuAs6goxOaKTsvPk7HNnzAyFN5lyHgqpX4/s1i66K8qMGj+VhA9504x7DQ==", + "dev": true, + "requires": { + "repeat-string": "^1.5.4" + } + }, + "detect-indent": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-3.0.1.tgz", + "integrity": "sha1-ncXl3bzu+DJXZLlFGwK8bVQIT3U=", + "dev": true, + "requires": { + "get-stdin": "^4.0.1", + "minimist": "^1.1.0", + "repeating": "^1.1.0" + } + }, + "detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true + }, + "detective": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/detective/-/detective-4.7.0.tgz", + "integrity": "sha512-4mBqSEdMfBpRAo/DQZnTcAXenpiSIJmVKbCMSotS+SFWWcrP/CKM6iBRPdTiEO+wZhlfEsoZlGqpG6ycl5vTqw==", + "dev": true, + "requires": { + "acorn": "^5.2.1", + "defined": "^1.0.0" + } + }, + "diff": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz", + "integrity": "sha1-fyjS657nsVqX79ic5j3P2qPMur8=", + "dev": true + }, + "disparity": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/disparity/-/disparity-2.0.0.tgz", + "integrity": "sha1-V92stHMkrl9Y0swNqIbbTOnutxg=", + "dev": true, + "requires": { + "ansi-styles": "^2.0.1", + "diff": "^1.3.2" + } + }, + "doctrine-temporary-fork": { + "version": "2.0.0-alpha-allowarrayindex", + "resolved": "https://registry.npmjs.org/doctrine-temporary-fork/-/doctrine-temporary-fork-2.0.0-alpha-allowarrayindex.tgz", + "integrity": "sha1-QAFahn6yfnWybIKLcVJPE3+J+fA=", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + }, + "dependencies": { + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + } + } + }, + "documentation": { + "version": "5.3.5", + "resolved": "https://registry.npmjs.org/documentation/-/documentation-5.3.5.tgz", + "integrity": "sha512-VApv5dCFxjD5WZxEYGqZypK7L3l00clw9qbSTYCwdnvsaAhu7/U+FCHvkdtnCtkmLupIF/SxXPfXc4kB3UfXEg==", + "dev": true, + "requires": { + "ansi-html": "^0.0.7", + "babel-core": "^6.17.0", + "babel-generator": "^6.25.0", + "babel-plugin-system-import-transformer": "3.1.0", + "babel-plugin-transform-decorators-legacy": "^1.3.4", + "babel-preset-env": "^1.6.0", + "babel-preset-react": "^6.16.0", + "babel-preset-stage-0": "^6.16.0", + "babel-traverse": "^6.16.0", + "babel-types": "^6.16.0", + "babelify": "^8.0.0", + "babylon": "^6.17.2", + "chalk": "^2.0.0", + "chokidar": "^1.2.0", + "concat-stream": "^1.5.0", + "disparity": "^2.0.0", + "doctrine-temporary-fork": "2.0.0-alpha-allowarrayindex", + "get-port": "^3.1.0", + "git-url-parse": "^6.0.1", + "github-slugger": "1.2.0", + "glob": "^7.0.0", + "globals-docs": "^2.4.0", + "highlight.js": "^9.1.0", + "js-yaml": "^3.8.4", + "lodash": "^4.11.1", + "mdast-util-inject": "^1.1.0", + "micromatch": "^3.0.0", + "mime": "^1.4.1", + "module-deps-sortable": "4.0.6", + "parse-filepath": "^1.0.1", + "pify": "^3.0.0", + "read-pkg-up": "^3.0.0", + "remark": "^8.0.0", + "remark-html": "7.0.0", + "remark-toc": "^4.0.0", + "remote-origin-url": "0.4.0", + "shelljs": "^0.7.5", + "stream-array": "^1.1.0", + "strip-json-comments": "^2.0.0", + "tiny-lr": "^1.0.3", + "unist-builder": "^1.0.0", + "unist-util-visit": "^1.0.1", + "vfile": "^2.0.0", + "vfile-reporter": "^4.0.0", + "vfile-sort": "^2.0.0", + "vinyl": "^2.0.0", + "vinyl-fs": "^3.0.0", + "yargs": "^9.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", + "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "babel-core": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.0.tgz", + "integrity": "sha1-rzL3izGm/O8RnIew/Y2XU/A6C7g=", + "dev": true, + "requires": { + "babel-code-frame": "^6.26.0", + "babel-generator": "^6.26.0", + "babel-helpers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-register": "^6.26.0", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "convert-source-map": "^1.5.0", + "debug": "^2.6.8", + "json5": "^0.5.1", + "lodash": "^4.17.4", + "minimatch": "^3.0.4", + "path-is-absolute": "^1.0.1", + "private": "^0.1.7", + "slash": "^1.0.0", + "source-map": "^0.5.6" + } + }, + "babelify": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/babelify/-/babelify-8.0.0.tgz", + "integrity": "sha512-xVr63fKEvMWUrrIbqlHYsMcc5Zdw4FSVesAHgkgajyCE1W8gbm9rbMakqavhxKvikGYMhEcqxTwB/gQmQ6lBtw==", + "dev": true + }, + "chalk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", + "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.1.0", + "escape-string-regexp": "^1.0.5", + "supports-color": "^4.0.0" + } + }, + "convert-source-map": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz", + "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=", + "dev": true + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "^2.0.0" + } + } + } + }, + "dom-serializer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", + "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=", + "dev": true, + "requires": { + "domelementtype": "~1.1.1", + "entities": "~1.1.1" + }, + "dependencies": { + "domelementtype": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", + "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=", + "dev": true + }, + "entities": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", + "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=", + "dev": true + } + } + }, + "domain-browser": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.1.7.tgz", + "integrity": "sha1-hnqksJP6oF8d4IwG9NeyH9+GmLw=", + "dev": true + }, + "domelementtype": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz", + "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=", + "dev": true + }, + "domhandler": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz", + "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=", + "dev": true, + "requires": { + "domelementtype": "1" + } + }, + "domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "dev": true, + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "dot-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-3.0.0.tgz", + "integrity": "sha1-G3CK8JSknJoOfbyteQq6U52sEXc=", + "dev": true, + "requires": { + "is-obj": "^1.0.0" + } + }, + "dotgitignore": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/dotgitignore/-/dotgitignore-2.1.0.tgz", + "integrity": "sha512-sCm11ak2oY6DglEPpCB8TixLjWAxd3kJTs6UIcSasNYxXdFPV+YKlye92c8H4kKFqV5qYMIh7d+cYecEg0dIkA==", + "dev": true, + "requires": { + "find-up": "^3.0.0", + "minimatch": "^3.0.4" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + } + } + }, + "duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", + "dev": true, + "requires": { + "readable-stream": "^2.0.2" + } + }, + "duplexify": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.1.tgz", + "integrity": "sha512-j5goxHTwVED1Fpe5hh3q9R93Kip0Bg2KVAt4f8CEYM3UEwYcPSvWbXaUQOzdX/HtiNomipv+gU7ASQPDbV7pGQ==", + "dev": true, + "requires": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "electron-to-chromium": { + "version": "1.3.28", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.28.tgz", + "integrity": "sha1-jdTmRYCGZE6fnwoc8y4qH53/2e4=", + "dev": true + }, + "emoji-regex": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-6.1.1.tgz", + "integrity": "sha1-xs0OwbBkLio8Z6ETfvxeeW2k+I4=", + "dev": true + }, + "emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", + "dev": true + }, + "end-of-stream": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.0.tgz", + "integrity": "sha1-epDYM+/abPpurA9JSduw+tOmMgY=", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "enhanced-resolve": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-0.9.1.tgz", + "integrity": "sha1-TW5omzcl+GCQknzMhs2fFjW4ni4=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.2.0", + "tapable": "^0.1.8" + }, + "dependencies": { + "memory-fs": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.2.0.tgz", + "integrity": "sha1-8rslNovBIeORwlIN6Slpyu4KApA=", + "dev": true + } + } + }, + "entities": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", + "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=", + "dev": true + }, + "errno": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.6.tgz", + "integrity": "sha512-IsORQDpaaSwcDP4ZZnHxgE85werpo34VYn1Ud3mq+eUsF593faR8oCZNXrROVkpFu2TsbrNhHin0aUrTsQ9vNw==", + "dev": true, + "requires": { + "prr": "~1.0.1" + } + }, + "error": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/error/-/error-7.0.2.tgz", + "integrity": "sha1-pfdf/02ZJhJt2sDqXcOOaJFTywI=", + "dev": true, + "requires": { + "string-template": "~0.2.1", + "xtend": "~4.0.0" + } + }, + "error-ex": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", + "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es6ify": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/es6ify/-/es6ify-1.6.0.tgz", + "integrity": "sha1-4pJbcZIrLX+FT2GXnNDWXMImclU=", + "dev": true, + "requires": { + "through": "~2.2.7", + "traceur": "0.0.79", + "xtend": "~2.2.0" + }, + "dependencies": { + "through": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/through/-/through-2.2.7.tgz", + "integrity": "sha1-bo4hIAGR1OtqmfbwEN9Gqhxusr0=", + "dev": true + }, + "xtend": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.2.0.tgz", + "integrity": "sha1-7vax8ZjByN6vrYsXZaBNrUoBxak=", + "dev": true + } + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "esprima": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", + "dev": true + }, + "estraverse": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", + "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", + "dev": true + }, + "esutils": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-1.1.6.tgz", + "integrity": "sha1-wBzKqa5LiXxtDD4hCuUvPHqEQ3U=", + "dev": true + }, + "events": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", + "dev": true + }, + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "dev": true, + "requires": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "dev": true, + "requires": { + "is-posix-bracket": "^0.1.0" + } + }, + "expand-range": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "dev": true, + "requires": { + "fill-range": "^2.1.0" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "dev": true, + "requires": { + "is-extglob": "^1.0.0" + } + }, + "faye-websocket": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", + "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", + "dev": true, + "requires": { + "websocket-driver": ">=0.5.1" + } + }, + "figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "filename-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", + "dev": true + }, + "fill-range": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", + "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", + "dev": true, + "requires": { + "is-number": "^2.1.0", + "isobject": "^2.0.0", + "randomatic": "^1.1.3", + "repeat-element": "^1.1.2", + "repeat-string": "^1.5.2" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "flush-write-stream": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.2.tgz", + "integrity": "sha1-yBuQ2HRnZvGmCaRoCZRsRd2K5Bc=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.4" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "dev": true, + "requires": { + "for-in": "^1.0.1" + } + }, + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", + "dev": true + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "fs-access": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fs-access/-/fs-access-1.0.1.tgz", + "integrity": "sha1-1qh/JiJxzv6+wwxVNAf7mV2od3o=", + "dev": true, + "requires": { + "null-check": "^1.0.0" + } + }, + "fs-mkdirp-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", + "integrity": "sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "through2": "^2.0.3" + } + }, + "fs-readdir-recursive": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-0.1.2.tgz", + "integrity": "sha1-MVtPuMHKW4xH3v7zGdBz2tNWgFk=", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.3.tgz", + "integrity": "sha512-WIr7iDkdmdbxu/Gh6eKEZJL6KPE74/5MEsf2whTOFNxbIoIixogroLdKYqB6FDav4Wavh/lZdzzd3b2KxIXC5Q==", + "dev": true, + "optional": true, + "requires": { + "nan": "^2.3.0", + "node-pre-gyp": "^0.6.39" + }, + "dependencies": { + "abbrev": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "ajv": { + "version": "4.11.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "co": "^4.6.0", + "json-stable-stringify": "^1.0.1" + } + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "aproba": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "asn1": { + "version": "0.2.3", + "bundled": true, + "dev": true, + "optional": true + }, + "assert-plus": { + "version": "0.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "asynckit": { + "version": "0.4.0", + "bundled": true, + "dev": true, + "optional": true + }, + "aws-sign2": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "aws4": { + "version": "1.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "balanced-match": { + "version": "0.4.2", + "bundled": true, + "dev": true, + "optional": true + }, + "bcrypt-pbkdf": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "block-stream": { + "version": "0.0.9", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "inherits": "~2.0.0" + } + }, + "boom": { + "version": "2.10.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "hoek": "2.x.x" + } + }, + "brace-expansion": { + "version": "1.1.7", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "balanced-match": "^0.4.1", + "concat-map": "0.0.1" + } + }, + "buffer-shims": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "caseless": { + "version": "0.12.0", + "bundled": true, + "dev": true, + "optional": true + }, + "co": { + "version": "4.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "combined-stream": { + "version": "1.0.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "cryptiles": { + "version": "2.0.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "boom": "2.x.x" + } + }, + "dashdash": { + "version": "1.14.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "assert-plus": "^1.0.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "debug": { + "version": "2.6.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-extend": { + "version": "0.4.2", + "bundled": true, + "dev": true, + "optional": true + }, + "delayed-stream": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "ecc-jsbn": { + "version": "0.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "jsbn": "~0.1.0" + } + }, + "extsprintf": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "forever-agent": { + "version": "0.6.1", + "bundled": true, + "dev": true, + "optional": true + }, + "form-data": { + "version": "2.1.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.5", + "mime-types": "^2.1.12" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "fstream": { + "version": "1.0.11", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + } + }, + "fstream-ignore": { + "version": "1.0.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "fstream": "^1.0.0", + "inherits": "2", + "minimatch": "^3.0.0" + } + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "getpass": { + "version": "0.1.7", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "assert-plus": "^1.0.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "glob": { + "version": "7.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "graceful-fs": { + "version": "4.1.11", + "bundled": true, + "dev": true, + "optional": true + }, + "har-schema": { + "version": "1.0.5", + "bundled": true, + "dev": true, + "optional": true + }, + "har-validator": { + "version": "4.2.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ajv": "^4.9.1", + "har-schema": "^1.0.5" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "hawk": { + "version": "3.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "boom": "2.x.x", + "cryptiles": "2.x.x", + "hoek": "2.x.x", + "sntp": "1.x.x" + } + }, + "hoek": { + "version": "2.16.3", + "bundled": true, + "dev": true, + "optional": true + }, + "http-signature": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "assert-plus": "^0.2.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "ini": { + "version": "1.3.4", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-typedarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "isstream": { + "version": "0.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "jodid25519": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "jsbn": "~0.1.0" + } + }, + "jsbn": { + "version": "0.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "json-schema": { + "version": "0.2.3", + "bundled": true, + "dev": true, + "optional": true + }, + "json-stable-stringify": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "jsonify": "~0.0.0" + } + }, + "json-stringify-safe": { + "version": "5.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "jsonify": { + "version": "0.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "jsprim": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.0.2", + "json-schema": "0.2.3", + "verror": "1.3.6" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "mime-db": { + "version": "1.27.0", + "bundled": true, + "dev": true, + "optional": true + }, + "mime-types": { + "version": "2.1.15", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "mime-db": "~1.27.0" + } + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true, + "optional": true + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "node-pre-gyp": { + "version": "0.6.39", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "hawk": "3.1.3", + "mkdirp": "^0.5.1", + "nopt": "^4.0.1", + "npmlog": "^4.0.2", + "rc": "^1.1.7", + "request": "2.81.0", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^2.2.1", + "tar-pack": "^3.4.0" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npmlog": { + "version": "4.1.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "oauth-sign": { + "version": "0.8.2", + "bundled": true, + "dev": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "performance-now": { + "version": "0.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "1.0.7", + "bundled": true, + "dev": true, + "optional": true + }, + "punycode": { + "version": "1.4.1", + "bundled": true, + "dev": true, + "optional": true + }, + "qs": { + "version": "6.4.0", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "~0.4.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.2.9", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "buffer-shims": "~1.0.0", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~1.0.0", + "util-deprecate": "~1.0.1" + } + }, + "request": { + "version": "2.81.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aws-sign2": "~0.6.0", + "aws4": "^1.2.1", + "caseless": "~0.12.0", + "combined-stream": "~1.0.5", + "extend": "~3.0.0", + "forever-agent": "~0.6.1", + "form-data": "~2.1.1", + "har-validator": "~4.2.1", + "hawk": "~3.1.3", + "http-signature": "~1.1.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.7", + "oauth-sign": "~0.8.1", + "performance-now": "^0.2.0", + "qs": "~6.4.0", + "safe-buffer": "^5.0.1", + "stringstream": "~0.0.4", + "tough-cookie": "~2.3.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.0.0" + } + }, + "rimraf": { + "version": "2.6.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "glob": "^7.0.5" + } + }, + "safe-buffer": { + "version": "5.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "semver": { + "version": "5.3.0", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sntp": { + "version": "1.0.9", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "hoek": "2.x.x" + } + }, + "sshpk": { + "version": "1.13.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jodid25519": "^1.0.0", + "jsbn": "~0.1.0", + "tweetnacl": "~0.14.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "stringstream": { + "version": "0.0.5", + "bundled": true, + "dev": true, + "optional": true + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "2.2.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "block-stream": "*", + "fstream": "^1.0.2", + "inherits": "2" + } + }, + "tar-pack": { + "version": "3.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "^2.2.0", + "fstream": "^1.0.10", + "fstream-ignore": "^1.0.5", + "once": "^1.3.3", + "readable-stream": "^2.1.4", + "rimraf": "^2.5.1", + "tar": "^2.2.1", + "uid-number": "^0.0.6" + } + }, + "tough-cookie": { + "version": "2.3.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "punycode": "^1.4.1" + } + }, + "tunnel-agent": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "bundled": true, + "dev": true, + "optional": true + }, + "uid-number": { + "version": "0.0.6", + "bundled": true, + "dev": true, + "optional": true + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "uuid": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "verror": { + "version": "1.3.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "extsprintf": "1.0.2" + } + }, + "wide-align": { + "version": "1.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "^1.0.2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "fuse": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/fuse/-/fuse-0.4.0.tgz", + "integrity": "sha1-LDjq+IirsKm6eWDP4zOdHz9T9uY=", + "dev": true, + "requires": { + "colors": ">=0.6.x", + "jshint": "0.9.x", + "optimist": ">=0.3.5", + "uglify-js": ">=2.2.x", + "underscore": ">=1.4.x" + }, + "dependencies": { + "jshint": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/jshint/-/jshint-0.9.1.tgz", + "integrity": "sha1-/zLsfwn4QAH3SY7q/WPJ5Puy3A4=", + "dev": true, + "requires": { + "cli": "0.4.3", + "minimatch": "0.0.x" + } + }, + "lru-cache": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-1.0.6.tgz", + "integrity": "sha1-qlD5cEdCKsclQ72hd6nJ0BjZhFI=", + "dev": true + }, + "minimatch": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.0.5.tgz", + "integrity": "sha1-lrtJC707poNrv6wRGt91MBsVhN4=", + "dev": true, + "requires": { + "lru-cache": "~1.0.2" + } + } + } + }, + "get-caller-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", + "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=", + "dev": true + }, + "get-pkg-repo": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/get-pkg-repo/-/get-pkg-repo-1.4.0.tgz", + "integrity": "sha1-xztInAbYDMVTbCyFP54FIyBWly0=", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "meow": "^3.3.0", + "normalize-package-data": "^2.3.0", + "parse-github-repo-url": "^1.3.0", + "through2": "^2.0.0" + }, + "dependencies": { + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "dev": true + }, + "camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "dev": true, + "requires": { + "camelcase": "^2.0.0", + "map-obj": "^1.0.0" + } + }, + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "dev": true, + "requires": { + "repeating": "^2.0.0" + } + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + } + }, + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + }, + "meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "dev": true, + "requires": { + "camelcase-keys": "^2.0.0", + "decamelize": "^1.1.2", + "loud-rejection": "^1.0.0", + "map-obj": "^1.0.1", + "minimist": "^1.1.3", + "normalize-package-data": "^2.3.4", + "object-assign": "^4.0.1", + "read-pkg-up": "^1.0.1", + "redent": "^1.0.0", + "trim-newlines": "^1.0.0" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "^2.0.0" + } + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true, + "requires": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true, + "requires": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + } + }, + "redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "dev": true, + "requires": { + "indent-string": "^2.1.0", + "strip-indent": "^1.0.1" + } + }, + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "dev": true, + "requires": { + "is-finite": "^1.0.0" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "^0.2.0" + } + }, + "strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "dev": true, + "requires": { + "get-stdin": "^4.0.1" + } + }, + "trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", + "dev": true + } + } + }, + "get-port": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", + "integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=", + "dev": true + }, + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "dev": true + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "git-raw-commits": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.0.tgz", + "integrity": "sha512-w4jFEJFgKXMQJ0H0ikBk2S+4KP2VEjhCvLCNqbNRQC8BgGWgLKNCO7a9K9LI+TVT7Gfoloje502sEnctibffgg==", + "dev": true, + "requires": { + "dargs": "^4.0.1", + "lodash.template": "^4.0.2", + "meow": "^4.0.0", + "split2": "^2.0.0", + "through2": "^2.0.0" + }, + "dependencies": { + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "camelcase-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz", + "integrity": "sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=", + "dev": true, + "requires": { + "camelcase": "^4.1.0", + "map-obj": "^2.0.0", + "quick-lru": "^1.0.0" + } + }, + "indent-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", + "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", + "dev": true + }, + "map-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", + "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=", + "dev": true + }, + "meow": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-4.0.1.tgz", + "integrity": "sha512-xcSBHD5Z86zaOc+781KrupuHAzeGXSLtiAOmBsiLDiPSaYSB6hdew2ng9EBAnZ62jagG9MHAOdxpDi/lWBFJ/A==", + "dev": true, + "requires": { + "camelcase-keys": "^4.0.0", + "decamelize-keys": "^1.0.0", + "loud-rejection": "^1.0.0", + "minimist": "^1.1.3", + "minimist-options": "^3.0.1", + "normalize-package-data": "^2.3.4", + "read-pkg-up": "^3.0.0", + "redent": "^2.0.0", + "trim-newlines": "^2.0.0" + } + }, + "minimist-options": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-3.0.2.tgz", + "integrity": "sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ==", + "dev": true, + "requires": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0" + } + }, + "quick-lru": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz", + "integrity": "sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g=", + "dev": true + }, + "redent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz", + "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=", + "dev": true, + "requires": { + "indent-string": "^3.0.0", + "strip-indent": "^2.0.0" + } + }, + "strip-indent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", + "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", + "dev": true + }, + "trim-newlines": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", + "integrity": "sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA=", + "dev": true + } + } + }, + "git-remote-origin-url": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz", + "integrity": "sha1-UoJlna4hBxRaERJhEq0yFuxfpl8=", + "dev": true, + "requires": { + "gitconfiglocal": "^1.0.0", + "pify": "^2.3.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "git-semver-tags": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-4.0.0.tgz", + "integrity": "sha512-LajaAWLYVBff+1NVircURJFL8TQ3EMIcLAfHisWYX/nPoMwnTYfWAznQDmMujlLqoD12VtLmoSrF1sQ5MhimEQ==", + "dev": true, + "requires": { + "meow": "^7.0.0", + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "git-up": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/git-up/-/git-up-2.0.9.tgz", + "integrity": "sha1-IZv9J8gtrurYSVvrOG3Bjq5jY20=", + "dev": true, + "requires": { + "is-ssh": "^1.3.0", + "parse-url": "^1.3.0" + } + }, + "git-url-parse": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-6.2.2.tgz", + "integrity": "sha1-vkkCThS4SHVTQ2tFcri0OVMvqHE=", + "dev": true, + "requires": { + "git-up": "^2.0.0" + } + }, + "gitconfiglocal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz", + "integrity": "sha1-QdBF84UaXqiPA/JMocYXgRRGS5s=", + "dev": true, + "requires": { + "ini": "^1.3.2" + } + }, + "github-slugger": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.2.0.tgz", + "integrity": "sha512-wIaa75k1vZhyPm9yWrD08A5Xnx/V+RmzGrpjQuLemGKSb77Qukiaei58Bogrl/LZSADDfPzKJX8jhLs4CRTl7Q==", + "dev": true, + "requires": { + "emoji-regex": ">=6.0.0 <=6.1.1" + } + }, + "glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dev": true, + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "dev": true, + "requires": { + "glob-parent": "^2.0.0", + "is-glob": "^2.0.0" + } + }, + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "dev": true, + "requires": { + "is-glob": "^2.0.0" + } + }, + "glob-stream": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz", + "integrity": "sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ=", + "dev": true, + "requires": { + "extend": "^3.0.0", + "glob": "^7.1.1", + "glob-parent": "^3.1.0", + "is-negated-glob": "^1.0.0", + "ordered-read-streams": "^1.0.0", + "pumpify": "^1.3.5", + "readable-stream": "^2.1.5", + "remove-trailing-separator": "^1.0.1", + "to-absolute-glob": "^2.0.0", + "unique-stream": "^2.0.2" + }, + "dependencies": { + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "globals": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/globals/-/globals-6.4.1.tgz", + "integrity": "sha1-hJgDKzttHMge68X3lpDY/in6v08=", + "dev": true + }, + "globals-docs": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/globals-docs/-/globals-docs-2.4.0.tgz", + "integrity": "sha512-B69mWcqCmT3jNYmSxRxxOXWfzu3Go8NQXPfl2o0qPd1EEFhwW0dFUg9ztTu915zPQzqwIhWAlw6hmfIcCK4kkQ==", + "dev": true + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + }, + "handlebars": { + "version": "4.7.6", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.6.tgz", + "integrity": "sha512-1f2BACcBfiwAfStCKZNrUCgqNZkGsAT7UM3kkYtXuLo0KnaVfjKOyf7PRzB6++aK9STyT1Pd2ZCPe3EGOXleXA==", + "dev": true, + "requires": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4", + "wordwrap": "^1.0.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "uglify-js": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.10.0.tgz", + "integrity": "sha512-Esj5HG5WAyrLIdYU74Z3JdG2PxdIusvj6IWHMtlyESxc7kcDz7zYlYjpnSokn1UbpV0d/QX9fan7gkCNd/9BQA==", + "dev": true, + "optional": true + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + } + } + }, + "hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "dev": true + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hast-util-is-element": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-1.0.0.tgz", + "integrity": "sha1-P3IWl4sq4U2YdJh4eCZ18zvjzgA=", + "dev": true + }, + "hast-util-sanitize": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/hast-util-sanitize/-/hast-util-sanitize-1.1.2.tgz", + "integrity": "sha1-0QvWdXoh5ZwTq8iuNTDdO219Z54=", + "dev": true, + "requires": { + "xtend": "^4.0.1" + } + }, + "hast-util-to-html": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-3.1.0.tgz", + "integrity": "sha1-iCyZhJ5AEw6ZHAQuRW1FPZXDbP8=", + "dev": true, + "requires": { + "ccount": "^1.0.0", + "comma-separated-tokens": "^1.0.1", + "hast-util-is-element": "^1.0.0", + "hast-util-whitespace": "^1.0.0", + "html-void-elements": "^1.0.0", + "kebab-case": "^1.0.0", + "property-information": "^3.1.0", + "space-separated-tokens": "^1.0.0", + "stringify-entities": "^1.0.1", + "unist-util-is": "^2.0.0", + "xtend": "^4.0.1" + } + }, + "hast-util-whitespace": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-1.0.0.tgz", + "integrity": "sha1-vQlpGWJdKTbh/xe8Tff9cn8X7Ok=", + "dev": true + }, + "highlight.js": { + "version": "9.12.0", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.12.0.tgz", + "integrity": "sha1-5tnb5Xy+/mB1HwKvM2GVhwyQwB4=", + "dev": true + }, + "home-or-tmp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", + "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", + "dev": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.1" + } + }, + "hosted-git-info": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", + "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==", + "dev": true + }, + "html-void-elements": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-1.0.2.tgz", + "integrity": "sha1-nSLgyjKsyVs/RbjVtPb73AWv/VU=", + "dev": true + }, + "htmlparser2": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz", + "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=", + "dev": true, + "requires": { + "domelementtype": "1", + "domhandler": "2.3", + "domutils": "1.5", + "entities": "1.0", + "readable-stream": "1.1" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, + "http-parser-js": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.9.tgz", + "integrity": "sha1-6hoE+2St/wJC6ZdPKX3Uw8rSceE=", + "dev": true + }, + "https-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-0.0.1.tgz", + "integrity": "sha1-P5E2XKvmC3ftDruiS0VOPgnZWoI=", + "dev": true + }, + "iconv-lite": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", + "dev": true + }, + "ieee754": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz", + "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=", + "dev": true + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true + }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true + }, + "interpret": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", + "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", + "dev": true + }, + "invariant": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz", + "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=", + "dev": true, + "requires": { + "loose-envify": "^1.0.0" + } + }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "dev": true + }, + "is-absolute": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-0.2.6.tgz", + "integrity": "sha1-IN5p89uULvLYe5wto28XIjWxtes=", + "dev": true, + "requires": { + "is-relative": "^0.2.1", + "is-windows": "^0.2.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-alphabetical": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.1.tgz", + "integrity": "sha1-x3B5zJHU76x3W+EDS/LSQ/lebwg=", + "dev": true + }, + "is-alphanumeric": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-alphanumeric/-/is-alphanumeric-1.0.0.tgz", + "integrity": "sha1-Spzvcdr0wAHB2B1j0UDPU/1oifQ=", + "dev": true + }, + "is-alphanumerical": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.1.tgz", + "integrity": "sha1-37SqTRCF4zvbYcLe6cgOnGwZ9Ts=", + "dev": true, + "requires": { + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-builtin-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "dev": true, + "requires": { + "builtin-modules": "^1.0.0" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-decimal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.1.tgz", + "integrity": "sha1-9ftqlJlq2ejjdh+/vQkfH8qMToI=", + "dev": true + }, + "is-descriptor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.1.tgz", + "integrity": "sha512-G3fFVFTqfaqu7r4YuSBHKBAuOaLz8Sy7ekklUpFEliaLMP1Y2ZjoN9jS62YWCAPQrQpMUQSitRlrzibbuCZjdA==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-dotfile": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", + "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", + "dev": true + }, + "is-equal-shallow": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "dev": true, + "requires": { + "is-primitive": "^2.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "dev": true + }, + "is-finite": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", + "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dev": true, + "requires": { + "is-extglob": "^1.0.0" + } + }, + "is-hexadecimal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.1.tgz", + "integrity": "sha1-bghLvJIGH7sJcexYts5tQE4k2mk=", + "dev": true + }, + "is-integer": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-integer/-/is-integer-1.0.7.tgz", + "integrity": "sha1-a96Bqs3feLZZtmKdYpytxRqIbVw=", + "dev": true, + "requires": { + "is-finite": "^1.0.0" + } + }, + "is-negated-glob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", + "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=", + "dev": true + }, + "is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "dev": true + }, + "is-odd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-odd/-/is-odd-1.0.0.tgz", + "integrity": "sha1-O4qTLrAos3dcObsJ6RdnrM22kIg=", + "dev": true, + "requires": { + "is-number": "^3.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + } + } + }, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "is-posix-bracket": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", + "dev": true + }, + "is-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", + "dev": true + }, + "is-relative": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-0.2.1.tgz", + "integrity": "sha1-0n9MfVFtF1+2ENuEu+7yPDvJeqU=", + "dev": true, + "requires": { + "is-unc-path": "^0.1.1" + } + }, + "is-ssh": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.3.0.tgz", + "integrity": "sha1-6+oRaaJhTaOSpjdANmw84EnY3/Y=", + "dev": true, + "requires": { + "protocols": "^1.1.0" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-text-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", + "integrity": "sha1-Thqg+1G/vLPpJogAE5cgLBd1tm4=", + "dev": true, + "requires": { + "text-extensions": "^1.0.0" + } + }, + "is-unc-path": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-0.1.2.tgz", + "integrity": "sha1-arBTpyVzwQJQ/0FqOBTDUXivObk=", + "dev": true, + "requires": { + "unc-path-regex": "^0.1.0" + } + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "is-valid-glob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz", + "integrity": "sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao=", + "dev": true + }, + "is-whitespace-character": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.1.tgz", + "integrity": "sha1-muAXbzKCtlRXoZks2whPil+DPjs=", + "dev": true + }, + "is-windows": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz", + "integrity": "sha1-3hqm1j6indJIc3tp8f+LgALSEIw=", + "dev": true + }, + "is-word-character": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.1.tgz", + "integrity": "sha1-WgP6HqkazopusMfNdw64bWXIvvs=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + }, + "jest": { + "version": "0.1.40", + "resolved": "https://registry.npmjs.org/jest/-/jest-0.1.40.tgz", + "integrity": "sha1-yUeefqGac7gUGjCFPIRsM25k1Y8=", + "dev": true, + "requires": { + "sji": "^0.0.1", + "underscore": "^1.8.3" + }, + "dependencies": { + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=", + "dev": true + } + } + }, + "js-tokens": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-1.0.0.tgz", + "integrity": "sha1-J4sua2jfpMhBavETcKVepAG/TN4=", + "dev": true + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "dependencies": { + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + } + } + }, + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + }, + "jshint": { + "version": "2.9.5", + "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.9.5.tgz", + "integrity": "sha1-HnJSkVzmgbQIJ+4UJIxG006apiw=", + "dev": true, + "requires": { + "cli": "~1.0.0", + "console-browserify": "1.1.x", + "exit": "0.1.x", + "htmlparser2": "3.8.x", + "lodash": "3.7.x", + "minimatch": "~3.0.2", + "shelljs": "0.3.x", + "strip-json-comments": "1.0.x" + }, + "dependencies": { + "cli": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cli/-/cli-1.0.1.tgz", + "integrity": "sha1-IoF1NPJL+klQw01TLUjsvGIbjBQ=", + "dev": true, + "requires": { + "exit": "0.1.2", + "glob": "^7.1.1" + } + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "lodash": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.7.0.tgz", + "integrity": "sha1-Nni9irmVBXwHreg27S7wh9qBHUU=", + "dev": true + }, + "shelljs": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", + "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=", + "dev": true + }, + "strip-json-comments": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", + "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=", + "dev": true + } + } + }, + "jshint-loader": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/jshint-loader/-/jshint-loader-0.8.4.tgz", + "integrity": "sha1-tD7kXRN3adVliUChH479mg7c1Hs=", + "dev": true, + "requires": { + "loader-utils": "^1.0.2", + "rcloader": "=0.1.2", + "strip-json-comments": "0.1.x" + }, + "dependencies": { + "loader-utils": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz", + "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=", + "dev": true, + "requires": { + "big.js": "^3.1.3", + "emojis-list": "^2.0.0", + "json5": "^0.5.0" + } + }, + "strip-json-comments": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-0.1.3.tgz", + "integrity": "sha1-Fkxk43Coo8wAyeAbU55WmCPw7lQ=", + "dev": true + } + } + }, + "json-parse-better-errors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.1.tgz", + "integrity": "sha512-xyQpxeWWMKyJps9CuGJYeng6ssI5bpqS9ltQpdVQ90t4ql6NdnxFKh95JcRt2cun/DjMVNrdjniLPuMA69xmCw==", + "dev": true + }, + "json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "dev": true, + "requires": { + "jsonify": "~0.0.0" + } + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "dev": true + }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "dev": true + }, + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", + "dev": true + }, + "kebab-case": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/kebab-case/-/kebab-case-1.0.0.tgz", + "integrity": "sha1-P55JkK3K0MaGwOcB92RYaPdfkes=", + "dev": true + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + }, + "lazy-cache": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-2.0.2.tgz", + "integrity": "sha1-uRkKT5EzVGlIQIWfio9whNiCImQ=", + "dev": true, + "requires": { + "set-getter": "^0.1.0" + } + }, + "lazystream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", + "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", + "dev": true, + "requires": { + "readable-stream": "^2.0.5" + } + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "dev": true, + "requires": { + "invert-kv": "^1.0.0" + } + }, + "lead": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz", + "integrity": "sha1-bxT5mje+Op3XhPVJVpDlkDRm7kI=", + "dev": true, + "requires": { + "flush-write-stream": "^1.0.2" + } + }, + "left-pad": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/left-pad/-/left-pad-0.0.3.tgz", + "integrity": "sha1-BNmbSh6vnl95wF5ddF1T7dGqiqE=", + "dev": true + }, + "leven": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/leven/-/leven-1.0.2.tgz", + "integrity": "sha1-kUS27ryl8dBoAWnxpncNzqYLdcM=", + "dev": true + }, + "line-numbers": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/line-numbers/-/line-numbers-0.2.0.tgz", + "integrity": "sha1-a8AoFJRA5XDUlatQlpKqCL13nG4=", + "dev": true, + "requires": { + "left-pad": "0.0.3" + } + }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, + "livereload-js": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-2.2.2.tgz", + "integrity": "sha1-bIclfmSKtHW8JOoldFftzB+NC8I=", + "dev": true + }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + } + }, + "loader-utils": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", + "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", + "dev": true, + "requires": { + "big.js": "^3.1.3", + "emojis-list": "^2.0.0", + "json5": "^0.5.0", + "object-assign": "^4.0.1" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", + "dev": true + }, + "lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", + "dev": true + }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, + "lodash.ismatch": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", + "integrity": "sha1-dWy1FQyjum8RCFp4hJZF8Yj4Xzc=", + "dev": true + }, + "lodash.template": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", + "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", + "dev": true, + "requires": { + "lodash._reinterpolate": "^3.0.0", + "lodash.templatesettings": "^4.0.0" + } + }, + "lodash.templatesettings": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", + "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", + "dev": true, + "requires": { + "lodash._reinterpolate": "^3.0.0" + } + }, + "longest": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", + "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", + "dev": true + }, + "longest-streak": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.2.tgz", + "integrity": "sha512-TmYTeEYxiAmSVdpbnQDXGtvYOIRsCMg89CVZzwzc2o7GFL1CjoiRPjH5ec0NFAVlAx3fVof9dX/t6KKRAo2OWA==", + "dev": true + }, + "loose-envify": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", + "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", + "dev": true, + "requires": { + "js-tokens": "^3.0.0" + }, + "dependencies": { + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + } + } + }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "dev": true, + "requires": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" + } + }, + "lru-cache": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", + "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.1.0.tgz", + "integrity": "sha512-glc9y00wgtwcDmp7GaE/0b0OnxpNJsVf3ael/An6Fe2Q51LLwN1er6sdomLRzz5h0+yMpiYLhWYF5R7HeqVd4g==", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "markdown-escapes": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.1.tgz", + "integrity": "sha1-GZTfLTr0gR3lmmcUk0wrIpJzRRg=", + "dev": true + }, + "markdown-table": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.1.tgz", + "integrity": "sha1-Sz3ToTPRUYuO8NvHCb8qG0gkvIw=", + "dev": true + }, + "mdast-util-compact": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-compact/-/mdast-util-compact-1.0.1.tgz", + "integrity": "sha1-zbX4TitqLTEU3zO9BdnLMuPECDo=", + "dev": true, + "requires": { + "unist-util-modify-children": "^1.0.0", + "unist-util-visit": "^1.1.0" + } + }, + "mdast-util-definitions": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-1.2.2.tgz", + "integrity": "sha512-9NloPSwaB9f1PKcGqaScfqRf6zKOEjTIXVIbPOmgWI/JKxznlgVXC5C+8qgl3AjYg2vJBRgLYfLICaNiac89iA==", + "dev": true, + "requires": { + "unist-util-visit": "^1.0.0" + } + }, + "mdast-util-inject": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-inject/-/mdast-util-inject-1.1.0.tgz", + "integrity": "sha1-2wa4tYW+lZotzS+H9HK6m3VvNnU=", + "dev": true, + "requires": { + "mdast-util-to-string": "^1.0.0" + } + }, + "mdast-util-to-hast": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-3.0.0.tgz", + "integrity": "sha512-zvEXH2AUevWfKuBqtEPNcDUPI8UC6yIVvgEgNi1v1dLnzb5Pfm+PZjnZn0FhW1WmHcrGMX059MAoqicEauzjcw==", + "dev": true, + "requires": { + "collapse-white-space": "^1.0.0", + "detab": "^2.0.0", + "mdast-util-definitions": "^1.2.0", + "mdurl": "^1.0.1", + "trim": "0.0.1", + "trim-lines": "^1.0.0", + "unist-builder": "^1.0.1", + "unist-util-generated": "^1.1.0", + "unist-util-position": "^3.0.0", + "unist-util-visit": "^1.1.0", + "xtend": "^4.0.1" + } + }, + "mdast-util-to-string": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.0.4.tgz", + "integrity": "sha1-XEVch4yTVfDB5/PotxnPWDaRrPs=", + "dev": true + }, + "mdast-util-toc": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-toc/-/mdast-util-toc-2.0.1.tgz", + "integrity": "sha1-sdLLI7+wH4Evp7Vb/+iwqL7fbyE=", + "dev": true, + "requires": { + "github-slugger": "^1.1.1", + "mdast-util-to-string": "^1.0.2", + "unist-util-visit": "^1.1.0" + } + }, + "mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", + "dev": true + }, + "mem": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", + "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "memory-fs": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.3.0.tgz", + "integrity": "sha1-e8xrYp46Q+hx1+Kaymrop/FcuyA=", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "meow": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-7.0.1.tgz", + "integrity": "sha512-tBKIQqVrAHqwit0vfuFPY3LlzJYkEOFyKa3bPgxzNl6q/RtN8KQ+ALYEASYuFayzSAsjlhXj/JZ10rH85Q6TUw==", + "dev": true, + "requires": { + "@types/minimist": "^1.2.0", + "arrify": "^2.0.1", + "camelcase": "^6.0.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "^4.0.2", + "normalize-package-data": "^2.5.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.13.1", + "yargs-parser": "^18.1.3" + }, + "dependencies": { + "camelcase": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.0.0.tgz", + "integrity": "sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w==", + "dev": true + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "dependencies": { + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + } + } + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + } + } + } + } + }, + "micromatch": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.4.tgz", + "integrity": "sha512-kFRtviKYoAJT+t7HggMl0tBFGNAKLw/S7N+CO9qfEQyisob1Oy4pao+geRbkyeEd+V9aOkvZ4mhuyPvI/q9Sfg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.0", + "define-property": "^1.0.0", + "extend-shallow": "^2.0.1", + "extglob": "^2.0.2", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.0", + "nanomatch": "^1.2.5", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "braces": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.0.tgz", + "integrity": "sha512-P4O8UQRdGiMLWSizsApmXVQDBS6KCt7dSexgLKBmH5Hr1CZq7vsnscFh8oR1sP1ab1Zj0uCHCEzZeV6SfUf3rA==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "extglob": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.2.tgz", + "integrity": "sha512-I0+eZBH+jFGL8F5BnIz2ON2nKCjTS3AS3H/5PeSmCp7UVC70Ym8IhdRiQly2juKYQ//f7z1aj1BRpQniFJoU1w==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + } + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + }, + "mimic-fn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz", + "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=", + "dev": true + }, + "min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dev": true, + "requires": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "dependencies": { + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + } + } + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + } + } + }, + "modify-values": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", + "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==", + "dev": true + }, + "module-deps-sortable": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/module-deps-sortable/-/module-deps-sortable-4.0.6.tgz", + "integrity": "sha1-ElGkuixEqS32mJvQKdoSGk8hCbA=", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "browser-resolve": "^1.7.0", + "concat-stream": "~1.5.0", + "defined": "^1.0.0", + "detective": "^4.0.0", + "duplexer2": "^0.1.2", + "inherits": "^2.0.1", + "parents": "^1.0.0", + "readable-stream": "^2.0.2", + "resolve": "^1.1.3", + "stream-combiner2": "^1.1.1", + "subarg": "^1.0.0", + "through2": "^2.0.0", + "xtend": "^4.0.0" + }, + "dependencies": { + "concat-stream": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.2.tgz", + "integrity": "sha1-cIl4Yk2FavQaWnQd790mHadSwmY=", + "dev": true, + "requires": { + "inherits": "~2.0.1", + "readable-stream": "~2.0.0", + "typedarray": "~0.0.5" + }, + "dependencies": { + "readable-stream": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~0.10.x", + "util-deprecate": "~1.0.1" + } + } + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "nan": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.8.0.tgz", + "integrity": "sha1-7XFfP+neArV6XmJS2QqWZ14fCFo=", + "dev": true, + "optional": true + }, + "nanomatch": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.6.tgz", + "integrity": "sha512-WJ6XTCbvWXUFPbi/bDwKcYkCeOGUHzaJj72KbuPqGn78Ba/F5Vu26Zlo6SuMQbCIst1RGKL1zfWBCOGAlbRLAg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "is-odd": "^1.0.0", + "kind-of": "^5.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node-libs-browser": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-0.7.0.tgz", + "integrity": "sha1-PicsCBnjCJNeJmdECNevDhSRuDs=", + "dev": true, + "requires": { + "assert": "^1.1.1", + "browserify-zlib": "^0.1.4", + "buffer": "^4.9.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "3.3.0", + "domain-browser": "^1.1.1", + "events": "^1.0.0", + "https-browserify": "0.0.1", + "os-browserify": "^0.2.0", + "path-browserify": "0.0.0", + "process": "^0.11.0", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.0.5", + "stream-browserify": "^2.0.1", + "stream-http": "^2.3.1", + "string_decoder": "^0.10.25", + "timers-browserify": "^2.0.2", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.10.3", + "vm-browserify": "0.0.4" + }, + "dependencies": { + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, + "normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "is-builtin-module": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "now-and-later": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.0.tgz", + "integrity": "sha1-vGHLtFbXnLMiB85HygUTb/Ln1u4=", + "dev": true, + "requires": { + "once": "^1.3.2" + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "null-check": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/null-check/-/null-check-1.0.0.tgz", + "integrity": "sha1-l33/1xdgErnsMNKjnbXPcqBDnt0=", + "dev": true + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + } + } + }, + "object-keys": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz", + "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=", + "dev": true + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "object.assign": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.0.4.tgz", + "integrity": "sha1-scnMBE7xuf5jYG/BQau7MuFHMMw=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.0", + "object-keys": "^1.0.10" + } + }, + "object.omit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "dev": true, + "requires": { + "for-own": "^0.1.4", + "is-extendable": "^0.1.1" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "dev": true, + "requires": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + }, + "dependencies": { + "minimist": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", + "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", + "dev": true + } + } + }, + "ordered-read-streams": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", + "integrity": "sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4=", + "dev": true, + "requires": { + "readable-stream": "^2.0.1" + } + }, + "os-browserify": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.2.1.tgz", + "integrity": "sha1-Y/xMzuXS13Y9Jrv4YBB45sLgBE8=", + "dev": true + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "os-locale": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", + "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", + "dev": true, + "requires": { + "execa": "^0.7.0", + "lcid": "^1.0.0", + "mem": "^1.1.0" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "output-file-sync": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/output-file-sync/-/output-file-sync-1.1.2.tgz", + "integrity": "sha1-0KM+7+YaIF+suQCS6CZZjVJFznY=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.4", + "mkdirp": "^0.5.1", + "object-assign": "^4.1.0" + } + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "p-limit": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz", + "integrity": "sha1-sH/y2aXYi+yAYDWJWiurZqJ5iLw=", + "dev": true + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "pako": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", + "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=", + "dev": true + }, + "parents": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", + "integrity": "sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E=", + "dev": true, + "requires": { + "path-platform": "~0.11.15" + } + }, + "parse-entities": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.1.1.tgz", + "integrity": "sha1-gRLYhHExnyerrk1klksSL+ThuJA=", + "dev": true, + "requires": { + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" + } + }, + "parse-filepath": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.1.tgz", + "integrity": "sha1-FZ1hVdQ5BNFsEO9piRHaHpGWm3M=", + "dev": true, + "requires": { + "is-absolute": "^0.2.3", + "map-cache": "^0.2.0", + "path-root": "^0.1.1" + } + }, + "parse-git-config": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/parse-git-config/-/parse-git-config-0.2.0.tgz", + "integrity": "sha1-Jygz/dFf6hRvt10zbSNrljtv9wY=", + "dev": true, + "requires": { + "ini": "^1.3.3" + } + }, + "parse-github-repo-url": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/parse-github-repo-url/-/parse-github-repo-url-1.4.1.tgz", + "integrity": "sha1-nn2LslKmy2ukJZUGC3v23z28H1A=", + "dev": true + }, + "parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "dev": true, + "requires": { + "glob-base": "^0.3.0", + "is-dotfile": "^1.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.0" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "parse-url": { + "version": "1.3.11", + "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-1.3.11.tgz", + "integrity": "sha1-V8FUKKuKiSsfQ4aWRccR0OFEtVQ=", + "dev": true, + "requires": { + "is-ssh": "^1.3.0", + "protocols": "^1.4.0" + } + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "path-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", + "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=", + "dev": true + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", + "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", + "dev": true + }, + "path-platform": { + "version": "0.11.15", + "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz", + "integrity": "sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I=", + "dev": true + }, + "path-root": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", + "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", + "dev": true, + "requires": { + "path-root-regex": "^0.1.0" + } + }, + "path-root-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", + "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", + "dev": true + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "pbkdf2-compat": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pbkdf2-compat/-/pbkdf2-compat-2.0.1.tgz", + "integrity": "sha1-tuDI+plJTZTgURV1gCpZpcFC8og=", + "dev": true + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "^2.0.0" + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, + "preserve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", + "dev": true + }, + "private": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", + "dev": true + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", + "dev": true + }, + "property-information": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-3.2.0.tgz", + "integrity": "sha1-/RSDyPusYYCPX+NZ52k6H0ilgzE=", + "dev": true + }, + "protocols": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/protocols/-/protocols-1.4.6.tgz", + "integrity": "sha1-+LsmPqG1/Xp2BNJri+Ob13Z4v4o=", + "dev": true + }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "pump": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz", + "integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "pumpify": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.3.5.tgz", + "integrity": "sha1-G2ccYZlAq8rqwK0OOjwWS+dgmTs=", + "dev": true, + "requires": { + "duplexify": "^3.1.2", + "inherits": "^2.0.1", + "pump": "^1.0.0" + } + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + }, + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + "dev": true + }, + "qs": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", + "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", + "dev": true + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true + }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "dev": true + }, + "quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "dev": true + }, + "randomatic": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", + "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "raw-body": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-1.1.7.tgz", + "integrity": "sha1-HQJ8K/oRasxmI7yo8AAWVyqH1CU=", + "dev": true, + "requires": { + "bytes": "1", + "string_decoder": "0.10" + }, + "dependencies": { + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, + "rcfinder": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/rcfinder/-/rcfinder-0.1.9.tgz", + "integrity": "sha1-8+gPOH3fmugK4wpBADKWQuroERU=", + "dev": true, + "requires": { + "lodash.clonedeep": "^4.3.2" + } + }, + "rcloader": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/rcloader/-/rcloader-0.1.2.tgz", + "integrity": "sha1-oJY6ZDfQnvjLktky0trUl7DRc2w=", + "dev": true, + "requires": { + "lodash": "~2.4.1", + "rcfinder": "~0.1.6" + }, + "dependencies": { + "lodash": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", + "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=", + "dev": true + } + } + }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + } + }, + "read-pkg-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^3.0.0" + } + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.0.3", + "util-deprecate": "~1.0.1" + } + }, + "readdirp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", + "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "minimatch": "^3.0.2", + "readable-stream": "^2.0.2", + "set-immediate-shim": "^1.0.1" + } + }, + "recast": { + "version": "0.11.23", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.11.23.tgz", + "integrity": "sha1-RR/TAEqx5N+bTktmN2sqIZEkYtM=", + "dev": true, + "requires": { + "ast-types": "0.9.6", + "esprima": "~3.1.0", + "private": "~0.1.5", + "source-map": "~0.5.0" + }, + "dependencies": { + "ast-types": { + "version": "0.9.6", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.9.6.tgz", + "integrity": "sha1-ECyenpAF0+fjgpvwxPok7oYu6bk=", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dev": true, + "requires": { + "resolve": "^1.1.6" + } + }, + "redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "requires": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + } + }, + "regenerate": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.3.tgz", + "integrity": "sha512-jVpo1GadrDAK59t/0jRx5VxYWQEDkkEKi6+HjE3joFVLfDOh9Xrdh0dF1eSq+BI/SwvTQ44gSscJ8N5zYL61sg==", + "dev": true + }, + "regenerator-babel": { + "version": "0.8.13-2", + "resolved": "https://registry.npmjs.org/regenerator-babel/-/regenerator-babel-0.8.13-2.tgz", + "integrity": "sha1-HAdf9SQgjpNZFBkYCNB5j9j7xOU=", + "dev": true, + "requires": { + "ast-types": "~0.7.0", + "commoner": "~0.10.0", + "private": "~0.1.5", + "through": "~2.3.6" + } + }, + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "dev": true + }, + "regenerator-transform": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz", + "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", + "dev": true, + "requires": { + "babel-runtime": "^6.18.0", + "babel-types": "^6.19.0", + "private": "^0.1.6" + } + }, + "regex-cache": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", + "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", + "dev": true, + "requires": { + "is-equal-shallow": "^0.1.3" + } + }, + "regex-not": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.0.tgz", + "integrity": "sha1-Qvg+OXcWIt+CawKvF2Ul1qXxV/k=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1" + } + }, + "regexpu": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/regexpu/-/regexpu-1.3.0.tgz", + "integrity": "sha1-5TTcmRqeWEYFDJjebX3UpVyeoW0=", + "dev": true, + "requires": { + "esprima": "^2.6.0", + "recast": "^0.10.10", + "regenerate": "^1.2.1", + "regjsgen": "^0.2.0", + "regjsparser": "^0.1.4" + }, + "dependencies": { + "ast-types": { + "version": "0.8.15", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.8.15.tgz", + "integrity": "sha1-ju8IJ/BN/w7IhXupJavj/qYZTlI=", + "dev": true + }, + "esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "dev": true + }, + "recast": { + "version": "0.10.43", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.10.43.tgz", + "integrity": "sha1-uV1Q9tYHYaX2JS4V2AZ4FoSRzn8=", + "dev": true, + "requires": { + "ast-types": "0.8.15", + "esprima-fb": "~15001.1001.0-dev-harmony-fb", + "private": "~0.1.5", + "source-map": "~0.5.0" + }, + "dependencies": { + "esprima-fb": { + "version": "15001.1001.0-dev-harmony-fb", + "resolved": "https://registry.npmjs.org/esprima-fb/-/esprima-fb-15001.1001.0-dev-harmony-fb.tgz", + "integrity": "sha1-Q761fsJujPI3092LM+QlM1d/Jlk=", + "dev": true + } + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "regexpu-core": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", + "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", + "dev": true, + "requires": { + "regenerate": "^1.2.1", + "regjsgen": "^0.2.0", + "regjsparser": "^0.1.4" + } + }, + "regjsgen": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", + "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", + "dev": true + }, + "regjsparser": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", + "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + } + }, + "remark": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/remark/-/remark-8.0.0.tgz", + "integrity": "sha512-K0PTsaZvJlXTl9DN6qYlvjTkqSZBFELhROZMrblm2rB+085flN84nz4g/BscKRMqDvhzlK1oQ/xnWQumdeNZYw==", + "dev": true, + "requires": { + "remark-parse": "^4.0.0", + "remark-stringify": "^4.0.0", + "unified": "^6.0.0" + } + }, + "remark-html": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/remark-html/-/remark-html-7.0.0.tgz", + "integrity": "sha512-jqRzkZXCkM12gIY2ibMLTW41m7rfanliMTVQCFTezHJFsbH00YaTox/BX4gU+f/zCdzfhFJONtebFByvpMv37w==", + "dev": true, + "requires": { + "hast-util-sanitize": "^1.0.0", + "hast-util-to-html": "^3.0.0", + "mdast-util-to-hast": "^3.0.0", + "xtend": "^4.0.1" + } + }, + "remark-parse": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-4.0.0.tgz", + "integrity": "sha512-XZgICP2gJ1MHU7+vQaRM+VA9HEL3X253uwUM/BGgx3iv6TH2B3bF3B8q00DKcyP9YrJV+/7WOWEWBFF/u8cIsw==", + "dev": true, + "requires": { + "collapse-white-space": "^1.0.2", + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-whitespace-character": "^1.0.0", + "is-word-character": "^1.0.0", + "markdown-escapes": "^1.0.0", + "parse-entities": "^1.0.2", + "repeat-string": "^1.5.4", + "state-toggle": "^1.0.0", + "trim": "0.0.1", + "trim-trailing-lines": "^1.0.0", + "unherit": "^1.0.4", + "unist-util-remove-position": "^1.0.0", + "vfile-location": "^2.0.0", + "xtend": "^4.0.1" + } + }, + "remark-slug": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/remark-slug/-/remark-slug-4.2.3.tgz", + "integrity": "sha1-jZh9Dl5j1KSeo3uQ/pmaPc/IG3I=", + "dev": true, + "requires": { + "github-slugger": "^1.0.0", + "mdast-util-to-string": "^1.0.0", + "unist-util-visit": "^1.0.0" + } + }, + "remark-stringify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-4.0.0.tgz", + "integrity": "sha512-xLuyKTnuQer3ke9hkU38SUYLiTmS078QOnoFavztmbt/pAJtNSkNtFgR0U//uCcmG0qnyxao+PDuatQav46F1w==", + "dev": true, + "requires": { + "ccount": "^1.0.0", + "is-alphanumeric": "^1.0.0", + "is-decimal": "^1.0.0", + "is-whitespace-character": "^1.0.0", + "longest-streak": "^2.0.1", + "markdown-escapes": "^1.0.0", + "markdown-table": "^1.1.0", + "mdast-util-compact": "^1.0.0", + "parse-entities": "^1.0.2", + "repeat-string": "^1.5.4", + "state-toggle": "^1.0.0", + "stringify-entities": "^1.0.1", + "unherit": "^1.0.4", + "xtend": "^4.0.1" + } + }, + "remark-toc": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-toc/-/remark-toc-4.0.1.tgz", + "integrity": "sha1-/zb/beVOoH3Vnj9TNKSjqsHpMYU=", + "dev": true, + "requires": { + "mdast-util-toc": "^2.0.0", + "remark-slug": "^4.0.0" + } + }, + "remote-origin-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/remote-origin-url/-/remote-origin-url-0.4.0.tgz", + "integrity": "sha1-TT4pAvNOLTfRwmPYdxC3frQIajA=", + "dev": true, + "requires": { + "parse-git-config": "^0.2.0" + } + }, + "remove-bom-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz", + "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==", + "dev": true, + "requires": { + "is-buffer": "^1.1.5", + "is-utf8": "^0.2.1" + } + }, + "remove-bom-stream": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz", + "integrity": "sha1-BfGlk/FuQuH7kOv1nejlaVJflSM=", + "dev": true, + "requires": { + "remove-bom-buffer": "^3.0.0", + "safe-buffer": "^5.1.0", + "through2": "^2.0.3" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", + "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "repeating": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-1.1.3.tgz", + "integrity": "sha1-PUEUIYh3U3SU+X93+Xhfq4EPpKw=", + "dev": true, + "requires": { + "is-finite": "^1.0.0" + } + }, + "replace-ext": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", + "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", + "dev": true + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "dev": true + }, + "resolve": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz", + "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==", + "dev": true, + "requires": { + "path-parse": "^1.0.5" + } + }, + "resolve-options": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz", + "integrity": "sha1-MrueOcBtZzONyTeMDW1gdFZq0TE=", + "dev": true, + "requires": { + "value-or-function": "^3.0.0" + } + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "right-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", + "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", + "dev": true, + "requires": { + "align-text": "^0.1.1" + } + }, + "ripemd160": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-0.2.0.tgz", + "integrity": "sha1-K/GYveFnys+lHAqSjoS2i74XH84=", + "dev": true + }, + "rsvp": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-3.6.2.tgz", + "integrity": "sha512-OfWGQTb9vnwRjwtA2QwpG2ICclHC3pgXZO5xt8H2EfgDquO0qVdSb5T88L4qJVAEugbS56pAuV4XZM58UX8ulw==", + "dev": true + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", + "dev": true + }, + "safe-json-parse": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/safe-json-parse/-/safe-json-parse-1.0.1.tgz", + "integrity": "sha1-PnZyPjjf3aE8mx0poeB//uSzC1c=", + "dev": true + }, + "semver": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "set-getter": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/set-getter/-/set-getter-0.1.0.tgz", + "integrity": "sha1-12nBgsnVpR9AkUXy+6guXoboA3Y=", + "dev": true, + "requires": { + "to-object-path": "^0.3.0" + } + }, + "set-immediate-shim": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", + "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", + "dev": true + }, + "set-value": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", + "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + } + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, + "sha.js": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.2.6.tgz", + "integrity": "sha1-F93t3F9yL7ZlAWWIlUYZd4ZzFbo=", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "shelljs": { + "version": "0.7.8", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", + "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", + "dev": true, + "requires": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "dependencies": { + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "sji": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/sji/-/sji-0.0.1.tgz", + "integrity": "sha1-RtVhIvhmU5LCwZb45Cwm8lT5w0Y=", + "dev": true + }, + "slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "dev": true + }, + "snapdragon": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.1.tgz", + "integrity": "sha1-4StUh/re0+PeoKyR6UAL91tAE3A=", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^2.0.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + } + }, + "source-list-map": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-0.1.8.tgz", + "integrity": "sha1-xVCyq1Qn9rPyH1r+rYjE9Vh7IQY=", + "dev": true + }, + "source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "dev": true, + "requires": { + "amdefine": ">=0.0.4" + } + }, + "source-map-resolve": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.1.tgz", + "integrity": "sha512-0KW2wvzfxm8NCTb30z0LMNyPqWCdDGE2viwzUaucqJdkTRXtZiSY3I+2A6nVAjmdOy0I4gU8DwnVVGsk9jvP2A==", + "dev": true, + "requires": { + "atob": "^2.0.0", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.2.10.tgz", + "integrity": "sha1-6lo5AKHByyUJagrozFwrSxDe09w=", + "dev": true, + "requires": { + "source-map": "0.1.32" + }, + "dependencies": { + "source-map": { + "version": "0.1.32", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.32.tgz", + "integrity": "sha1-yLbBZ3l7pHQKjqMyUhYv8IWRsmY=", + "dev": true, + "requires": { + "amdefine": ">=0.0.4" + } + } + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "space-separated-tokens": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.1.tgz", + "integrity": "sha1-lpW5355lrsGBHUw/nOUlILwvfk0=", + "dev": true, + "requires": { + "trim": "0.0.1" + } + }, + "spdx-correct": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", + "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", + "dev": true, + "requires": { + "spdx-license-ids": "^1.0.2" + } + }, + "spdx-expression-parse": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", + "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=", + "dev": true + }, + "spdx-license-ids": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", + "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", + "dev": true + }, + "split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "dev": true, + "requires": { + "through": "2" + } + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + }, + "dependencies": { + "extend-shallow": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.1.tgz", + "integrity": "sha512-Fg1xXAv+qXKdwHiJFMcZSqsMcbPlkzsZtf8KkLJ2fqnP+lqg2RjEKgDcSfO9CO1+p4LZKgApDBUUUqKaaRhwZQ==", + "dev": true, + "requires": { + "is-extendable": "^1.0.1" + } + }, + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "split2": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-2.2.0.tgz", + "integrity": "sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw==", + "dev": true, + "requires": { + "through2": "^2.0.2" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "standard-version": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/standard-version/-/standard-version-8.0.1.tgz", + "integrity": "sha512-FLZdjvL2tBdwlctfQeyBf4+dX+SFljwdWfUA0F3wPiU9Rn0+FSuD3I0WXuzC1RmcaWwU5WL3EyV4Aanejc8Pqg==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "conventional-changelog": "3.1.21", + "conventional-changelog-config-spec": "2.1.0", + "conventional-changelog-conventionalcommits": "4.3.0", + "conventional-recommended-bump": "6.0.9", + "detect-indent": "^6.0.0", + "detect-newline": "^3.1.0", + "dotgitignore": "^2.1.0", + "figures": "^3.1.0", + "find-up": "^4.1.0", + "fs-access": "^1.0.1", + "git-semver-tags": "^4.0.0", + "semver": "^7.1.1", + "stringify-package": "^1.0.1", + "yargs": "^15.3.1" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "detect-indent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.0.0.tgz", + "integrity": "sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + } + } + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "state-toggle": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.0.tgz", + "integrity": "sha1-0g+aYWu08MO5i5GSLSW2QKorxCU=", + "dev": true + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "stream-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/stream-array/-/stream-array-1.1.2.tgz", + "integrity": "sha1-nl9zRfITfDDuO0mLkRToC1K7frU=", + "dev": true, + "requires": { + "readable-stream": "~2.1.0" + }, + "dependencies": { + "readable-stream": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.1.5.tgz", + "integrity": "sha1-ZvqLcg4UOLNkaB8q0aY8YYRIydA=", + "dev": true, + "requires": { + "buffer-shims": "^1.0.0", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~0.10.x", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, + "stream-browserify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", + "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=", + "dev": true, + "requires": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-combiner2": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", + "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=", + "dev": true, + "requires": { + "duplexer2": "~0.1.0", + "readable-stream": "^2.0.2" + } + }, + "stream-http": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.7.2.tgz", + "integrity": "sha512-c0yTD2rbQzXtSsFSVhtpvY/vS6u066PcXOX9kBB3mSO76RiUQzL340uJkGBWnlBg4/HZzqiUXtaVA7wcRcJgEw==", + "dev": true, + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.2.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "stream-shift": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", + "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", + "dev": true + }, + "string-template": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz", + "integrity": "sha1-QpMuWYo1LQH8IuwzZ9nYTuxsmt0=", + "dev": true + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "stringify-entities": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-1.3.1.tgz", + "integrity": "sha1-sVDsLXKsTBtfMktR+2soyc3/BYw=", + "dev": true, + "requires": { + "character-entities-html4": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-hexadecimal": "^1.0.0" + } + }, + "stringify-package": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stringify-package/-/stringify-package-1.0.1.tgz", + "integrity": "sha512-sa4DUQsYciMP1xhKWGuFM04fB0LG/9DlluZoSVywUMRNvzid6XucHK0/90xGxRoHrAaROrcHK1aPKaijCtSrhg==", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "requires": { + "min-indent": "^1.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "subarg": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", + "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", + "dev": true, + "requires": { + "minimist": "^1.1.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + }, + "tapable": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.1.10.tgz", + "integrity": "sha1-KcNXB8K3DlDQdIK10gLo7URtr9Q=", + "dev": true + }, + "text-extensions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz", + "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "dev": true, + "requires": { + "readable-stream": "^2.1.5", + "xtend": "~4.0.1" + } + }, + "through2-filter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-2.0.0.tgz", + "integrity": "sha1-YLxVoNrLdghdsfna6Zq0P4PWIuw=", + "dev": true, + "requires": { + "through2": "~2.0.0", + "xtend": "~4.0.0" + } + }, + "timers-browserify": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.4.tgz", + "integrity": "sha512-uZYhyU3EX8O7HQP+J9fTVYwsq90Vr68xPEFo7yrVImIxYvHgukBEgOB/SgGoorWVTzGM/3Z+wUNnboA4M8jWrg==", + "dev": true, + "requires": { + "setimmediate": "^1.0.4" + } + }, + "tiny-lr": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-1.0.5.tgz", + "integrity": "sha512-YrxUSiMgOVh3PnAqtdAUQuUVEVRnqcRCxJ3BHrl/aaWV2fplKKB60oClM0GH2Gio2hcXvkxMUxsC/vXZrQePlg==", + "dev": true, + "requires": { + "body": "^5.1.0", + "debug": "~2.6.7", + "faye-websocket": "~0.10.0", + "livereload-js": "^2.2.2", + "object-assign": "^4.1.0", + "qs": "^6.4.0" + } + }, + "to-absolute-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.1.tgz", + "integrity": "sha1-cMN1gFueMQXome6NvdapqhCPQHs=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-absolute": "^0.2.5", + "is-negated-glob": "^1.0.0" + } + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, + "to-fast-properties": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", + "dev": true + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "to-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.1.tgz", + "integrity": "sha1-FTWL7kosg712N3uh3ASdDxiDeq4=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "regex-not": "^1.0.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + } + } + }, + "to-through": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz", + "integrity": "sha1-/JKtq6ByZHvAtn1rA2ZKoZUJOvY=", + "dev": true, + "requires": { + "through2": "^2.0.3" + } + }, + "traceur": { + "version": "0.0.79", + "resolved": "https://registry.npmjs.org/traceur/-/traceur-0.0.79.tgz", + "integrity": "sha1-r73EXjq5cl73iz+7P0IZwiUj8pY=", + "dev": true, + "requires": { + "commander": "2.x", + "glob": "4.3", + "rsvp": "^3.0.13", + "semver": "2.x", + "source-map-support": "~0.2.8" + }, + "dependencies": { + "glob": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-4.3.5.tgz", + "integrity": "sha1-gPuwjKVA8jiszl0R0em8QedRc9M=", + "dev": true, + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^2.0.1", + "once": "^1.3.0" + } + }, + "minimatch": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", + "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=", + "dev": true, + "requires": { + "brace-expansion": "^1.0.0" + } + }, + "semver": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-2.3.2.tgz", + "integrity": "sha1-uYSPJdbPNjMwc+ye+IVtQvEjPlI=", + "dev": true + } + } + }, + "trim": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", + "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=", + "dev": true + }, + "trim-lines": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-1.1.0.tgz", + "integrity": "sha1-mSbQPt4Tuhj31CIiYx+wTHn/Jv4=", + "dev": true + }, + "trim-newlines": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.0.tgz", + "integrity": "sha512-C4+gOpvmxaSMKuEf9Qc134F1ZuOHVXKRbtEflf4NTtuuJDEIJ9p5PXsalL8SkeRw+qit1Mo+yuvMPAKwWg/1hA==", + "dev": true + }, + "trim-off-newlines": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz", + "integrity": "sha1-n5up2e+odkw4dpi8v+sshI8RrbM=", + "dev": true + }, + "trim-right": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", + "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", + "dev": true + }, + "trim-trailing-lines": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.0.tgz", + "integrity": "sha1-eu+7eAjfnWafbaLkOMrIxGradoQ=", + "dev": true + }, + "trough": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.1.tgz", + "integrity": "sha1-qf2LA5Swro//guBjOgo2zK1bX4Y=", + "dev": true + }, + "tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", + "dev": true + }, + "type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "dev": true + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "uglify-js": { + "version": "2.8.29", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", + "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", + "dev": true, + "requires": { + "source-map": "~0.5.1", + "uglify-to-browserify": "~1.0.0", + "yargs": "~3.10.0" + }, + "dependencies": { + "camelcase": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", + "dev": true + }, + "cliui": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", + "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", + "dev": true, + "requires": { + "center-align": "^0.1.1", + "right-align": "^0.1.1", + "wordwrap": "0.0.2" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "wordwrap": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", + "dev": true + }, + "yargs": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "dev": true, + "requires": { + "camelcase": "^1.0.2", + "cliui": "^2.1.0", + "decamelize": "^1.0.0", + "window-size": "0.1.0" + } + } + } + }, + "uglify-to-browserify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", + "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", + "dev": true + }, + "unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", + "dev": true + }, + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=", + "dev": true + }, + "unherit": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.0.tgz", + "integrity": "sha1-a5qu379z3xdWrZ4xbdmBiFhAzX0=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "xtend": "^4.0.1" + } + }, + "unified": { + "version": "6.1.6", + "resolved": "https://registry.npmjs.org/unified/-/unified-6.1.6.tgz", + "integrity": "sha512-pW2f82bCIo2ifuIGYcV12fL96kMMYgw7JKVEgh7ODlrM9rj6vXSY3BV+H6lCcv1ksxynFf582hwWLnA1qRFy4w==", + "dev": true, + "requires": { + "bail": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^1.1.0", + "trough": "^1.0.0", + "vfile": "^2.0.0", + "x-is-function": "^1.0.4", + "x-is-string": "^0.1.0" + } + }, + "union-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", + "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^0.4.3" + }, + "dependencies": { + "set-value": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", + "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.1", + "to-object-path": "^0.3.0" + } + } + } + }, + "unique-stream": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.2.1.tgz", + "integrity": "sha1-WqADz76Uxf+GbE59ZouxxNuts2k=", + "dev": true, + "requires": { + "json-stable-stringify": "^1.0.0", + "through2-filter": "^2.0.0" + } + }, + "unist-builder": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unist-builder/-/unist-builder-1.0.2.tgz", + "integrity": "sha1-jDuZA+9kvPsRfdfPal2Y/Bs7J7Y=", + "dev": true, + "requires": { + "object-assign": "^4.1.0" + } + }, + "unist-util-generated": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-1.1.1.tgz", + "integrity": "sha1-mfFseJWayFTe58YVwpGSTIv03n8=", + "dev": true + }, + "unist-util-is": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-2.1.1.tgz", + "integrity": "sha1-DDEmKeP5YMZukx6BLT2A53AQlHs=", + "dev": true + }, + "unist-util-modify-children": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unist-util-modify-children/-/unist-util-modify-children-1.1.1.tgz", + "integrity": "sha1-ZtfmpEnm9nIguXarPLi166w55R0=", + "dev": true, + "requires": { + "array-iterate": "^1.0.0" + } + }, + "unist-util-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-3.0.0.tgz", + "integrity": "sha1-5uHgPu64HF4a/lU+jUrfvXwNj4I=", + "dev": true + }, + "unist-util-remove-position": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-1.1.1.tgz", + "integrity": "sha1-WoXBVV/BugwQG4ZwfRXlD6TIcbs=", + "dev": true, + "requires": { + "unist-util-visit": "^1.1.0" + } + }, + "unist-util-stringify-position": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-1.1.1.tgz", + "integrity": "sha1-PMvcU2ee7W7PN3fdf14yKcG2qjw=", + "dev": true + }, + "unist-util-visit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.3.0.tgz", + "integrity": "sha512-9ntYcxPFtl44gnwXrQKZ5bMqXMY0ZHzUpqMFiU4zcc8mmf/jzYm8GhYgezuUlX4cJIM1zIDYaO6fG/fI+L6iiQ==", + "dev": true, + "requires": { + "unist-util-is": "^2.1.1" + } + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + } + } + }, + "use": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/use/-/use-2.0.2.tgz", + "integrity": "sha1-riig1y+TvyJCKhii43mZMRLeyOg=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "lazy-cache": "^2.0.2" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "requires": { + "inherits": "2.0.1" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + } + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", + "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", + "dev": true, + "requires": { + "spdx-correct": "~1.0.0", + "spdx-expression-parse": "~1.0.0" + } + }, + "value-or-function": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz", + "integrity": "sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM=", + "dev": true + }, + "vfile": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-2.3.0.tgz", + "integrity": "sha512-ASt4mBUHcTpMKD/l5Q+WJXNtshlWxOogYyGYYrg4lt/vuRjC1EFQtlAofL5VmtVNIZJzWYFJjzGWZ0Gw8pzW1w==", + "dev": true, + "requires": { + "is-buffer": "^1.1.4", + "replace-ext": "1.0.0", + "unist-util-stringify-position": "^1.0.0", + "vfile-message": "^1.0.0" + } + }, + "vfile-location": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.2.tgz", + "integrity": "sha1-02dcWch3SY5JK0dW/2Xkrxp1IlU=", + "dev": true + }, + "vfile-message": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-1.0.0.tgz", + "integrity": "sha512-HPREhzTOB/sNDc9/Mxf8w0FmHnThg5CRSJdR9VRFkD2riqYWs+fuXlj5z8mIpv2LrD7uU41+oPWFOL4Mjlf+dw==", + "dev": true, + "requires": { + "unist-util-stringify-position": "^1.1.1" + } + }, + "vfile-reporter": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/vfile-reporter/-/vfile-reporter-4.0.0.tgz", + "integrity": "sha1-6m8K4TQvSEFXOYXgX5QXNvJ96do=", + "dev": true, + "requires": { + "repeat-string": "^1.5.0", + "string-width": "^1.0.0", + "supports-color": "^4.1.0", + "unist-util-stringify-position": "^1.0.0", + "vfile-statistics": "^1.1.0" + }, + "dependencies": { + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, + "requires": { + "has-flag": "^2.0.0" + } + } + } + }, + "vfile-sort": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/vfile-sort/-/vfile-sort-2.1.0.tgz", + "integrity": "sha1-SVAcnou+Wt/y6bOnZx7hseIMUhA=", + "dev": true + }, + "vfile-statistics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vfile-statistics/-/vfile-statistics-1.1.0.tgz", + "integrity": "sha1-AhBMYP3u0dEbH3OtZTMLdjSz2JU=", + "dev": true + }, + "vinyl": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.1.0.tgz", + "integrity": "sha1-Ah+cLPlR1rk5lDyJ617lrdT9kkw=", + "dev": true, + "requires": { + "clone": "^2.1.1", + "clone-buffer": "^1.0.0", + "clone-stats": "^1.0.0", + "cloneable-readable": "^1.0.0", + "remove-trailing-separator": "^1.0.1", + "replace-ext": "^1.0.0" + } + }, + "vinyl-fs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.0.tgz", + "integrity": "sha1-zjRZK5DAM4vaLVwSFWaXNlH5DCM=", + "dev": true, + "requires": { + "flush-write-stream": "^1.0.0", + "fs-mkdirp-stream": "^1.0.0", + "glob-stream": "^6.1.0", + "graceful-fs": "^4.0.0", + "is-valid-glob": "^1.0.0", + "lazystream": "^1.0.0", + "lead": "^1.0.0", + "object.assign": "^4.0.4", + "pumpify": "^1.3.5", + "remove-bom-buffer": "^3.0.0", + "remove-bom-stream": "^1.2.0", + "resolve-options": "^1.1.0", + "through2": "^2.0.0", + "to-through": "^2.0.0", + "value-or-function": "^3.0.0", + "vinyl": "^2.0.0", + "vinyl-sourcemap": "^1.1.0" + } + }, + "vinyl-sourcemap": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz", + "integrity": "sha1-kqgAWTo4cDqM2xHYswCtS+Y7PhY=", + "dev": true, + "requires": { + "append-buffer": "^1.0.2", + "convert-source-map": "^1.5.0", + "graceful-fs": "^4.1.6", + "normalize-path": "^2.1.1", + "now-and-later": "^2.0.0", + "remove-bom-buffer": "^3.0.0", + "vinyl": "^2.0.0" + }, + "dependencies": { + "convert-source-map": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz", + "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=", + "dev": true + } + } + }, + "vm-browserify": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", + "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", + "dev": true, + "requires": { + "indexof": "0.0.1" + } + }, + "waaclock": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/waaclock/-/waaclock-0.5.3.tgz", + "integrity": "sha1-TT3/G4PrQ5+3I134JxuJHi/Fots=", + "dev": true + }, + "watchpack": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-0.2.9.tgz", + "integrity": "sha1-Yuqkq15bo1/fwBgnVibjwPXj+ws=", + "dev": true, + "requires": { + "async": "^0.9.0", + "chokidar": "^1.0.0", + "graceful-fs": "^4.1.2" + }, + "dependencies": { + "async": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", + "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=", + "dev": true + } + } + }, + "webpack": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-1.15.0.tgz", + "integrity": "sha1-T/MfU9sDM55VFkqdRo7gMklo/pg=", + "dev": true, + "requires": { + "acorn": "^3.0.0", + "async": "^1.3.0", + "clone": "^1.0.2", + "enhanced-resolve": "~0.9.0", + "interpret": "^0.6.4", + "loader-utils": "^0.2.11", + "memory-fs": "~0.3.0", + "mkdirp": "~0.5.0", + "node-libs-browser": "^0.7.0", + "optimist": "~0.6.0", + "supports-color": "^3.1.0", + "tapable": "~0.1.8", + "uglify-js": "~2.7.3", + "watchpack": "^0.2.1", + "webpack-core": "~0.6.9" + }, + "dependencies": { + "acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", + "dev": true + }, + "camelcase": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", + "dev": true + }, + "cliui": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", + "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", + "dev": true, + "requires": { + "center-align": "^0.1.1", + "right-align": "^0.1.1", + "wordwrap": "0.0.2" + } + }, + "clone": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.3.tgz", + "integrity": "sha1-KY1+IjFmD0DAA8LtMUDezz9TCF8=", + "dev": true + }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true + }, + "interpret": { + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-0.6.6.tgz", + "integrity": "sha1-/s16GOfOXKar+5U+H4YhOknxYls=", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "requires": { + "has-flag": "^1.0.0" + } + }, + "uglify-js": { + "version": "2.7.5", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.7.5.tgz", + "integrity": "sha1-RhLAx7qu4rp8SH3kkErhIgefLKg=", + "dev": true, + "requires": { + "async": "~0.2.6", + "source-map": "~0.5.1", + "uglify-to-browserify": "~1.0.0", + "yargs": "~3.10.0" + }, + "dependencies": { + "async": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", + "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=", + "dev": true + } + } + }, + "wordwrap": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", + "dev": true + }, + "yargs": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "dev": true, + "requires": { + "camelcase": "^1.0.2", + "cliui": "^2.1.0", + "decamelize": "^1.0.0", + "window-size": "0.1.0" + } + } + } + }, + "webpack-core": { + "version": "0.6.9", + "resolved": "https://registry.npmjs.org/webpack-core/-/webpack-core-0.6.9.tgz", + "integrity": "sha1-/FcViMhVjad76e+23r3Fo7FyvcI=", + "dev": true, + "requires": { + "source-list-map": "~0.1.7", + "source-map": "~0.4.1" + } + }, + "websocket-driver": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.0.tgz", + "integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=", + "dev": true, + "requires": { + "http-parser-js": ">=0.4.0", + "websocket-extensions": ">=0.1.1" + } + }, + "websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "dev": true + }, + "which": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", + "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "window-size": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", + "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", + "dev": true + }, + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "x-is-function": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/x-is-function/-/x-is-function-1.0.4.tgz", + "integrity": "sha1-XSlNw9Joy90GJYDgxd93o5HR+h4=", + "dev": true + }, + "x-is-string": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/x-is-string/-/x-is-string-0.1.0.tgz", + "integrity": "sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI=", + "dev": true + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "yargs": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-9.0.1.tgz", + "integrity": "sha1-UqzCP+7Kw0BCB47njAwAf1CF20w=", + "dev": true, + "requires": { + "camelcase": "^4.1.0", + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "os-locale": "^2.0.0", + "read-pkg-up": "^2.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^7.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + } + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "yargs-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", + "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=", + "dev": true, + "requires": { + "camelcase": "^4.1.0" + } + } + } +} ADDED public/nexus-js/package.json Index: public/nexus-js/package.json ================================================================== --- public/nexus-js/package.json +++ public/nexus-js/package.json @@ -0,0 +1,55 @@ +{ + "name": "nexusui", + "version": "2.1.6", + "description": "NexusUI: Web Audio Interfaces", + "main": "dist/NexusUI.js", + "scripts": { + "serve": "npm run docserve", + "build": "bash script/build", + "start": "script/watch", + "docgen": "node_modules/.bin/documentation build lib/** -f json -o api/api.json", + "docserve": "script/docserve-nix", + "test": "jest", + "release": "standard-version" + }, + "repository": { + "type": "git", + "url": "https://github.com/nexus-js/ui" + }, + "keywords": [], + "author": "Benjamin Taylor", + "license": "MIT", + "bugs": { + "url": "https://github.com/nexus-js/ui/issues" + }, + "homepage": "https://nexus-js.github.io/ui", + "devDependencies": { + "babel-core": "^4.7.16", + "babel-jest": "^4.0.0", + "babel-loader": "^4.0.0", + "babelify": "^5.0.3", + "color-ops": "^2.0.0", + "documentation": "^5.3.5", + "es6ify": "^1.6.0", + "fuse": "^0.4.0", + "jest": "^0.1.37", + "jshint": "^2.6.3", + "jshint-loader": "^0.8.3", + "standard-version": "^8.0.1", + "uglify-js": "^2.4.16", + "waaclock": "^0.5.3", + "webpack": "^1.5.3" + }, + "jest": { + "scriptPreprocessor": "./node_modules/babel-jest", + "testFileExtensions": [ + "es6", + "js" + ], + "moduleFileExtensions": [ + "js", + "json", + "es6" + ] + } +} ADDED public/nexus-js/script/build Index: public/nexus-js/script/build ================================================================== --- public/nexus-js/script/build +++ public/nexus-js/script/build @@ -0,0 +1,8 @@ +#!/bin/sh +webpack --devtool source-map --colors + +node_modules/.bin/uglifyjs dist/NexusUI.js \ + --output dist/NexusUI.min.js \ + --source-map dist/NexusUI.min.map \ + --source-map-url NexusUI.min.map \ + --compress warnings=false ADDED public/nexus-js/script/docserve-nix Index: public/nexus-js/script/docserve-nix ================================================================== --- public/nexus-js/script/docserve-nix +++ public/nexus-js/script/docserve-nix @@ -0,0 +1,12 @@ +#!/bin/sh +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[0;33m' +BLUE='\033[0;34m' +NC='\033[0m' + +echo "${BLUE}Running in parallel:${NC} \n**Webpack build, \n**documentation.js build > api/api.json, \n**Python SimpleHTTPServer" +echo "${YELLOW}Warning:${NC} documentation.js does not display current build status. ${YELLOW}TODO:${NC} integrate into webpack configuration" +webpack --watch --devtool inline-source-map & \ +node_modules/.bin/documentation build lib/** -f json -o api/api.json -w & \ +python -m SimpleHTTPServer 8000 || true ADDED public/nexus-js/script/watch Index: public/nexus-js/script/watch ================================================================== --- public/nexus-js/script/watch +++ public/nexus-js/script/watch @@ -0,0 +1,2 @@ +#!/bin/sh +webpack --watch --devtool inline-source-map ADDED public/nexus-js/webpack.config.js Index: public/nexus-js/webpack.config.js ================================================================== --- public/nexus-js/webpack.config.js +++ public/nexus-js/webpack.config.js @@ -0,0 +1,63 @@ +module.exports = { + entry: './index.js', + output: { + filename: './dist/NexusUI.js', + sourceMapFilename: './dist/NexusUI.map', + library: 'Nexus', + libraryTarget: 'umd' + }, + module: { + preLoaders: [{ + test: /\.js$/, // include .js files + exclude: /node_modules/, // exclude any and all files in the node_modules folder + loader: 'jshint-loader' + }], + loaders: [{ + test: /\.js$/, + exclude: /node_modules/, + loader: 'babel-loader' + }] + }, + resolve: { + extensions: ['', '.js'] + }, + jshint: { + 'node': true, + 'browser': true, + 'esnext': true, + 'bitwise': false, + 'camelcase': false, + 'curly': false, + 'eqeqeq': false, + 'immed': true, + 'latedef': true, + 'newcap': true, + 'noarg': true, + 'regexp': true, + 'undef': true, + 'unused': true, + 'strict': true, + 'trailing': true, + 'smarttabs': false, + 'globals': {}, + 'predef': [ + 'define', + 'require', + 'exports', + 'module', + 'describe', + 'before', + 'beforeEach', + 'after', + 'afterEach', + 'it', + 'inject', + 'expect', + 'spyOn' + ], + 'indent': 4, + 'devel': true, + 'noempty': true, + 'maxlen': 0 + } +}; ADDED public/riot-3.13.2/LICENSE.txt Index: public/riot-3.13.2/LICENSE.txt ================================================================== --- public/riot-3.13.2/LICENSE.txt +++ public/riot-3.13.2/LICENSE.txt @@ -0,0 +1,25 @@ +The MIT License (MIT) + +Copyright (c) 2015-present +Originally created by Muut Inc. +Actively maintained by: + - Gianluca Guarini https://github.com/GianlucaGuarini + +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. + ADDED public/riot-3.13.2/Makefile Index: public/riot-3.13.2/Makefile ================================================================== --- public/riot-3.13.2/Makefile +++ public/riot-3.13.2/Makefile @@ -0,0 +1,161 @@ + +# if no "v" var given, default to package version +v ?= $(shell node -pe "require('./package.json').version") + +# expand variable (so we can use it on branches w/o package.json) +VERSION := $(v) + +# get x.x.* part of the version number +MINOR_VERSION = `echo $(VERSION) | sed 's/\.[^.]*$$//'` + +# Command line paths +KARMA = ./node_modules/karma/bin/karma +ESLINT = ./node_modules/eslint/bin/eslint.js +MOCHA = ./node_modules/mocha/bin/_mocha +SMASH = ./node_modules/.bin/smash +ROLLUP = ./node_modules/.bin/rollup +UGLIFY = ./node_modules/uglify-js/bin/uglifyjs +COVERALLS = ./node_modules/coveralls/bin/coveralls.js +RIOT_CLI = ./node_modules/.bin/riot +CHOKIDAR = ./node_modules/.bin/chokidar + +# folders +DIST = dist/riot/ +LIB = lib/ +CONFIG = config/ + +GENERATED_FILES = riot.js riot+compiler.js + + +test: eslint test-mocha test-karma + +eslint: + # check code style + @ $(ESLINT) -c ./.eslintrc.json lib test + +test-mocha: + RIOT=../../dist/riot/riot.js $(MOCHA) -- test/specs/server + +tags: + @ $(RIOT_CLI) --silent test/tag dist/tags.js + +test-karma: + # Test riot+compiler.js + @ TEST_FOLDER=browser/compiler $(KARMA) start test/karma.conf.js + # Test only riot.js and generate the coverage + @ TEST_FOLDER=browser/riot $(KARMA) start test/karma.conf.js + +test-coveralls: + @ RIOT_COV=1 cat ./coverage/report-lcov/lcov.info | $(COVERALLS) + +test-sauce: + # run the riot tests on saucelabs + @ SAUCELABS=1 make test-karma + +test-chrome: + @ DEBUG=1 TEST_FOLDER=browser/riot ${KARMA} start test/karma.conf.js --browsers=Chrome --no-single-run --watch + +compare: + # compare the current release with the previous one + du -h riot.min.js riot+compiler.min.js + du -h dist/riot/riot.min.js dist/riot/riot+compiler.min.js + +raw: + # build riot + @ mkdir -p $(DIST) + # Default builds UMD + @ $(ROLLUP) lib/riot.js --config $(CONFIG)rollup.config.js > $(DIST)riot.js + @ $(ROLLUP) lib/riot+compiler.js --config $(CONFIG)rollup.config.js > $(DIST)riot+compiler.js + # Chrome Security Policy build + @ $(ROLLUP) lib/riot.js --config $(CONFIG)rollup.config.csp.js > $(DIST)riot.csp.js + +clean: + # clean $(DIST) + @ rm -rf $(DIST) + +riot: clean raw test + +min: + # minify riot + @ for f in $(GENERATED_FILES); do \ + $(UGLIFY) $(DIST)$$f \ + --comments \ + --toplevel \ + --mangle \ + --compress \ + -o $(DIST)$${f%.*}.min.js; \ + done + +perf: riot + # run the performance tests + @ node test/performance/benchmarks ../riot.2.6.1 --expose-gc + @ node test/performance/benchmarks ../../../riot --expose-gc + @ node test/performance/benchmarks ../../../dist/riot/riot --expose-gc + +perf-leaks: riot + # detect memory leaks + @ node --expose-gc test/performance/memory + +watch: + # watch and rebuild riot and its testswatch: + @ $(CHOKIDAR) lib -c 'make raw & make tags' + +build: + # generate riot.js & riot.min.js + @ make min + @ cp dist/riot/* . + # write version in riot.js + @ sed -i '' 's/WIP/v$(VERSION)/g' riot*.js + + +bump: + # grab all latest changes to master + # (if there's any uncommited changes, it will stop here) + # bump version in *.json files + @ mv package-lock.json package-lock.tmp + @ sed -i '' 's/\("version": "\)[^"]*/\1'$(VERSION)'/' *.json + @ mv package-lock.tmp package-lock.json + @ make build + @ git status --short + +bump-undo: + # remove all uncommited changes + @ git reset --hard + + +version: + # @ git checkout master + # create version commit + @ git status --short + @ git add --all + @ git commit -am "$(VERSION)" + @ git log --oneline -2 + # create version tag + @ git tag -a 'v'$(VERSION) -m $(VERSION) + @ git describe + +version-undo: + # remove the version tag + @ git tag -d 'v'$(VERSION) + @ git describe + # remove the version commit + @ git reset `git rev-parse :/$(VERSION)` + @ git reset HEAD^ + @ git log --oneline -2 + + +release: bump version + +release-undo: + make version-undo + make bump-undo + + +publish: + # push new version to npm and github + # (github tag will also trigger an update in bower, component, cdnjs, etc) + @ npm publish + @ git push origin master + @ git push origin master --tags + +.PHONY: test min eslint test-mocha test-compiler test-coveralls test-sauce compare raw riot perf watch tags perf-leaks build bump bump-undo version version-undo release-undo publish ADDED public/riot-3.13.2/README.md Index: public/riot-3.13.2/README.md ================================================================== --- public/riot-3.13.2/README.md +++ public/riot-3.13.2/README.md @@ -0,0 +1,386 @@ + +[![Riot logo](https://riot.js.org/img/logo/riot480x.png)](https://riot.js.org) + + +## Simple and elegant component-based UI library + +[![Build Status][travis-image]][travis-url] +[![MIT License][license-image]][license-url] +[![Riot Forum][riot-forum-image]][riot-forum-url] +[![Join the chat at https://gitter.im/riot/riot][gitter-image]][gitter-url] +[![Join the chat (ja) at https://riot-jp-slackin.herokuapp.com/][slack-ja-image]][slack-ja-url] +[![OpenCollective Backers][backer-badge]][backer-url] [![OpenCollective Sponsors][sponsor-badge]][sponsor-url] + +[![NPM version][npm-version-image]][npm-url] +[![NPM downloads][npm-downloads-image]][npm-url] +[![jsDelivr Hits][jsdelivr-image]][jsdelivr-url] +[![Coverage Status][coverage-image]][coverage-url] +![Riot Size][lib-size] +[![Code Quality][codeclimate-image]][codeclimate-url] + +[![Sauce Test Status][saucelabs-image]][saucelabs-url] + +### Framework Size Comparison + +| Framework | Version | Minified Size (gzip) | +|------------------------------------------------|-----------------|----------------------| +| @angular/core + Polyfills | 7.0.0 | 314.18kb | +| Ember | 2.18.2 | 121.84kb | +| Polymer + Web Components Polyfill Lite | 1.8.0 | 66.3kb | +| Polymer + webcomponents-loader.js + webcomponents-bundle.js |3.0.0 | 45.70kb | +| React + Map and Set Polyfills | 16.5.2 | 44.75kb | +| Web Components Polyfill | 0.7.24 | 33.68kb | +| Vue | 2.5.17 | 31.65kb | +| __Riot__ | 3.13.2 | 10.85kb | +| Inferno | 6.0.0 | 7.65kb | +| Preact | 8.3.1 | 3.48kb | + +The above comparison includes polyfills to support old browsers like IE9 that in Riot.js are supported by default. + +### Browsers support + +Riot is supported by all modern browsers and it does not require any additional polyfill + +- IE 9+ +- Edge +- Chrome +- Safari 7+ +- Firefox +- Safari iOS +- Android + +### Custom tags • Concise syntax • Simple API • Tiny Size + +Riot brings custom tags to all modern browsers. Think React + Polymer but with enjoyable syntax and a small learning curve. + +#### Tag definition + +``` javascript + + +

Seconds Elapsed: { time }

+ + this.time = opts.start || 0 + + tick() { + this.update({ time: ++this.time }) + } + + var timer = setInterval(this.tick, 1000) + + this.on('unmount', function() { + clearInterval(timer) + }) + +
+``` + +[Open this example on Plunker](http://riot.js.org/examples/plunker/?app=timer) + +#### Mounting + +``` javascript +riot.mount('timer', { start: 0 }) +``` + +#### Nesting + +Custom tags lets you build complex views with HTML. + +``` html + + + + + +``` + +HTML syntax is the de facto language on the web and it's designed for building user interfaces. The syntax is explicit, nesting is inherent to the language and attributes offer a clean way to provide options for custom tags. + + +### Expressions Bindings +- Absolutely the smallest possible amount of DOM updates and reflows. +- One way data flow: updates and unmounts are propagated downwards from parent to children. +- Expressions are pre-compiled and cached for high performance. +- Lifecycle events for more control. + + +### Close to standards +- No proprietary event system. +- Event normalization. +- The rendered DOM can be freely manipulated with other tools. +- No extra HTML root elements or `data-` attributes. +- Plays well with any frontend framework. + + +### Use your dearest language and tools +- Create tags with CoffeeScript, Jade, LiveScript, Typescript, ES6 or [any pre-processor](http://riot.js.org/guide/compiler/#pre-processors) you want. +- Integrate with NPM, CommonJS, AMD, Bower or Component +- Develop with [Gulp](https://github.com/e-jigsaw/gulp-riot), [Grunt](https://github.com/ariesjia/grunt-riot), [Wintersmith](https://github.com/collingreen/wintersmith-riot), [webpack*](https://github.com/riot/tag-loader), [Rollup*](https://github.com/riot/rollup-plugin-riot), [Browserify*](https://github.com/riot/riotify), [Babel*](https://github.com/riot/babel-preset-es2015-riot) or Bublé +- Test with [Karma*](https://github.com/riot/karma-riot), Mocha or whatever you like + +*Note*: `*` officially maintained + +### CDN hosting +- [jsDelivr](http://www.jsdelivr.com/projects/riot) +- [cdnjs](https://cdnjs.com/libraries/riot) + + +### Concise syntax +- Power shortcuts: `class={ enabled: is_enabled, hidden: hasErrors() }`. +- No extra brain load such as `render`, `state`, or `constructor`. +- Interpolation: `Add #{ items.length + 1 }` or `class="item { selected: flag }"` +- Compact ES6 method syntax. + +### Demos +- [**Riot Examples** - Community's Official](https://github.com/riot/examples) +- [**Riot Animore** - Official Tags Animations Library](https://github.com/riot/animore) +- [Riot Todo MVC](http://todomvc.com/examples/riotjs/) +- [Hackernews reader](http://git.io/riot-hn) +- [Vuejs examples by Riotjs](https://github.com/txchen/feplay/tree/gh-pages/riot_vue) +- [Flux-like ES6 Todo](https://github.com/srackham/riot-todo) +- [Timer](http://jsfiddle.net/gnumanth/h9kuozp5/) +- [Another flux demo comparable to React ones](http://txchen.github.io/feplay/riot_flux) +- [Various experiments](http://richardbondi.net/programming/riot) +- [Isomorphic application](https://github.com/Avnerus/riot-isomorphic) +- [Isomorphic proof of concept](https://github.com/PabloSichert/isomorphic-proof-of-concept) +- [flux-riot todo](http://mingliangfeng.me/flux-riot) +- [Another Riot Todo MVC](http://nippur72.github.io/riotjs-todomvc/#/) +- [Cheft isomorphic by express](https://github.com/cheft/cheft) +- [electron-riot - Riot in an electron application](https://github.com/mike-ward/electron-riot) +- [An express, riot, jade, webpack simple boilerplate](https://github.com/revington/frontend-boilerplate) +- [Riot.js vs React.js comparison of a simple comment box](https://github.com/vitogit/riot.js-vs-react.js-comment-box) +- [Riot Seed project - webpack, routing, ava tests, dispatcher](https://github.com/continuata/riot-seed) +- [Riot-Redux League Table example](https://github.com/drewmiley/PoolLeague) +- [Riot vs React vs Ractive Counters using Redux store](https://github.com/drewmiley/ractive-react-riot-redux-counters-example) +- [Riot Chrome Extension Boilerplate](https://github.com/acesmndr/chrome-extension-boilerplate-riot) + +### Books +- [Building Apps with Riot](https://bleedingedgepress.com/building-apps-with-riot/) + +### Tutorials +- [Building Apps with Riot, ES6 and Webpack](http://blog.srackham.com/posts/riot-es6-webpack-apps/) +- [Building Apps with Riot, Babel, RiotControl and Webpack](https://github.com/txchen/feplay/tree/gh-pages/riot_webpack) +- [Building tabs with Riot](http://robertwpearce.com/blog/riotjs-example.html) +- [The "React tutorial" for Riot](https://juriansluiman.nl/article/154/the-react-tutorial-for-riot) +- [How to package "tag libraries" in Riot](https://github.com/ivan-saorin/riot-tutorial-tags-pack-app) +- [Another React tutorial with Riot](https://github.com/viliamjr/commentsTuto) +- [Riot Custom Tag by Example](http://www.triplet.fi/blog/riot-custom-tag-by-example/) +- [Riot Compiler Explained](http://www.triplet.fi/blog/riot-compiler-explained/) +- [Adding compiled Riot tags to your Gulp + Browserify build](http://www.triplet.fi/blog/adding_compiled_riot_tags_to_your_gulp_browserify_build/) +- [The anatomy of a tag - a primer tutorial](http://www.marcusoft.net/2015/12/riotjs-anatomy-of-a-tag.html) +- [Using TDD with Riot+mocha+chai](http://vitomd.com/blog/coding/tutorial_tdd_riot_mocha/) +- [The Basics - from ground up to connected tag-networks](http://happy-css.com/lessons/riotjs/) +- [Hello Riot.js : a quick tutorial about this awesome lib](http://vitomd.com/blog/coding/hello-riot-js-quick-tutorial-about-this-awesome-lib/) + +### Video Tutorials +- [Introduction](https://www.youtube.com/watch?v=al87U6NgRTc) +- [Loops, Events and Callbacks](https://www.youtube.com/watch?v=T-ZV9dv93sw) +- [Server Rendering with Node & Express](http://youtu.be/6ww1UXGJzcs) +- [Riot And Webpack Setup](https://youtu.be/UgdZbT-KPpY) +- [Riot and Redux - Part 1](https://youtu.be/Y6vpKAGT2-8) +- [Riot and Redux - Part 2](https://youtu.be/DgM03bvgCYc) +- [Riot and Redux - Part 3](https://youtu.be/QuwnbuneAzM) +- [Riot and Redux - Part 4](https://youtu.be/qc6bjtu7KG0) +- [Riot and Redux - Part 5](https://youtu.be/M4BNsRMatVY) +- [Riot and Redux - Part 6](https://youtu.be/jr8KDpwtRsk) + + +### Libraries / Frameworks +- [Flux- like event controller for Riot](https://github.com/jimsparkman/RiotControl) +- [flux-riot framework](https://github.com/mingliangfeng/flux-riot) +- [Cheftjs - chinese framework for Riot](https://github.com/cheft/cheftjs) +- [Veronica - flux adaption for Riot](https://www.npmjs.com/package/veronica-x) +- [Minimal Flux dispatcher pattern](https://gist.github.com/continuata/c605846751c09a5e94d12ae8c91cbf05) +- [riot-format: a format library for riotjs, like angular $filter](https://github.com/joylei/riot-format) +- [riot-view-router: a simple state based router mixin](https://github.com/neetjn/riot-view-router) +- [riotx - Centralized State Management for riot.js](https://github.com/cam-inc/riotx) +- [storybook for riot.js components alpha](https://github.com/storybooks/storybook/tree/master/app/riot) + +### Components +- [Material UI](http://kysonic.github.io/riot-mui/) +- [RiotGear Components](https://riotgear.js.org) +- [RiotGear Router](http://riotgear.js.org/components/router/) +- [Riot Bootstrap](http://cognitom.github.io/riot-bootstrap/) +- [iToolkit](https://github.com/BE-FE/iToolkit) +- [Riot Routehandler](https://github.com/crisward/riot-routehandler)-[(Demo)](http://codepen.io/crisward/pen/xwGJpM?editors=101) +- [Riot Flipcard](https://github.com/crisward/riot-flipcard) - [(Demo)](https://crisward.github.io/riot-flipcard/) +- [Riot Grid](https://github.com/crisward/riot-grid) - [(Demo)](http://codepen.io/crisward/pen/rxepMX?editors=101) +- [Riot Grid2](https://github.com/crisward/riot-grid2) - [(Demo)](http://crisward.github.io/riot-grid2/) +- [Riot Subtag](https://github.com/crisward/riot-subtag) - faster than lots of if's +- [ESLint Riot Plugin](https://github.com/txchen/eslint-plugin-riot) +- [riot-animate](https://github.com/sartaj/riot-animate) +- [Nest UI](https://github.com/fengzilong/Nest) - [(Demo)](https://fengzilong.github.io/Nest/) +- [rGrid](https://github.com/limodou/rgrid) - [(Demo)](https://limodou.github.io/rgrid/examples.html) +- [typewriter](https://github.com/amitguptagwl/web-snippets/tree/master/riotjs-components/typewriter) - [(Demo)](http://amitkumargupta.work) + +### Resources +- [create-riot-app](https://github.com/alexstep/create-riot-app-ejected) dev environment +- [Riot + AngularJS](https://github.com/lucasbrigida/angular-riot) +- [Module loader for WebPack](https://www.npmjs.com/package/riotjs-loader) +- [Riot + Meteor]( https://atmospherejs.com/baysao/riotjs) +- [Riot Snake Game](http://cdn.rawgit.com/atian25/blog/master/assets/riot-snake.html) +- [Riot Tag Syntax Checker](http://cognitom.github.io/riot-checker/) +- [Riot 文档中译版](https://github.com/Centaur/riotjs_doc_cn) :cn: +- [Riot + Wintersmith](https://github.com/collingreen/wintersmith-riot) +- [Riot precompiler plugin for lineman](https://github.com/Power-Inside/lineman-riot) +- [Riot Startkit - Flux inspired skeleton app + WebPack + PostCSS](https://github.com/wbkd/riotjs-startkit) +- [Yeoman generator - Generator riot mobile](https://www.npmjs.com/package/generator-riot-mobile) +- [Yeoman generator - Generator riot element](https://www.npmjs.com/package/generator-riot-element) +- [Riot for TypeScript](https://github.com/nippur72/RiotTS) +- [Riot loader plugin for RequireJS](https://github.com/amenadiel/requirejs-riot) +- [Riot loader plugin for JSPM/SystemJS](https://github.com/amenadiel/systemjs-riot) +- [RiotJS Style Guide](https://github.com/voorhoede/riotjs-style-guide) +- [Riot Cheatsheet](http://martinmuzatko.github.io/riot-cheatsheet/) + +### Performance +- **Riot vs React performance:** [(Riot version)](https://github.com/kazzkiq/samples/tree/gh-pages/perf/dom-riot-vs-vanilla) vs [(React version)](https://github.com/kazzkiq/samples/tree/gh-pages/perf/dom-react-vs-vanilla) + +### Miscellaneous +- [Q&A with RiotJS author Tero Piirainen](http://www.triplet.fi/blog/q-and-a-with-riotjs-author-tero-piirainen/) +- [riot-detector (Chrome Extension)](https://chrome.google.com/webstore/detail/riot-detector/cnnmjeggdmicjojlnjghdgkdlijiobke) + +### Editors / Editor Plugins (Syntax highlighting, autcompletion, etc...) +- [riot (Atom Package)](https://atom.io/packages/riot) +- [language-riot-tag (Atom Package)](https://github.com/dekimasoon/language-riot-tag) + - Based on Vue's official Sublime Text highlighter + - Note: Designed for html, not jade. +- [sublime-tag (Sublime Text)](https://github.com/crisward/sublime-tag) +- [riot-tag (Visual Studio)](https://github.com/crisward/riot-tag) +- [web-mode (Emacs)](http://web-mode.org) + - See how to configure [#1967](https://github.com/riot/riot/issues/1967) + +### How to contribute + +If you are reading this it's already a good sign and we are thankful for it! We try our best working as much as we could on riot but your help is always appreciated. + +If you want to contribute to riot helping us maintaining the project please check first the list of [our open issues](https://github.com/riot/riot/issues) to understand whether there is a task where you could help. + +Riot is mainly developed on UNIX systems so you will be able to run all the commands necessary to build and test the library using our [Makefile](Makefile). If you are on a Microsoft machine it could be harder to set up you development environment properly. + +Following the steps below you should be able to properly submit your patch to the project + +#### 1) Clone the repo and browse to the riot folder + +```shell +$ git clone git@github.com:riot/riot.git && cd riot +``` +#### 2) Set up your git branch + +```shell +$ git checkout -b feature/my-awesome-patch +``` + +#### 3) Install the npm dependencies + +```shell +$ npm i +``` + +#### 4) Build and test riot using the Makefile + +```shell +# To build and test riot +$ make riot + +# To build without testing +$ make raw + +# To build anytime you change a src file +$ make watch + +# To bench riot +$ make perf +``` + +#### 5) Pull request only against the `dev` branch making sure you have read [our pull request template](.github/PULL_REQUEST_TEMPLATE.md) + +#### 6) Be patient + + +### Credits + +Riot is made with :heart: by many smart people from all over the world. Thanks to all the contributors
+It's actively maintained by: + + + + + + +
+ +
+ Gianluca Guarini +
+ +## Official Website + +http://riot.js.org + +## Backers + +Support us with a monthly donation and help us continue our activities. [Become a backer][support-url] + +[![Backers][backers-image]][support-url] + +## Sponsors + +Become a sponsor to get your logo on our README. [Become a sponsor][support-url] + +[![Sponsors][sponsors-image]][support-url] + +## Thanks + +Special thanks to Browserstack for their support + + + browser stack + + +[travis-image]:https://img.shields.io/travis/riot/riot.svg?style=flat-square +[travis-url]:https://travis-ci.org/riot/riot + +[license-image]:http://img.shields.io/badge/license-MIT-000000.svg?style=flat-square +[license-url]:LICENSE.txt + +[npm-version-image]:http://img.shields.io/npm/v/riot.svg?style=flat-square +[npm-downloads-image]:http://img.shields.io/npm/dm/riot.svg?style=flat-square +[npm-url]:https://npmjs.org/package/riot + +[riot-forum-image]:https://img.shields.io/badge/muut-JOIN_FORUM%E2%86%92-ff0044.svg?style=flat-square +[riot-forum-url]:http://riot.js.org/forum/ + +[coverage-image]:https://img.shields.io/coveralls/riot/riot/dev.svg?style=flat-square +[coverage-url]:https://coveralls.io/r/riot/riot?branch=dev + +[saucelabs-image]:https://saucelabs.com/browser-matrix/testsriotjs.svg?1 +[saucelabs-url]:https://saucelabs.com/u/testsriotjs + +[gitter-image]:https://img.shields.io/badge/GITTER-JOIN_CHAT_%E2%86%92-1dce73.svg?style=flat-square +[gitter-url]:https://gitter.im/riot/riot?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge + +[slack-ja-image]:https://img.shields.io/badge/SLACK_(ja)-JOIN_CHAT_%E2%86%92-551a8b.svg?style=flat-square +[slack-ja-url]:https://riot-jp-slackin.herokuapp.com/ + +[codeclimate-image]:https://api.codeclimate.com/v1/badges/b81ddf3c77e8189876da/maintainability +[codeclimate-url]:https://codeclimate.com/github/riot/riot + +[donations-campaign-url]:https://pledgie.com/campaigns/31139 +[donations-campaign-image]:https://pledgie.com/campaigns/31139.png?skin_name=chrome + +[jsdelivr-image]: https://data.jsdelivr.com/v1/package/npm/riot/badge +[jsdelivr-url]: https://www.jsdelivr.com/package/npm/riot + + +[backer-url]: #backers +[backer-badge]: https://opencollective.com/riot/backers/badge.svg?color=blue +[sponsor-url]: #sponsors +[sponsor-badge]: https://opencollective.com/riot/sponsors/badge.svg?color=blue + +[support-url]: https://opencollective.com/riot#support + +[lib-size]: http://img.badgesize.io/https://unpkg.com/riot/riot.min.js?compression=gzip + +[backers-image]: https://opencollective.com/riot/backers.svg +[sponsors-image]: https://opencollective.com/riot/sponsors.svg ADDED public/riot-3.13.2/bin/index.js Index: public/riot-3.13.2/bin/index.js ================================================================== --- public/riot-3.13.2/bin/index.js +++ public/riot-3.13.2/bin/index.js @@ -0,0 +1,3 @@ +#!/usr/bin/env node + +require('riot-cli')._cli() ADDED public/riot-3.13.2/bower.json Index: public/riot-3.13.2/bower.json ================================================================== --- public/riot-3.13.2/bower.json +++ public/riot-3.13.2/bower.json @@ -0,0 +1,46 @@ +{ + "name": "riot", + "version": "3.13.2", + "description": "Simple and elegant component-based UI library", + "homepage": "http://riot.js.org/", + "repository": { "type": "git", "url": "git://github.com/riot/riot.git" }, + "authors": [ + "Gianluca Guarini https://github.com/GianlucaGuarini" + ], + "license": "MIT", + "keywords": [ + "custom tags", + "custom elements", + "web components", + "virtual dom", + "shadow dom", + "polymer", + "react", + "jsx", + "minimal", + "minimalist", + "client-side", + "framework", + "declarative", + "templating", + "template", + "data binding", + "mvc", + "router", + "model", + "view", + "controller", + "riotjs", + "riot.js" + ], + "ignore": [ + "**/*", + "!/riot.js", + "!/riot.min.js", + "!/riot.csp.js", + "!/riot.csp.min.js", + "!/riot+compiler.js", + "!/riot+compiler.min.js" + ], + "main": "riot.js" +} ADDED public/riot-3.13.2/component.json Index: public/riot-3.13.2/component.json ================================================================== --- public/riot-3.13.2/component.json +++ public/riot-3.13.2/component.json @@ -0,0 +1,38 @@ +{ + "name": "riot", + "version": "3.13.2", + "description": "Simple and elegant component-based UI library", + "repository": "riot/riot", + "license": "MIT", + "keywords": [ + "custom tags", + "custom elements", + "web components", + "virtual dom", + "shadow dom", + "polymer", + "react", + "jsx", + "minimal", + "minimalist", + "client-side", + "framework", + "declarative", + "templating", + "template", + "data binding", + "mvc", + "router", + "model", + "view", + "controller", + "riotjs", + "riot.js" + ], + "scripts": [ + "riot.js", + "compiler.js", + "riot+compiler.js" + ], + "main": "riot.js" +} ADDED public/riot-3.13.2/config/defaults.js Index: public/riot-3.13.2/config/defaults.js ================================================================== --- public/riot-3.13.2/config/defaults.js +++ public/riot-3.13.2/config/defaults.js @@ -0,0 +1,32 @@ +const commonjs = require('rollup-plugin-commonjs'), + nodeResolve = require('rollup-plugin-node-resolve'), + buble = require('rollup-plugin-buble') + +module.exports = { + output: { + name: 'riot', + format: 'umd', + banner: '/* Riot WIP, @license MIT */', + }, + onwarn(warning) { + if (warning.code === 'CIRCULAR_DEPENDENCY') return + }, + plugins: [ + nodeResolve({ jsnext: true, main: true }), + commonjs({ + include: 'node_modules/**', + ignoreGlobal: true + }), + // ignore the coverage of riot external modules like riot-tmpl + { + transform (code) { + return { + code: code.replace(/(export\nvar (brackets|tmpl)|var (observable)|var (skipRegex)) =/g, function(m) { + return ['/* istanbul ignore next */', m].join('\n') + }) + } + } + }, + buble() + ] +} ADDED public/riot-3.13.2/config/rollup.config.csp.js Index: public/riot-3.13.2/config/rollup.config.csp.js ================================================================== --- public/riot-3.13.2/config/rollup.config.csp.js +++ public/riot-3.13.2/config/rollup.config.csp.js @@ -0,0 +1,24 @@ +import nodeResolve from 'rollup-plugin-node-resolve' +import commonjs from 'rollup-plugin-commonjs' +import alias from 'rollup-plugin-alias' +import buble from 'rollup-plugin-buble' +import path from 'path' +var defaults = require('./defaults') + +const tmplPath = path.resolve(process.cwd(), 'node_modules', 'riot-tmpl', 'dist', 'csp.tmpl.js') + +export default Object.assign(defaults, { + plugins: [ + alias({ + 'riot-tmpl': tmplPath + }), + nodeResolve({ jsnext: true, main: true }), + commonjs({ + include: 'node_modules/**', + namedExports: { + [tmplPath]: ['tmpl', 'brackets'] + } + }), + buble() + ] +}) ADDED public/riot-3.13.2/config/rollup.config.js Index: public/riot-3.13.2/config/rollup.config.js ================================================================== --- public/riot-3.13.2/config/rollup.config.js +++ public/riot-3.13.2/config/rollup.config.js @@ -0,0 +1,2 @@ +var defaults = require('./defaults') +export default defaults ADDED public/riot-3.13.2/lib/browser/common/global-variables.js Index: public/riot-3.13.2/lib/browser/common/global-variables.js ================================================================== --- public/riot-3.13.2/lib/browser/common/global-variables.js +++ public/riot-3.13.2/lib/browser/common/global-variables.js @@ -0,0 +1,60 @@ +export +const + // be aware, internal usage + // ATTENTION: prefix the global dynamic variables with `__` + // tags instances cache + __TAGS_CACHE = [], + // tags implementation cache + __TAG_IMPL = {}, + YIELD_TAG = 'yield', + + /** + * Const + */ + GLOBAL_MIXIN = '__global_mixin', + + // riot specific prefixes or attributes + ATTRS_PREFIX = 'riot-', + + // Riot Directives + REF_DIRECTIVES = ['ref', 'data-ref'], + IS_DIRECTIVE = 'data-is', + CONDITIONAL_DIRECTIVE = 'if', + LOOP_DIRECTIVE = 'each', + LOOP_NO_REORDER_DIRECTIVE = 'no-reorder', + SHOW_DIRECTIVE = 'show', + HIDE_DIRECTIVE = 'hide', + KEY_DIRECTIVE = 'key', + RIOT_EVENTS_KEY = '__riot-events__', + + // for typeof == '' comparisons + T_STRING = 'string', + T_OBJECT = 'object', + T_UNDEF = 'undefined', + T_FUNCTION = 'function', + + XLINK_NS = 'http://www.w3.org/1999/xlink', + SVG_NS = 'http://www.w3.org/2000/svg', + XLINK_REGEX = /^xlink:(\w+)/, + + WIN = typeof window === T_UNDEF ? /* istanbul ignore next */ undefined : window, + + // special native tags that cannot be treated like the others + RE_SPECIAL_TAGS = /^(?:t(?:body|head|foot|[rhd])|caption|col(?:group)?|opt(?:ion|group))$/, + RE_SPECIAL_TAGS_NO_OPTION = /^(?:t(?:body|head|foot|[rhd])|caption|col(?:group)?)$/, + RE_EVENTS_PREFIX = /^on/, + RE_HTML_ATTRS = /([-\w]+) ?= ?(?:"([^"]*)|'([^']*)|({[^}]*}))/g, + // some DOM attributes must be normalized + CASE_SENSITIVE_ATTRIBUTES = { + 'viewbox': 'viewBox', + 'preserveaspectratio': 'preserveAspectRatio' + }, + /** + * Matches boolean HTML attributes in the riot tag definition. + * With a long list like this, a regex is faster than `[].indexOf` in most browsers. + * @const {RegExp} + * @see [attributes.md](https://github.com/riot/compiler/blob/dev/doc/attributes.md) + */ + RE_BOOL_ATTRS = /^(?:disabled|checked|readonly|required|allowfullscreen|auto(?:focus|play)|compact|controls|default|formnovalidate|hidden|ismap|itemscope|loop|multiple|muted|no(?:resize|shade|validate|wrap)?|open|reversed|seamless|selected|sortable|truespeed|typemustmatch)$/, + // version# for IE 8-11, 0 for others + IE_VERSION = (WIN && WIN.document || /* istanbul ignore next */ {}).documentMode | 0 ADDED public/riot-3.13.2/lib/browser/common/util/checks/index.js Index: public/riot-3.13.2/lib/browser/common/util/checks/index.js ================================================================== --- public/riot-3.13.2/lib/browser/common/util/checks/index.js +++ public/riot-3.13.2/lib/browser/common/util/checks/index.js @@ -0,0 +1,10 @@ +export { default as isBlank } from './is-blank' +export { default as isFunction } from './is-function' +export { default as isObject } from './is-object' +export { default as isSvg } from './is-svg' +export { default as isWritable } from './is-writable' +export { default as isArray } from './is-array' +export { default as isBoolAttr } from './is-boolean-attribute' +export { default as isNil } from './is-nil' +export { default as isString } from './is-string' +export { default as isUndefined } from './is-undefined' ADDED public/riot-3.13.2/lib/browser/common/util/checks/is-array.js Index: public/riot-3.13.2/lib/browser/common/util/checks/is-array.js ================================================================== --- public/riot-3.13.2/lib/browser/common/util/checks/is-array.js +++ public/riot-3.13.2/lib/browser/common/util/checks/is-array.js @@ -0,0 +1,8 @@ +/** + * Check if passed argument is a kind of array + * @param { * } value - + * @returns { Boolean } - + */ +export default function isArray(value) { + return Array.isArray(value) || value instanceof Array +} ADDED public/riot-3.13.2/lib/browser/common/util/checks/is-blank.js Index: public/riot-3.13.2/lib/browser/common/util/checks/is-blank.js ================================================================== --- public/riot-3.13.2/lib/browser/common/util/checks/is-blank.js +++ public/riot-3.13.2/lib/browser/common/util/checks/is-blank.js @@ -0,0 +1,10 @@ +import isNil from './is-nil' + +/** + * Check if passed argument is empty. Different from falsy, because we dont consider 0 or false to be blank + * @param { * } value - + * @returns { Boolean } - + */ +export default function isBlank(value) { + return isNil(value) || value === '' +} ADDED public/riot-3.13.2/lib/browser/common/util/checks/is-boolean-attribute.js Index: public/riot-3.13.2/lib/browser/common/util/checks/is-boolean-attribute.js ================================================================== --- public/riot-3.13.2/lib/browser/common/util/checks/is-boolean-attribute.js +++ public/riot-3.13.2/lib/browser/common/util/checks/is-boolean-attribute.js @@ -0,0 +1,9 @@ +import { RE_BOOL_ATTRS } from './../../global-variables' +/** + * Check if the passed argument is a boolean attribute + * @param { String } value - + * @returns { Boolean } - + */ +export default function isBoolAttr(value) { + return RE_BOOL_ATTRS.test(value) +} ADDED public/riot-3.13.2/lib/browser/common/util/checks/is-function.js Index: public/riot-3.13.2/lib/browser/common/util/checks/is-function.js ================================================================== --- public/riot-3.13.2/lib/browser/common/util/checks/is-function.js +++ public/riot-3.13.2/lib/browser/common/util/checks/is-function.js @@ -0,0 +1,9 @@ +import { T_FUNCTION } from './../../global-variables' +/** + * Check if passed argument is a function + * @param { * } value - + * @returns { Boolean } - + */ +export default function isFunction(value) { + return typeof value === T_FUNCTION +} ADDED public/riot-3.13.2/lib/browser/common/util/checks/is-nil.js Index: public/riot-3.13.2/lib/browser/common/util/checks/is-nil.js ================================================================== --- public/riot-3.13.2/lib/browser/common/util/checks/is-nil.js +++ public/riot-3.13.2/lib/browser/common/util/checks/is-nil.js @@ -0,0 +1,10 @@ +import isUndefined from './is-undefined' + +/** + * Check against the null and undefined values + * @param { * } value - + * @returns {Boolean} - + */ +export default function isNil(value) { + return isUndefined(value) || value === null +} ADDED public/riot-3.13.2/lib/browser/common/util/checks/is-object.js Index: public/riot-3.13.2/lib/browser/common/util/checks/is-object.js ================================================================== --- public/riot-3.13.2/lib/browser/common/util/checks/is-object.js +++ public/riot-3.13.2/lib/browser/common/util/checks/is-object.js @@ -0,0 +1,11 @@ +import { T_OBJECT } from './../../global-variables' + +/** + * Check if passed argument is an object, exclude null + * NOTE: use isObject(x) && !isArray(x) to excludes arrays. + * @param { * } value - + * @returns { Boolean } - + */ +export default function isObject(value) { + return value && typeof value === T_OBJECT // typeof null is 'object' +} ADDED public/riot-3.13.2/lib/browser/common/util/checks/is-string.js Index: public/riot-3.13.2/lib/browser/common/util/checks/is-string.js ================================================================== --- public/riot-3.13.2/lib/browser/common/util/checks/is-string.js +++ public/riot-3.13.2/lib/browser/common/util/checks/is-string.js @@ -0,0 +1,10 @@ +import { T_STRING } from './../../global-variables' + +/** + * Check if passed argument is a string + * @param { * } value - + * @returns { Boolean } - + */ +export default function isString(value) { + return typeof value === T_STRING +} ADDED public/riot-3.13.2/lib/browser/common/util/checks/is-svg.js Index: public/riot-3.13.2/lib/browser/common/util/checks/is-svg.js ================================================================== --- public/riot-3.13.2/lib/browser/common/util/checks/is-svg.js +++ public/riot-3.13.2/lib/browser/common/util/checks/is-svg.js @@ -0,0 +1,9 @@ +/** + * Check if a DOM node is an svg tag or part of an svg + * @param { HTMLElement } el - node we want to test + * @returns {Boolean} true if it's an svg node + */ +export default function isSvg(el) { + const owner = el.ownerSVGElement + return !!owner || owner === null +} ADDED public/riot-3.13.2/lib/browser/common/util/checks/is-undefined.js Index: public/riot-3.13.2/lib/browser/common/util/checks/is-undefined.js ================================================================== --- public/riot-3.13.2/lib/browser/common/util/checks/is-undefined.js +++ public/riot-3.13.2/lib/browser/common/util/checks/is-undefined.js @@ -0,0 +1,10 @@ +import { T_UNDEF } from './../../global-variables' + +/** + * Check if passed argument is undefined + * @param { * } value - + * @returns { Boolean } - + */ +export default function isUndefined(value) { + return typeof value === T_UNDEF +} ADDED public/riot-3.13.2/lib/browser/common/util/checks/is-writable.js Index: public/riot-3.13.2/lib/browser/common/util/checks/is-writable.js ================================================================== --- public/riot-3.13.2/lib/browser/common/util/checks/is-writable.js +++ public/riot-3.13.2/lib/browser/common/util/checks/is-writable.js @@ -0,0 +1,12 @@ +import getPropDescriptor from '../misc/get-prop-descriptor' +import isUndefined from './is-undefined' +/** + * Check whether object's property could be overridden + * @param { Object } obj - source object + * @param { String } key - object property + * @returns { Boolean } true if writable + */ +export default function isWritable(obj, key) { + const descriptor = getPropDescriptor(obj, key) + return isUndefined(obj[key]) || descriptor && descriptor.writable +} ADDED public/riot-3.13.2/lib/browser/common/util/dom/$$.js Index: public/riot-3.13.2/lib/browser/common/util/dom/$$.js ================================================================== --- public/riot-3.13.2/lib/browser/common/util/dom/$$.js +++ public/riot-3.13.2/lib/browser/common/util/dom/$$.js @@ -0,0 +1,9 @@ +/** + * Shorter and fast way to select multiple nodes in the DOM + * @param { String } selector - DOM selector + * @param { Object } ctx - DOM node where the targets of our search will is located + * @returns { Object } dom nodes found + */ +export default function $$(selector, ctx) { + return [].slice.call((ctx || document).querySelectorAll(selector)) +} ADDED public/riot-3.13.2/lib/browser/common/util/dom/$.js Index: public/riot-3.13.2/lib/browser/common/util/dom/$.js ================================================================== --- public/riot-3.13.2/lib/browser/common/util/dom/$.js +++ public/riot-3.13.2/lib/browser/common/util/dom/$.js @@ -0,0 +1,9 @@ +/** + * Shorter and fast way to select a single node in the DOM + * @param { String } selector - unique dom selector + * @param { Object } ctx - DOM node where the target of our search will is located + * @returns { Object } dom node found + */ +export default function $(selector, ctx) { + return (ctx || document).querySelector(selector) +} ADDED public/riot-3.13.2/lib/browser/common/util/dom/create-fragment.js Index: public/riot-3.13.2/lib/browser/common/util/dom/create-fragment.js ================================================================== --- public/riot-3.13.2/lib/browser/common/util/dom/create-fragment.js +++ public/riot-3.13.2/lib/browser/common/util/dom/create-fragment.js @@ -0,0 +1,7 @@ +/** + * Create a document fragment + * @returns { Object } document fragment + */ +export default function createFragment() { + return document.createDocumentFragment() +} ADDED public/riot-3.13.2/lib/browser/common/util/dom/create-placeholder.js Index: public/riot-3.13.2/lib/browser/common/util/dom/create-placeholder.js ================================================================== --- public/riot-3.13.2/lib/browser/common/util/dom/create-placeholder.js +++ public/riot-3.13.2/lib/browser/common/util/dom/create-placeholder.js @@ -0,0 +1,7 @@ +/** + * Create a document text node + * @returns { Object } create a text node to use as placeholder + */ +export default function createDOMPlaceholder() { + return document.createTextNode('') +} ADDED public/riot-3.13.2/lib/browser/common/util/dom/get-attribute.js Index: public/riot-3.13.2/lib/browser/common/util/dom/get-attribute.js ================================================================== --- public/riot-3.13.2/lib/browser/common/util/dom/get-attribute.js +++ public/riot-3.13.2/lib/browser/common/util/dom/get-attribute.js @@ -0,0 +1,9 @@ +/** + * Get the value of any DOM attribute on a node + * @param { Object } dom - DOM node we want to parse + * @param { String } name - name of the attribute we want to get + * @returns { String | undefined } name of the node attribute whether it exists + */ +export default function getAttribute(dom, name) { + return dom.getAttribute(name) +} ADDED public/riot-3.13.2/lib/browser/common/util/dom/index.js Index: public/riot-3.13.2/lib/browser/common/util/dom/index.js ================================================================== --- public/riot-3.13.2/lib/browser/common/util/dom/index.js +++ public/riot-3.13.2/lib/browser/common/util/dom/index.js @@ -0,0 +1,14 @@ +export { default as $$ } from './$$' +export { default as $ } from './$' +export { default as createDOMPlaceholder } from './create-placeholder' +export { default as mkEl } from './make-element' +export { default as setAttr } from './set-attribute' +export { default as toggleVisibility } from './toggle-visibility' +export { default as getAttr } from './get-attribute' +export { default as remAttr } from './remove-attribute' +export { default as setInnerHTML } from './set-inner-HTML' +export { default as walkAttrs } from './walk-attributes' +export { default as createFrag } from './create-fragment' +export { default as safeInsert } from './safe-insert' +export { default as styleObjectToString } from './style-object-to-string' +export { default as walkNodes } from './walk-nodes' ADDED public/riot-3.13.2/lib/browser/common/util/dom/make-element.js Index: public/riot-3.13.2/lib/browser/common/util/dom/make-element.js ================================================================== --- public/riot-3.13.2/lib/browser/common/util/dom/make-element.js +++ public/riot-3.13.2/lib/browser/common/util/dom/make-element.js @@ -0,0 +1,9 @@ +import { SVG_NS } from './../../global-variables' +/** + * Create a generic DOM node + * @param { String } name - name of the DOM node we want to create + * @returns { Object } DOM node just created + */ +export default function makeElement(name) { + return name === 'svg' ? document.createElementNS(SVG_NS, name) : document.createElement(name) +} ADDED public/riot-3.13.2/lib/browser/common/util/dom/remove-attribute.js Index: public/riot-3.13.2/lib/browser/common/util/dom/remove-attribute.js ================================================================== --- public/riot-3.13.2/lib/browser/common/util/dom/remove-attribute.js +++ public/riot-3.13.2/lib/browser/common/util/dom/remove-attribute.js @@ -0,0 +1,8 @@ +/** + * Remove any DOM attribute from a node + * @param { Object } dom - DOM node we want to update + * @param { String } name - name of the property we want to remove + */ +export default function removeAttribute(dom, name) { + dom.removeAttribute(name) +} ADDED public/riot-3.13.2/lib/browser/common/util/dom/safe-insert.js Index: public/riot-3.13.2/lib/browser/common/util/dom/safe-insert.js ================================================================== --- public/riot-3.13.2/lib/browser/common/util/dom/safe-insert.js +++ public/riot-3.13.2/lib/browser/common/util/dom/safe-insert.js @@ -0,0 +1,9 @@ +/** + * Insert safely a tag to fix #1962 #1649 + * @param { HTMLElement } root - children container + * @param { HTMLElement } curr - node to insert + * @param { HTMLElement } next - node that should preceed the current node inserted + */ +export default function safeInsert(root, curr, next) { + root.insertBefore(curr, next.parentNode && next) +} ADDED public/riot-3.13.2/lib/browser/common/util/dom/set-attribute.js Index: public/riot-3.13.2/lib/browser/common/util/dom/set-attribute.js ================================================================== --- public/riot-3.13.2/lib/browser/common/util/dom/set-attribute.js +++ public/riot-3.13.2/lib/browser/common/util/dom/set-attribute.js @@ -0,0 +1,14 @@ +import { XLINK_NS, XLINK_REGEX } from './../../global-variables' +/** + * Set any DOM attribute + * @param { Object } dom - DOM node we want to update + * @param { String } name - name of the property we want to set + * @param { String } val - value of the property we want to set + */ +export default function setAttribute(dom, name, val) { + const xlink = XLINK_REGEX.exec(name) + if (xlink && xlink[1]) + dom.setAttributeNS(XLINK_NS, xlink[1], val) + else + dom.setAttribute(name, val) +} ADDED public/riot-3.13.2/lib/browser/common/util/dom/set-inner-HTML.js Index: public/riot-3.13.2/lib/browser/common/util/dom/set-inner-HTML.js ================================================================== --- public/riot-3.13.2/lib/browser/common/util/dom/set-inner-HTML.js +++ public/riot-3.13.2/lib/browser/common/util/dom/set-inner-HTML.js @@ -0,0 +1,24 @@ +import { SVG_NS } from './../../global-variables' + +/** + * Set the inner html of any DOM node SVGs included + * @param { Object } container - DOM node where we'll inject new html + * @param { String } html - html to inject + * @param { Boolean } isSvg - svg tags should be treated a bit differently + */ +/* istanbul ignore next */ +export default function setInnerHTML(container, html, isSvg) { + // innerHTML is not supported on svg tags so we neet to treat them differently + if (isSvg) { + const node = container.ownerDocument.importNode( + new DOMParser() + .parseFromString(`${ html }`, 'application/xml') + .documentElement, + true + ) + + container.appendChild(node) + } else { + container.innerHTML = html + } +} ADDED public/riot-3.13.2/lib/browser/common/util/dom/style-object-to-string.js Index: public/riot-3.13.2/lib/browser/common/util/dom/style-object-to-string.js ================================================================== --- public/riot-3.13.2/lib/browser/common/util/dom/style-object-to-string.js +++ public/riot-3.13.2/lib/browser/common/util/dom/style-object-to-string.js @@ -0,0 +1,12 @@ +/** + * Convert a style object to a string + * @param { Object } style - style object we need to parse + * @returns { String } resulting css string + * @example + * styleObjectToString({ color: 'red', height: '10px'}) // => 'color: red; height: 10px' + */ +export default function styleObjectToString(style) { + return Object.keys(style).reduce((acc, prop) => { + return `${acc} ${prop}: ${style[prop]};` + }, '') +} ADDED public/riot-3.13.2/lib/browser/common/util/dom/toggle-visibility.js Index: public/riot-3.13.2/lib/browser/common/util/dom/toggle-visibility.js ================================================================== --- public/riot-3.13.2/lib/browser/common/util/dom/toggle-visibility.js +++ public/riot-3.13.2/lib/browser/common/util/dom/toggle-visibility.js @@ -0,0 +1,10 @@ +/** + * Toggle the visibility of any DOM node + * @param { Object } dom - DOM node we want to hide + * @param { Boolean } show - do we want to show it? + */ + +export default function toggleVisibility(dom, show) { + dom.style.display = show ? '' : 'none' + dom.hidden = show ? false : true +} ADDED public/riot-3.13.2/lib/browser/common/util/dom/walk-attributes.js Index: public/riot-3.13.2/lib/browser/common/util/dom/walk-attributes.js ================================================================== --- public/riot-3.13.2/lib/browser/common/util/dom/walk-attributes.js +++ public/riot-3.13.2/lib/browser/common/util/dom/walk-attributes.js @@ -0,0 +1,12 @@ +import { RE_HTML_ATTRS } from './../../global-variables' +/** + * Minimize risk: only zero or one _space_ between attr & value + * @param { String } html - html string we want to parse + * @param { Function } fn - callback function to apply on any attribute found + */ +export default function walkAttributes(html, fn) { + if (!html) return + let m + while (m = RE_HTML_ATTRS.exec(html)) + fn(m[1].toLowerCase(), m[2] || m[3] || m[4]) +} ADDED public/riot-3.13.2/lib/browser/common/util/dom/walk-nodes.js Index: public/riot-3.13.2/lib/browser/common/util/dom/walk-nodes.js ================================================================== --- public/riot-3.13.2/lib/browser/common/util/dom/walk-nodes.js +++ public/riot-3.13.2/lib/browser/common/util/dom/walk-nodes.js @@ -0,0 +1,22 @@ +/** + * Walk down recursively all the children tags starting dom node + * @param { Object } dom - starting node where we will start the recursion + * @param { Function } fn - callback to transform the child node just found + * @param { Object } context - fn can optionally return an object, which is passed to children + */ +export default function walkNodes(dom, fn, context) { + if (dom) { + const res = fn(dom, context) + let next + // stop the recursion + if (res === false) return + + dom = dom.firstChild + + while (dom) { + next = dom.nextSibling + walkNodes(dom, fn, res) + dom = next + } + } +} ADDED public/riot-3.13.2/lib/browser/common/util/misc/contains.js Index: public/riot-3.13.2/lib/browser/common/util/misc/contains.js ================================================================== --- public/riot-3.13.2/lib/browser/common/util/misc/contains.js +++ public/riot-3.13.2/lib/browser/common/util/misc/contains.js @@ -0,0 +1,9 @@ +/** + * Check whether an array contains an item + * @param { Array } array - target array + * @param { * } item - item to test + * @returns { Boolean } - + */ +export default function contains(array, item) { + return array.indexOf(item) !== -1 +} ADDED public/riot-3.13.2/lib/browser/common/util/misc/define.js Index: public/riot-3.13.2/lib/browser/common/util/misc/define.js ================================================================== --- public/riot-3.13.2/lib/browser/common/util/misc/define.js +++ public/riot-3.13.2/lib/browser/common/util/misc/define.js @@ -0,0 +1,19 @@ +import extend from './extend' + +/** + * Helper function to set an immutable property + * @param { Object } el - object where the new property will be set + * @param { String } key - object key where the new property will be stored + * @param { * } value - value of the new property + * @param { Object } options - set the propery overriding the default options + * @returns { Object } - the initial object + */ +export default function define(el, key, value, options) { + Object.defineProperty(el, key, extend({ + value, + enumerable: false, + writable: false, + configurable: true + }, options)) + return el +} ADDED public/riot-3.13.2/lib/browser/common/util/misc/each.js Index: public/riot-3.13.2/lib/browser/common/util/misc/each.js ================================================================== --- public/riot-3.13.2/lib/browser/common/util/misc/each.js +++ public/riot-3.13.2/lib/browser/common/util/misc/each.js @@ -0,0 +1,12 @@ +/** + * Specialized function for looping an array-like collection with `each={}` + * @param { Array } list - collection of items + * @param {Function} fn - callback function + * @returns { Array } the array looped + */ +export default function each(list, fn) { + const len = list ? list.length : 0 + let i = 0 + for (; i < len; i++) fn(list[i], i) + return list +} ADDED public/riot-3.13.2/lib/browser/common/util/misc/extend.js Index: public/riot-3.13.2/lib/browser/common/util/misc/extend.js ================================================================== --- public/riot-3.13.2/lib/browser/common/util/misc/extend.js +++ public/riot-3.13.2/lib/browser/common/util/misc/extend.js @@ -0,0 +1,29 @@ +import isWritable from '../checks/is-writable' + +/** + * Extend any object with other properties + * @param { Object } src - source object + * @returns { Object } the resulting extended object + * + * var obj = { foo: 'baz' } + * extend(obj, {bar: 'bar', foo: 'bar'}) + * console.log(obj) => {bar: 'bar', foo: 'bar'} + * + */ +export default function extend(src) { + let obj + let i = 1 + const args = arguments + const l = args.length + + for (; i < l; i++) { + if (obj = args[i]) { + for (const key in obj) { + // check if this property of the source object could be overridden + if (isWritable(src, key)) + src[key] = obj[key] + } + } + } + return src +} ADDED public/riot-3.13.2/lib/browser/common/util/misc/get-prop-descriptor.js Index: public/riot-3.13.2/lib/browser/common/util/misc/get-prop-descriptor.js ================================================================== --- public/riot-3.13.2/lib/browser/common/util/misc/get-prop-descriptor.js +++ public/riot-3.13.2/lib/browser/common/util/misc/get-prop-descriptor.js @@ -0,0 +1,6 @@ +/** + * Short alias for Object.getOwnPropertyDescriptor + */ +export default function getPropDescriptor (o, k) { + return Object.getOwnPropertyDescriptor(o, k) +} ADDED public/riot-3.13.2/lib/browser/common/util/misc/index.js Index: public/riot-3.13.2/lib/browser/common/util/misc/index.js ================================================================== --- public/riot-3.13.2/lib/browser/common/util/misc/index.js +++ public/riot-3.13.2/lib/browser/common/util/misc/index.js @@ -0,0 +1,10 @@ +export { default as contains } from './contains' +export { default as each } from './each' +export { default as getPropDescriptor } from './get-prop-descriptor' +export { default as startsWith } from './starts-with' +export { default as uid } from './uid' +export { default as defineProperty } from './define' +export { default as objectCreate } from './object-create' +export { default as extend } from './extend' +export { default as toCamel } from './to-camel' +export { default as warn } from './warn' ADDED public/riot-3.13.2/lib/browser/common/util/misc/is-event-attribute.js Index: public/riot-3.13.2/lib/browser/common/util/misc/is-event-attribute.js ================================================================== --- public/riot-3.13.2/lib/browser/common/util/misc/is-event-attribute.js +++ public/riot-3.13.2/lib/browser/common/util/misc/is-event-attribute.js @@ -0,0 +1,10 @@ +const EVENT_ATTR_RE = /^on/ + +/** + * True if the event attribute starts with 'on' + * @param { String } attribute - event attribute + * @returns { Boolean } + */ +export default function isEventAttribute(attribute) { + return EVENT_ATTR_RE.test(attribute) +} ADDED public/riot-3.13.2/lib/browser/common/util/misc/object-create.js Index: public/riot-3.13.2/lib/browser/common/util/misc/object-create.js ================================================================== --- public/riot-3.13.2/lib/browser/common/util/misc/object-create.js +++ public/riot-3.13.2/lib/browser/common/util/misc/object-create.js @@ -0,0 +1,6 @@ +/** + * Alias for Object.create + */ +export default function create(src) { + return Object.create(src) +} ADDED public/riot-3.13.2/lib/browser/common/util/misc/starts-with.js Index: public/riot-3.13.2/lib/browser/common/util/misc/starts-with.js ================================================================== --- public/riot-3.13.2/lib/browser/common/util/misc/starts-with.js +++ public/riot-3.13.2/lib/browser/common/util/misc/starts-with.js @@ -0,0 +1,9 @@ +/** + * Faster String startsWith alternative + * @param { String } str - source string + * @param { String } value - test string + * @returns { Boolean } - + */ +export default function startsWith(str, value) { + return str.slice(0, value.length) === value +} ADDED public/riot-3.13.2/lib/browser/common/util/misc/to-camel.js Index: public/riot-3.13.2/lib/browser/common/util/misc/to-camel.js ================================================================== --- public/riot-3.13.2/lib/browser/common/util/misc/to-camel.js +++ public/riot-3.13.2/lib/browser/common/util/misc/to-camel.js @@ -0,0 +1,8 @@ +/** + * Convert a string containing dashes to camel case + * @param { String } str - input string + * @returns { String } my-string -> myString + */ +export default function toCamel(str) { + return str.replace(/-(\w)/g, (_, c) => c.toUpperCase()) +} ADDED public/riot-3.13.2/lib/browser/common/util/misc/uid.js Index: public/riot-3.13.2/lib/browser/common/util/misc/uid.js ================================================================== --- public/riot-3.13.2/lib/browser/common/util/misc/uid.js +++ public/riot-3.13.2/lib/browser/common/util/misc/uid.js @@ -0,0 +1,9 @@ +/** + * Function returning always a unique identifier + * @returns { Number } - number from 0...n + */ +export default (function uid() { + let i = -1 + return () => ++i +})() + ADDED public/riot-3.13.2/lib/browser/common/util/misc/warn.js Index: public/riot-3.13.2/lib/browser/common/util/misc/warn.js ================================================================== --- public/riot-3.13.2/lib/browser/common/util/misc/warn.js +++ public/riot-3.13.2/lib/browser/common/util/misc/warn.js @@ -0,0 +1,7 @@ +/** + * Warn a message via console + * @param {String} message - warning message + */ +export default function warn(message) { + if (console && console.warn) console.warn(message) +} ADDED public/riot-3.13.2/lib/browser/compiler/index.js Index: public/riot-3.13.2/lib/browser/compiler/index.js ================================================================== --- public/riot-3.13.2/lib/browser/compiler/index.js +++ public/riot-3.13.2/lib/browser/compiler/index.js @@ -0,0 +1,157 @@ +import observable from 'riot-observable' +import compiler from 'riot-compiler' +import { T_STRING } from './../common/global-variables' + +import isArray from './../common/util/checks/is-array' +import isObject from './../common/util/checks/is-object' +import isFunction from './../common/util/checks/is-function' + +import extend from './../common/util/misc/extend' + +import $$ from './../common/util/dom/$$' +import getAttribute from './../common/util/dom/get-attribute' +import makeElement from './../common/util/dom/make-element' + +var + promise, // emits the 'ready' event and runs the first callback + ready // all the scripts were compiled? + +// gets the source of an external tag with an async call +function GET (url, fn, opts) { + var req = new XMLHttpRequest() + + req.onreadystatechange = function () { + if (req.readyState === 4) { + if (req.status === 200 || !req.status && req.responseText.length) { + fn(req.responseText, opts, url) + } else { + compile.error(`"${ url }" not found`) + } + } + } + + req.onerror = e => compile.error(e) + + req.open('GET', url, true) + req.send('') +} + +// evaluates a compiled tag within the global context +function globalEval (js, url) { + if (typeof js === T_STRING) { + var + node = makeElement('script'), + root = document.documentElement + + // make the source available in the "(no domain)" tab + // of Chrome DevTools, with a .js extension + if (url) js += '\n//# sourceURL=' + url + '.js' + + node.text = js + root.appendChild(node) + root.removeChild(node) + } +} + +// compiles all the internal and external tags on the page +function compileScripts (fn, xopt) { + var + scripts = $$('script[type="riot/tag"]'), + scriptsAmount = scripts.length + + function done() { + promise.trigger('ready') + ready = true + if (fn) fn() + } + + function compileTag (src, opts, url) { + var code = compiler.compile(src, opts, url) + + globalEval(code, url) + if (!--scriptsAmount) done() + } + + if (!scriptsAmount) done() + else { + for (var i = 0; i < scripts.length; ++i) { + var + script = scripts[i], + opts = extend({template: getAttribute(script, 'template')}, xopt), + url = getAttribute(script, 'src') || getAttribute(script, 'data-src') + + url ? GET(url, compileTag, opts) : compileTag(script.innerHTML, opts) + } + } +} + +export const parsers = compiler.parsers + +/* + Compilation for the browser +*/ +export function compile (arg, fn, opts) { + + if (typeof arg === T_STRING) { + + // 2nd parameter is optional, but can be null + if (isObject(fn)) { + opts = fn + fn = false + } + + // `riot.compile(tag [, callback | true][, options])` + if (/^\s* { + throw new Error(e) +} ADDED public/riot-3.13.2/lib/browser/tag/component/mixin.js Index: public/riot-3.13.2/lib/browser/tag/component/mixin.js ================================================================== --- public/riot-3.13.2/lib/browser/tag/component/mixin.js +++ public/riot-3.13.2/lib/browser/tag/component/mixin.js @@ -0,0 +1,61 @@ +import { mixin } from './../core' +import isString from './../../common/util/checks/is-string' +import isFunction from './../../common/util/checks/is-function' +import each from './../../common/util/misc/each' +import contains from './../../common/util/misc/contains' +import getPropDescriptor from './../../common/util/misc/get-prop-descriptor' + +/** + * Add a mixin to this tag + * @returns { Tag } the current tag instance + */ +export default function componentMixin(tag, ...mixins) { + each(mixins, (mix) => { + let instance + let obj + let props = [] + + // properties blacklisted and will not be bound to the tag instance + const propsBlacklist = ['init', '__proto__'] + + mix = isString(mix) ? mixin(mix) : mix + + // check if the mixin is a function + if (isFunction(mix)) { + // create the new mixin instance + instance = new mix() + } else instance = mix + + const proto = Object.getPrototypeOf(instance) + + // build multilevel prototype inheritance chain property list + do props = props.concat(Object.getOwnPropertyNames(obj || instance)) + while (obj = Object.getPrototypeOf(obj || instance)) + + // loop the keys in the function prototype or the all object keys + each(props, (key) => { + // bind methods to tag + // allow mixins to override other properties/parent mixins + if (!contains(propsBlacklist, key)) { + // check for getters/setters + const descriptor = getPropDescriptor(instance, key) || getPropDescriptor(proto, key) + const hasGetterSetter = descriptor && (descriptor.get || descriptor.set) + + // apply method only if it does not already exist on the instance + if (!tag.hasOwnProperty(key) && hasGetterSetter) { + Object.defineProperty(tag, key, descriptor) + } else { + tag[key] = isFunction(instance[key]) ? + instance[key].bind(tag) : + instance[key] + } + } + }) + + // init method will be called automatically + if (instance.init) + instance.init.bind(tag)(tag.opts) + }) + + return tag +} ADDED public/riot-3.13.2/lib/browser/tag/component/mount.js Index: public/riot-3.13.2/lib/browser/tag/component/mount.js ================================================================== --- public/riot-3.13.2/lib/browser/tag/component/mount.js +++ public/riot-3.13.2/lib/browser/tag/component/mount.js @@ -0,0 +1,83 @@ +import { parseExpressions, parseAttributes } from '../parse' +import RefExpr from '../ref' +import { mixin } from '../core' + +import { GLOBAL_MIXIN } from './../../common/global-variables' + +import setAttribute from './../../common/util/dom/set-attribute' +import walkAttributes from './../../common/util/dom/walk-attributes' + +import each from './../../common/util/misc/each' +import define from './../../common/util/misc/define' + +import getImmediateCustomParent from './../../common/util/tags/get-immediate-custom-parent' +import updateOpts from './../../common/util/tags/update-options' +import setMountState from './../../common/util/tags/set-mount-state' + +/** + * Mount the current tag instance + * @returns { Tag } the current tag instance + */ +export default function componentMount(tag, dom, expressions, opts) { + const __ = tag.__ + const root = __.root + root._tag = tag // keep a reference to the tag just created + + // Read all the attrs on this instance. This give us the info we need for updateOpts + parseAttributes.apply(__.parent, [root, root.attributes, (attr, expr) => { + if (!__.isAnonymous && RefExpr.isPrototypeOf(expr)) expr.tag = tag + attr.expr = expr + __.instAttrs.push(attr) + }]) + + // update the root adding custom attributes coming from the compiler + walkAttributes(__.impl.attrs, (k, v) => { __.implAttrs.push({name: k, value: v}) }) + parseAttributes.apply(tag, [root, __.implAttrs, (attr, expr) => { + if (expr) expressions.push(expr) + else setAttribute(root, attr.name, attr.value) + }]) + + // initialiation + updateOpts.apply(tag, [__.isLoop, __.parent, __.isAnonymous, opts, __.instAttrs]) + + // add global mixins + const globalMixin = mixin(GLOBAL_MIXIN) + + if (globalMixin && !__.skipAnonymous) { + for (const i in globalMixin) { + if (globalMixin.hasOwnProperty(i)) { + tag.mixin(globalMixin[i]) + } + } + } + + if (__.impl.fn) __.impl.fn.call(tag, opts) + + if (!__.skipAnonymous) tag.trigger('before-mount') + + // parse layout after init. fn may calculate args for nested custom tags + each(parseExpressions.apply(tag, [dom, __.isAnonymous]), e => expressions.push(e)) + + tag.update(__.item) + + if (!__.isAnonymous && !__.isInline) { + while (dom.firstChild) root.appendChild(dom.firstChild) + } + + define(tag, 'root', root) + + // if we need to wait that the parent "mount" or "updated" event gets triggered + if (!__.skipAnonymous && tag.parent) { + const p = getImmediateCustomParent(tag.parent) + p.one(!p.isMounted ? 'mount' : 'updated', () => { + setMountState.call(tag, true) + }) + } else { + // otherwise it's not a child tag we can trigger its mount event + setMountState.call(tag, true) + } + + tag.__.wasCreated = true + + return tag +} ADDED public/riot-3.13.2/lib/browser/tag/component/unmount.js Index: public/riot-3.13.2/lib/browser/tag/component/unmount.js ================================================================== --- public/riot-3.13.2/lib/browser/tag/component/unmount.js +++ public/riot-3.13.2/lib/browser/tag/component/unmount.js @@ -0,0 +1,93 @@ +import { + __TAGS_CACHE, + ATTRS_PREFIX, + RIOT_EVENTS_KEY +} from './../../common/global-variables' + +import removeAttribute from './../../common/util/dom/remove-attribute' +import walkAttributes from './../../common/util/dom/walk-attributes' +import setInnerHTML from './../../common/util/dom/set-inner-HTML' +import each from './../../common/util/misc/each' +import startsWith from './../../common/util/misc/starts-with' + +import unmountAll from './../../common/util/tags/unmount-all' + +import arrayishRemove from './../../common/util/tags/arrayish-remove' +import getImmediateCustomParent from './../../common/util/tags/get-immediate-custom-parent' +import setMountState from './../../common/util/tags/set-mount-state' + + +/** + * Unmount the tag instance + * @param { Boolean } mustKeepRoot - if it's true the root node will not be removed + * @returns { Tag } the current tag instance + */ +export default function tagUnmount(tag, mustKeepRoot, expressions) { + const __ = tag.__ + const root = __.root + const tagIndex = __TAGS_CACHE.indexOf(tag) + const p = root.parentNode + + if (!__.skipAnonymous) tag.trigger('before-unmount') + + // clear all attributes coming from the mounted tag + walkAttributes(__.impl.attrs, (name) => { + if (startsWith(name, ATTRS_PREFIX)) + name = name.slice(ATTRS_PREFIX.length) + + removeAttribute(root, name) + }) + + // remove all the event listeners + tag.__.listeners.forEach((dom) => { + Object.keys(dom[RIOT_EVENTS_KEY]).forEach((eventName) => { + dom.removeEventListener(eventName, dom[RIOT_EVENTS_KEY][eventName]) + }) + }) + + // remove tag instance from the global tags cache collection + if (tagIndex !== -1) __TAGS_CACHE.splice(tagIndex, 1) + + // clean up the parent tags object + if (__.parent && !__.isAnonymous) { + const ptag = getImmediateCustomParent(__.parent) + + if (__.isVirtual) { + Object + .keys(tag.tags) + .forEach(tagName => arrayishRemove(ptag.tags, tagName, tag.tags[tagName])) + } else { + arrayishRemove(ptag.tags, __.tagName, tag) + } + } + + // unmount all the virtual directives + if (tag.__.virts) { + each(tag.__.virts, (v) => { + if (v.parentNode) v.parentNode.removeChild(v) + }) + } + + // allow expressions to unmount themselves + unmountAll(expressions) + each(__.instAttrs, a => a.expr && a.expr.unmount && a.expr.unmount()) + + // clear the tag html if it's necessary + if (mustKeepRoot) setInnerHTML(root, '') + // otherwise detach the root tag from the DOM + else if (p) p.removeChild(root) + + // custom internal unmount function to avoid relying on the observable + if (__.onUnmount) __.onUnmount() + + // weird fix for a weird edge case #2409 and #2436 + // some users might use your software not as you've expected + // so I need to add these dirty hacks to mitigate unexpected issues + if (!tag.isMounted) setMountState.call(tag, true) + + setMountState.call(tag, false) + + delete root._tag + + return tag +} ADDED public/riot-3.13.2/lib/browser/tag/component/update.js Index: public/riot-3.13.2/lib/browser/tag/component/update.js ================================================================== --- public/riot-3.13.2/lib/browser/tag/component/update.js +++ public/riot-3.13.2/lib/browser/tag/component/update.js @@ -0,0 +1,39 @@ +import update from '../update' +import extend from './../../common/util/misc/extend' +import isFunction from './../../common/util/checks/is-function' +import updateOpts from './../../common/util/tags/update-options' + +/** + * Update the tag expressions and options + * @param { Tag } tag - tag object + * @param { * } data - data we want to use to extend the tag properties + * @param { Array } expressions - component expressions array + * @returns { Tag } the current tag instance + */ +export default function componentUpdate(tag, data, expressions) { + const __ = tag.__ + const nextOpts = {} + const canTrigger = tag.isMounted && !__.skipAnonymous + + // inherit properties from the parent tag + if (__.isAnonymous && __.parent) extend(tag, __.parent) + extend(tag, data) + + updateOpts.apply(tag, [__.isLoop, __.parent, __.isAnonymous, nextOpts, __.instAttrs]) + + if ( + canTrigger && + tag.isMounted && + isFunction(tag.shouldUpdate) && !tag.shouldUpdate(data, nextOpts) + ) { + return tag + } + + extend(tag.opts, nextOpts) + + if (canTrigger) tag.trigger('update', data) + update.call(tag, expressions) + if (canTrigger) tag.trigger('updated') + + return tag +} ADDED public/riot-3.13.2/lib/browser/tag/core.js Index: public/riot-3.13.2/lib/browser/tag/core.js ================================================================== --- public/riot-3.13.2/lib/browser/tag/core.js +++ public/riot-3.13.2/lib/browser/tag/core.js @@ -0,0 +1,225 @@ +import styleManager from './styleManager' +import isString from './../common/util/checks/is-string' +import isUndefined from './../common/util/checks/is-undefined' +import isObject from './../common/util/checks/is-object' +import isFunction from './../common/util/checks/is-function' +import setAttribute from './../common/util/dom/set-attribute' +import getAttribute from './../common/util/dom/get-attribute' +import $$ from './../common/util/dom/$$' +import each from './../common/util/misc/each' +import extend from './../common/util/misc/extend' +import mountTo from './../common/util/tags/mount' +import query from './../common/util/tags/query' + +import { + __TAG_IMPL, + __TAGS_CACHE, + GLOBAL_MIXIN, + IS_DIRECTIVE +} from './../common/global-variables' + +/** + * Another way to create a riot tag a bit more es6 friendly + * @param { HTMLElement } el - tag DOM selector or DOM node/s + * @param { Object } opts - tag logic + * @returns { Tag } new riot tag instance + */ +export function Tag(el, opts) { + // get the tag properties from the class constructor + const {name, tmpl, css, attrs, onCreate} = this + // register a new tag and cache the class prototype + if (!__TAG_IMPL[name]) { + tag(name, tmpl, css, attrs, onCreate) + // cache the class constructor + __TAG_IMPL[name].class = this.constructor + } + + // mount the tag using the class instance + mountTo(el, name, opts, this) + // inject the component css + if (css) styleManager.inject() + + return this +} + +/** + * Create a new riot tag implementation + * @param { String } name - name/id of the new riot tag + * @param { String } tmpl - tag template + * @param { String } css - custom tag css + * @param { String } attrs - root tag attributes + * @param { Function } fn - user function + * @returns { String } name/id of the tag just created + */ +export function tag(name, tmpl, css, attrs, fn) { + if (isFunction(attrs)) { + fn = attrs + + if (/^[\w-]+\s?=/.test(css)) { + attrs = css + css = '' + } else + attrs = '' + } + + if (css) { + if (isFunction(css)) + fn = css + else + styleManager.add(css, name) + } + + name = name.toLowerCase() + __TAG_IMPL[name] = { name, tmpl, attrs, fn } + + return name +} + +/** + * Create a new riot tag implementation (for use by the compiler) + * @param { String } name - name/id of the new riot tag + * @param { String } tmpl - tag template + * @param { String } css - custom tag css + * @param { String } attrs - root tag attributes + * @param { Function } fn - user function + * @returns { String } name/id of the tag just created + */ +export function tag2(name, tmpl, css, attrs, fn) { + if (css) styleManager.add(css, name) + + __TAG_IMPL[name] = { name, tmpl, attrs, fn } + + return name +} + +/** + * Mount a tag using a specific tag implementation + * @param { * } selector - tag DOM selector or DOM node/s + * @param { String } tagName - tag implementation name + * @param { Object } opts - tag logic + * @returns { Array } new tags instances + */ +export function mount(selector, tagName, opts) { + const tags = [] + let elem, allTags + + function pushTagsTo(root) { + if (root.tagName) { + let riotTag = getAttribute(root, IS_DIRECTIVE), tag + + // have tagName? force riot-tag to be the same + if (tagName && riotTag !== tagName) { + riotTag = tagName + setAttribute(root, IS_DIRECTIVE, tagName) + } + + tag = mountTo( + root, + riotTag || root.tagName.toLowerCase(), + isFunction(opts) ? opts() : opts + ) + + if (tag) + tags.push(tag) + } else if (root.length) + each(root, pushTagsTo) // assume nodeList + } + + // inject styles into DOM + styleManager.inject() + + if (isObject(tagName) || isFunction(tagName)) { + opts = tagName + tagName = 0 + } + + // crawl the DOM to find the tag + if (isString(selector)) { + selector = selector === '*' ? + // select all registered tags + // & tags found with the riot-tag attribute set + allTags = query() : + // or just the ones named like the selector + selector + query(selector.split(/, */)) + + // make sure to pass always a selector + // to the querySelectorAll function + elem = selector ? $$(selector) : [] + } + else + // probably you have passed already a tag or a NodeList + elem = selector + + // select all the registered and mount them inside their root elements + if (tagName === '*') { + // get all custom tags + tagName = allTags || query() + // if the root els it's just a single tag + if (elem.tagName) + elem = $$(tagName, elem) + else { + // select all the children for all the different root elements + var nodeList = [] + + each(elem, _el => nodeList.push($$(tagName, _el))) + + elem = nodeList + } + // get rid of the tagName + tagName = 0 + } + + pushTagsTo(elem) + + return tags +} + +// Create a mixin that could be globally shared across all the tags +const mixins = {} +const globals = mixins[GLOBAL_MIXIN] = {} +let mixins_id = 0 + +/** + * Create/Return a mixin by its name + * @param { String } name - mixin name (global mixin if object) + * @param { Object } mix - mixin logic + * @param { Boolean } g - is global? + * @returns { Object } the mixin logic + */ +export function mixin(name, mix, g) { + // Unnamed global + if (isObject(name)) { + mixin(`__${mixins_id++}__`, name, true) + return + } + + const store = g ? globals : mixins + + // Getter + if (!mix) { + if (isUndefined(store[name])) + throw new Error(`Unregistered mixin: ${ name }`) + + return store[name] + } + + // Setter + store[name] = isFunction(mix) ? + extend(mix.prototype, store[name] || {}) && mix : + extend(store[name] || {}, mix) +} + +/** + * Update all the tags instances created + * @returns { Array } all the tags instances + */ +export function update() { + return each(__TAGS_CACHE, tag => tag.update()) +} + +export function unregister(name) { + styleManager.remove(name) + return delete __TAG_IMPL[name] +} + +export const version = 'WIP' ADDED public/riot-3.13.2/lib/browser/tag/each.js Index: public/riot-3.13.2/lib/browser/tag/each.js ================================================================== --- public/riot-3.13.2/lib/browser/tag/each.js +++ public/riot-3.13.2/lib/browser/tag/each.js @@ -0,0 +1,303 @@ +import { + T_STRING, + T_OBJECT, + __TAG_IMPL, + CONDITIONAL_DIRECTIVE, + LOOP_DIRECTIVE, + LOOP_NO_REORDER_DIRECTIVE, + KEY_DIRECTIVE +} from './../common/global-variables' + +import isString from './../common/util/checks/is-string' +import isArray from './../common/util/checks/is-array' +import removeAttribute from './../common/util/dom/remove-attribute' +import getAttribute from './../common/util/dom/get-attribute' +import createPlaceholder from './../common/util/dom/create-placeholder' +import safeInsert from './../common/util/dom/safe-insert' +import createFragment from './../common/util/dom/create-fragment' + +import each from './../common/util/misc/each' +import contains from './../common/util/misc/contains' +import create from './../common/util/misc/object-create' +import extend from './../common/util/misc/extend' + +import moveChild from './../common/util/tags/move-child' +import getTag from './../common/util/tags/get' +import getTagName from './../common/util/tags/get-name' +import arrayishAdd from './../common/util/tags/arrayish-add' +import arrayishRemove from './../common/util/tags/arrayish-remove' +import makeVirtual from './../common/util/tags/make-virtual' +import moveVirtual from './../common/util/tags/move-virtual' + +import createTag from './tag' +import { tmpl } from 'riot-tmpl' + + +/** + * Convert the item looped into an object used to extend the child tag properties + * @param { Object } expr - object containing the keys used to extend the children tags + * @param { * } key - value to assign to the new object returned + * @param { * } val - value containing the position of the item in the array + * @returns { Object } - new object containing the values of the original item + * + * The variables 'key' and 'val' are arbitrary. + * They depend on the collection type looped (Array, Object) + * and on the expression used on the each tag + * + */ +function mkitem(expr, key, val) { + const item = {} + item[expr.key] = key + if (expr.pos) item[expr.pos] = val + return item +} + +/** + * Unmount the redundant tags + * @param { Array } items - array containing the current items to loop + * @param { Array } tags - array containing all the children tags + */ +function unmountRedundant(items, tags, filteredItemsCount) { + let i = tags.length + const j = items.length - filteredItemsCount + + while (i > j) { + i-- + remove.apply(tags[i], [tags, i]) + } +} + + +/** + * Remove a child tag + * @this Tag + * @param { Array } tags - tags collection + * @param { Number } i - index of the tag to remove + */ +function remove(tags, i) { + tags.splice(i, 1) + this.unmount() + arrayishRemove(this.parent, this, this.__.tagName, true) +} + +/** + * Move the nested custom tags in non custom loop tags + * @this Tag + * @param { Number } i - current position of the loop tag + */ +function moveNestedTags(i) { + each(Object.keys(this.tags), (tagName) => { + moveChild.apply(this.tags[tagName], [tagName, i]) + }) +} + +/** + * Move a child tag + * @this Tag + * @param { HTMLElement } root - dom node containing all the loop children + * @param { Tag } nextTag - instance of the next tag preceding the one we want to move + * @param { Boolean } isVirtual - is it a virtual tag? + */ +function move(root, nextTag, isVirtual) { + if (isVirtual) + moveVirtual.apply(this, [root, nextTag]) + else + safeInsert(root, this.root, nextTag.root) +} + +/** + * Insert and mount a child tag + * @this Tag + * @param { HTMLElement } root - dom node containing all the loop children + * @param { Tag } nextTag - instance of the next tag preceding the one we want to insert + * @param { Boolean } isVirtual - is it a virtual tag? + */ +function insert(root, nextTag, isVirtual) { + if (isVirtual) + makeVirtual.apply(this, [root, nextTag]) + else + safeInsert(root, this.root, nextTag.root) +} + +/** + * Append a new tag into the DOM + * @this Tag + * @param { HTMLElement } root - dom node containing all the loop children + * @param { Boolean } isVirtual - is it a virtual tag? + */ +function append(root, isVirtual) { + if (isVirtual) + makeVirtual.call(this, root) + else + root.appendChild(this.root) +} + +/** + * Return the value we want to use to lookup the postion of our items in the collection + * @param { String } keyAttr - lookup string or expression + * @param { * } originalItem - original item from the collection + * @param { Object } keyedItem - object created by riot via { item, i in collection } + * @param { Boolean } hasKeyAttrExpr - flag to check whether the key is an expression + * @returns { * } value that we will use to figure out the item position via collection.indexOf + */ +function getItemId(keyAttr, originalItem, keyedItem, hasKeyAttrExpr) { + if (keyAttr) { + return hasKeyAttrExpr ? tmpl(keyAttr, keyedItem) : originalItem[keyAttr] + } + + return originalItem +} + +/** + * Manage tags having the 'each' + * @param { HTMLElement } dom - DOM node we need to loop + * @param { Tag } parent - parent tag instance where the dom node is contained + * @param { String } expr - string contained in the 'each' attribute + * @returns { Object } expression object for this each loop + */ +export default function _each(dom, parent, expr) { + const mustReorder = typeof getAttribute(dom, LOOP_NO_REORDER_DIRECTIVE) !== T_STRING || removeAttribute(dom, LOOP_NO_REORDER_DIRECTIVE) + const keyAttr = getAttribute(dom, KEY_DIRECTIVE) + const hasKeyAttrExpr = keyAttr ? tmpl.hasExpr(keyAttr) : false + const tagName = getTagName(dom) + const impl = __TAG_IMPL[tagName] + const parentNode = dom.parentNode + const placeholder = createPlaceholder() + const child = getTag(dom) + const ifExpr = getAttribute(dom, CONDITIONAL_DIRECTIVE) + const tags = [] + const isLoop = true + const innerHTML = dom.innerHTML + const isAnonymous = !__TAG_IMPL[tagName] + const isVirtual = dom.tagName === 'VIRTUAL' + let oldItems = [] + + // remove the each property from the original tag + removeAttribute(dom, LOOP_DIRECTIVE) + removeAttribute(dom, KEY_DIRECTIVE) + + // parse the each expression + expr = tmpl.loopKeys(expr) + expr.isLoop = true + + if (ifExpr) removeAttribute(dom, CONDITIONAL_DIRECTIVE) + + // insert a marked where the loop tags will be injected + parentNode.insertBefore(placeholder, dom) + parentNode.removeChild(dom) + + expr.update = function updateEach() { + // get the new items collection + expr.value = tmpl(expr.val, parent) + + let items = expr.value + const frag = createFragment() + const isObject = !isArray(items) && !isString(items) + const root = placeholder.parentNode + const tmpItems = [] + const hasKeys = isObject && !!items + + // if this DOM was removed the update here is useless + // this condition fixes also a weird async issue on IE in our unit test + if (!root) return + + // object loop. any changes cause full redraw + if (isObject) { + items = items ? Object.keys(items).map(key => mkitem(expr, items[key], key)) : [] + } + + // store the amount of filtered items + let filteredItemsCount = 0 + + // loop all the new items + each(items, (_item, index) => { + const i = index - filteredItemsCount + const item = !hasKeys && expr.key ? mkitem(expr, _item, index) : _item + + // skip this item because it must be filtered + if (ifExpr && !tmpl(ifExpr, extend(create(parent), item))) { + filteredItemsCount ++ + return + } + + const itemId = getItemId(keyAttr, _item, item, hasKeyAttrExpr) + // reorder only if the items are not objects + // or a key attribute has been provided + const doReorder = !isObject && mustReorder && typeof _item === T_OBJECT || keyAttr + const oldPos = oldItems.indexOf(itemId) + const isNew = oldPos === -1 + const pos = !isNew && doReorder ? oldPos : i + // does a tag exist in this position? + let tag = tags[pos] + const mustAppend = i >= oldItems.length + const mustCreate = doReorder && isNew || !doReorder && !tag || !tags[i] + + // new tag + if (mustCreate) { + tag = createTag(impl, { + parent, + isLoop, + isAnonymous, + tagName, + root: dom.cloneNode(isAnonymous), + item, + index: i, + }, innerHTML) + + // mount the tag + tag.mount() + + if (mustAppend) + append.apply(tag, [frag || root, isVirtual]) + else + insert.apply(tag, [root, tags[i], isVirtual]) + + if (!mustAppend) oldItems.splice(i, 0, item) + tags.splice(i, 0, tag) + if (child) arrayishAdd(parent.tags, tagName, tag, true) + } else if (pos !== i && doReorder) { + // move + if (keyAttr || contains(items, oldItems[pos])) { + move.apply(tag, [root, tags[i], isVirtual]) + // move the old tag instance + tags.splice(i, 0, tags.splice(pos, 1)[0]) + // move the old item + oldItems.splice(i, 0, oldItems.splice(pos, 1)[0]) + } + + // update the position attribute if it exists + if (expr.pos) tag[expr.pos] = i + + // if the loop tags are not custom + // we need to move all their custom tags into the right position + if (!child && tag.tags) moveNestedTags.call(tag, i) + } + + // cache the original item to use it in the events bound to this node + // and its children + extend(tag.__, { + item, + index: i, + parent + }) + + tmpItems[i] = itemId + + if (!mustCreate) tag.update(item) + }) + + // remove the redundant tags + unmountRedundant(items, tags, filteredItemsCount) + + // clone the items array + oldItems = tmpItems.slice() + + root.insertBefore(frag, placeholder) + } + + expr.unmount = () => { + each(tags, t => { t.unmount() }) + } + + return expr +} ADDED public/riot-3.13.2/lib/browser/tag/if.js Index: public/riot-3.13.2/lib/browser/tag/if.js ================================================================== --- public/riot-3.13.2/lib/browser/tag/if.js +++ public/riot-3.13.2/lib/browser/tag/if.js @@ -0,0 +1,48 @@ +import removeAttribute from './../common/util/dom/remove-attribute' +import createPlacholder from './../common/util/dom/create-placeholder' +import unmountAll from './../common/util/tags/unmount-all' +import extend from './../common/util/misc/extend' +import { tmpl } from 'riot-tmpl' +import { CONDITIONAL_DIRECTIVE } from './../common/global-variables' +import { parseExpressions } from './parse' +import updateAllExpressions from './update' + +export default { + init(dom, tag, expr) { + removeAttribute(dom, CONDITIONAL_DIRECTIVE) + extend(this, { tag, expr, stub: createPlacholder(), pristine: dom }) + const p = dom.parentNode + p.insertBefore(this.stub, dom) + p.removeChild(dom) + + return this + }, + update() { + this.value = tmpl(this.expr, this.tag) + + if (!this.stub.parentNode) return + + if (this.value && !this.current) { // insert + this.current = this.pristine.cloneNode(true) + this.stub.parentNode.insertBefore(this.current, this.stub) + this.expressions = parseExpressions.apply(this.tag, [this.current, true]) + } else if (!this.value && this.current) { // remove + this.unmount() + this.current = null + this.expressions = [] + } + + if (this.value) updateAllExpressions.call(this.tag, this.expressions) + }, + unmount() { + if (this.current) { + if (this.current._tag) { + this.current._tag.unmount() + } else if (this.current.parentNode) { + this.current.parentNode.removeChild(this.current) + } + } + + unmountAll(this.expressions || []) + } +} ADDED public/riot-3.13.2/lib/browser/tag/mkdom.js Index: public/riot-3.13.2/lib/browser/tag/mkdom.js ================================================================== --- public/riot-3.13.2/lib/browser/tag/mkdom.js +++ public/riot-3.13.2/lib/browser/tag/mkdom.js @@ -0,0 +1,106 @@ +import makeElement from './../common/util/dom/make-element' +import setInnerHTML from './../common/util/dom/set-inner-HTML' +import $ from './../common/util/dom/$' + +import { + IE_VERSION, + RE_SPECIAL_TAGS, + RE_SPECIAL_TAGS_NO_OPTION +} from './../common/global-variables' + +/* + Includes hacks needed for the Internet Explorer version 9 and below + See: http://kangax.github.io/compat-table/es5/#ie8 + http://codeplanet.io/dropping-ie8/ +*/ + +const + reHasYield = /|>([\S\s]*?)<\/yield\s*>|>)/ig, + reYieldSrc = /]*)['"]\s*>([\S\s]*?)<\/yield\s*>/ig, + reYieldDest = /|>([\S\s]*?)<\/yield\s*>)/ig, + rootEls = { tr: 'tbody', th: 'tr', td: 'tr', col: 'colgroup' }, + tblTags = IE_VERSION && IE_VERSION < 10 ? RE_SPECIAL_TAGS : RE_SPECIAL_TAGS_NO_OPTION, + GENERIC = 'div', + SVG = 'svg' + + +/* + Creates the root element for table or select child elements: + tr/th/td/thead/tfoot/tbody/caption/col/colgroup/option/optgroup +*/ +function specialTags(el, tmpl, tagName) { + + let + select = tagName[0] === 'o', + parent = select ? 'select>' : 'table>' + + // trim() is important here, this ensures we don't have artifacts, + // so we can check if we have only one element inside the parent + el.innerHTML = '<' + parent + tmpl.trim() + ' { + const type = dom.nodeType + let attr + let tagImpl + + if (!mustIncludeRoot && dom === root) return + + // text node + if (type === 3 && dom.parentNode.tagName !== 'STYLE' && tmpl.hasExpr(dom.nodeValue)) + expressions.push({dom, expr: dom.nodeValue}) + + if (type !== 1) return + + const isVirtual = dom.tagName === 'VIRTUAL' + + // loop. each does it's own thing (for now) + if (attr = getAttribute(dom, LOOP_DIRECTIVE)) { + if(isVirtual) setAttribute(dom, 'loopVirtual', true) // ignore here, handled in _each + expressions.push(_each(dom, this, attr)) + return false + } + + // if-attrs become the new parent. Any following expressions (either on the current + // element, or below it) become children of this expression. + if (attr = getAttribute(dom, CONDITIONAL_DIRECTIVE)) { + expressions.push(createIfDirective(dom, this, attr)) + return false + } + + if (attr = getAttribute(dom, IS_DIRECTIVE)) { + if (tmpl.hasExpr(attr)) { + expressions.push({ + isRtag: true, + expr: attr, + dom, + attrs: [].slice.call(dom.attributes) + }) + + return false + } + } + + // if this is a tag, stop traversing here. + // we ignore the root, since parseExpressions is called while we're mounting that root + tagImpl = getTag(dom) + + if(isVirtual) { + if(getAttribute(dom, 'virtualized')) {dom.parentElement.removeChild(dom) } // tag created, remove from dom + if(!tagImpl && !getAttribute(dom, 'virtualized') && !getAttribute(dom, 'loopVirtual')) // ok to create virtual tag + tagImpl = { tmpl: dom.outerHTML } + } + + if (tagImpl && (dom !== root || mustIncludeRoot)) { + const hasIsDirective = getAttribute(dom, IS_DIRECTIVE) + if(isVirtual && !hasIsDirective) { // handled in update + // can not remove attribute like directives + // so flag for removal after creation to prevent maximum stack error + setAttribute(dom, 'virtualized', true) + const tag = createTag( + {tmpl: dom.outerHTML}, + {root: dom, parent: this}, + dom.innerHTML + ) + + expressions.push(tag) // no return, anonymous tag, keep parsing + } else { + if (hasIsDirective && isVirtual) + warn(`Virtual tags shouldn't be used together with the "${IS_DIRECTIVE}" attribute - https://github.com/riot/riot/issues/2511`) + + expressions.push( + initChild( + tagImpl, + { + root: dom, + parent: this + }, + dom.innerHTML, + this + ) + ) + return false + } + } + + // attribute expressions + parseAttributes.apply(this, [dom, dom.attributes, (attr, expr) => { + if (!expr) return + expressions.push(expr) + }]) + }) + + return expressions +} + +/** + * Calls `fn` for every attribute on an element. If that attr has an expression, + * it is also passed to fn. + * @this Tag + * @param { HTMLElement } dom - dom node to parse + * @param { Array } attrs - array of attributes + * @param { Function } fn - callback to exec on any iteration + */ +export function parseAttributes(dom, attrs, fn) { + each(attrs, (attr) => { + if (!attr) return false + + const name = attr.name + const bool = isBoolAttr(name) + let expr + + if (contains(REF_DIRECTIVES, name) && dom.tagName.toLowerCase() !== YIELD_TAG) { + expr = createRefDirective(dom, this, name, attr.value) + } else if (tmpl.hasExpr(attr.value)) { + expr = {dom, expr: attr.value, attr: name, bool} + } + + fn(attr, expr) + }) +} ADDED public/riot-3.13.2/lib/browser/tag/ref.js Index: public/riot-3.13.2/lib/browser/tag/ref.js ================================================================== --- public/riot-3.13.2/lib/browser/tag/ref.js +++ public/riot-3.13.2/lib/browser/tag/ref.js @@ -0,0 +1,60 @@ +import { tmpl } from 'riot-tmpl' +import isBlank from './../common/util/checks/is-blank' +import isString from './../common/util/checks/is-string' +import removeAttribute from './../common/util/dom/remove-attribute' +import setAttribute from './../common/util/dom/set-attribute' + +import { + getImmediateCustomParentTag, + arrayishAdd, + arrayishRemove +} from './../common/util/tags' + +export default { + init(dom, parent, attrName, attrValue) { + this.dom = dom + this.attr = attrName + this.rawValue = attrValue + this.parent = parent + this.hasExp = tmpl.hasExpr(attrValue) + return this + }, + update() { + const old = this.value + const customParent = this.parent && getImmediateCustomParentTag(this.parent) + // if the referenced element is a custom tag, then we set the tag itself, rather than DOM + const tagOrDom = this.dom.__ref || this.tag || this.dom + + this.value = this.hasExp ? tmpl(this.rawValue, this.parent) : this.rawValue + + // the name changed, so we need to remove it from the old key (if present) + if (!isBlank(old) && customParent) arrayishRemove(customParent.refs, old, tagOrDom) + if (!isBlank(this.value) && isString(this.value)) { + // add it to the refs of parent tag (this behavior was changed >=3.0) + if (customParent) arrayishAdd( + customParent.refs, + this.value, + tagOrDom, + // use an array if it's a looped node and the ref is not an expression + null, + this.parent.__.index + ) + + if (this.value !== old) { + setAttribute(this.dom, this.attr, this.value) + } + } else { + removeAttribute(this.dom, this.attr) + } + + // cache the ref bound to this dom node + // to reuse it in future (see also #2329) + if (!this.dom.__ref) this.dom.__ref = tagOrDom + }, + unmount() { + const tagOrDom = this.tag || this.dom + const customParent = this.parent && getImmediateCustomParentTag(this.parent) + if (!isBlank(this.value) && customParent) + arrayishRemove(customParent.refs, this.value, tagOrDom) + } +} ADDED public/riot-3.13.2/lib/browser/tag/setEventHandler.js Index: public/riot-3.13.2/lib/browser/tag/setEventHandler.js ================================================================== --- public/riot-3.13.2/lib/browser/tag/setEventHandler.js +++ public/riot-3.13.2/lib/browser/tag/setEventHandler.js @@ -0,0 +1,70 @@ +import isWritable from './../common/util/checks/is-writable' +import contains from './../common/util/misc/contains' +import { RE_EVENTS_PREFIX, RIOT_EVENTS_KEY } from '../common/global-variables' +import getImmediateCustomParent from './../common/util/tags/get-immediate-custom-parent' +import settings from '../../settings' + +/** + * Trigger DOM events + * @param { HTMLElement } dom - dom element target of the event + * @param { Function } handler - user function + * @param { Object } e - event object + */ +function handleEvent(dom, handler, e) { + let ptag = this.__.parent + let item = this.__.item + + if (!item) + while (ptag && !item) { + item = ptag.__.item + ptag = ptag.__.parent + } + + // override the event properties + /* istanbul ignore next */ + if (isWritable(e, 'currentTarget')) e.currentTarget = dom + /* istanbul ignore next */ + if (isWritable(e, 'target')) e.target = e.srcElement + /* istanbul ignore next */ + if (isWritable(e, 'which')) e.which = e.charCode || e.keyCode + + e.item = item + + handler.call(this, e) + + // avoid auto updates + if (!settings.autoUpdate) return + + if (!e.preventUpdate) { + const p = getImmediateCustomParent(this) + // fixes #2083 + if (p.isMounted) p.update() + } +} + +/** + * Attach an event to a DOM node + * @param { String } name - event name + * @param { Function } handler - event callback + * @param { Object } dom - dom node + * @param { Tag } tag - tag instance + */ +export default function setEventHandler(name, handler, dom, tag) { + let eventName + const cb = handleEvent.bind(tag, dom, handler) + + // avoid to bind twice the same event + // possible fix for #2332 + dom[name] = null + + // normalize event name + eventName = name.replace(RE_EVENTS_PREFIX, '') + + // cache the listener into the listeners array + if (!contains(tag.__.listeners, dom)) tag.__.listeners.push(dom) + if (!dom[RIOT_EVENTS_KEY]) dom[RIOT_EVENTS_KEY] = {} + if (dom[RIOT_EVENTS_KEY][name]) dom.removeEventListener(eventName, dom[RIOT_EVENTS_KEY][name]) + + dom[RIOT_EVENTS_KEY][name] = cb + dom.addEventListener(eventName, cb, false) +} ADDED public/riot-3.13.2/lib/browser/tag/styleManager.js Index: public/riot-3.13.2/lib/browser/tag/styleManager.js ================================================================== --- public/riot-3.13.2/lib/browser/tag/styleManager.js +++ public/riot-3.13.2/lib/browser/tag/styleManager.js @@ -0,0 +1,69 @@ +import $ from './../common/util/dom/$' +import makeElement from './../common/util/dom/make-element' +import setAttribute from './../common/util/dom/set-attribute' +import { WIN } from './../common/global-variables' + +let styleNode +// Create cache and shortcut to the correct property +let cssTextProp +let byName = {} +let needsInject = false + +// skip the following code on the server +if (WIN) { + styleNode = ((() => { + // create a new style element with the correct type + const newNode = makeElement('style') + // replace any user node or insert the new one into the head + const userNode = $('style[type=riot]') + + setAttribute(newNode, 'type', 'text/css') + /* istanbul ignore next */ + if (userNode) { + if (userNode.id) newNode.id = userNode.id + userNode.parentNode.replaceChild(newNode, userNode) + } else document.head.appendChild(newNode) + + return newNode + }))() + cssTextProp = styleNode.styleSheet +} + +/** + * Object that will be used to inject and manage the css of every tag instance + */ +export default { + styleNode, + /** + * Save a tag style to be later injected into DOM + * @param { String } css - css string + * @param { String } name - if it's passed we will map the css to a tagname + */ + add(css, name) { + byName[name] = css + needsInject = true + }, + /** + * Inject all previously saved tag styles into DOM + * innerHTML seems slow: http://jsperf.com/riot-insert-style + */ + inject() { + if (!WIN || !needsInject) return + needsInject = false + const style = Object.keys(byName) + .map(k => byName[k]) + .join('\n') + /* istanbul ignore next */ + if (cssTextProp) cssTextProp.cssText = style + else styleNode.innerHTML = style + }, + + /** + * Remove a tag style of injected DOM later. + * @param {String} name a registered tagname + */ + remove(name) { + delete byName[name] + needsInject = true + } +} ADDED public/riot-3.13.2/lib/browser/tag/tag.js Index: public/riot-3.13.2/lib/browser/tag/tag.js ================================================================== --- public/riot-3.13.2/lib/browser/tag/tag.js +++ public/riot-3.13.2/lib/browser/tag/tag.js @@ -0,0 +1,100 @@ +import observable from 'riot-observable' +import mkdom from './mkdom' +import settings from '../../settings' +import isSvg from './../common/util/checks/is-svg' +import extend from './../common/util/misc/extend' +import uid from './../common/util/misc/uid' +import define from './../common/util/misc/define' +import getTagName from './../common/util/tags/get-name' +import componentUpdate from './component/update' +import componentMixin from './component/mixin' +import componentMount from './component/mount' +import componentUnmount from './component/unmount' + +/** + * Tag creation factory function + * @constructor + * @param { Object } impl - it contains the tag template, and logic + * @param { Object } conf - tag options + * @param { String } innerHTML - html that eventually we need to inject in the tag + */ +export default function createTag(impl = {}, conf = {}, innerHTML) { + const tag = conf.context || {} + const opts = conf.opts || {} + const parent = conf.parent + const isLoop = conf.isLoop + const isAnonymous = !!conf.isAnonymous + const skipAnonymous = settings.skipAnonymousTags && isAnonymous + const item = conf.item + // available only for the looped nodes + const index = conf.index + // All attributes on the Tag when it's first parsed + const instAttrs = [] + // expressions on this type of Tag + const implAttrs = [] + const tmpl = impl.tmpl + const expressions = [] + const root = conf.root + const tagName = conf.tagName || getTagName(root) + const isVirtual = tagName === 'virtual' + const isInline = !isVirtual && !tmpl + let dom + + if (isInline || isLoop && isAnonymous) { + dom = root + } else { + if (!isVirtual) root.innerHTML = '' + dom = mkdom(tmpl, innerHTML, isSvg(root)) + } + + // make this tag observable + if (!skipAnonymous) observable(tag) + + // only call unmount if we have a valid __TAG_IMPL (has name property) + if (impl.name && root._tag) root._tag.unmount(true) + + define(tag, '__', { + impl, + root, + skipAnonymous, + implAttrs, + isAnonymous, + instAttrs, + innerHTML, + tagName, + index, + isLoop, + isInline, + item, + parent, + // tags having event listeners + // it would be better to use weak maps here but we can not introduce breaking changes now + listeners: [], + // these vars will be needed only for the virtual tags + virts: [], + wasCreated: false, + tail: null, + head: null + }) + + // tag protected properties + return [ + ['isMounted', false], + // create a unique id to this tag + // it could be handy to use it also to improve the virtual dom rendering speed + ['_riot_id', uid()], + ['root', root], + ['opts', opts, { writable: true, enumerable: true }], + ['parent', parent || null], + // protect the "tags" and "refs" property from being overridden + ['tags', {}], + ['refs', {}], + ['update', data => componentUpdate(tag, data, expressions)], + ['mixin', (...mixins) => componentMixin(tag, ...mixins)], + ['mount', () => componentMount(tag, dom, expressions, opts)], + ['unmount', mustKeepRoot => componentUnmount(tag, mustKeepRoot, expressions)] + ].reduce((acc, [key, value, opts]) => { + define(tag, key, value, opts) + return acc + }, extend(tag, item)) +} ADDED public/riot-3.13.2/lib/browser/tag/update.js Index: public/riot-3.13.2/lib/browser/tag/update.js ================================================================== --- public/riot-3.13.2/lib/browser/tag/update.js +++ public/riot-3.13.2/lib/browser/tag/update.js @@ -0,0 +1,255 @@ +import { tmpl } from 'riot-tmpl' +import each from './../common/util/misc/each' +import contains from './../common/util/misc/contains' +import riotSettings from '../../settings' + +import isBlank from './../common/util/checks/is-blank' +import isObject from './../common/util/checks/is-object' +import isString from './../common/util/checks/is-string' +import isFunction from './../common/util/checks/is-function' + +import removeAttribute from './../common/util/dom/remove-attribute' +import getAttribute from './../common/util/dom/get-attribute' +import setAttribute from './../common/util/dom/set-attribute' +import createPlaceholder from './../common/util/dom/create-placeholder' +import toggleVisibility from './../common/util/dom/toggle-visibility' +import styleObjectToString from './../common/util/dom/style-object-to-string' +import isEventAttribute from './../common/util/misc/is-event-attribute' + +import setEventHandler from './setEventHandler' + +import initChild from './../common/util/tags/init-child' +import arrayishRemove from './../common/util/tags/arrayish-remove' +import inheritParentProps from './../common/util/tags/inherit-parent-properties' +import replaceVirtual from './../common/util/tags/replace-virtual' + +import { + __TAG_IMPL, + ATTRS_PREFIX, + SHOW_DIRECTIVE, + HIDE_DIRECTIVE, + IE_VERSION, + CASE_SENSITIVE_ATTRIBUTES +} from './../common/global-variables' + +/** + * Update dynamically created data-is tags with changing expressions + * @param { Object } expr - expression tag and expression info + * @param { Tag } parent - parent for tag creation + * @param { String } tagName - tag implementation we want to use + */ +export function updateDataIs(expr, parent, tagName) { + let tag = expr.tag || expr.dom._tag + let ref + + const { head } = tag ? tag.__ : {} + const isVirtual = expr.dom.tagName === 'VIRTUAL' + + if (tag && expr.tagName === tagName) { + tag.update() + return + } + + // sync _parent to accommodate changing tagnames + if (tag) { + // need placeholder before unmount + if(isVirtual) { + ref = createPlaceholder() + head.parentNode.insertBefore(ref, head) + } + + tag.unmount(true) + } + + // unable to get the tag name + if (!isString(tagName)) return + + expr.impl = __TAG_IMPL[tagName] + + // unknown implementation + if (!expr.impl) return + + expr.tag = tag = initChild( + expr.impl, { + root: expr.dom, + parent, + tagName + }, + expr.dom.innerHTML, + parent + ) + + each(expr.attrs, a => setAttribute(tag.root, a.name, a.value)) + expr.tagName = tagName + tag.mount() + + // root exist first time, after use placeholder + if (isVirtual) replaceVirtual(tag, ref || tag.root) + + // parent is the placeholder tag, not the dynamic tag so clean up + parent.__.onUnmount = () => { + const delName = tag.opts.dataIs + arrayishRemove(tag.parent.tags, delName, tag) + arrayishRemove(tag.__.parent.tags, delName, tag) + tag.unmount() + } +} + +/** + * Nomalize any attribute removing the "riot-" prefix + * @param { String } attrName - original attribute name + * @returns { String } valid html attribute name + */ +export function normalizeAttrName(attrName) { + if (!attrName) return null + attrName = attrName.replace(ATTRS_PREFIX, '') + if (CASE_SENSITIVE_ATTRIBUTES[attrName]) attrName = CASE_SENSITIVE_ATTRIBUTES[attrName] + return attrName +} + +/** + * Update on single tag expression + * @this Tag + * @param { Object } expr - expression logic + * @returns { undefined } + */ +export function updateExpression(expr) { + if (this.root && getAttribute(this.root,'virtualized')) return + + const dom = expr.dom + // remove the riot- prefix + const attrName = normalizeAttrName(expr.attr) + const isToggle = contains([SHOW_DIRECTIVE, HIDE_DIRECTIVE], attrName) + const isVirtual = expr.root && expr.root.tagName === 'VIRTUAL' + const { isAnonymous } = this.__ + const parent = dom && (expr.parent || dom.parentNode) + const { keepValueAttributes } = riotSettings + // detect the style attributes + const isStyleAttr = attrName === 'style' + const isClassAttr = attrName === 'class' + const isValueAttr = attrName === 'value' + + let value + + // if it's a tag we could totally skip the rest + if (expr._riot_id) { + if (expr.__.wasCreated) { + expr.update() + // if it hasn't been mounted yet, do that now. + } else { + expr.mount() + if (isVirtual) { + replaceVirtual(expr, expr.root) + } + } + return + } + + // if this expression has the update method it means it can handle the DOM changes by itself + if (expr.update) return expr.update() + + const context = isToggle && !isAnonymous ? inheritParentProps.call(this) : this + + // ...it seems to be a simple expression so we try to calculate its value + value = tmpl(expr.expr, context) + + const hasValue = !isBlank(value) + const isObj = isObject(value) + + // convert the style/class objects to strings + if (isObj) { + if (isClassAttr) { + value = tmpl(JSON.stringify(value), this) + } else if (isStyleAttr) { + value = styleObjectToString(value) + } + } + + // remove original attribute + if (expr.attr && + ( + // the original attribute can be removed only if we are parsing the original expression + !expr.wasParsedOnce || + // or its value is false + value === false || + // or if its value is currently falsy... + // We will keep the "value" attributes if the "keepValueAttributes" + // is enabled though + (!hasValue && (!isValueAttr || isValueAttr && !keepValueAttributes)) + ) + ) { + // remove either riot-* attributes or just the attribute name + removeAttribute(dom, getAttribute(dom, expr.attr) ? expr.attr : attrName) + } + + // for the boolean attributes we don't need the value + // we can convert it to checked=true to checked=checked + if (expr.bool) value = value ? attrName : false + if (expr.isRtag) return updateDataIs(expr, this, value) + if (expr.wasParsedOnce && expr.value === value) return + + // update the expression value + expr.value = value + expr.wasParsedOnce = true + + // if the value is an object (and it's not a style or class attribute) we can not do much more with it + if (isObj && !isClassAttr && !isStyleAttr && !isToggle) return + // avoid to render undefined/null values + if (!hasValue) value = '' + + // textarea and text nodes have no attribute name + if (!attrName) { + // about #815 w/o replace: the browser converts the value to a string, + // the comparison by "==" does too, but not in the server + value += '' + // test for parent avoids error with invalid assignment to nodeValue + if (parent) { + // cache the parent node because somehow it will become null on IE + // on the next iteration + expr.parent = parent + if (parent.tagName === 'TEXTAREA') { + parent.value = value // #1113 + if (!IE_VERSION) dom.nodeValue = value // #1625 IE throws here, nodeValue + } // will be available on 'updated' + else dom.nodeValue = value + } + return + } + + switch (true) { + // handle events binding + case isFunction(value): + if (isEventAttribute(attrName)) { + setEventHandler(attrName, value, dom, this) + } + break + // show / hide + case isToggle: + toggleVisibility(dom, attrName === HIDE_DIRECTIVE ? !value : value) + break + // handle attributes + default: + if (expr.bool) { + dom[attrName] = value + } + + if (isValueAttr && dom.value !== value) { + dom.value = value + } else if (hasValue && value !== false) { + setAttribute(dom, attrName, value) + } + + // make sure that in case of style changes + // the element stays hidden + if (isStyleAttr && dom.hidden) toggleVisibility(dom, false) + } +} + +/** + * Update all the expressions in a Tag instance + * @this Tag + * @param { Array } expressions - expression that must be re evaluated + */ +export default function update(expressions) { + each(expressions, updateExpression.bind(this)) +} ADDED public/riot-3.13.2/lib/riot+compiler.js Index: public/riot-3.13.2/lib/riot+compiler.js ================================================================== --- public/riot-3.13.2/lib/riot+compiler.js +++ public/riot-3.13.2/lib/riot+compiler.js @@ -0,0 +1,15 @@ +import * as riot from './riot' +import { compile, parsers } from './browser/compiler/index' +import extend from './browser/common/util/misc/extend' + +function mount(...args) { + var ret + compile(function () { ret = riot.mount.apply(riot, args) }) + return ret +} + +export default extend({}, riot, { + mount, + compile, + parsers +}) ADDED public/riot-3.13.2/lib/riot.js Index: public/riot-3.13.2/lib/riot.js ================================================================== --- public/riot-3.13.2/lib/riot.js +++ public/riot-3.13.2/lib/riot.js @@ -0,0 +1,44 @@ +import styleManager from './browser/tag/styleManager' +import { tmpl, brackets } from 'riot-tmpl' +import o from 'riot-observable' +import s from './settings' +import { __TAGS_CACHE as vdom } from './browser/common/global-variables' +import * as dom from './browser/common/util/dom' +import * as check from './browser/common/util/checks' // avoid to add breaking changes +import * as misc from './browser/common/util/misc' +import * as tags from './browser/common/util/tags' +import * as core from './browser/tag/core' + +/** + * Riot public api + */ +export const settings = s +export const util = { + tmpl, + brackets, + styleManager, + vdom, + styleNode: styleManager.styleNode, + // export the riot internal utils as well + dom, + check, + misc, + tags +} + +// export the core props/methods +export const Tag = core.Tag +export const tag = core.tag +export const tag2 = core.tag2 +export const mount = core.mount +export const mixin = core.mixin +export const update = core.update +export const unregister = core.unregister +export const version = core.version +export const observable = o + +export default misc.extend({}, core, { + observable: o, + settings, + util, +}) ADDED public/riot-3.13.2/lib/server/index.js Index: public/riot-3.13.2/lib/server/index.js ================================================================== --- public/riot-3.13.2/lib/server/index.js +++ public/riot-3.13.2/lib/server/index.js @@ -0,0 +1,125 @@ + +// allow to require('riot') +const + path = require('path'), + fs = require('fs'), + hasRiotPath = !!process.env.RIOT, + riotPath = path.normalize(process.env.RIOT || path.join('..', '..', 'riot')), + riot = require(riotPath), + // simple-dom helper + sdom = require('./sdom'), + Module = require('module'), + compiler = require('riot-compiler') + +// fix #2225 +// rollup considers the riot.default key as default export value instead of what we export here +delete riot.default + +// time riot should wait before throwing during an async rendering +riot.settings.asyncRenderTimeout = 1000 + +/** + * Function that will be used by riot.require and by require('some.tag') + * @param { String } filename - path to the file to load and compile + * @param { Object } opts - compiler options + * @param { Object } context - context where the tag will be mounted (Module) + */ +function loadAndCompile(filename, opts, context) { + const src = compiler.compile(fs.readFileSync(filename, 'utf8'), opts) + const preTag = src.substring(0, src.indexOf('riot.tag')) + const tagDefinition = src.substring(src.indexOf('riot.tag')) + + // here we will use template strings in riot@3.0.0 + context._compile(` + var riot = require('${ hasRiotPath ? riotPath : 'riot' }') + ${ preTag } + module.exports = ${ tagDefinition } + `, filename) +} + +/** + * Enable the loading of riot tags with options riot.require('some.tag', { template: 'pug' }) + * @param { String } filename - path to the file to load and compile + * @param { Object } opts - compiler options + * @returns { String } tag name + */ +function riotRequire(filename, opts) { + var module = new Module() + module.id = module.filename = filename + loadAndCompile(filename, opts, module) + return module.exports +} + +// allow to require('some.tag') +if (require.extensions) { + require.extensions['.tag'] = function(module, filename) { + loadAndCompile(filename, {}, module) + } +} + +/** + * Get the html as string form any riot tag instance + * @param { Tag } tag - riot tag instance + * @returns { String } tag template + */ +function getTagHtml(tag) { + return sdom.serialize(tag.root) +} + +/** + * Render riot tags returning a strings + * @param { String } tagName - tag identifier + * @param { Object } opts - options to pass to the tag + * @returns { String } tag resulting template + */ +function render(tagName, opts) { + var tag = render.tag(tagName, opts), + html = getTagHtml(tag) + // unmount the tag avoiding memory leaks + tag.unmount() + return html +} + +/** + * Render riot tags asynchronously + * @param { String } tagName - tag identifier + * @param { Object } opts - options to pass to the tag + * @returns { Promise } a promise resolved with the tag template string + */ +function renderAsync(tagName, opts) { + return Promise.race([ + new Promise((resolve, reject) => { + setTimeout(function() { + reject(new Error(`Timeout error:: the tag "${ tagName }" didn't trigger the "ready" event during the rendering process`)) + }, riot.settings.asyncRenderTimeout) + }), + new Promise(resolve => { + var tag = render.tag(tagName, opts) + tag.on('ready', function() { + var html = getTagHtml(tag) + tag.unmount() + resolve(html) + }) + }) + ]) +} + +// extend the render function with some static methods +render.dom = function(tagName, opts) { + return riot.render.tag(tagName, opts).root +} +render.tag = function(tagName, opts) { + var root = document.createElement(tagName), + tag = riot.mount(root, opts)[0] + return tag +} + +// extend the riot api adding some useful serverside methods +module.exports = exports.default = Object.assign(riot, { + // allow to require('riot').compile + compile: compiler.compile, + parsers: compiler.parsers, + require: riotRequire, + render, + renderAsync +}) ADDED public/riot-3.13.2/lib/server/sdom.js Index: public/riot-3.13.2/lib/server/sdom.js ================================================================== --- public/riot-3.13.2/lib/server/sdom.js +++ public/riot-3.13.2/lib/server/sdom.js @@ -0,0 +1,95 @@ +// simple-dom helper + +var simpleDom = require('simple-dom') +var simpleTokenizer = require('simple-html-tokenizer') + +// create `document` to make riot work +if (typeof window === 'undefined') { + /*eslint-disable*/ + document = new simpleDom.Document() + /*eslint-enable*/ +} + +// easy like a pie! closes #1780 +document.createElementNS = document.createElement + +// add `innerHTML` property to simple-dom element +Object.defineProperty(simpleDom.Element.prototype, 'innerHTML', { + set: function(html) { + var frag = sdom.parse(html) + while (this.firstChild) this.removeChild(this.firstChild) + this.appendChild(frag) + }, + get: function() { + var html = '', + next = this.firstChild + + while (next) { + html += sdom.serialize(next) + next = next.nextSibling + } + + return html + } +}) + + +// add `addEventListener` property to simple-dom element +Object.defineProperty(simpleDom.Element.prototype, 'addEventListener', { + value: function(type, fn) { + this[`on${ type }`] = fn + } +}) + +Object.defineProperty(simpleDom.Element.prototype, 'removeEventListener', { + value: function(type) { + this[`on${ type }`] = null + } +}) + +// set the value attribute correctly on the input tags +Object.defineProperty(simpleDom.Element.prototype, 'value', { + set: function(val) { + val = String(val) // make sure it's always a string + if (this.getAttribute('value') !== val) { + this.setAttribute('value', val) + this.value = val + } + } +}) + +// add `outerHTML` property to simple-dom element +Object.defineProperty(simpleDom.Element.prototype, 'outerHTML', { + get: function() { + var html = sdom.serialize(this) + var rxstr = '^(<' + this.tagName + '>.*?)' + var match = html.match(new RegExp(rxstr, 'i')) + return match ? match[0] : html + } +}) + +// add `style` property to simple-dom element +Object.defineProperty(simpleDom.Element.prototype, 'style', { + get: function() { + var el = this + return Object.defineProperty({}, 'display', { + set: function(value) { + el.setAttribute('style', 'display: ' + value + ';') + } + }) + } +}) + +var sdom = module.exports = { + parse: function(html) { + // parse html string to simple-dom document + var blank = new simpleDom.Document() + var parser = new simpleDom.HTMLParser(simpleTokenizer.tokenize, blank, simpleDom.voidMap) + return parser.parse(html) + }, + serialize: function(doc) { + // serialize simple-dom document to html string + var serializer = new simpleDom.HTMLSerializer(simpleDom.voidMap) + return serializer.serialize(doc) + } +} ADDED public/riot-3.13.2/lib/settings.js Index: public/riot-3.13.2/lib/settings.js ================================================================== --- public/riot-3.13.2/lib/settings.js +++ public/riot-3.13.2/lib/settings.js @@ -0,0 +1,11 @@ +import extend from './browser/common/util/misc/extend' +import create from './browser/common/util/misc/object-create' +import { brackets } from 'riot-tmpl' + +export default extend(create(brackets.settings), { + skipAnonymousTags: true, + // the "value" attributes will be preserved + keepValueAttributes: false, + // handle the auto updates on any DOM event + autoUpdate: true +}) ADDED public/riot-3.13.2/package-lock.json Index: public/riot-3.13.2/package-lock.json ================================================================== --- public/riot-3.13.2/package-lock.json +++ public/riot-3.13.2/package-lock.json @@ -0,0 +1,7610 @@ +{ + "name": "riot", + "version": "3.13.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@sinonjs/formatio": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-2.0.0.tgz", + "integrity": "sha512-ls6CAMA6/5gG+O/IdsBcblvnd8qcO/l1TYoNeAzp3wcISOxlPXQEus0mLcdwazEkWjaBdaJ3TaxmNgCLWwvWzg==", + "dev": true, + "requires": { + "samsam": "1.3.0" + } + }, + "@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "dev": true + }, + "@types/node": { + "version": "9.6.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.5.tgz", + "integrity": "sha512-NOLEgsT6UiDTjnWG5Hd2Mg25LRyz/oe8ql3wbjzgSFeRzRROhPmtlsvIrei4B46UjERF0td9SZ1ZXPLOdcrBHg==", + "dev": true + }, + "abab": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/abab/-/abab-1.0.4.tgz", + "integrity": "sha1-X6rZwsB/YN12dw9xzwJbYqY8/U4=", + "dev": true + }, + "abbrev": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", + "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=", + "dev": true + }, + "accepts": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", + "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", + "dev": true, + "requires": { + "mime-types": "~2.1.18", + "negotiator": "0.6.1" + } + }, + "acorn": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.5.3.tgz", + "integrity": "sha512-jd5MkIUlbbmb07nXH0DT3y7rDVtkzDi4XZOUVWAer8ajmF/DTSSbl5oNFyDOl/OXA33Bl79+ypHhl2pN20VeOQ==", + "dev": true + }, + "acorn-dynamic-import": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz", + "integrity": "sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg==", + "dev": true, + "requires": { + "acorn": "^5.0.0" + } + }, + "acorn-globals": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.1.0.tgz", + "integrity": "sha512-KjZwU26uG3u6eZcfGbTULzFcsoz6pegNKtHPksZPOUsiKo5bUmiBPa38FuHZ/Eun+XYh/JCCkS9AS3Lu4McQOQ==", + "dev": true, + "requires": { + "acorn": "^5.0.0" + } + }, + "acorn-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", + "dev": true, + "requires": { + "acorn": "^3.0.4" + }, + "dependencies": { + "acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", + "dev": true + } + } + }, + "adm-zip": { + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.11.tgz", + "integrity": "sha512-L8vcjDTCOIJk7wFvmlEUN7AsSb8T+2JrdP7KINBjzr24TJ5Mwj590sLu3BC7zNZowvJWa/JtPmD8eJCzdtDWjA==", + "dev": true + }, + "after": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", + "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=", + "dev": true + }, + "ajv": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "dev": true, + "requires": { + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" + } + }, + "ajv-keywords": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", + "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=", + "dev": true + }, + "align-text": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", + "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", + "dev": true, + "requires": { + "kind-of": "^3.0.2", + "longest": "^1.0.1", + "repeat-string": "^1.5.2" + } + }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "dev": true + }, + "ansi-escapes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", + "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==", + "dev": true + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "anymatch": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", + "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "requires": { + "micromatch": "^2.1.5", + "normalize-path": "^2.0.0" + } + }, + "archiver": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-2.1.1.tgz", + "integrity": "sha1-/2YrSnggFJSj7lRNOjP+dJZQnrw=", + "dev": true, + "requires": { + "archiver-utils": "^1.3.0", + "async": "^2.0.0", + "buffer-crc32": "^0.2.1", + "glob": "^7.0.0", + "lodash": "^4.8.0", + "readable-stream": "^2.0.0", + "tar-stream": "^1.5.0", + "zip-stream": "^1.2.0" + }, + "dependencies": { + "async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", + "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", + "dev": true, + "requires": { + "lodash": "^4.17.10" + }, + "dependencies": { + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + } + } + } + } + }, + "archiver-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-1.3.0.tgz", + "integrity": "sha1-5QtMCccL89aA4y/xt5lOn52JUXQ=", + "dev": true, + "requires": { + "glob": "^7.0.0", + "graceful-fs": "^4.1.0", + "lazystream": "^1.0.0", + "lodash": "^4.8.0", + "normalize-path": "^2.0.0", + "readable-stream": "^2.0.0" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "requires": { + "arr-flatten": "^1.0.1" + } + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", + "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", + "dev": true + }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true + }, + "array-slice": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz", + "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=", + "dev": true + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "^1.0.1" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=" + }, + "arraybuffer.slice": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", + "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==", + "dev": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + }, + "async-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", + "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=" + }, + "async-limiter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", + "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "atob": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.0.tgz", + "integrity": "sha512-SuiKH8vbsOyCALjA/+EINmt/Kdl+TQPrtFgW7XZZcwtryFu9e5kQoX3bjCW6mIvGH1fbeAZZuvwGR5IlBRznGw==", + "dev": true + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true + }, + "aws4": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", + "dev": true + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + } + } + }, + "base64-arraybuffer": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", + "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=", + "dev": true + }, + "base64-js": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", + "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", + "dev": true + }, + "base64id": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz", + "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "benchmark": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/benchmark/-/benchmark-2.1.4.tgz", + "integrity": "sha1-CfPeMckWQl1JjMLuVloOvzwqVik=", + "dev": true, + "requires": { + "lodash": "^4.17.4", + "platform": "^1.3.3" + } + }, + "better-assert": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", + "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", + "dev": true, + "requires": { + "callsite": "1.0.0" + } + }, + "binary-extensions": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", + "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=" + }, + "bl": { + "version": "1.2.2", + "resolved": "http://registry.npmjs.org/bl/-/bl-1.2.2.tgz", + "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", + "dev": true, + "requires": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + } + }, + "blob": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz", + "integrity": "sha1-vPEwUspURj8w+fx+lbmkdjCpSSE=", + "dev": true + }, + "bluebird": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", + "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==", + "dev": true + }, + "body-parser": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", + "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", + "dev": true, + "requires": { + "bytes": "3.0.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "~1.6.3", + "iconv-lite": "0.4.23", + "on-finished": "~2.3.0", + "qs": "6.5.2", + "raw-body": "2.3.3", + "type-is": "~1.6.16" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "iconv-lite": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", + "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + } + } + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", + "dev": true + }, + "boom": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", + "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", + "dev": true, + "requires": { + "hoek": "4.x.x" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "requires": { + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" + } + }, + "browser-process-hrtime": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.2.tgz", + "integrity": "sha1-Ql1opY00R/AqBKqJQYf86K+Le44=", + "dev": true + }, + "browser-stdout": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", + "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", + "dev": true + }, + "buble": { + "version": "0.19.3", + "resolved": "https://registry.npmjs.org/buble/-/buble-0.19.3.tgz", + "integrity": "sha512-3B0Lcy2u6x6km0BqTz/FS3UnrOJlnIlBWsyjvtqzdtmWkqiS0+Sg4hc6L9Mmm63hZKTACpYS9vUeIoKSi1vcrQ==", + "dev": true, + "requires": { + "acorn": "^5.4.1", + "acorn-dynamic-import": "^3.0.0", + "acorn-jsx": "^4.1.1", + "chalk": "^2.3.1", + "magic-string": "^0.22.4", + "minimist": "^1.2.0", + "os-homedir": "^1.0.1", + "vlq": "^1.0.0" + }, + "dependencies": { + "acorn-jsx": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-4.1.1.tgz", + "integrity": "sha512-JY+iV6r+cO21KtntVvFkD+iqjtdpRUpGqKWgfkCdZq1R+kbreEl8EcdcJR4SmiIgsIQT33s6QzheQ9a275Q8xw==", + "dev": true, + "requires": { + "acorn": "^5.0.3" + } + } + } + }, + "buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz", + "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + }, + "buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "dev": true, + "requires": { + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" + } + }, + "buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", + "dev": true + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true + }, + "buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=", + "dev": true + }, + "buffer-from": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.0.0.tgz", + "integrity": "sha512-83apNb8KK0Se60UE1+4Ukbe3HbfELJ6UlI4ldtOGs7So4KD26orJM8hIY9lxdzP+UpItH1Yh/Y8GUvNFWFFRxA==", + "dev": true + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true + }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", + "dev": true + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "caller-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "dev": true, + "requires": { + "callsites": "^0.2.0" + } + }, + "callsite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", + "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=", + "dev": true + }, + "callsites": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", + "dev": true + }, + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "dev": true + }, + "camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "dev": true, + "requires": { + "camelcase": "^2.0.0", + "map-obj": "^1.0.0" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "center-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", + "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", + "dev": true, + "optional": true, + "requires": { + "align-text": "^0.1.3", + "lazy-cache": "^1.0.3" + } + }, + "chai": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.1.2.tgz", + "integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=", + "dev": true, + "requires": { + "assertion-error": "^1.0.1", + "check-error": "^1.0.1", + "deep-eql": "^3.0.0", + "get-func-name": "^2.0.0", + "pathval": "^1.0.0", + "type-detect": "^4.0.0" + } + }, + "chalk": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz", + "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "chardet": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", + "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", + "dev": true + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "cheerio": { + "version": "1.0.0-rc.2", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.2.tgz", + "integrity": "sha1-S59TqBsn5NXawxwP/Qz6A8xoMNs=", + "dev": true, + "requires": { + "css-select": "~1.2.0", + "dom-serializer": "~0.1.0", + "entities": "~1.1.1", + "htmlparser2": "^3.9.1", + "lodash": "^4.15.0", + "parse5": "^3.0.1" + } + }, + "chokidar": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", + "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", + "requires": { + "anymatch": "^1.3.0", + "async-each": "^1.0.0", + "fsevents": "^1.0.0", + "glob-parent": "^2.0.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^2.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0" + } + }, + "chokidar-cli": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/chokidar-cli/-/chokidar-cli-1.2.1.tgz", + "integrity": "sha512-JIrV9Z/pT7KjBWp9u+Uba0utdl2rmNaTj6t4ucaFseYDQASHZnWXy6vJIufDX+4FVh081gQZ2odrqorMfQhn7w==", + "dev": true, + "requires": { + "bluebird": "3.5.1", + "chokidar": "2.0.4", + "lodash": "4.17.10", + "yargs": "12.0.1" + }, + "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "chokidar": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", + "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.0", + "braces": "^2.3.0", + "fsevents": "^1.2.2", + "glob-parent": "^3.1.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "lodash.debounce": "^4.0.8", + "normalize-path": "^2.1.1", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0", + "upath": "^1.0.5" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-glob": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", + "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + }, + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "upath": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz", + "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==", + "dev": true + } + } + }, + "circular-json": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", + "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", + "dev": true + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, + "cliui": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "dev": true, + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color-convert": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", + "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", + "requires": { + "color-name": "^1.1.1" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "colors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.0.tgz", + "integrity": "sha512-EDpX3a7wHMWFA7PUHWPHNWqOxIIRSJetuwl0AS5Oi/5FMV8kWm69RTlgm00GKjBO1xFHMtBbL49yRtMMdticBw==", + "dev": true + }, + "combine-lists": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/combine-lists/-/combine-lists-1.0.1.tgz", + "integrity": "sha1-RYwH4J4NkA/Ci3Cj/sLazR0st/Y=", + "dev": true, + "requires": { + "lodash": "^4.5.0" + } + }, + "combined-stream": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", + "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "2.17.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", + "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", + "dev": true + }, + "component-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", + "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=", + "dev": true + }, + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "dev": true + }, + "component-inherit": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", + "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=", + "dev": true + }, + "compress-commons": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-1.2.2.tgz", + "integrity": "sha1-UkqfEJA/OoEzibAiXSfEi7dRiQ8=", + "dev": true, + "requires": { + "buffer-crc32": "^0.2.1", + "crc32-stream": "^2.0.0", + "normalize-path": "^2.0.0", + "readable-stream": "^2.0.0" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "connect": { + "version": "3.6.6", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz", + "integrity": "sha1-Ce/2xVr3I24TcTWnJXSFi2eG9SQ=", + "dev": true, + "requires": { + "debug": "2.6.9", + "finalhandler": "1.1.0", + "parseurl": "~1.3.2", + "utils-merge": "1.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true + }, + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", + "dev": true + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, + "core-js": { + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz", + "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "coveralls": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.0.2.tgz", + "integrity": "sha512-Tv0LKe/MkBOilH2v7WBiTBdudg2ChfGbdXafc/s330djpF3zKOmuehTeRwjXWc7pzfj9FrDUTA7tEx6Div8NFw==", + "dev": true, + "requires": { + "growl": "~> 1.10.0", + "js-yaml": "^3.11.0", + "lcov-parse": "^0.0.10", + "log-driver": "^1.2.7", + "minimist": "^1.2.0", + "request": "^2.85.0" + } + }, + "crc": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", + "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", + "dev": true, + "requires": { + "buffer": "^5.1.0" + } + }, + "crc32-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-2.0.0.tgz", + "integrity": "sha1-483TtN8xaN10494/u8t7KX/pCPQ=", + "dev": true, + "requires": { + "crc": "^3.4.4", + "readable-stream": "^2.0.0" + } + }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "cryptiles": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.4.tgz", + "integrity": "sha512-8I1sgZHfVwcSOY6mSGpVU3lw/GSIZvusg8dD2+OGehCJpOhQRLNcH0qb9upQnOH4XhgxxFJSg6E2kx95deb1Tw==", + "dev": true, + "requires": { + "boom": "5.x.x" + }, + "dependencies": { + "boom": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", + "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", + "dev": true, + "requires": { + "hoek": "4.x.x" + } + } + } + }, + "css-select": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", + "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", + "dev": true, + "requires": { + "boolbase": "~1.0.0", + "css-what": "2.1", + "domutils": "1.5.1", + "nth-check": "~1.0.1" + } + }, + "css-what": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.0.tgz", + "integrity": "sha1-lGfQMsOM+u+58teVASUwYvh/ob0=", + "dev": true + }, + "cssom": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.2.tgz", + "integrity": "sha1-uANhcMefB6kP8vFuIihAJ6JDhIs=", + "dev": true + }, + "cssstyle": { + "version": "0.2.37", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-0.2.37.tgz", + "integrity": "sha1-VBCXI0yyUTyDzu06zdwn/yeYfVQ=", + "dev": true, + "requires": { + "cssom": "0.3.x" + } + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dev": true, + "requires": { + "array-find-index": "^1.0.1" + } + }, + "custom-event": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", + "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=", + "dev": true + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "data-urls": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.0.0.tgz", + "integrity": "sha512-ai40PPQR0Fn1lD2PPie79CibnlMN2AYiDhwFX/rZHVsxbs5kNJSjegqXIprhouGXlRdEnfybva7kqRGnB6mypA==", + "dev": true, + "requires": { + "abab": "^1.0.4", + "whatwg-mimetype": "^2.0.0", + "whatwg-url": "^6.4.0" + } + }, + "date-format": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-1.2.0.tgz", + "integrity": "sha1-YV6CjiM90aubua4JUODOzPpuytg=", + "dev": true + }, + "dateformat": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz", + "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=", + "dev": true, + "requires": { + "get-stdin": "^4.0.1", + "meow": "^3.3.0" + } + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + } + } + }, + "del": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", + "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", + "dev": true, + "requires": { + "globby": "^5.0.0", + "is-path-cwd": "^1.0.0", + "is-path-in-cwd": "^1.0.0", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "rimraf": "^2.2.8" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true + }, + "di": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", + "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=", + "dev": true + }, + "diff": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", + "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", + "dev": true + }, + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "dom-serialize": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", + "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=", + "dev": true, + "requires": { + "custom-event": "~1.0.0", + "ent": "~2.2.0", + "extend": "^3.0.0", + "void-elements": "^2.0.0" + } + }, + "dom-serializer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", + "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=", + "dev": true, + "requires": { + "domelementtype": "~1.1.1", + "entities": "~1.1.1" + }, + "dependencies": { + "domelementtype": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", + "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=", + "dev": true + } + } + }, + "domelementtype": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz", + "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=", + "dev": true + }, + "domexception": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", + "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", + "dev": true, + "requires": { + "webidl-conversions": "^4.0.2" + } + }, + "domhandler": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.1.tgz", + "integrity": "sha1-iS5HAAqZvlW783dP/qBWHYh5wlk=", + "dev": true, + "requires": { + "domelementtype": "1" + } + }, + "domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "dev": true, + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true + }, + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "engine.io": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.2.0.tgz", + "integrity": "sha512-mRbgmAtQ4GAlKwuPnnAvXXwdPhEx+jkc0OBCLrXuD/CRvwNK3AxRSnqK4FSqmAMRRHryVJP8TopOvmEaA64fKw==", + "dev": true, + "requires": { + "accepts": "~1.3.4", + "base64id": "1.0.0", + "cookie": "0.3.1", + "debug": "~3.1.0", + "engine.io-parser": "~2.1.0", + "ws": "~3.3.1" + }, + "dependencies": { + "ws": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" + } + } + } + }, + "engine.io-client": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.2.1.tgz", + "integrity": "sha512-y5AbkytWeM4jQr7m/koQLc5AxpRKC1hEVUb/s1FUAWEJq5AzJJ4NLvzuKPuxtDi5Mq755WuDvZ6Iv2rXj4PTzw==", + "dev": true, + "requires": { + "component-emitter": "1.2.1", + "component-inherit": "0.0.3", + "debug": "~3.1.0", + "engine.io-parser": "~2.1.1", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "ws": "~3.3.1", + "xmlhttprequest-ssl": "~1.5.4", + "yeast": "0.1.2" + }, + "dependencies": { + "ws": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" + } + } + } + }, + "engine.io-parser": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.2.tgz", + "integrity": "sha512-dInLFzr80RijZ1rGpx1+56/uFoH7/7InhH3kZt+Ms6hT8tNx3NGW/WNSA/f8As1WkOfkuyb3tnRyuXGxusclMw==", + "dev": true, + "requires": { + "after": "0.8.2", + "arraybuffer.slice": "~0.0.7", + "base64-arraybuffer": "0.1.5", + "blob": "0.0.4", + "has-binary2": "~1.0.2" + } + }, + "ent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", + "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", + "dev": true + }, + "entities": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", + "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=", + "dev": true + }, + "error-ex": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", + "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es6-promise": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz", + "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==", + "dev": true + }, + "es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "dev": true, + "requires": { + "es6-promise": "^4.0.3" + } + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "escodegen": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", + "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", + "dev": true, + "requires": { + "esprima": "^2.7.1", + "estraverse": "^1.9.1", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.2.0" + }, + "dependencies": { + "esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "dev": true + }, + "estraverse": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", + "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", + "dev": true + }, + "source-map": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", + "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", + "dev": true, + "optional": true, + "requires": { + "amdefine": ">=0.0.4" + } + } + } + }, + "eslint": { + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz", + "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==", + "dev": true, + "requires": { + "ajv": "^5.3.0", + "babel-code-frame": "^6.22.0", + "chalk": "^2.1.0", + "concat-stream": "^1.6.0", + "cross-spawn": "^5.1.0", + "debug": "^3.1.0", + "doctrine": "^2.1.0", + "eslint-scope": "^3.7.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^3.5.4", + "esquery": "^1.0.0", + "esutils": "^2.0.2", + "file-entry-cache": "^2.0.0", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.0.1", + "ignore": "^3.3.3", + "imurmurhash": "^0.1.4", + "inquirer": "^3.0.6", + "is-resolvable": "^1.0.0", + "js-yaml": "^3.9.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.4", + "minimatch": "^3.0.2", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.2", + "pluralize": "^7.0.0", + "progress": "^2.0.0", + "regexpp": "^1.0.1", + "require-uncached": "^1.0.3", + "semver": "^5.3.0", + "strip-ansi": "^4.0.0", + "strip-json-comments": "~2.0.1", + "table": "4.0.2", + "text-table": "~0.2.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "eslint-config-riot": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-riot/-/eslint-config-riot-1.0.0.tgz", + "integrity": "sha1-+9ZThpgLMPvNDhMF1MP7hhTvIRk=" + }, + "eslint-scope": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", + "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", + "dev": true + }, + "espree": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", + "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", + "dev": true, + "requires": { + "acorn": "^5.5.0", + "acorn-jsx": "^3.0.0" + } + }, + "esprima": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", + "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", + "dev": true + }, + "esquery": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", + "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "dev": true, + "requires": { + "estraverse": "^4.0.0" + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + }, + "estree-walker": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.3.1.tgz", + "integrity": "sha1-5rGlHPcpJSTnI3wxLl/mZgwc4ao=", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "eventemitter3": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz", + "integrity": "sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA==", + "dev": true + }, + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "dev": true, + "requires": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "expand-braces": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/expand-braces/-/expand-braces-0.1.2.tgz", + "integrity": "sha1-SIsdHSRRyz06axks/AMPRMWFX+o=", + "dev": true, + "requires": { + "array-slice": "^0.2.3", + "array-unique": "^0.2.1", + "braces": "^0.1.2" + }, + "dependencies": { + "braces": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-0.1.5.tgz", + "integrity": "sha1-wIVxEIUpHYt1/ddOqw+FlygHEeY=", + "dev": true, + "requires": { + "expand-range": "^0.1.0" + } + }, + "expand-range": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-0.1.1.tgz", + "integrity": "sha1-TLjtoJk8pW+k9B/ELzy7TMrf8EQ=", + "dev": true, + "requires": { + "is-number": "^0.1.1", + "repeat-string": "^0.2.2" + } + }, + "is-number": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-0.1.1.tgz", + "integrity": "sha1-aaevEWlj1HIG7JvZtIoUIW8eOAY=", + "dev": true + }, + "repeat-string": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-0.2.2.tgz", + "integrity": "sha1-x6jTI2BoNiBZp+RlH8aITosftK4=", + "dev": true + } + } + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "requires": { + "is-posix-bracket": "^0.1.0" + } + }, + "expand-range": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "requires": { + "fill-range": "^2.1.0" + } + }, + "extend": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", + "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", + "dev": true + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "external-editor": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", + "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", + "dev": true, + "requires": { + "chardet": "^0.4.0", + "iconv-lite": "^0.4.17", + "tmp": "^0.0.33" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "requires": { + "is-extglob": "^1.0.0" + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, + "fast-deep-equal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", + "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "dev": true, + "requires": { + "flat-cache": "^1.2.1", + "object-assign": "^4.0.1" + } + }, + "filename-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=" + }, + "fill-range": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", + "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", + "requires": { + "is-number": "^2.1.0", + "isobject": "^2.0.0", + "randomatic": "^3.0.0", + "repeat-element": "^1.1.2", + "repeat-string": "^1.5.2" + }, + "dependencies": { + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + }, + "randomatic": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.0.0.tgz", + "integrity": "sha512-VdxFOIEY3mNO5PtSRkkle/hPJDHvQhK21oa73K4yAc9qmp6N429gAyF1gZMOTMeS0/AYzaV/2Trcef+NaIonSA==", + "requires": { + "is-number": "^4.0.0", + "kind-of": "^6.0.0", + "math-random": "^1.0.1" + }, + "dependencies": { + "is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==" + } + } + } + } + }, + "finalhandler": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz", + "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=", + "dev": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.1", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "statuses": "~1.3.1", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "statuses": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", + "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", + "dev": true + } + } + }, + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "flat-cache": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", + "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", + "dev": true, + "requires": { + "circular-json": "^0.3.1", + "del": "^2.0.2", + "graceful-fs": "^4.1.2", + "write": "^0.2.1" + } + }, + "follow-redirects": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.0.tgz", + "integrity": "sha512-fdrt472/9qQ6Kgjvb935ig6vJCuofpBUD14f9Vb+SLlm7xIe4Qva5gey8EKtv8lp7ahE1wilg3xL1znpVGtZIA==", + "dev": true, + "requires": { + "debug": "^3.1.0" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" + }, + "for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "requires": { + "for-in": "^1.0.1" + } + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "fs-access": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fs-access/-/fs-access-1.0.1.tgz", + "integrity": "sha1-1qh/JiJxzv6+wwxVNAf7mV2od3o=", + "dev": true, + "requires": { + "null-check": "^1.0.0" + } + }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz", + "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==", + "optional": true, + "requires": { + "nan": "^2.9.2", + "node-pre-gyp": "^0.10.0" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.4", + "bundled": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.0.1", + "bundled": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "debug": { + "version": "2.6.9", + "bundled": true, + "optional": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-extend": { + "version": "0.5.1", + "bundled": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.5", + "bundled": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.2", + "bundled": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.21", + "bundled": true, + "optional": true, + "requires": { + "safer-buffer": "^2.1.0" + } + }, + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true + }, + "minipass": { + "version": "2.2.4", + "bundled": true, + "requires": { + "safe-buffer": "^5.1.1", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.1.0", + "bundled": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "bundled": true, + "optional": true + }, + "needle": { + "version": "2.2.0", + "bundled": true, + "optional": true, + "requires": { + "debug": "^2.1.2", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.10.0", + "bundled": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.0", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.1.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.3", + "bundled": true, + "optional": true + }, + "npm-packlist": { + "version": "1.1.10", + "bundled": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true, + "optional": true + }, + "rc": { + "version": "1.2.7", + "bundled": true, + "optional": true, + "requires": { + "deep-extend": "^0.5.1", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.6.2", + "bundled": true, + "optional": true, + "requires": { + "glob": "^7.0.5" + } + }, + "safe-buffer": { + "version": "5.1.1", + "bundled": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "optional": true + }, + "semver": { + "version": "5.5.0", + "bundled": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "optional": true + }, + "tar": { + "version": "4.4.1", + "bundled": true, + "optional": true, + "requires": { + "chownr": "^1.0.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.2.4", + "minizlib": "^1.1.0", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.1", + "yallist": "^3.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "wide-align": { + "version": "1.1.2", + "bundled": true, + "optional": true, + "requires": { + "string-width": "^1.0.2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true + }, + "yallist": { + "version": "3.0.2", + "bundled": true + } + } + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "get-caller-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", + "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=", + "dev": true + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "dev": true + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "requires": { + "glob-parent": "^2.0.0", + "is-glob": "^2.0.0" + } + }, + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "requires": { + "is-glob": "^2.0.0" + } + }, + "globals": { + "version": "11.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.4.0.tgz", + "integrity": "sha512-Dyzmifil8n/TmSqYDEXbm+C8yitzJQqQIlJQLNRMwa+BOUJpRC19pyVeN12JAjt61xonvXjtff+hJruTRXn5HA==", + "dev": true + }, + "globby": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", + "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "arrify": "^1.0.0", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" + }, + "growl": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", + "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", + "dev": true + }, + "handlebars": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.11.tgz", + "integrity": "sha1-Ywo13+ApS8KB7a5v/F0yn8eYLcw=", + "dev": true, + "requires": { + "async": "^1.4.0", + "optimist": "^0.6.1", + "source-map": "^0.4.4", + "uglify-js": "^2.6" + }, + "dependencies": { + "camelcase": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", + "dev": true, + "optional": true + }, + "cliui": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", + "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", + "dev": true, + "optional": true, + "requires": { + "center-align": "^0.1.1", + "right-align": "^0.1.1", + "wordwrap": "0.0.2" + } + }, + "source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "dev": true, + "requires": { + "amdefine": ">=0.0.4" + } + }, + "uglify-js": { + "version": "2.8.29", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", + "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", + "dev": true, + "optional": true, + "requires": { + "source-map": "~0.5.1", + "uglify-to-browserify": "~1.0.0", + "yargs": "~3.10.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "optional": true + } + } + }, + "window-size": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", + "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", + "dev": true, + "optional": true + }, + "wordwrap": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", + "dev": true, + "optional": true + }, + "yargs": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "dev": true, + "optional": true, + "requires": { + "camelcase": "^1.0.2", + "cliui": "^2.1.0", + "decamelize": "^1.0.0", + "window-size": "0.1.0" + } + } + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true + }, + "har-validator": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.0.tgz", + "integrity": "sha512-+qnmNjI4OfH2ipQ9VQOw23bBd/ibtfbVdK2fYbY4acTDqKTW/YDp9McimZdDbG8iV9fZizUqQMD5xvriB146TA==", + "dev": true, + "requires": { + "ajv": "^5.3.0", + "har-schema": "^2.0.0" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-binary2": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", + "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", + "dev": true, + "requires": { + "isarray": "2.0.1" + }, + "dependencies": { + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", + "dev": true + } + } + }, + "has-cors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", + "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hawk": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", + "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", + "dev": true, + "requires": { + "boom": "4.x.x", + "cryptiles": "3.x.x", + "hoek": "4.x.x", + "sntp": "2.x.x" + } + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true + }, + "hoek": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", + "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==", + "dev": true + }, + "hosted-git-info": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.6.0.tgz", + "integrity": "sha512-lIbgIIQA3lz5XaB6vxakj6sDHADJiZadYEJB+FgA+C4nubM1NwcuvUr9EJPmnH1skZqpqUzWborWo8EIUi0Sdw==", + "dev": true + }, + "html-encoding-sniffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", + "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", + "dev": true, + "requires": { + "whatwg-encoding": "^1.0.1" + } + }, + "htmlparser2": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.9.2.tgz", + "integrity": "sha1-G9+HrMoPP55T+k/M6w9LTLsAszg=", + "dev": true, + "requires": { + "domelementtype": "^1.3.0", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^2.0.2" + } + }, + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "http-proxy": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz", + "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==", + "dev": true, + "requires": { + "eventemitter3": "^3.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "iconv-lite": { + "version": "0.4.21", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.21.tgz", + "integrity": "sha512-En5V9za5mBt2oUA03WGD3TwDv0MKAruqsuxstbMUZaj9W9k/m1CV/9py3l0L5kw9Bln8fdHQmzHSYtvpvTLpKw==", + "dev": true, + "requires": { + "safer-buffer": "^2.1.0" + } + }, + "ieee754": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz", + "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==", + "dev": true + }, + "ignore": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz", + "integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==", + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "dev": true, + "requires": { + "repeating": "^2.0.0" + } + }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "inquirer": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", + "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", + "dev": true, + "requires": { + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.0", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^2.0.4", + "figures": "^2.0.0", + "lodash": "^4.3.0", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rx-lite": "^4.0.8", + "rx-lite-aggregates": "^4.0.8", + "string-width": "^2.1.0", + "strip-ansi": "^4.0.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "dev": true + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "is-builtin-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "dev": true, + "requires": { + "builtin-modules": "^1.0.0" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-dotfile": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", + "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=" + }, + "is-equal-shallow": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "requires": { + "is-primitive": "^2.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" + }, + "is-finite": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", + "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "requires": { + "is-extglob": "^1.0.0" + } + }, + "is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", + "dev": true + }, + "is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-odd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-odd/-/is-odd-2.0.0.tgz", + "integrity": "sha512-OTiixgpZAT1M4NHgS5IguFp/Vz2VI3U7Goh4/HA1adtwyLtSBrxYlcSYkhpAE07s4fKEcjrFxyvtQBND4vFQyQ==", + "dev": true, + "requires": { + "is-number": "^4.0.0" + }, + "dependencies": { + "is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", + "dev": true + } + } + }, + "is-path-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", + "dev": true + }, + "is-path-in-cwd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", + "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", + "dev": true, + "requires": { + "is-path-inside": "^1.0.0" + } + }, + "is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "dev": true, + "requires": { + "path-is-inside": "^1.0.1" + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "is-posix-bracket": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=" + }, + "is-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=" + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "is-resolvable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isbinaryfile": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.2.tgz", + "integrity": "sha1-Sj6XTsDLqQBNP8bN5yCeppNopiE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "requires": { + "isarray": "1.0.0" + } + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "istanbul": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/istanbul/-/istanbul-0.4.5.tgz", + "integrity": "sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs=", + "dev": true, + "requires": { + "abbrev": "1.0.x", + "async": "1.x", + "escodegen": "1.8.x", + "esprima": "2.7.x", + "glob": "^5.0.15", + "handlebars": "^4.0.1", + "js-yaml": "3.x", + "mkdirp": "0.5.x", + "nopt": "3.x", + "once": "1.x", + "resolve": "1.1.x", + "supports-color": "^3.1.0", + "which": "^1.1.1", + "wordwrap": "^1.0.0" + }, + "dependencies": { + "esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "dev": true + }, + "glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dev": true, + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "requires": { + "has-flag": "^1.0.0" + } + } + } + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "js-yaml": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.11.0.tgz", + "integrity": "sha512-saJstZWv7oNeOyBh3+Dx1qWzhW0+e6/8eDzo7p5rDFqxntSztloLtuKu+Ejhtq82jsilwOIZYsCz+lIjthg1Hw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "jsdom": { + "version": "11.10.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.10.0.tgz", + "integrity": "sha512-x5No5FpJgBg3j5aBwA8ka6eGuS5IxbC8FOkmyccKvObtFT0bDMict/LOxINZsZGZSfGdNomLZ/qRV9Bpq/GIBA==", + "dev": true, + "requires": { + "abab": "^1.0.4", + "acorn": "^5.3.0", + "acorn-globals": "^4.1.0", + "array-equal": "^1.0.0", + "cssom": ">= 0.3.2 < 0.4.0", + "cssstyle": ">= 0.2.37 < 0.3.0", + "data-urls": "^1.0.0", + "domexception": "^1.0.0", + "escodegen": "^1.9.0", + "html-encoding-sniffer": "^1.0.2", + "left-pad": "^1.2.0", + "nwmatcher": "^1.4.3", + "parse5": "4.0.0", + "pn": "^1.1.0", + "request": "^2.83.0", + "request-promise-native": "^1.0.5", + "sax": "^1.2.4", + "symbol-tree": "^3.2.2", + "tough-cookie": "^2.3.3", + "w3c-hr-time": "^1.0.1", + "webidl-conversions": "^4.0.2", + "whatwg-encoding": "^1.0.3", + "whatwg-mimetype": "^2.1.0", + "whatwg-url": "^6.4.0", + "ws": "^4.0.0", + "xml-name-validator": "^3.0.0" + }, + "dependencies": { + "escodegen": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.9.1.tgz", + "integrity": "sha512-6hTjO1NAWkHnDk3OqQ4YrCuwwmGHL9S3nPlzBOUG/R44rda3wLNrfvQ5fkSGjyhHFKM7ALPKcKGrwvCLe0lC7Q==", + "dev": true, + "requires": { + "esprima": "^3.1.3", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + } + }, + "esprima": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", + "dev": true + }, + "parse5": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", + "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", + "dev": true + } + } + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "just-extend": { + "version": "1.1.27", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-1.1.27.tgz", + "integrity": "sha512-mJVp13Ix6gFo3SBAy9U/kL+oeZqzlYYYLQBwXVBlVzIsZwBqGREnOro24oC/8s8aox+rJhtZ2DiQof++IrkA+g==", + "dev": true + }, + "karma": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/karma/-/karma-3.0.0.tgz", + "integrity": "sha512-ZTjyuDXVXhXsvJ1E4CnZzbCjSxD6sEdzEsFYogLuZM0yqvg/mgz+O+R1jb0J7uAQeuzdY8kJgx6hSNXLwFuHIQ==", + "dev": true, + "requires": { + "bluebird": "^3.3.0", + "body-parser": "^1.16.1", + "chokidar": "^2.0.3", + "colors": "^1.1.0", + "combine-lists": "^1.0.0", + "connect": "^3.6.0", + "core-js": "^2.2.0", + "di": "^0.0.1", + "dom-serialize": "^2.2.0", + "expand-braces": "^0.1.1", + "glob": "^7.1.1", + "graceful-fs": "^4.1.2", + "http-proxy": "^1.13.0", + "isbinaryfile": "^3.0.0", + "lodash": "^4.17.4", + "log4js": "^3.0.0", + "mime": "^2.3.1", + "minimatch": "^3.0.2", + "optimist": "^0.6.1", + "qjobs": "^1.1.4", + "range-parser": "^1.2.0", + "rimraf": "^2.6.0", + "safe-buffer": "^5.0.1", + "socket.io": "2.1.1", + "source-map": "^0.6.1", + "tmp": "0.0.33", + "useragent": "2.2.1" + }, + "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "bluebird": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", + "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==", + "dev": true + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "chokidar": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.3.tgz", + "integrity": "sha512-zW8iXYZtXMx4kux/nuZVXjkLP+CyIK5Al5FHnj1OgTKGZfp4Oy6/ymtMSKFv3GD8DviEmUPmJg9eFdJ/JzudMg==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.0", + "braces": "^2.3.0", + "fsevents": "^1.1.2", + "glob-parent": "^3.1.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^2.1.1", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0", + "upath": "^1.0.0" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-glob": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", + "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + } + } + }, + "karma-chrome-launcher": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-2.2.0.tgz", + "integrity": "sha512-uf/ZVpAabDBPvdPdveyk1EPgbnloPvFFGgmRhYLTDH7gEB4nZdSBk8yTU47w1g/drLSx5uMOkjKk7IWKfWg/+w==", + "dev": true, + "requires": { + "fs-access": "^1.0.0", + "which": "^1.2.1" + } + }, + "karma-coverage": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/karma-coverage/-/karma-coverage-1.1.2.tgz", + "integrity": "sha512-eQawj4Cl3z/CjxslYy9ariU4uDh7cCNFZHNWXWRpl0pNeblY/4wHR7M7boTYXWrn9bY0z2pZmr11eKje/S/hIw==", + "dev": true, + "requires": { + "dateformat": "^1.0.6", + "istanbul": "^0.4.0", + "lodash": "^4.17.0", + "minimatch": "^3.0.0", + "source-map": "^0.5.1" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "karma-mocha": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/karma-mocha/-/karma-mocha-1.3.0.tgz", + "integrity": "sha1-7qrH/8DiAetjxGdEDStpx883eL8=", + "dev": true, + "requires": { + "minimist": "1.2.0" + } + }, + "karma-rollup-preprocessor": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/karma-rollup-preprocessor/-/karma-rollup-preprocessor-6.0.0.tgz", + "integrity": "sha512-oXs18fMcWFm62J86VNZ3hmFo0rizb07j7bc7lTPmm8P35uyi8B2JRR1n+82qDk7f/Pl1HoGHJeJ2WXl2DcVzfA==", + "dev": true, + "requires": { + "chokidar": "^2.0.0" + }, + "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "chokidar": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.3.tgz", + "integrity": "sha512-zW8iXYZtXMx4kux/nuZVXjkLP+CyIK5Al5FHnj1OgTKGZfp4Oy6/ymtMSKFv3GD8DviEmUPmJg9eFdJ/JzudMg==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.0", + "braces": "^2.3.0", + "fsevents": "^1.1.2", + "glob-parent": "^3.1.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^2.1.1", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0", + "upath": "^1.0.0" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-glob": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", + "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + } + } + }, + "karma-sauce-launcher": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/karma-sauce-launcher/-/karma-sauce-launcher-1.2.0.tgz", + "integrity": "sha512-lEhtGRGS+3Yw6JSx/vJY9iQyHNtTjcojrSwNzqNUOaDceKDu9dPZqA/kr69bUO9G2T6GKbu8AZgXqy94qo31Jg==", + "dev": true, + "requires": { + "q": "^1.5.0", + "sauce-connect-launcher": "^1.2.2", + "saucelabs": "^1.4.0", + "wd": "^1.4.0" + }, + "dependencies": { + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + "dev": true + } + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + }, + "lazy-cache": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", + "dev": true, + "optional": true + }, + "lazystream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", + "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", + "dev": true, + "requires": { + "readable-stream": "^2.0.5" + } + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "dev": true, + "requires": { + "invert-kv": "^1.0.0" + } + }, + "lcov-parse": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-0.0.10.tgz", + "integrity": "sha1-GwuP+ayceIklBYK3C3ExXZ2m2aM=", + "dev": true + }, + "left-pad": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz", + "integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==", + "dev": true + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "dependencies": { + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + } + } + }, + "lodash": { + "version": "4.17.5", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz", + "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==", + "dev": true + }, + "lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", + "dev": true + }, + "lodash.every": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.every/-/lodash.every-4.6.0.tgz", + "integrity": "sha1-64mYS+vENkJ5uzrvu9HKGb+mxqc=" + }, + "lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=" + }, + "lodash.foreach": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz", + "integrity": "sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM=" + }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "dev": true + }, + "lodash.map": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", + "integrity": "sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=" + }, + "lodash.maxby": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.maxby/-/lodash.maxby-4.6.0.tgz", + "integrity": "sha1-CCJABo88eiJ6oAqDgOTzjPB4bj0=" + }, + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", + "dev": true + }, + "log-driver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", + "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==", + "dev": true + }, + "log4js": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-3.0.5.tgz", + "integrity": "sha512-IX5c3G/7fuTtdr0JjOT2OIR12aTESVhsH6cEsijloYwKgcPRlO6DgOU72v0UFhWcoV1HN6+M3dwT89qVPLXm0w==", + "dev": true, + "requires": { + "circular-json": "^0.5.5", + "date-format": "^1.2.0", + "debug": "^3.1.0", + "rfdc": "^1.1.2", + "streamroller": "0.7.0" + }, + "dependencies": { + "circular-json": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.5.5.tgz", + "integrity": "sha512-13YaR6kiz0kBNmIVM87Io8Hp7bWOo4r61vkEANy8iH9R9bc6avud/1FT0SBpqR1RpIQADOh/Q+yHZDA1iL6ysA==", + "dev": true + } + } + }, + "lolex": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.3.2.tgz", + "integrity": "sha512-A5pN2tkFj7H0dGIAM6MFvHKMJcPnjZsOMvR7ujCjfgW5TbV6H9vb1PgxLtHvjqNZTHsUolz+6/WEO0N1xNx2ng==", + "dev": true + }, + "longest": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", + "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", + "dev": true + }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "dev": true, + "requires": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" + } + }, + "lru-cache": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.2.tgz", + "integrity": "sha512-wgeVXhrDwAWnIF/yZARsFnMBtdFXOg1b8RIrhilp+0iDYN4mdQcNZElDZ0e4B64BhaxeQ5zN7PMyvu7we1kPeQ==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "magic-string": { + "version": "0.22.5", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.22.5.tgz", + "integrity": "sha512-oreip9rJZkzvA8Qzk9HFs8fZGF/u7H/gtrE8EN6RjKJ9kh2HlC+yQ2QezifqTZfGyiuAV0dRv5a+y/8gBb1m9w==", + "dev": true, + "requires": { + "vlq": "^0.2.2" + }, + "dependencies": { + "vlq": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/vlq/-/vlq-0.2.3.tgz", + "integrity": "sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow==", + "dev": true + } + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "math-random": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz", + "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w=" + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true + }, + "mem": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", + "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "dev": true, + "requires": { + "camelcase-keys": "^2.0.0", + "decamelize": "^1.1.2", + "loud-rejection": "^1.0.0", + "map-obj": "^1.0.1", + "minimist": "^1.1.3", + "normalize-package-data": "^2.3.4", + "object-assign": "^4.0.1", + "read-pkg-up": "^1.0.1", + "redent": "^1.0.0", + "trim-newlines": "^1.0.0" + } + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "requires": { + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.2", + "expand-brackets": "^0.1.4", + "extglob": "^0.3.1", + "filename-regex": "^2.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.1", + "kind-of": "^3.0.2", + "normalize-path": "^2.0.1", + "object.omit": "^2.0.0", + "parse-glob": "^3.0.4", + "regex-cache": "^0.4.2" + } + }, + "mime": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.3.1.tgz", + "integrity": "sha512-OEUllcVoydBHGN1z84yfQDimn58pZNNNXgZlHXSboxMlFvgI6MXSWpWKpFRra7H1HxpVhHTkrghfRW49k6yjeg==", + "dev": true + }, + "mime-db": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", + "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", + "dev": true + }, + "mime-types": { + "version": "2.1.18", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", + "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", + "dev": true, + "requires": { + "mime-db": "~1.33.0" + } + }, + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "mixin-deep": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", + "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + } + } + }, + "mocha": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", + "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", + "dev": true, + "requires": { + "browser-stdout": "1.3.0", + "commander": "2.11.0", + "debug": "3.1.0", + "diff": "3.3.1", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.3", + "he": "1.1.1", + "mkdirp": "0.5.1", + "supports-color": "4.4.0" + }, + "dependencies": { + "commander": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", + "dev": true + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "^2.0.0" + } + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true + }, + "nan": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", + "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", + "optional": true + }, + "nanomatch": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.9.tgz", + "integrity": "sha512-n8R9bS8yQ6eSXaV6jHUpKzD8gLsin02w1HSFiegwrs9E098Ylhw5jdyKPaYqvHknHaSCKTPp7C8dGCQ0q9koXA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-odd": "^2.0.0", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + } + } + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "negotiator": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", + "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", + "dev": true + }, + "nise": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/nise/-/nise-1.3.2.tgz", + "integrity": "sha512-KPKb+wvETBiwb4eTwtR/OsA2+iijXP+VnlSFYJo3EHjm2yjek1NWxHOUQat3i7xNLm1Bm18UA5j5Wor0yO2GtA==", + "dev": true, + "requires": { + "@sinonjs/formatio": "^2.0.0", + "just-extend": "^1.1.27", + "lolex": "^2.3.2", + "path-to-regexp": "^1.7.0", + "text-encoding": "^0.6.4" + } + }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "dev": true, + "requires": { + "abbrev": "1" + } + }, + "normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "is-builtin-module": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "nth-check": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz", + "integrity": "sha1-mSms32KPwsQQmN6rgqxYDPFJquQ=", + "dev": true, + "requires": { + "boolbase": "~1.0.0" + } + }, + "null-check": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/null-check/-/null-check-1.0.0.tgz", + "integrity": "sha1-l33/1xdgErnsMNKjnbXPcqBDnt0=", + "dev": true + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "nwmatcher": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.4.tgz", + "integrity": "sha512-3iuY4N5dhgMpCUrOVnuAdGrgxVqV2cJpM+XNccjR2DKOB1RUP0aA+wGXEiNziG/UKboFyGBIoKOaNlJxx8bciQ==", + "dev": true + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-component": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", + "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=", + "dev": true + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "object.omit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "requires": { + "for-own": "^0.1.4", + "is-extendable": "^0.1.1" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "dev": true, + "requires": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + }, + "dependencies": { + "minimist": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", + "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", + "dev": true + }, + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "dev": true + } + } + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "os-locale": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", + "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", + "dev": true, + "requires": { + "execa": "^0.7.0", + "lcid": "^1.0.0", + "mem": "^1.1.0" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "p-limit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.0.0.tgz", + "integrity": "sha512-fl5s52lI5ahKCernzzIyAP0QAZbGIovtVHGwpcu1Jr/EpzLVDI2myISHwGqK7m8uQFugVWSrbxH7XnhGtvEc+A==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", + "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==", + "dev": true + }, + "parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "requires": { + "glob-base": "^0.3.0", + "is-dotfile": "^1.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.0" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "parse5": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz", + "integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "parseqs": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", + "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", + "dev": true, + "requires": { + "better-assert": "~1.0.0" + } + }, + "parseuri": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", + "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", + "dev": true, + "requires": { + "better-assert": "~1.0.0" + } + }, + "parseurl": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", + "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=", + "dev": true + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "^2.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", + "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", + "dev": true + }, + "path-to-regexp": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "dev": true, + "requires": { + "isarray": "0.0.1" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + } + } + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "dev": true + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "^2.0.0" + } + }, + "platform": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.5.tgz", + "integrity": "sha512-TuvHS8AOIZNAlE77WUDiR4rySV/VMptyMfcfeoMgs4P8apaZM3JrnbzBiixKUv+XR6i+BXrQh8WAnjaSPFO65Q==", + "dev": true + }, + "pluralize": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", + "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", + "dev": true + }, + "pn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", + "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==", + "dev": true + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" + }, + "preserve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=" + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + }, + "progress": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz", + "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=", + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "psl": { + "version": "1.1.29", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz", + "integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==", + "dev": true + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + }, + "q": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz", + "integrity": "sha1-VXBbzZPF82c1MMLCy8DCs63cKG4=", + "dev": true + }, + "qjobs": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", + "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", + "dev": true + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + }, + "range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=", + "dev": true + }, + "raw-body": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", + "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", + "dev": true, + "requires": { + "bytes": "3.0.0", + "http-errors": "1.6.3", + "iconv-lite": "0.4.23", + "unpipe": "1.0.0" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", + "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + } + } + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true, + "requires": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true, + "requires": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + } + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "readdirp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", + "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", + "requires": { + "graceful-fs": "^4.1.2", + "minimatch": "^3.0.2", + "readable-stream": "^2.0.2", + "set-immediate-shim": "^1.0.1" + } + }, + "redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "dev": true, + "requires": { + "indent-string": "^2.1.0", + "strip-indent": "^1.0.1" + } + }, + "regex-cache": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", + "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", + "requires": { + "is-equal-shallow": "^0.1.3" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "regexpp": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz", + "integrity": "sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw==", + "dev": true + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" + }, + "repeat-element": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", + "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=" + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "dev": true, + "requires": { + "is-finite": "^1.0.0" + } + }, + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "mime-db": { + "version": "1.37.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", + "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==", + "dev": true + }, + "mime-types": { + "version": "2.1.21", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", + "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", + "dev": true, + "requires": { + "mime-db": "~1.37.0" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "dev": true, + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + } + } + } + }, + "request-promise-core": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.1.tgz", + "integrity": "sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY=", + "dev": true, + "requires": { + "lodash": "^4.13.1" + } + }, + "request-promise-native": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.5.tgz", + "integrity": "sha1-UoF3D2jgyXGeUWP9P6tIIhX0/aU=", + "dev": true, + "requires": { + "request-promise-core": "1.1.1", + "stealthy-require": "^1.1.0", + "tough-cookie": ">=2.3.3" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "dev": true + }, + "require-uncached": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "dev": true, + "requires": { + "caller-path": "^0.1.0", + "resolve-from": "^1.0.0" + } + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "dev": true + }, + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + }, + "resolve-from": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", + "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", + "dev": true + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + } + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "rfdc": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.1.2.tgz", + "integrity": "sha512-92ktAgvZhBzYTIK0Mja9uen5q5J3NRVMoDkJL2VMwq6SXjVCgqvQeVP2XAaUY6HT+XpQYeLSjb3UoitBryKmdA==", + "dev": true + }, + "right-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", + "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", + "dev": true, + "optional": true, + "requires": { + "align-text": "^0.1.1" + } + }, + "rimraf": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "dev": true, + "requires": { + "glob": "^7.0.5" + } + }, + "riot-cli": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/riot-cli/-/riot-cli-4.0.2.tgz", + "integrity": "sha512-lOiFgmdjS9GSdQ1ctw+n2yK8kgxMH3I2BL30u2dTfRcvRUmZJoKKOkA36Ri+BCXX4MbPbBuBtbqK7ntBfmNhFw==", + "requires": { + "chalk": "^2.3.0", + "chokidar": "^1.7.0", + "co": "^4.6.0", + "optionator": "^0.8.2", + "riot-compiler": "^3.4.0", + "rollup": "^0.52.1" + }, + "dependencies": { + "rollup": { + "version": "0.52.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-0.52.3.tgz", + "integrity": "sha512-cw+vb9NqaTXlwJyb8G+Ve+uhhlVTcl1NKBkfANdeQqVcpZFilQgeNnAnNiu7MwfeXrqiKEGz+3R03a3zeFkmEQ==" + } + } + }, + "riot-compiler": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/riot-compiler/-/riot-compiler-3.5.2.tgz", + "integrity": "sha512-GGYWxuDy67Votz6UlM1MCZO8b/7FHOqt80OhTi4hjjjJIBh8qD7hDAUT87u2ru+4T3TZBJ2ZEqJF35dXFRUdIw==", + "requires": { + "skip-regex": "^0.3.1", + "source-map": "^0.7.2", + "string-similarity": "^1.2.0" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" + } + } + }, + "riot-observable": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/riot-observable/-/riot-observable-3.0.0.tgz", + "integrity": "sha1-i70tr3KiFBuwQwgt9AI9xQS60us=" + }, + "riot-tmpl": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/riot-tmpl/-/riot-tmpl-3.0.8.tgz", + "integrity": "sha1-3WVOcqOhUgywCcvvcMc4Vt7VhKY=", + "requires": { + "eslint-config-riot": "^1.0.0" + } + }, + "rollup": { + "version": "0.66.6", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-0.66.6.tgz", + "integrity": "sha512-J7/SWanrcb83vfIHqa8+aVVGzy457GcjA6GVZEnD0x2u4OnOd0Q1pCrEoNe8yLwM6z6LZP02zBT2uW0yh5TqOw==", + "dev": true, + "requires": { + "@types/estree": "0.0.39", + "@types/node": "*" + } + }, + "rollup-plugin-alias": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-alias/-/rollup-plugin-alias-1.4.0.tgz", + "integrity": "sha512-lB094zdi19FS+1bVarVp9kBN0Zk41PdTGoCk0z8xesKO7RGjOo18cp1hUzEqrOQ4bM9+KLD9nbnu/XUxQm9pbg==", + "dev": true, + "requires": { + "slash": "^1.0.0" + } + }, + "rollup-plugin-buble": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-buble/-/rollup-plugin-buble-0.19.2.tgz", + "integrity": "sha512-dxK0prR8j/7qhI2EZDz/evKCRuhuZMpRlUGPrRWmpg5/2V8tP1XFW+Uk0WfxyNgFfJHvy0GmxnJSTb5dIaNljQ==", + "dev": true, + "requires": { + "buble": "^0.19.2", + "rollup-pluginutils": "^2.0.1" + } + }, + "rollup-plugin-commonjs": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/rollup-plugin-commonjs/-/rollup-plugin-commonjs-9.1.3.tgz", + "integrity": "sha512-g91ZZKZwTW7F7vL6jMee38I8coj/Q9GBdTmXXeFL7ldgC1Ky5WJvHgbKlAiXXTh762qvohhExwUgeQGFh9suGg==", + "dev": true, + "requires": { + "estree-walker": "^0.5.1", + "magic-string": "^0.22.4", + "resolve": "^1.5.0", + "rollup-pluginutils": "^2.0.1" + }, + "dependencies": { + "estree-walker": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.5.1.tgz", + "integrity": "sha512-7HgCgz1axW7w5aOvgOQkoR1RMBkllygJrssU3BvymKQ95lxXYv6Pon17fBRDm9qhkvXZGijOULoSF9ShOk/ZLg==", + "dev": true + }, + "resolve": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.0.tgz", + "integrity": "sha512-QdgZ5bjR1WAlpLaO5yHepFvC+o3rCr6wpfE2tpJNMkXdulf2jKomQBdNRQITF3ZKHNlT71syG98yQP03gasgnA==", + "dev": true, + "requires": { + "path-parse": "^1.0.5" + } + } + } + }, + "rollup-plugin-node-resolve": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-3.3.0.tgz", + "integrity": "sha512-9zHGr3oUJq6G+X0oRMYlzid9fXicBdiydhwGChdyeNRGPcN/majtegApRKHLR5drboUvEWU+QeUmGTyEZQs3WA==", + "dev": true, + "requires": { + "builtin-modules": "^2.0.0", + "is-module": "^1.0.0", + "resolve": "^1.1.6" + }, + "dependencies": { + "builtin-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-2.0.0.tgz", + "integrity": "sha512-3U5kUA5VPsRUA3nofm/BXX7GVHKfxz0hOBAPxXrIvHzlDRkQVqEn6yi8QJegxl4LzOHLdvb7XF5dVawa/VVYBg==", + "dev": true + } + } + }, + "rollup-plugin-riot": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-riot/-/rollup-plugin-riot-2.0.0.tgz", + "integrity": "sha512-PRx2BHnfM/xjmWvC///y2HTsWxAR1QD4jA50lmEKm4vAeWXIrFl8z1GZJ117DZEGPRDK/VlvgiwgohkPz9YFlw==", + "dev": true, + "requires": { + "magic-string": "^0.22.4", + "object-assign": "^4.1.1", + "rollup-pluginutils": "^2.0.1" + } + }, + "rollup-pluginutils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.0.1.tgz", + "integrity": "sha1-fslbNXP2VDpGpkYb2afFRFJdD8A=", + "dev": true, + "requires": { + "estree-walker": "^0.3.0", + "micromatch": "^2.3.11" + } + }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "dev": true, + "requires": { + "is-promise": "^2.1.0" + } + }, + "rx-lite": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", + "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", + "dev": true + }, + "rx-lite-aggregates": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", + "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", + "dev": true, + "requires": { + "rx-lite": "*" + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "samsam": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.3.0.tgz", + "integrity": "sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg==", + "dev": true + }, + "sauce-connect-launcher": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sauce-connect-launcher/-/sauce-connect-launcher-1.2.4.tgz", + "integrity": "sha512-X2vfwulR6brUGiicXKxPm1GJ7dBEeP1II450Uv4bHGrcGOapZNgzJvn9aioea5IC5BPp/7qjKdE3xbbTBIVXMA==", + "dev": true, + "requires": { + "adm-zip": "~0.4.3", + "async": "^2.1.2", + "https-proxy-agent": "^2.2.1", + "lodash": "^4.16.6", + "rimraf": "^2.5.4" + }, + "dependencies": { + "agent-base": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.0.tgz", + "integrity": "sha512-c+R/U5X+2zz2+UCrCFv6odQzJdoqI+YecuhnAJLa1zYaMc13zPfwMwZrr91Pd1DYNo/yPRbiM4WVf9whgwFsIg==", + "dev": true, + "requires": { + "es6-promisify": "^5.0.0" + } + }, + "async": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", + "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", + "dev": true, + "requires": { + "lodash": "^4.14.0" + } + }, + "https-proxy-agent": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz", + "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==", + "dev": true, + "requires": { + "agent-base": "^4.1.0", + "debug": "^3.1.0" + } + } + } + }, + "saucelabs": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/saucelabs/-/saucelabs-1.5.0.tgz", + "integrity": "sha512-jlX3FGdWvYf4Q3LFfFWS1QvPg3IGCGWxIc8QBFdPTbpTJnt/v17FHXYVAn7C8sHf1yUXo2c7yIM0isDryfYtHQ==", + "dev": true, + "requires": { + "https-proxy-agent": "^2.2.1" + }, + "dependencies": { + "agent-base": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.0.tgz", + "integrity": "sha512-c+R/U5X+2zz2+UCrCFv6odQzJdoqI+YecuhnAJLa1zYaMc13zPfwMwZrr91Pd1DYNo/yPRbiM4WVf9whgwFsIg==", + "dev": true, + "requires": { + "es6-promisify": "^5.0.0" + } + }, + "https-proxy-agent": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz", + "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==", + "dev": true, + "requires": { + "agent-base": "^4.1.0", + "debug": "^3.1.0" + } + } + } + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "set-immediate-shim": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", + "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=" + }, + "set-value": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", + "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "simple-dom": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/simple-dom/-/simple-dom-1.3.0.tgz", + "integrity": "sha512-RVjr6e80FFGDqDJZeQd4EMwoDLatn4Jy2SfuXecrP1IgG4ZAqkGSokE8LNV5i0kzWR2IM0e257xGN9JS8lxm0Q==" + }, + "simple-html-tokenizer": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/simple-html-tokenizer/-/simple-html-tokenizer-0.5.7.tgz", + "integrity": "sha512-APW9iYbkJ5cijjX4Ljhf3VG8SwYPUJT5gZrwci/wieMabQxWFiV5VwsrP5c6GMRvXKEQMGkAB1d9dvW66dTqpg==" + }, + "sinon": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-4.5.0.tgz", + "integrity": "sha512-trdx+mB0VBBgoYucy6a9L7/jfQOmvGeaKZT4OOJ+lPAtI8623xyGr8wLiE4eojzBS8G9yXbhx42GHUOVLr4X2w==", + "dev": true, + "requires": { + "@sinonjs/formatio": "^2.0.0", + "diff": "^3.1.0", + "lodash.get": "^4.4.2", + "lolex": "^2.2.0", + "nise": "^1.2.0", + "supports-color": "^5.1.0", + "type-detect": "^4.0.5" + } + }, + "sinon-chai": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/sinon-chai/-/sinon-chai-3.0.0.tgz", + "integrity": "sha512-+cqeKiuMZjZs800fRf4kjJR/Pp4p7bYY3ciZHClFNS8tSzJoAcWni/ZUZD8TrfZ+oFRyLiKWX3fTClDATGy5vQ==", + "dev": true + }, + "skip-regex": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/skip-regex/-/skip-regex-0.3.1.tgz", + "integrity": "sha1-F5GarirEzj1h1ed+7diCBsZKohU=" + }, + "slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "dev": true + }, + "slice-ansi": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", + "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + } + } + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + } + }, + "sntp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", + "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", + "dev": true, + "requires": { + "hoek": "4.x.x" + } + }, + "socket.io": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.1.1.tgz", + "integrity": "sha512-rORqq9c+7W0DAK3cleWNSyfv/qKXV99hV4tZe+gGLfBECw3XEhBy7x85F3wypA9688LKjtwO9pX9L33/xQI8yA==", + "dev": true, + "requires": { + "debug": "~3.1.0", + "engine.io": "~3.2.0", + "has-binary2": "~1.0.2", + "socket.io-adapter": "~1.1.0", + "socket.io-client": "2.1.1", + "socket.io-parser": "~3.2.0" + } + }, + "socket.io-adapter": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz", + "integrity": "sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs=", + "dev": true + }, + "socket.io-client": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.1.1.tgz", + "integrity": "sha512-jxnFyhAuFxYfjqIgduQlhzqTcOEQSn+OHKVfAxWaNWa7ecP7xSNk2Dx/3UEsDcY7NcFafxvNvKPmmO7HTwTxGQ==", + "dev": true, + "requires": { + "backo2": "1.0.2", + "base64-arraybuffer": "0.1.5", + "component-bind": "1.0.0", + "component-emitter": "1.2.1", + "debug": "~3.1.0", + "engine.io-client": "~3.2.0", + "has-binary2": "~1.0.2", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "object-component": "0.0.3", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "socket.io-parser": "~3.2.0", + "to-array": "0.1.4" + } + }, + "socket.io-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.2.0.tgz", + "integrity": "sha512-FYiBx7rc/KORMJlgsXysflWx/RIvtqZbyGLlHZvjfmPTPeuD/I8MaW7cfFrj5tRltICJdgwflhfZ3NVVbVLFQA==", + "dev": true, + "requires": { + "component-emitter": "1.2.1", + "debug": "~3.1.0", + "isarray": "2.0.1" + }, + "dependencies": { + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", + "dev": true + } + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-resolve": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.1.tgz", + "integrity": "sha512-0KW2wvzfxm8NCTb30z0LMNyPqWCdDGE2viwzUaucqJdkTRXtZiSY3I+2A6nVAjmdOy0I4gU8DwnVVGsk9jvP2A==", + "dev": true, + "requires": { + "atob": "^2.0.0", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "spdx-correct": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", + "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz", + "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz", + "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==", + "dev": true + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.15.2.tgz", + "integrity": "sha512-Ra/OXQtuh0/enyl4ETZAfTaeksa6BXks5ZcjpSUNrjBr0DvrJKX+1fsKDPpT9TBXgHAFsa4510aNVgI8g/+SzA==", + "dev": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true + }, + "stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "dev": true + }, + "streamroller": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-0.7.0.tgz", + "integrity": "sha512-WREzfy0r0zUqp3lGO096wRuUp7ho1X6uo/7DJfTlEi0Iv/4gT7YHqXDjKC2ioVGBZtE8QzsQD9nx1nIuoZ57jQ==", + "dev": true, + "requires": { + "date-format": "^1.2.0", + "debug": "^3.1.0", + "mkdirp": "^0.5.1", + "readable-stream": "^2.3.0" + } + }, + "string-similarity": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/string-similarity/-/string-similarity-1.2.2.tgz", + "integrity": "sha512-IoHUjcw3Srl8nsPlW04U3qwWPk3oG2ffLM0tN853d/E/JlIvcmZmDY2Kz5HzKp4lEi2T7QD7Zuvjq/1rDw+XcQ==", + "requires": { + "lodash.every": "^4.6.0", + "lodash.flattendeep": "^4.4.0", + "lodash.foreach": "^4.5.0", + "lodash.map": "^4.6.0", + "lodash.maxby": "^4.6.0" + } + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "stringstream": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.6.tgz", + "integrity": "sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA==", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "^0.2.0" + } + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "dev": true, + "requires": { + "get-stdin": "^4.0.1" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "supports-color": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz", + "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "symbol-tree": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz", + "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=", + "dev": true + }, + "table": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", + "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", + "dev": true, + "requires": { + "ajv": "^5.2.3", + "ajv-keywords": "^2.1.0", + "chalk": "^2.1.0", + "lodash": "^4.17.4", + "slice-ansi": "1.0.0", + "string-width": "^2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "tar-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", + "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", + "dev": true, + "requires": { + "bl": "^1.0.0", + "buffer-alloc": "^1.2.0", + "end-of-stream": "^1.0.0", + "fs-constants": "^1.0.0", + "readable-stream": "^2.3.0", + "to-buffer": "^1.1.1", + "xtend": "^4.0.0" + } + }, + "text-encoding": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", + "integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=", + "dev": true + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "to-array": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", + "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=", + "dev": true + }, + "to-buffer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", + "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==", + "dev": true + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + } + } + }, + "tough-cookie": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", + "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", + "dev": true, + "requires": { + "punycode": "^1.4.1" + } + }, + "tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", + "dev": true, + "requires": { + "punycode": "^2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", + "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=", + "dev": true + } + } + }, + "trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", + "dev": true + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "type-is": { + "version": "1.6.16", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", + "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", + "dev": true, + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.18" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "uglify-js": { + "version": "3.4.9", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz", + "integrity": "sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q==", + "dev": true, + "requires": { + "commander": "~2.17.1", + "source-map": "~0.6.1" + } + }, + "uglify-to-browserify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", + "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", + "dev": true, + "optional": true + }, + "ultron": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", + "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", + "dev": true + }, + "union-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", + "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^0.4.3" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "set-value": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", + "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.1", + "to-object-path": "^0.3.0" + } + } + } + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + } + } + }, + "upath": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.0.4.tgz", + "integrity": "sha512-d4SJySNBXDaQp+DPrziv3xGS6w3d2Xt69FijJr86zMPBy23JEloMCEOUBBzuN7xCtjLCnmB9tI/z7SBCahHBOw==", + "dev": true + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "use": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.0.tgz", + "integrity": "sha512-6UJEQM/L+mzC3ZJNM56Q4DFGLX/evKGRg15UJHGB9X5j5Z3AFbgZvjUh2yq/UJUY4U5dh7Fal++XbNg1uzpRAw==", + "dev": true, + "requires": { + "kind-of": "^6.0.2" + }, + "dependencies": { + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + } + } + }, + "useragent": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/useragent/-/useragent-2.2.1.tgz", + "integrity": "sha1-z1k+9PLRdYdei7ZY6pLhik/QbY4=", + "dev": true, + "requires": { + "lru-cache": "2.2.x", + "tmp": "0.0.x" + }, + "dependencies": { + "lru-cache": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.2.4.tgz", + "integrity": "sha1-bGWGGb7PFAMdDQtZSxYELOTcBj0=", + "dev": true + } + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "dev": true + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz", + "integrity": "sha512-63ZOUnL4SIXj4L0NixR3L1lcjO38crAbgrTpl28t8jjrfuiOBL5Iygm+60qPs/KsZGzPNg6Smnc/oY16QTjF0g==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "vargs": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/vargs/-/vargs-0.1.0.tgz", + "integrity": "sha1-a2GE2mUgzDIEzhtAfKwm2SYJ6/8=", + "dev": true + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "vlq": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/vlq/-/vlq-1.0.0.tgz", + "integrity": "sha512-o3WmXySo+oI5thgqr7Qy8uBkT/v9Zr+sRyrh1lr8aWPUkgDWdWt4Nae2WKBrLsocgE8BuWWD0jLc+VW8LeU+2g==", + "dev": true + }, + "void-elements": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", + "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=", + "dev": true + }, + "w3c-hr-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz", + "integrity": "sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=", + "dev": true, + "requires": { + "browser-process-hrtime": "^0.1.2" + } + }, + "wd": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/wd/-/wd-1.11.0.tgz", + "integrity": "sha512-h2EBfJvmsWocIjOOg5BsHh9IJKrqZDG4Az4jEZhFugEH7sOPcX6feZQ30aFuktqDI0jquarZJmNpA6V0A0Q7Mg==", + "dev": true, + "requires": { + "archiver": "2.1.1", + "async": "2.0.1", + "lodash": "4.17.10", + "mkdirp": "^0.5.1", + "q": "1.4.1", + "request": "2.85.0", + "vargs": "0.1.0" + }, + "dependencies": { + "async": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/async/-/async-2.0.1.tgz", + "integrity": "sha1-twnMAoCpw28J9FNr6CPIOKkEniU=", + "dev": true, + "requires": { + "lodash": "^4.8.0" + } + }, + "har-validator": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", + "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", + "dev": true, + "requires": { + "ajv": "^5.1.0", + "har-schema": "^2.0.0" + } + }, + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + }, + "oauth-sign": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", + "dev": true + }, + "request": { + "version": "2.85.0", + "resolved": "http://registry.npmjs.org/request/-/request-2.85.0.tgz", + "integrity": "sha512-8H7Ehijd4js+s6wuVPLjwORxD4zeuyjYugprdOXlPSqaApmL/QOy+EB/beICHVCHkGMKNh5rvihb5ov+IDw4mg==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.6.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.5", + "extend": "~3.0.1", + "forever-agent": "~0.6.1", + "form-data": "~2.3.1", + "har-validator": "~5.0.3", + "hawk": "~6.0.2", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.17", + "oauth-sign": "~0.8.2", + "performance-now": "^2.1.0", + "qs": "~6.5.1", + "safe-buffer": "^5.1.1", + "stringstream": "~0.0.5", + "tough-cookie": "~2.3.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.1.0" + } + } + } + }, + "webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "dev": true + }, + "whatwg-encoding": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.3.tgz", + "integrity": "sha512-jLBwwKUhi8WtBfsMQlL4bUUcT8sMkAtQinscJAe/M4KHCkHuUJAF6vuB0tueNIw4c8ziO6AkRmgY+jL3a0iiPw==", + "dev": true, + "requires": { + "iconv-lite": "0.4.19" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", + "dev": true + } + } + }, + "whatwg-mimetype": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.1.0.tgz", + "integrity": "sha512-FKxhYLytBQiUKjkYteN71fAUA3g6KpNXoho1isLiLSB3N1G4F35Q5vUxWfKFhBwi5IWF27VE6WxhrnnC+m0Mew==", + "dev": true + }, + "whatwg-url": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.4.1.tgz", + "integrity": "sha512-FwygsxsXx27x6XXuExA/ox3Ktwcbf+OAvrKmLulotDAiO1Q6ixchPFaHYsis2zZBZSJTR0+dR+JVtf7MlbqZjw==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "which": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", + "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", + "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } + }, + "ws": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-4.1.0.tgz", + "integrity": "sha512-ZGh/8kF9rrRNffkLFV4AzhvooEclrOH0xaugmqGsIfFgOE/pIz4fMc4Ef+5HSQqTEug2S9JZIWDR47duDSLfaA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0" + } + }, + "xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", + "dev": true + }, + "xmlhttprequest-ssl": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", + "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=", + "dev": true + }, + "xregexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.0.0.tgz", + "integrity": "sha512-PHyM+sQouu7xspQQwELlGwwd05mXUFqwFYfqPO0cC7x4fxyHnnuetmQr6CjJiafIDoH4MogHb9dOoJzR/Y4rFg==", + "dev": true + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "yargs": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.1.tgz", + "integrity": "sha512-B0vRAp1hRX4jgIOWFtjfNjd9OA9RWYZ6tqGA9/I/IrTMsxmKvtWy+ersM+jzpQqbC3YfLzeABPdeTgcJ9eu1qQ==", + "dev": true, + "requires": { + "cliui": "^4.0.0", + "decamelize": "^2.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^1.0.1", + "os-locale": "^2.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1 || ^4.0.0", + "yargs-parser": "^10.1.0" + }, + "dependencies": { + "decamelize": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-2.0.0.tgz", + "integrity": "sha512-Ikpp5scV3MSYxY39ymh45ZLEecsTdv/Xj2CaQfI8RLMuwi7XvjX9H/fhraiSuU+C5w5NTDu4ZU72xNiZnurBPg==", + "dev": true, + "requires": { + "xregexp": "4.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + } + } + }, + "yargs-parser": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", + "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", + "dev": true, + "requires": { + "camelcase": "^4.1.0" + }, + "dependencies": { + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + } + } + }, + "yeast": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", + "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=", + "dev": true + }, + "zip-stream": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-1.2.0.tgz", + "integrity": "sha1-qLxF9MG0lpnGuQGYuqyqzbzUugQ=", + "dev": true, + "requires": { + "archiver-utils": "^1.3.0", + "compress-commons": "^1.2.0", + "lodash": "^4.8.0", + "readable-stream": "^2.0.0" + } + } + } +} ADDED public/riot-3.13.2/package.json Index: public/riot-3.13.2/package.json ================================================================== --- public/riot-3.13.2/package.json +++ public/riot-3.13.2/package.json @@ -0,0 +1,99 @@ +{ + "name": "riot", + "version": "3.13.2", + "description": "Simple and elegant component-based UI library", + "homepage": "http://riot.js.org/", + "repository": "riot/riot", + "author": "Riot maintainers team + smart people from all over the world", + "contributors": [ + "Gianluca Guarini https://github.com/GianlucaGuarini" + ], + "license": "MIT", + "engines": { + "node": ">=4.0.0" + }, + "scripts": { + "test": "make riot" + }, + "keywords": [ + "custom tags", + "custom elements", + "web components", + "virtual dom", + "shadow dom", + "minimal", + "simple", + "easy", + "dom", + "minimalist", + "client-side", + "framework", + "declarative", + "templating", + "template", + "data binding", + "mvc", + "model", + "view", + "controller", + "riotjs", + "riot.js" + ], + "dependencies": { + "riot-cli": "^4.0.2", + "riot-compiler": "^3.5.2", + "riot-observable": "^3.0.0", + "riot-tmpl": "^3.0.8", + "simple-dom": "1.3.0", + "simple-html-tokenizer": "^0.5.7" + }, + "devDependencies": { + "benchmark": "^2.1.4", + "chai": "^4.1.2", + "cheerio": "^1.0.0-rc.2", + "chokidar-cli": "^1.2.1", + "coveralls": "^3.0.2", + "eslint": "^4.19.1", + "eslint-config-riot": "^1.0.0", + "glob": "^7.1.2", + "istanbul": "^0.4.5", + "jsdom": "^11.10.0", + "karma": "^3.0.0", + "karma-chrome-launcher": "^2.2.0", + "karma-coverage": "^1.1.2", + "karma-mocha": "^1.3.0", + "karma-rollup-preprocessor": "^6.0.0", + "karma-sauce-launcher": "^1.2.0", + "mocha": "^4.1.0", + "rollup": "^0.66.6", + "rollup-plugin-alias": "1.4.0", + "rollup-plugin-buble": "^0.19.2", + "rollup-plugin-commonjs": "^9.1.3", + "rollup-plugin-node-resolve": "^3.3.0", + "rollup-plugin-riot": "^2.0.0", + "sinon": "^4.5.0", + "sinon-chai": "^3.0.0", + "uglify-js": "^3.4.9" + }, + "preferGlobal": true, + "directories": { + "bin": "bin", + "lib": "lib" + }, + "files": [ + "lib", + "bin", + "riot.js", + "riot.min.js", + "riot.csp.js", + "riot+compiler.js", + "riot+compiler.min.js" + ], + "bin": { + "riot": "bin/index.js" + }, + "main": "lib/server/index.js", + "module": "lib/riot.js", + "jsnext:main": "lib/riot.js", + "browser": "riot.js" +} ADDED public/riot-3.13.2/riot+compiler.js Index: public/riot-3.13.2/riot+compiler.js ================================================================== --- public/riot-3.13.2/riot+compiler.js +++ public/riot-3.13.2/riot+compiler.js @@ -0,0 +1,4130 @@ +/* Riot v3.13.2, @license MIT */ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global.riot = factory()); +}(this, (function () { 'use strict'; + + /** + * Shorter and fast way to select a single node in the DOM + * @param { String } selector - unique dom selector + * @param { Object } ctx - DOM node where the target of our search will is located + * @returns { Object } dom node found + */ + function $(selector, ctx) { + return (ctx || document).querySelector(selector) + } + + var + // be aware, internal usage + // ATTENTION: prefix the global dynamic variables with `__` + // tags instances cache + __TAGS_CACHE = [], + // tags implementation cache + __TAG_IMPL = {}, + YIELD_TAG = 'yield', + + /** + * Const + */ + GLOBAL_MIXIN = '__global_mixin', + + // riot specific prefixes or attributes + ATTRS_PREFIX = 'riot-', + + // Riot Directives + REF_DIRECTIVES = ['ref', 'data-ref'], + IS_DIRECTIVE = 'data-is', + CONDITIONAL_DIRECTIVE = 'if', + LOOP_DIRECTIVE = 'each', + LOOP_NO_REORDER_DIRECTIVE = 'no-reorder', + SHOW_DIRECTIVE = 'show', + HIDE_DIRECTIVE = 'hide', + KEY_DIRECTIVE = 'key', + RIOT_EVENTS_KEY = '__riot-events__', + + // for typeof == '' comparisons + T_STRING = 'string', + T_OBJECT = 'object', + T_UNDEF = 'undefined', + T_FUNCTION = 'function', + + XLINK_NS = 'http://www.w3.org/1999/xlink', + SVG_NS = 'http://www.w3.org/2000/svg', + XLINK_REGEX = /^xlink:(\w+)/, + + WIN = typeof window === T_UNDEF ? /* istanbul ignore next */ undefined : window, + + // special native tags that cannot be treated like the others + RE_SPECIAL_TAGS = /^(?:t(?:body|head|foot|[rhd])|caption|col(?:group)?|opt(?:ion|group))$/, + RE_SPECIAL_TAGS_NO_OPTION = /^(?:t(?:body|head|foot|[rhd])|caption|col(?:group)?)$/, + RE_EVENTS_PREFIX = /^on/, + RE_HTML_ATTRS = /([-\w]+) ?= ?(?:"([^"]*)|'([^']*)|({[^}]*}))/g, + // some DOM attributes must be normalized + CASE_SENSITIVE_ATTRIBUTES = { + 'viewbox': 'viewBox', + 'preserveaspectratio': 'preserveAspectRatio' + }, + /** + * Matches boolean HTML attributes in the riot tag definition. + * With a long list like this, a regex is faster than `[].indexOf` in most browsers. + * @const {RegExp} + * @see [attributes.md](https://github.com/riot/compiler/blob/dev/doc/attributes.md) + */ + RE_BOOL_ATTRS = /^(?:disabled|checked|readonly|required|allowfullscreen|auto(?:focus|play)|compact|controls|default|formnovalidate|hidden|ismap|itemscope|loop|multiple|muted|no(?:resize|shade|validate|wrap)?|open|reversed|seamless|selected|sortable|truespeed|typemustmatch)$/, + // version# for IE 8-11, 0 for others + IE_VERSION = (WIN && WIN.document || /* istanbul ignore next */ {}).documentMode | 0; + + /** + * Create a generic DOM node + * @param { String } name - name of the DOM node we want to create + * @returns { Object } DOM node just created + */ + function makeElement(name) { + return name === 'svg' ? document.createElementNS(SVG_NS, name) : document.createElement(name) + } + + /** + * Set any DOM attribute + * @param { Object } dom - DOM node we want to update + * @param { String } name - name of the property we want to set + * @param { String } val - value of the property we want to set + */ + function setAttribute(dom, name, val) { + var xlink = XLINK_REGEX.exec(name); + if (xlink && xlink[1]) + { dom.setAttributeNS(XLINK_NS, xlink[1], val); } + else + { dom.setAttribute(name, val); } + } + + var styleNode; + // Create cache and shortcut to the correct property + var cssTextProp; + var byName = {}; + var needsInject = false; + + // skip the following code on the server + if (WIN) { + styleNode = ((function () { + // create a new style element with the correct type + var newNode = makeElement('style'); + // replace any user node or insert the new one into the head + var userNode = $('style[type=riot]'); + + setAttribute(newNode, 'type', 'text/css'); + /* istanbul ignore next */ + if (userNode) { + if (userNode.id) { newNode.id = userNode.id; } + userNode.parentNode.replaceChild(newNode, userNode); + } else { document.head.appendChild(newNode); } + + return newNode + }))(); + cssTextProp = styleNode.styleSheet; + } + + /** + * Object that will be used to inject and manage the css of every tag instance + */ + var styleManager = { + styleNode: styleNode, + /** + * Save a tag style to be later injected into DOM + * @param { String } css - css string + * @param { String } name - if it's passed we will map the css to a tagname + */ + add: function add(css, name) { + byName[name] = css; + needsInject = true; + }, + /** + * Inject all previously saved tag styles into DOM + * innerHTML seems slow: http://jsperf.com/riot-insert-style + */ + inject: function inject() { + if (!WIN || !needsInject) { return } + needsInject = false; + var style = Object.keys(byName) + .map(function (k) { return byName[k]; }) + .join('\n'); + /* istanbul ignore next */ + if (cssTextProp) { cssTextProp.cssText = style; } + else { styleNode.innerHTML = style; } + }, + + /** + * Remove a tag style of injected DOM later. + * @param {String} name a registered tagname + */ + remove: function remove(name) { + delete byName[name]; + needsInject = true; + } + }; + + /** + * The riot template engine + * @version v3.0.8 + */ + + /* istanbul ignore next */ + var skipRegex = (function () { //eslint-disable-line no-unused-vars + + var beforeReChars = '[{(,;:?=|&!^~>%*/'; + + var beforeReWords = [ + 'case', + 'default', + 'do', + 'else', + 'in', + 'instanceof', + 'prefix', + 'return', + 'typeof', + 'void', + 'yield' + ]; + + var wordsLastChar = beforeReWords.reduce(function (s, w) { + return s + w.slice(-1) + }, ''); + + var RE_REGEX = /^\/(?=[^*>/])[^[/\\]*(?:(?:\\.|\[(?:\\.|[^\]\\]*)*\])[^[\\/]*)*?\/[gimuy]*/; + var RE_VN_CHAR = /[$\w]/; + + function prev (code, pos) { + while (--pos >= 0 && /\s/.test(code[pos])){ } + return pos + } + + function _skipRegex (code, start) { + + var re = /.*/g; + var pos = re.lastIndex = start++; + var match = re.exec(code)[0].match(RE_REGEX); + + if (match) { + var next = pos + match[0].length; + + pos = prev(code, pos); + var c = code[pos]; + + if (pos < 0 || ~beforeReChars.indexOf(c)) { + return next + } + + if (c === '.') { + + if (code[pos - 1] === '.') { + start = next; + } + + } else if (c === '+' || c === '-') { + + if (code[--pos] !== c || + (pos = prev(code, pos)) < 0 || + !RE_VN_CHAR.test(code[pos])) { + start = next; + } + + } else if (~wordsLastChar.indexOf(c)) { + + var end = pos + 1; + + while (--pos >= 0 && RE_VN_CHAR.test(code[pos])){ } + if (~beforeReWords.indexOf(code.slice(pos + 1, end))) { + start = next; + } + } + } + + return start + } + + return _skipRegex + + })(); + + /** + * riot.util.brackets + * + * - `brackets ` - Returns a string or regex based on its parameter + * - `brackets.set` - Change the current riot brackets + * + * @module + */ + + /* global riot */ + + /* istanbul ignore next */ + var brackets = (function (UNDEF) { + + var + REGLOB = 'g', + + R_MLCOMMS = /\/\*[^*]*\*+(?:[^*\/][^*]*\*+)*\//g, + + R_STRINGS = /"[^"\\]*(?:\\[\S\s][^"\\]*)*"|'[^'\\]*(?:\\[\S\s][^'\\]*)*'|`[^`\\]*(?:\\[\S\s][^`\\]*)*`/g, + + S_QBLOCKS = R_STRINGS.source + '|' + + /(?:\breturn\s+|(?:[$\w\)\]]|\+\+|--)\s*(\/)(?![*\/]))/.source + '|' + + /\/(?=[^*\/])[^[\/\\]*(?:(?:\[(?:\\.|[^\]\\]*)*\]|\\.)[^[\/\\]*)*?([^<]\/)[gim]*/.source, + + UNSUPPORTED = RegExp('[\\' + 'x00-\\x1F<>a-zA-Z0-9\'",;\\\\]'), + + NEED_ESCAPE = /(?=[[\]()*+?.^$|])/g, + + S_QBLOCK2 = R_STRINGS.source + '|' + /(\/)(?![*\/])/.source, + + FINDBRACES = { + '(': RegExp('([()])|' + S_QBLOCK2, REGLOB), + '[': RegExp('([[\\]])|' + S_QBLOCK2, REGLOB), + '{': RegExp('([{}])|' + S_QBLOCK2, REGLOB) + }, + + DEFAULT = '{ }'; + + var _pairs = [ + '{', '}', + '{', '}', + /{[^}]*}/, + /\\([{}])/g, + /\\({)|{/g, + RegExp('\\\\(})|([[({])|(})|' + S_QBLOCK2, REGLOB), + DEFAULT, + /^\s*{\^?\s*([$\w]+)(?:\s*,\s*(\S+))?\s+in\s+(\S.*)\s*}/, + /(^|[^\\]){=[\S\s]*?}/ + ]; + + var + cachedBrackets = UNDEF, + _regex, + _cache = [], + _settings; + + function _loopback (re) { return re } + + function _rewrite (re, bp) { + if (!bp) { bp = _cache; } + return new RegExp( + re.source.replace(/{/g, bp[2]).replace(/}/g, bp[3]), re.global ? REGLOB : '' + ) + } + + function _create (pair) { + if (pair === DEFAULT) { return _pairs } + + var arr = pair.split(' '); + + if (arr.length !== 2 || UNSUPPORTED.test(pair)) { + throw new Error('Unsupported brackets "' + pair + '"') + } + arr = arr.concat(pair.replace(NEED_ESCAPE, '\\').split(' ')); + + arr[4] = _rewrite(arr[1].length > 1 ? /{[\S\s]*?}/ : _pairs[4], arr); + arr[5] = _rewrite(pair.length > 3 ? /\\({|})/g : _pairs[5], arr); + arr[6] = _rewrite(_pairs[6], arr); + arr[7] = RegExp('\\\\(' + arr[3] + ')|([[({])|(' + arr[3] + ')|' + S_QBLOCK2, REGLOB); + arr[8] = pair; + return arr + } + + function _brackets (reOrIdx) { + return reOrIdx instanceof RegExp ? _regex(reOrIdx) : _cache[reOrIdx] + } + + _brackets.split = function split (str, tmpl, _bp) { + // istanbul ignore next: _bp is for the compiler + if (!_bp) { _bp = _cache; } + + var + parts = [], + match, + isexpr, + start, + pos, + re = _bp[6]; + + var qblocks = []; + var prevStr = ''; + var mark, lastIndex; + + isexpr = start = re.lastIndex = 0; + + while ((match = re.exec(str))) { + + lastIndex = re.lastIndex; + pos = match.index; + + if (isexpr) { + + if (match[2]) { + + var ch = match[2]; + var rech = FINDBRACES[ch]; + var ix = 1; + + rech.lastIndex = lastIndex; + while ((match = rech.exec(str))) { + if (match[1]) { + if (match[1] === ch) { ++ix; } + else if (!--ix) { break } + } else { + rech.lastIndex = pushQBlock(match.index, rech.lastIndex, match[2]); + } + } + re.lastIndex = ix ? str.length : rech.lastIndex; + continue + } + + if (!match[3]) { + re.lastIndex = pushQBlock(pos, lastIndex, match[4]); + continue + } + } + + if (!match[1]) { + unescapeStr(str.slice(start, pos)); + start = re.lastIndex; + re = _bp[6 + (isexpr ^= 1)]; + re.lastIndex = start; + } + } + + if (str && start < str.length) { + unescapeStr(str.slice(start)); + } + + parts.qblocks = qblocks; + + return parts + + function unescapeStr (s) { + if (prevStr) { + s = prevStr + s; + prevStr = ''; + } + if (tmpl || isexpr) { + parts.push(s && s.replace(_bp[5], '$1')); + } else { + parts.push(s); + } + } + + function pushQBlock(_pos, _lastIndex, slash) { //eslint-disable-line + if (slash) { + _lastIndex = skipRegex(str, _pos); + } + + if (tmpl && _lastIndex > _pos + 2) { + mark = '\u2057' + qblocks.length + '~'; + qblocks.push(str.slice(_pos, _lastIndex)); + prevStr += str.slice(start, _pos) + mark; + start = _lastIndex; + } + return _lastIndex + } + }; + + _brackets.hasExpr = function hasExpr (str) { + return _cache[4].test(str) + }; + + _brackets.loopKeys = function loopKeys (expr) { + var m = expr.match(_cache[9]); + + return m + ? { key: m[1], pos: m[2], val: _cache[0] + m[3].trim() + _cache[1] } + : { val: expr.trim() } + }; + + _brackets.array = function array (pair) { + return pair ? _create(pair) : _cache + }; + + function _reset (pair) { + if ((pair || (pair = DEFAULT)) !== _cache[8]) { + _cache = _create(pair); + _regex = pair === DEFAULT ? _loopback : _rewrite; + _cache[9] = _regex(_pairs[9]); + } + cachedBrackets = pair; + } + + function _setSettings (o) { + var b; + + o = o || {}; + b = o.brackets; + Object.defineProperty(o, 'brackets', { + set: _reset, + get: function () { return cachedBrackets }, + enumerable: true + }); + _settings = o; + _reset(b); + } + + Object.defineProperty(_brackets, 'settings', { + set: _setSettings, + get: function () { return _settings } + }); + + /* istanbul ignore next: in the browser riot is always in the scope */ + _brackets.settings = typeof riot !== 'undefined' && riot.settings || {}; + _brackets.set = _reset; + _brackets.skipRegex = skipRegex; + + _brackets.R_STRINGS = R_STRINGS; + _brackets.R_MLCOMMS = R_MLCOMMS; + _brackets.S_QBLOCKS = S_QBLOCKS; + _brackets.S_QBLOCK2 = S_QBLOCK2; + + return _brackets + + })(); + + /** + * @module tmpl + * + * tmpl - Root function, returns the template value, render with data + * tmpl.hasExpr - Test the existence of a expression inside a string + * tmpl.loopKeys - Get the keys for an 'each' loop (used by `_each`) + */ + + /* istanbul ignore next */ + var tmpl = (function () { + + var _cache = {}; + + function _tmpl (str, data) { + if (!str) { return str } + + return (_cache[str] || (_cache[str] = _create(str))).call( + data, _logErr.bind({ + data: data, + tmpl: str + }) + ) + } + + _tmpl.hasExpr = brackets.hasExpr; + + _tmpl.loopKeys = brackets.loopKeys; + + // istanbul ignore next + _tmpl.clearCache = function () { _cache = {}; }; + + _tmpl.errorHandler = null; + + function _logErr (err, ctx) { + + err.riotData = { + tagName: ctx && ctx.__ && ctx.__.tagName, + _riot_id: ctx && ctx._riot_id //eslint-disable-line camelcase + }; + + if (_tmpl.errorHandler) { _tmpl.errorHandler(err); } + else if ( + typeof console !== 'undefined' && + typeof console.error === 'function' + ) { + console.error(err.message); + console.log('<%s> %s', err.riotData.tagName || 'Unknown tag', this.tmpl); // eslint-disable-line + console.log(this.data); // eslint-disable-line + } + } + + function _create (str) { + var expr = _getTmpl(str); + + if (expr.slice(0, 11) !== 'try{return ') { expr = 'return ' + expr; } + + return new Function('E', expr + ';') // eslint-disable-line no-new-func + } + + var RE_DQUOTE = /\u2057/g; + var RE_QBMARK = /\u2057(\d+)~/g; + + function _getTmpl (str) { + var parts = brackets.split(str.replace(RE_DQUOTE, '"'), 1); + var qstr = parts.qblocks; + var expr; + + if (parts.length > 2 || parts[0]) { + var i, j, list = []; + + for (i = j = 0; i < parts.length; ++i) { + + expr = parts[i]; + + if (expr && (expr = i & 1 + + ? _parseExpr(expr, 1, qstr) + + : '"' + expr + .replace(/\\/g, '\\\\') + .replace(/\r\n?|\n/g, '\\n') + .replace(/"/g, '\\"') + + '"' + + )) { list[j++] = expr; } + + } + + expr = j < 2 ? list[0] + : '[' + list.join(',') + '].join("")'; + + } else { + + expr = _parseExpr(parts[1], 0, qstr); + } + + if (qstr.length) { + expr = expr.replace(RE_QBMARK, function (_, pos) { + return qstr[pos] + .replace(/\r/g, '\\r') + .replace(/\n/g, '\\n') + }); + } + return expr + } + + var RE_CSNAME = /^(?:(-?[_A-Za-z\xA0-\xFF][-\w\xA0-\xFF]*)|\u2057(\d+)~):/; + var + RE_BREND = { + '(': /[()]/g, + '[': /[[\]]/g, + '{': /[{}]/g + }; + + function _parseExpr (expr, asText, qstr) { + + expr = expr + .replace(/\s+/g, ' ').trim() + .replace(/\ ?([[\({},?\.:])\ ?/g, '$1'); + + if (expr) { + var + list = [], + cnt = 0, + match; + + while (expr && + (match = expr.match(RE_CSNAME)) && + !match.index + ) { + var + key, + jsb, + re = /,|([[{(])|$/g; + + expr = RegExp.rightContext; + key = match[2] ? qstr[match[2]].slice(1, -1).trim().replace(/\s+/g, ' ') : match[1]; + + while (jsb = (match = re.exec(expr))[1]) { skipBraces(jsb, re); } + + jsb = expr.slice(0, match.index); + expr = RegExp.rightContext; + + list[cnt++] = _wrapExpr(jsb, 1, key); + } + + expr = !cnt ? _wrapExpr(expr, asText) + : cnt > 1 ? '[' + list.join(',') + '].join(" ").trim()' : list[0]; + } + return expr + + function skipBraces (ch, re) { + var + mm, + lv = 1, + ir = RE_BREND[ch]; + + ir.lastIndex = re.lastIndex; + while (mm = ir.exec(expr)) { + if (mm[0] === ch) { ++lv; } + else if (!--lv) { break } + } + re.lastIndex = lv ? expr.length : ir.lastIndex; + } + } + + // istanbul ignore next: not both + var // eslint-disable-next-line max-len + JS_CONTEXT = '"in this?this:' + (typeof window !== 'object' ? 'global' : 'window') + ').', + JS_VARNAME = /[,{][\$\w]+(?=:)|(^ *|[^$\w\.{])(?!(?:typeof|true|false|null|undefined|in|instanceof|is(?:Finite|NaN)|void|NaN|new|Date|RegExp|Math)(?![$\w]))([$_A-Za-z][$\w]*)/g, + JS_NOPROPS = /^(?=(\.[$\w]+))\1(?:[^.[(]|$)/; + + function _wrapExpr (expr, asText, key) { + var tb; + + expr = expr.replace(JS_VARNAME, function (match, p, mvar, pos, s) { + if (mvar) { + pos = tb ? 0 : pos + match.length; + + if (mvar !== 'this' && mvar !== 'global' && mvar !== 'window') { + match = p + '("' + mvar + JS_CONTEXT + mvar; + if (pos) { tb = (s = s[pos]) === '.' || s === '(' || s === '['; } + } else if (pos) { + tb = !JS_NOPROPS.test(s.slice(pos)); + } + } + return match + }); + + if (tb) { + expr = 'try{return ' + expr + '}catch(e){E(e,this)}'; + } + + if (key) { + + expr = (tb + ? 'function(){' + expr + '}.call(this)' : '(' + expr + ')' + ) + '?"' + key + '":""'; + + } else if (asText) { + + expr = 'function(v){' + (tb + ? expr.replace('return ', 'v=') : 'v=(' + expr + ')' + ) + ';return v||v===0?v:""}.call(this)'; + } + + return expr + } + + _tmpl.version = brackets.version = 'v3.0.8'; + + return _tmpl + + })(); + + /* istanbul ignore next */ + var observable = function(el) { + + /** + * Extend the original object or create a new empty one + * @type { Object } + */ + + el = el || {}; + + /** + * Private variables + */ + var callbacks = {}, + slice = Array.prototype.slice; + + /** + * Public Api + */ + + // extend the el object adding the observable methods + Object.defineProperties(el, { + /** + * Listen to the given `event` ands + * execute the `callback` each time an event is triggered. + * @param { String } event - event id + * @param { Function } fn - callback function + * @returns { Object } el + */ + on: { + value: function(event, fn) { + if (typeof fn == 'function') + { (callbacks[event] = callbacks[event] || []).push(fn); } + return el + }, + enumerable: false, + writable: false, + configurable: false + }, + + /** + * Removes the given `event` listeners + * @param { String } event - event id + * @param { Function } fn - callback function + * @returns { Object } el + */ + off: { + value: function(event, fn) { + if (event == '*' && !fn) { callbacks = {}; } + else { + if (fn) { + var arr = callbacks[event]; + for (var i = 0, cb; cb = arr && arr[i]; ++i) { + if (cb == fn) { arr.splice(i--, 1); } + } + } else { delete callbacks[event]; } + } + return el + }, + enumerable: false, + writable: false, + configurable: false + }, + + /** + * Listen to the given `event` and + * execute the `callback` at most once + * @param { String } event - event id + * @param { Function } fn - callback function + * @returns { Object } el + */ + one: { + value: function(event, fn) { + function on() { + el.off(event, on); + fn.apply(el, arguments); + } + return el.on(event, on) + }, + enumerable: false, + writable: false, + configurable: false + }, + + /** + * Execute all callback functions that listen to + * the given `event` + * @param { String } event - event id + * @returns { Object } el + */ + trigger: { + value: function(event) { + var arguments$1 = arguments; + + + // getting the arguments + var arglen = arguments.length - 1, + args = new Array(arglen), + fns, + fn, + i; + + for (i = 0; i < arglen; i++) { + args[i] = arguments$1[i + 1]; // skip first argument + } + + fns = slice.call(callbacks[event] || [], 0); + + for (i = 0; fn = fns[i]; ++i) { + fn.apply(el, args); + } + + if (callbacks['*'] && event != '*') + { el.trigger.apply(el, ['*', event].concat(args)); } + + return el + }, + enumerable: false, + writable: false, + configurable: false + } + }); + + return el + + }; + + /** + * Short alias for Object.getOwnPropertyDescriptor + */ + function getPropDescriptor (o, k) { + return Object.getOwnPropertyDescriptor(o, k) + } + + /** + * Check if passed argument is undefined + * @param { * } value - + * @returns { Boolean } - + */ + function isUndefined(value) { + return typeof value === T_UNDEF + } + + /** + * Check whether object's property could be overridden + * @param { Object } obj - source object + * @param { String } key - object property + * @returns { Boolean } true if writable + */ + function isWritable(obj, key) { + var descriptor = getPropDescriptor(obj, key); + return isUndefined(obj[key]) || descriptor && descriptor.writable + } + + /** + * Extend any object with other properties + * @param { Object } src - source object + * @returns { Object } the resulting extended object + * + * var obj = { foo: 'baz' } + * extend(obj, {bar: 'bar', foo: 'bar'}) + * console.log(obj) => {bar: 'bar', foo: 'bar'} + * + */ + function extend(src) { + var obj; + var i = 1; + var args = arguments; + var l = args.length; + + for (; i < l; i++) { + if (obj = args[i]) { + for (var key in obj) { + // check if this property of the source object could be overridden + if (isWritable(src, key)) + { src[key] = obj[key]; } + } + } + } + return src + } + + /** + * Alias for Object.create + */ + function create(src) { + return Object.create(src) + } + + var settings = extend(create(brackets.settings), { + skipAnonymousTags: true, + // the "value" attributes will be preserved + keepValueAttributes: false, + // handle the auto updates on any DOM event + autoUpdate: true + }); + + /** + * Shorter and fast way to select multiple nodes in the DOM + * @param { String } selector - DOM selector + * @param { Object } ctx - DOM node where the targets of our search will is located + * @returns { Object } dom nodes found + */ + function $$(selector, ctx) { + return [].slice.call((ctx || document).querySelectorAll(selector)) + } + + /** + * Create a document text node + * @returns { Object } create a text node to use as placeholder + */ + function createDOMPlaceholder() { + return document.createTextNode('') + } + + /** + * Toggle the visibility of any DOM node + * @param { Object } dom - DOM node we want to hide + * @param { Boolean } show - do we want to show it? + */ + + function toggleVisibility(dom, show) { + dom.style.display = show ? '' : 'none'; + dom.hidden = show ? false : true; + } + + /** + * Get the value of any DOM attribute on a node + * @param { Object } dom - DOM node we want to parse + * @param { String } name - name of the attribute we want to get + * @returns { String | undefined } name of the node attribute whether it exists + */ + function getAttribute(dom, name) { + return dom.getAttribute(name) + } + + /** + * Remove any DOM attribute from a node + * @param { Object } dom - DOM node we want to update + * @param { String } name - name of the property we want to remove + */ + function removeAttribute(dom, name) { + dom.removeAttribute(name); + } + + /** + * Set the inner html of any DOM node SVGs included + * @param { Object } container - DOM node where we'll inject new html + * @param { String } html - html to inject + * @param { Boolean } isSvg - svg tags should be treated a bit differently + */ + /* istanbul ignore next */ + function setInnerHTML(container, html, isSvg) { + // innerHTML is not supported on svg tags so we neet to treat them differently + if (isSvg) { + var node = container.ownerDocument.importNode( + new DOMParser() + .parseFromString(("" + html + ""), 'application/xml') + .documentElement, + true + ); + + container.appendChild(node); + } else { + container.innerHTML = html; + } + } + + /** + * Minimize risk: only zero or one _space_ between attr & value + * @param { String } html - html string we want to parse + * @param { Function } fn - callback function to apply on any attribute found + */ + function walkAttributes(html, fn) { + if (!html) { return } + var m; + while (m = RE_HTML_ATTRS.exec(html)) + { fn(m[1].toLowerCase(), m[2] || m[3] || m[4]); } + } + + /** + * Create a document fragment + * @returns { Object } document fragment + */ + function createFragment() { + return document.createDocumentFragment() + } + + /** + * Insert safely a tag to fix #1962 #1649 + * @param { HTMLElement } root - children container + * @param { HTMLElement } curr - node to insert + * @param { HTMLElement } next - node that should preceed the current node inserted + */ + function safeInsert(root, curr, next) { + root.insertBefore(curr, next.parentNode && next); + } + + /** + * Convert a style object to a string + * @param { Object } style - style object we need to parse + * @returns { String } resulting css string + * @example + * styleObjectToString({ color: 'red', height: '10px'}) // => 'color: red; height: 10px' + */ + function styleObjectToString(style) { + return Object.keys(style).reduce(function (acc, prop) { + return (acc + " " + prop + ": " + (style[prop]) + ";") + }, '') + } + + /** + * Walk down recursively all the children tags starting dom node + * @param { Object } dom - starting node where we will start the recursion + * @param { Function } fn - callback to transform the child node just found + * @param { Object } context - fn can optionally return an object, which is passed to children + */ + function walkNodes(dom, fn, context) { + if (dom) { + var res = fn(dom, context); + var next; + // stop the recursion + if (res === false) { return } + + dom = dom.firstChild; + + while (dom) { + next = dom.nextSibling; + walkNodes(dom, fn, res); + dom = next; + } + } + } + + + + var dom = /*#__PURE__*/Object.freeze({ + $$: $$, + $: $, + createDOMPlaceholder: createDOMPlaceholder, + mkEl: makeElement, + setAttr: setAttribute, + toggleVisibility: toggleVisibility, + getAttr: getAttribute, + remAttr: removeAttribute, + setInnerHTML: setInnerHTML, + walkAttrs: walkAttributes, + createFrag: createFragment, + safeInsert: safeInsert, + styleObjectToString: styleObjectToString, + walkNodes: walkNodes + }); + + /** + * Check against the null and undefined values + * @param { * } value - + * @returns {Boolean} - + */ + function isNil(value) { + return isUndefined(value) || value === null + } + + /** + * Check if passed argument is empty. Different from falsy, because we dont consider 0 or false to be blank + * @param { * } value - + * @returns { Boolean } - + */ + function isBlank(value) { + return isNil(value) || value === '' + } + + /** + * Check if passed argument is a function + * @param { * } value - + * @returns { Boolean } - + */ + function isFunction(value) { + return typeof value === T_FUNCTION + } + + /** + * Check if passed argument is an object, exclude null + * NOTE: use isObject(x) && !isArray(x) to excludes arrays. + * @param { * } value - + * @returns { Boolean } - + */ + function isObject(value) { + return value && typeof value === T_OBJECT // typeof null is 'object' + } + + /** + * Check if a DOM node is an svg tag or part of an svg + * @param { HTMLElement } el - node we want to test + * @returns {Boolean} true if it's an svg node + */ + function isSvg(el) { + var owner = el.ownerSVGElement; + return !!owner || owner === null + } + + /** + * Check if passed argument is a kind of array + * @param { * } value - + * @returns { Boolean } - + */ + function isArray(value) { + return Array.isArray(value) || value instanceof Array + } + + /** + * Check if the passed argument is a boolean attribute + * @param { String } value - + * @returns { Boolean } - + */ + function isBoolAttr(value) { + return RE_BOOL_ATTRS.test(value) + } + + /** + * Check if passed argument is a string + * @param { * } value - + * @returns { Boolean } - + */ + function isString(value) { + return typeof value === T_STRING + } + + + + var check = /*#__PURE__*/Object.freeze({ + isBlank: isBlank, + isFunction: isFunction, + isObject: isObject, + isSvg: isSvg, + isWritable: isWritable, + isArray: isArray, + isBoolAttr: isBoolAttr, + isNil: isNil, + isString: isString, + isUndefined: isUndefined + }); + + /** + * Check whether an array contains an item + * @param { Array } array - target array + * @param { * } item - item to test + * @returns { Boolean } - + */ + function contains(array, item) { + return array.indexOf(item) !== -1 + } + + /** + * Specialized function for looping an array-like collection with `each={}` + * @param { Array } list - collection of items + * @param {Function} fn - callback function + * @returns { Array } the array looped + */ + function each(list, fn) { + var len = list ? list.length : 0; + var i = 0; + for (; i < len; i++) { fn(list[i], i); } + return list + } + + /** + * Faster String startsWith alternative + * @param { String } str - source string + * @param { String } value - test string + * @returns { Boolean } - + */ + function startsWith(str, value) { + return str.slice(0, value.length) === value + } + + /** + * Function returning always a unique identifier + * @returns { Number } - number from 0...n + */ + var uid = (function uid() { + var i = -1; + return function () { return ++i; } + })(); + + /** + * Helper function to set an immutable property + * @param { Object } el - object where the new property will be set + * @param { String } key - object key where the new property will be stored + * @param { * } value - value of the new property + * @param { Object } options - set the propery overriding the default options + * @returns { Object } - the initial object + */ + function define(el, key, value, options) { + Object.defineProperty(el, key, extend({ + value: value, + enumerable: false, + writable: false, + configurable: true + }, options)); + return el + } + + /** + * Convert a string containing dashes to camel case + * @param { String } str - input string + * @returns { String } my-string -> myString + */ + function toCamel(str) { + return str.replace(/-(\w)/g, function (_, c) { return c.toUpperCase(); }) + } + + /** + * Warn a message via console + * @param {String} message - warning message + */ + function warn(message) { + if (console && console.warn) { console.warn(message); } + } + + + + var misc = /*#__PURE__*/Object.freeze({ + contains: contains, + each: each, + getPropDescriptor: getPropDescriptor, + startsWith: startsWith, + uid: uid, + defineProperty: define, + objectCreate: create, + extend: extend, + toCamel: toCamel, + warn: warn + }); + + /** + * Set the property of an object for a given key. If something already + * exists there, then it becomes an array containing both the old and new value. + * @param { Object } obj - object on which to set the property + * @param { String } key - property name + * @param { Object } value - the value of the property to be set + * @param { Boolean } ensureArray - ensure that the property remains an array + * @param { Number } index - add the new item in a certain array position + */ + function arrayishAdd(obj, key, value, ensureArray, index) { + var dest = obj[key]; + var isArr = isArray(dest); + var hasIndex = !isUndefined(index); + + if (dest && dest === value) { return } + + // if the key was never set, set it once + if (!dest && ensureArray) { obj[key] = [value]; } + else if (!dest) { obj[key] = value; } + // if it was an array and not yet set + else { + if (isArr) { + var oldIndex = dest.indexOf(value); + // this item never changed its position + if (oldIndex === index) { return } + // remove the item from its old position + if (oldIndex !== -1) { dest.splice(oldIndex, 1); } + // move or add the item + if (hasIndex) { + dest.splice(index, 0, value); + } else { + dest.push(value); + } + } else { obj[key] = [dest, value]; } + } + } + + /** + * Detect the tag implementation by a DOM node + * @param { Object } dom - DOM node we need to parse to get its tag implementation + * @returns { Object } it returns an object containing the implementation of a custom tag (template and boot function) + */ + function get(dom) { + return dom.tagName && __TAG_IMPL[getAttribute(dom, IS_DIRECTIVE) || + getAttribute(dom, IS_DIRECTIVE) || dom.tagName.toLowerCase()] + } + + /** + * Get the tag name of any DOM node + * @param { Object } dom - DOM node we want to parse + * @param { Boolean } skipDataIs - hack to ignore the data-is attribute when attaching to parent + * @returns { String } name to identify this dom node in riot + */ + function getName(dom, skipDataIs) { + var child = get(dom); + var namedTag = !skipDataIs && getAttribute(dom, IS_DIRECTIVE); + return namedTag && !tmpl.hasExpr(namedTag) ? + namedTag : child ? child.name : dom.tagName.toLowerCase() + } + + /** + * Return a temporary context containing also the parent properties + * @this Tag + * @param { Tag } - temporary tag context containing all the parent properties + */ + function inheritParentProps() { + if (this.parent) { return extend(create(this), this.parent) } + return this + } + + /* + Includes hacks needed for the Internet Explorer version 9 and below + See: http://kangax.github.io/compat-table/es5/#ie8 + http://codeplanet.io/dropping-ie8/ + */ + + var + reHasYield = /|>([\S\s]*?)<\/yield\s*>|>)/ig, + reYieldSrc = /]*)['"]\s*>([\S\s]*?)<\/yield\s*>/ig, + reYieldDest = /|>([\S\s]*?)<\/yield\s*>)/ig, + rootEls = { tr: 'tbody', th: 'tr', td: 'tr', col: 'colgroup' }, + tblTags = IE_VERSION && IE_VERSION < 10 ? RE_SPECIAL_TAGS : RE_SPECIAL_TAGS_NO_OPTION, + GENERIC = 'div', + SVG = 'svg'; + + + /* + Creates the root element for table or select child elements: + tr/th/td/thead/tfoot/tbody/caption/col/colgroup/option/optgroup + */ + function specialTags(el, tmpl, tagName) { + + var + select = tagName[0] === 'o', + parent = select ? 'select>' : 'table>'; + + // trim() is important here, this ensures we don't have artifacts, + // so we can check if we have only one element inside the parent + el.innerHTML = '<' + parent + tmpl.trim() + ' 0 ) mixins[ len ] = arguments[ len + 1 ]; + + each(mixins, function (mix) { + var instance; + var obj; + var props = []; + + // properties blacklisted and will not be bound to the tag instance + var propsBlacklist = ['init', '__proto__']; + + mix = isString(mix) ? mixin(mix) : mix; + + // check if the mixin is a function + if (isFunction(mix)) { + // create the new mixin instance + instance = new mix(); + } else { instance = mix; } + + var proto = Object.getPrototypeOf(instance); + + // build multilevel prototype inheritance chain property list + do { props = props.concat(Object.getOwnPropertyNames(obj || instance)); } + while (obj = Object.getPrototypeOf(obj || instance)) + + // loop the keys in the function prototype or the all object keys + each(props, function (key) { + // bind methods to tag + // allow mixins to override other properties/parent mixins + if (!contains(propsBlacklist, key)) { + // check for getters/setters + var descriptor = getPropDescriptor(instance, key) || getPropDescriptor(proto, key); + var hasGetterSetter = descriptor && (descriptor.get || descriptor.set); + + // apply method only if it does not already exist on the instance + if (!tag$$1.hasOwnProperty(key) && hasGetterSetter) { + Object.defineProperty(tag$$1, key, descriptor); + } else { + tag$$1[key] = isFunction(instance[key]) ? + instance[key].bind(tag$$1) : + instance[key]; + } + } + }); + + // init method will be called automatically + if (instance.init) + { instance.init.bind(tag$$1)(tag$$1.opts); } + }); + + return tag$$1 + } + + /** + * Move the position of a custom tag in its parent tag + * @this Tag + * @param { String } tagName - key where the tag was stored + * @param { Number } newPos - index where the new tag will be stored + */ + function moveChild(tagName, newPos) { + var parent = this.parent; + var tags; + // no parent no move + if (!parent) { return } + + tags = parent.tags[tagName]; + + if (isArray(tags)) + { tags.splice(newPos, 0, tags.splice(tags.indexOf(this), 1)[0]); } + else { arrayishAdd(parent.tags, tagName, this); } + } + + /** + * Move virtual tag and all child nodes + * @this Tag + * @param { Node } src - the node that will do the inserting + * @param { Tag } target - insert before this tag's first child + */ + function moveVirtual(src, target) { + var this$1 = this; + + var el = this.__.head; + var sib; + var frag = createFragment(); + + while (el) { + sib = el.nextSibling; + frag.appendChild(el); + el = sib; + if (el === this$1.__.tail) { + frag.appendChild(el); + src.insertBefore(frag, target.__.head); + break + } + } + } + + /** + * Convert the item looped into an object used to extend the child tag properties + * @param { Object } expr - object containing the keys used to extend the children tags + * @param { * } key - value to assign to the new object returned + * @param { * } val - value containing the position of the item in the array + * @returns { Object } - new object containing the values of the original item + * + * The variables 'key' and 'val' are arbitrary. + * They depend on the collection type looped (Array, Object) + * and on the expression used on the each tag + * + */ + function mkitem(expr, key, val) { + var item = {}; + item[expr.key] = key; + if (expr.pos) { item[expr.pos] = val; } + return item + } + + /** + * Unmount the redundant tags + * @param { Array } items - array containing the current items to loop + * @param { Array } tags - array containing all the children tags + */ + function unmountRedundant(items, tags, filteredItemsCount) { + var i = tags.length; + var j = items.length - filteredItemsCount; + + while (i > j) { + i--; + remove.apply(tags[i], [tags, i]); + } + } + + + /** + * Remove a child tag + * @this Tag + * @param { Array } tags - tags collection + * @param { Number } i - index of the tag to remove + */ + function remove(tags, i) { + tags.splice(i, 1); + this.unmount(); + arrayishRemove(this.parent, this, this.__.tagName, true); + } + + /** + * Move the nested custom tags in non custom loop tags + * @this Tag + * @param { Number } i - current position of the loop tag + */ + function moveNestedTags(i) { + var this$1 = this; + + each(Object.keys(this.tags), function (tagName) { + moveChild.apply(this$1.tags[tagName], [tagName, i]); + }); + } + + /** + * Move a child tag + * @this Tag + * @param { HTMLElement } root - dom node containing all the loop children + * @param { Tag } nextTag - instance of the next tag preceding the one we want to move + * @param { Boolean } isVirtual - is it a virtual tag? + */ + function move(root, nextTag, isVirtual) { + if (isVirtual) + { moveVirtual.apply(this, [root, nextTag]); } + else + { safeInsert(root, this.root, nextTag.root); } + } + + /** + * Insert and mount a child tag + * @this Tag + * @param { HTMLElement } root - dom node containing all the loop children + * @param { Tag } nextTag - instance of the next tag preceding the one we want to insert + * @param { Boolean } isVirtual - is it a virtual tag? + */ + function insert(root, nextTag, isVirtual) { + if (isVirtual) + { makeVirtual.apply(this, [root, nextTag]); } + else + { safeInsert(root, this.root, nextTag.root); } + } + + /** + * Append a new tag into the DOM + * @this Tag + * @param { HTMLElement } root - dom node containing all the loop children + * @param { Boolean } isVirtual - is it a virtual tag? + */ + function append(root, isVirtual) { + if (isVirtual) + { makeVirtual.call(this, root); } + else + { root.appendChild(this.root); } + } + + /** + * Return the value we want to use to lookup the postion of our items in the collection + * @param { String } keyAttr - lookup string or expression + * @param { * } originalItem - original item from the collection + * @param { Object } keyedItem - object created by riot via { item, i in collection } + * @param { Boolean } hasKeyAttrExpr - flag to check whether the key is an expression + * @returns { * } value that we will use to figure out the item position via collection.indexOf + */ + function getItemId(keyAttr, originalItem, keyedItem, hasKeyAttrExpr) { + if (keyAttr) { + return hasKeyAttrExpr ? tmpl(keyAttr, keyedItem) : originalItem[keyAttr] + } + + return originalItem + } + + /** + * Manage tags having the 'each' + * @param { HTMLElement } dom - DOM node we need to loop + * @param { Tag } parent - parent tag instance where the dom node is contained + * @param { String } expr - string contained in the 'each' attribute + * @returns { Object } expression object for this each loop + */ + function _each(dom, parent, expr) { + var mustReorder = typeof getAttribute(dom, LOOP_NO_REORDER_DIRECTIVE) !== T_STRING || removeAttribute(dom, LOOP_NO_REORDER_DIRECTIVE); + var keyAttr = getAttribute(dom, KEY_DIRECTIVE); + var hasKeyAttrExpr = keyAttr ? tmpl.hasExpr(keyAttr) : false; + var tagName = getName(dom); + var impl = __TAG_IMPL[tagName]; + var parentNode = dom.parentNode; + var placeholder = createDOMPlaceholder(); + var child = get(dom); + var ifExpr = getAttribute(dom, CONDITIONAL_DIRECTIVE); + var tags = []; + var isLoop = true; + var innerHTML = dom.innerHTML; + var isAnonymous = !__TAG_IMPL[tagName]; + var isVirtual = dom.tagName === 'VIRTUAL'; + var oldItems = []; + + // remove the each property from the original tag + removeAttribute(dom, LOOP_DIRECTIVE); + removeAttribute(dom, KEY_DIRECTIVE); + + // parse the each expression + expr = tmpl.loopKeys(expr); + expr.isLoop = true; + + if (ifExpr) { removeAttribute(dom, CONDITIONAL_DIRECTIVE); } + + // insert a marked where the loop tags will be injected + parentNode.insertBefore(placeholder, dom); + parentNode.removeChild(dom); + + expr.update = function updateEach() { + // get the new items collection + expr.value = tmpl(expr.val, parent); + + var items = expr.value; + var frag = createFragment(); + var isObject = !isArray(items) && !isString(items); + var root = placeholder.parentNode; + var tmpItems = []; + var hasKeys = isObject && !!items; + + // if this DOM was removed the update here is useless + // this condition fixes also a weird async issue on IE in our unit test + if (!root) { return } + + // object loop. any changes cause full redraw + if (isObject) { + items = items ? Object.keys(items).map(function (key) { return mkitem(expr, items[key], key); }) : []; + } + + // store the amount of filtered items + var filteredItemsCount = 0; + + // loop all the new items + each(items, function (_item, index) { + var i = index - filteredItemsCount; + var item = !hasKeys && expr.key ? mkitem(expr, _item, index) : _item; + + // skip this item because it must be filtered + if (ifExpr && !tmpl(ifExpr, extend(create(parent), item))) { + filteredItemsCount ++; + return + } + + var itemId = getItemId(keyAttr, _item, item, hasKeyAttrExpr); + // reorder only if the items are not objects + // or a key attribute has been provided + var doReorder = !isObject && mustReorder && typeof _item === T_OBJECT || keyAttr; + var oldPos = oldItems.indexOf(itemId); + var isNew = oldPos === -1; + var pos = !isNew && doReorder ? oldPos : i; + // does a tag exist in this position? + var tag = tags[pos]; + var mustAppend = i >= oldItems.length; + var mustCreate = doReorder && isNew || !doReorder && !tag || !tags[i]; + + // new tag + if (mustCreate) { + tag = createTag(impl, { + parent: parent, + isLoop: isLoop, + isAnonymous: isAnonymous, + tagName: tagName, + root: dom.cloneNode(isAnonymous), + item: item, + index: i, + }, innerHTML); + + // mount the tag + tag.mount(); + + if (mustAppend) + { append.apply(tag, [frag || root, isVirtual]); } + else + { insert.apply(tag, [root, tags[i], isVirtual]); } + + if (!mustAppend) { oldItems.splice(i, 0, item); } + tags.splice(i, 0, tag); + if (child) { arrayishAdd(parent.tags, tagName, tag, true); } + } else if (pos !== i && doReorder) { + // move + if (keyAttr || contains(items, oldItems[pos])) { + move.apply(tag, [root, tags[i], isVirtual]); + // move the old tag instance + tags.splice(i, 0, tags.splice(pos, 1)[0]); + // move the old item + oldItems.splice(i, 0, oldItems.splice(pos, 1)[0]); + } + + // update the position attribute if it exists + if (expr.pos) { tag[expr.pos] = i; } + + // if the loop tags are not custom + // we need to move all their custom tags into the right position + if (!child && tag.tags) { moveNestedTags.call(tag, i); } + } + + // cache the original item to use it in the events bound to this node + // and its children + extend(tag.__, { + item: item, + index: i, + parent: parent + }); + + tmpItems[i] = itemId; + + if (!mustCreate) { tag.update(item); } + }); + + // remove the redundant tags + unmountRedundant(items, tags, filteredItemsCount); + + // clone the items array + oldItems = tmpItems.slice(); + + root.insertBefore(frag, placeholder); + }; + + expr.unmount = function () { + each(tags, function (t) { t.unmount(); }); + }; + + return expr + } + + var RefExpr = { + init: function init(dom, parent, attrName, attrValue) { + this.dom = dom; + this.attr = attrName; + this.rawValue = attrValue; + this.parent = parent; + this.hasExp = tmpl.hasExpr(attrValue); + return this + }, + update: function update() { + var old = this.value; + var customParent = this.parent && getImmediateCustomParent(this.parent); + // if the referenced element is a custom tag, then we set the tag itself, rather than DOM + var tagOrDom = this.dom.__ref || this.tag || this.dom; + + this.value = this.hasExp ? tmpl(this.rawValue, this.parent) : this.rawValue; + + // the name changed, so we need to remove it from the old key (if present) + if (!isBlank(old) && customParent) { arrayishRemove(customParent.refs, old, tagOrDom); } + if (!isBlank(this.value) && isString(this.value)) { + // add it to the refs of parent tag (this behavior was changed >=3.0) + if (customParent) { arrayishAdd( + customParent.refs, + this.value, + tagOrDom, + // use an array if it's a looped node and the ref is not an expression + null, + this.parent.__.index + ); } + + if (this.value !== old) { + setAttribute(this.dom, this.attr, this.value); + } + } else { + removeAttribute(this.dom, this.attr); + } + + // cache the ref bound to this dom node + // to reuse it in future (see also #2329) + if (!this.dom.__ref) { this.dom.__ref = tagOrDom; } + }, + unmount: function unmount() { + var tagOrDom = this.tag || this.dom; + var customParent = this.parent && getImmediateCustomParent(this.parent); + if (!isBlank(this.value) && customParent) + { arrayishRemove(customParent.refs, this.value, tagOrDom); } + } + }; + + /** + * Create a new ref directive + * @param { HTMLElement } dom - dom node having the ref attribute + * @param { Tag } context - tag instance where the DOM node is located + * @param { String } attrName - either 'ref' or 'data-ref' + * @param { String } attrValue - value of the ref attribute + * @returns { RefExpr } a new RefExpr object + */ + function createRefDirective(dom, tag, attrName, attrValue) { + return create(RefExpr).init(dom, tag, attrName, attrValue) + } + + /** + * Trigger the unmount method on all the expressions + * @param { Array } expressions - DOM expressions + */ + function unmountAll(expressions) { + each(expressions, function (expr) { + if (expr.unmount) { expr.unmount(true); } + else if (expr.tagName) { expr.tag.unmount(true); } + else if (expr.unmount) { expr.unmount(); } + }); + } + + var IfExpr = { + init: function init(dom, tag, expr) { + removeAttribute(dom, CONDITIONAL_DIRECTIVE); + extend(this, { tag: tag, expr: expr, stub: createDOMPlaceholder(), pristine: dom }); + var p = dom.parentNode; + p.insertBefore(this.stub, dom); + p.removeChild(dom); + + return this + }, + update: function update$$1() { + this.value = tmpl(this.expr, this.tag); + + if (!this.stub.parentNode) { return } + + if (this.value && !this.current) { // insert + this.current = this.pristine.cloneNode(true); + this.stub.parentNode.insertBefore(this.current, this.stub); + this.expressions = parseExpressions.apply(this.tag, [this.current, true]); + } else if (!this.value && this.current) { // remove + this.unmount(); + this.current = null; + this.expressions = []; + } + + if (this.value) { update.call(this.tag, this.expressions); } + }, + unmount: function unmount() { + if (this.current) { + if (this.current._tag) { + this.current._tag.unmount(); + } else if (this.current.parentNode) { + this.current.parentNode.removeChild(this.current); + } + } + + unmountAll(this.expressions || []); + } + }; + + /** + * Create a new if directive + * @param { HTMLElement } dom - if root dom node + * @param { Tag } context - tag instance where the DOM node is located + * @param { String } attr - if expression + * @returns { IFExpr } a new IfExpr object + */ + function createIfDirective(dom, tag, attr) { + return create(IfExpr).init(dom, tag, attr) + } + + /** + * Walk the tag DOM to detect the expressions to evaluate + * @this Tag + * @param { HTMLElement } root - root tag where we will start digging the expressions + * @param { Boolean } mustIncludeRoot - flag to decide whether the root must be parsed as well + * @returns { Array } all the expressions found + */ + function parseExpressions(root, mustIncludeRoot) { + var this$1 = this; + + var expressions = []; + + walkNodes(root, function (dom) { + var type = dom.nodeType; + var attr; + var tagImpl; + + if (!mustIncludeRoot && dom === root) { return } + + // text node + if (type === 3 && dom.parentNode.tagName !== 'STYLE' && tmpl.hasExpr(dom.nodeValue)) + { expressions.push({dom: dom, expr: dom.nodeValue}); } + + if (type !== 1) { return } + + var isVirtual = dom.tagName === 'VIRTUAL'; + + // loop. each does it's own thing (for now) + if (attr = getAttribute(dom, LOOP_DIRECTIVE)) { + if(isVirtual) { setAttribute(dom, 'loopVirtual', true); } // ignore here, handled in _each + expressions.push(_each(dom, this$1, attr)); + return false + } + + // if-attrs become the new parent. Any following expressions (either on the current + // element, or below it) become children of this expression. + if (attr = getAttribute(dom, CONDITIONAL_DIRECTIVE)) { + expressions.push(createIfDirective(dom, this$1, attr)); + return false + } + + if (attr = getAttribute(dom, IS_DIRECTIVE)) { + if (tmpl.hasExpr(attr)) { + expressions.push({ + isRtag: true, + expr: attr, + dom: dom, + attrs: [].slice.call(dom.attributes) + }); + + return false + } + } + + // if this is a tag, stop traversing here. + // we ignore the root, since parseExpressions is called while we're mounting that root + tagImpl = get(dom); + + if(isVirtual) { + if(getAttribute(dom, 'virtualized')) {dom.parentElement.removeChild(dom); } // tag created, remove from dom + if(!tagImpl && !getAttribute(dom, 'virtualized') && !getAttribute(dom, 'loopVirtual')) // ok to create virtual tag + { tagImpl = { tmpl: dom.outerHTML }; } + } + + if (tagImpl && (dom !== root || mustIncludeRoot)) { + var hasIsDirective = getAttribute(dom, IS_DIRECTIVE); + if(isVirtual && !hasIsDirective) { // handled in update + // can not remove attribute like directives + // so flag for removal after creation to prevent maximum stack error + setAttribute(dom, 'virtualized', true); + var tag = createTag( + {tmpl: dom.outerHTML}, + {root: dom, parent: this$1}, + dom.innerHTML + ); + + expressions.push(tag); // no return, anonymous tag, keep parsing + } else { + if (hasIsDirective && isVirtual) + { warn(("Virtual tags shouldn't be used together with the \"" + IS_DIRECTIVE + "\" attribute - https://github.com/riot/riot/issues/2511")); } + + expressions.push( + initChild( + tagImpl, + { + root: dom, + parent: this$1 + }, + dom.innerHTML, + this$1 + ) + ); + return false + } + } + + // attribute expressions + parseAttributes.apply(this$1, [dom, dom.attributes, function (attr, expr) { + if (!expr) { return } + expressions.push(expr); + }]); + }); + + return expressions + } + + /** + * Calls `fn` for every attribute on an element. If that attr has an expression, + * it is also passed to fn. + * @this Tag + * @param { HTMLElement } dom - dom node to parse + * @param { Array } attrs - array of attributes + * @param { Function } fn - callback to exec on any iteration + */ + function parseAttributes(dom, attrs, fn) { + var this$1 = this; + + each(attrs, function (attr) { + if (!attr) { return false } + + var name = attr.name; + var bool = isBoolAttr(name); + var expr; + + if (contains(REF_DIRECTIVES, name) && dom.tagName.toLowerCase() !== YIELD_TAG) { + expr = createRefDirective(dom, this$1, name, attr.value); + } else if (tmpl.hasExpr(attr.value)) { + expr = {dom: dom, expr: attr.value, attr: name, bool: bool}; + } + + fn(attr, expr); + }); + } + + /** + * Manage the mount state of a tag triggering also the observable events + * @this Tag + * @param { Boolean } value - ..of the isMounted flag + */ + function setMountState(value) { + var ref = this.__; + var isAnonymous = ref.isAnonymous; + var skipAnonymous = ref.skipAnonymous; + + define(this, 'isMounted', value); + + if (!isAnonymous || !skipAnonymous) { + if (value) { this.trigger('mount'); } + else { + this.trigger('unmount'); + this.off('*'); + this.__.wasCreated = false; + } + } + } + + /** + * Mount the current tag instance + * @returns { Tag } the current tag instance + */ + function componentMount(tag$$1, dom, expressions, opts) { + var __ = tag$$1.__; + var root = __.root; + root._tag = tag$$1; // keep a reference to the tag just created + + // Read all the attrs on this instance. This give us the info we need for updateOpts + parseAttributes.apply(__.parent, [root, root.attributes, function (attr, expr) { + if (!__.isAnonymous && RefExpr.isPrototypeOf(expr)) { expr.tag = tag$$1; } + attr.expr = expr; + __.instAttrs.push(attr); + }]); + + // update the root adding custom attributes coming from the compiler + walkAttributes(__.impl.attrs, function (k, v) { __.implAttrs.push({name: k, value: v}); }); + parseAttributes.apply(tag$$1, [root, __.implAttrs, function (attr, expr) { + if (expr) { expressions.push(expr); } + else { setAttribute(root, attr.name, attr.value); } + }]); + + // initialiation + updateOpts.apply(tag$$1, [__.isLoop, __.parent, __.isAnonymous, opts, __.instAttrs]); + + // add global mixins + var globalMixin = mixin(GLOBAL_MIXIN); + + if (globalMixin && !__.skipAnonymous) { + for (var i in globalMixin) { + if (globalMixin.hasOwnProperty(i)) { + tag$$1.mixin(globalMixin[i]); + } + } + } + + if (__.impl.fn) { __.impl.fn.call(tag$$1, opts); } + + if (!__.skipAnonymous) { tag$$1.trigger('before-mount'); } + + // parse layout after init. fn may calculate args for nested custom tags + each(parseExpressions.apply(tag$$1, [dom, __.isAnonymous]), function (e) { return expressions.push(e); }); + + tag$$1.update(__.item); + + if (!__.isAnonymous && !__.isInline) { + while (dom.firstChild) { root.appendChild(dom.firstChild); } + } + + define(tag$$1, 'root', root); + + // if we need to wait that the parent "mount" or "updated" event gets triggered + if (!__.skipAnonymous && tag$$1.parent) { + var p = getImmediateCustomParent(tag$$1.parent); + p.one(!p.isMounted ? 'mount' : 'updated', function () { + setMountState.call(tag$$1, true); + }); + } else { + // otherwise it's not a child tag we can trigger its mount event + setMountState.call(tag$$1, true); + } + + tag$$1.__.wasCreated = true; + + return tag$$1 + } + + /** + * Unmount the tag instance + * @param { Boolean } mustKeepRoot - if it's true the root node will not be removed + * @returns { Tag } the current tag instance + */ + function tagUnmount(tag, mustKeepRoot, expressions) { + var __ = tag.__; + var root = __.root; + var tagIndex = __TAGS_CACHE.indexOf(tag); + var p = root.parentNode; + + if (!__.skipAnonymous) { tag.trigger('before-unmount'); } + + // clear all attributes coming from the mounted tag + walkAttributes(__.impl.attrs, function (name) { + if (startsWith(name, ATTRS_PREFIX)) + { name = name.slice(ATTRS_PREFIX.length); } + + removeAttribute(root, name); + }); + + // remove all the event listeners + tag.__.listeners.forEach(function (dom) { + Object.keys(dom[RIOT_EVENTS_KEY]).forEach(function (eventName) { + dom.removeEventListener(eventName, dom[RIOT_EVENTS_KEY][eventName]); + }); + }); + + // remove tag instance from the global tags cache collection + if (tagIndex !== -1) { __TAGS_CACHE.splice(tagIndex, 1); } + + // clean up the parent tags object + if (__.parent && !__.isAnonymous) { + var ptag = getImmediateCustomParent(__.parent); + + if (__.isVirtual) { + Object + .keys(tag.tags) + .forEach(function (tagName) { return arrayishRemove(ptag.tags, tagName, tag.tags[tagName]); }); + } else { + arrayishRemove(ptag.tags, __.tagName, tag); + } + } + + // unmount all the virtual directives + if (tag.__.virts) { + each(tag.__.virts, function (v) { + if (v.parentNode) { v.parentNode.removeChild(v); } + }); + } + + // allow expressions to unmount themselves + unmountAll(expressions); + each(__.instAttrs, function (a) { return a.expr && a.expr.unmount && a.expr.unmount(); }); + + // clear the tag html if it's necessary + if (mustKeepRoot) { setInnerHTML(root, ''); } + // otherwise detach the root tag from the DOM + else if (p) { p.removeChild(root); } + + // custom internal unmount function to avoid relying on the observable + if (__.onUnmount) { __.onUnmount(); } + + // weird fix for a weird edge case #2409 and #2436 + // some users might use your software not as you've expected + // so I need to add these dirty hacks to mitigate unexpected issues + if (!tag.isMounted) { setMountState.call(tag, true); } + + setMountState.call(tag, false); + + delete root._tag; + + return tag + } + + /** + * Tag creation factory function + * @constructor + * @param { Object } impl - it contains the tag template, and logic + * @param { Object } conf - tag options + * @param { String } innerHTML - html that eventually we need to inject in the tag + */ + function createTag(impl, conf, innerHTML) { + if ( impl === void 0 ) impl = {}; + if ( conf === void 0 ) conf = {}; + + var tag = conf.context || {}; + var opts = conf.opts || {}; + var parent = conf.parent; + var isLoop = conf.isLoop; + var isAnonymous = !!conf.isAnonymous; + var skipAnonymous = settings.skipAnonymousTags && isAnonymous; + var item = conf.item; + // available only for the looped nodes + var index = conf.index; + // All attributes on the Tag when it's first parsed + var instAttrs = []; + // expressions on this type of Tag + var implAttrs = []; + var tmpl = impl.tmpl; + var expressions = []; + var root = conf.root; + var tagName = conf.tagName || getName(root); + var isVirtual = tagName === 'virtual'; + var isInline = !isVirtual && !tmpl; + var dom; + + if (isInline || isLoop && isAnonymous) { + dom = root; + } else { + if (!isVirtual) { root.innerHTML = ''; } + dom = mkdom(tmpl, innerHTML, isSvg(root)); + } + + // make this tag observable + if (!skipAnonymous) { observable(tag); } + + // only call unmount if we have a valid __TAG_IMPL (has name property) + if (impl.name && root._tag) { root._tag.unmount(true); } + + define(tag, '__', { + impl: impl, + root: root, + skipAnonymous: skipAnonymous, + implAttrs: implAttrs, + isAnonymous: isAnonymous, + instAttrs: instAttrs, + innerHTML: innerHTML, + tagName: tagName, + index: index, + isLoop: isLoop, + isInline: isInline, + item: item, + parent: parent, + // tags having event listeners + // it would be better to use weak maps here but we can not introduce breaking changes now + listeners: [], + // these vars will be needed only for the virtual tags + virts: [], + wasCreated: false, + tail: null, + head: null + }); + + // tag protected properties + return [ + ['isMounted', false], + // create a unique id to this tag + // it could be handy to use it also to improve the virtual dom rendering speed + ['_riot_id', uid()], + ['root', root], + ['opts', opts, { writable: true, enumerable: true }], + ['parent', parent || null], + // protect the "tags" and "refs" property from being overridden + ['tags', {}], + ['refs', {}], + ['update', function (data) { return componentUpdate(tag, data, expressions); }], + ['mixin', function () { + var mixins = [], len = arguments.length; + while ( len-- ) mixins[ len ] = arguments[ len ]; + + return componentMixin.apply(void 0, [ tag ].concat( mixins )); + }], + ['mount', function () { return componentMount(tag, dom, expressions, opts); }], + ['unmount', function (mustKeepRoot) { return tagUnmount(tag, mustKeepRoot, expressions); }] + ].reduce(function (acc, ref) { + var key = ref[0]; + var value = ref[1]; + var opts = ref[2]; + + define(tag, key, value, opts); + return acc + }, extend(tag, item)) + } + + /** + * Mount a tag creating new Tag instance + * @param { Object } root - dom node where the tag will be mounted + * @param { String } tagName - name of the riot tag we want to mount + * @param { Object } opts - options to pass to the Tag instance + * @param { Object } ctx - optional context that will be used to extend an existing class ( used in riot.Tag ) + * @returns { Tag } a new Tag instance + */ + function mount$1(root, tagName, opts, ctx) { + var impl = __TAG_IMPL[tagName]; + var implClass = __TAG_IMPL[tagName].class; + var context = ctx || (implClass ? create(implClass.prototype) : {}); + // cache the inner HTML to fix #855 + var innerHTML = root._innerHTML = root._innerHTML || root.innerHTML; + var conf = extend({ root: root, opts: opts, context: context }, { parent: opts ? opts.parent : null }); + var tag; + + if (impl && root) { tag = createTag(impl, conf, innerHTML); } + + if (tag && tag.mount) { + tag.mount(true); + // add this tag to the virtualDom variable + if (!contains(__TAGS_CACHE, tag)) { __TAGS_CACHE.push(tag); } + } + + return tag + } + + + + var tags = /*#__PURE__*/Object.freeze({ + arrayishAdd: arrayishAdd, + getTagName: getName, + inheritParentProps: inheritParentProps, + mountTo: mount$1, + selectTags: query, + arrayishRemove: arrayishRemove, + getTag: get, + initChildTag: initChild, + moveChildTag: moveChild, + makeReplaceVirtual: makeReplaceVirtual, + getImmediateCustomParentTag: getImmediateCustomParent, + makeVirtual: makeVirtual, + moveVirtual: moveVirtual, + unmountAll: unmountAll, + createIfDirective: createIfDirective, + createRefDirective: createRefDirective + }); + + /** + * Riot public api + */ + var settings$1 = settings; + var util = { + tmpl: tmpl, + brackets: brackets, + styleManager: styleManager, + vdom: __TAGS_CACHE, + styleNode: styleManager.styleNode, + // export the riot internal utils as well + dom: dom, + check: check, + misc: misc, + tags: tags + }; + + // export the core props/methods + var Tag$1 = Tag; + var tag$1 = tag; + var tag2$1 = tag2; + var mount$2 = mount; + var mixin$1 = mixin; + var update$2 = update$1; + var unregister$1 = unregister; + var version$1 = version; + var observable$1 = observable; + + var riot$1 = extend({}, core, { + observable: observable, + settings: settings$1, + util: util, + }); + + var riot$2 = /*#__PURE__*/Object.freeze({ + settings: settings$1, + util: util, + Tag: Tag$1, + tag: tag$1, + tag2: tag2$1, + mount: mount$2, + mixin: mixin$1, + update: update$2, + unregister: unregister$1, + version: version$1, + observable: observable$1, + default: riot$1 + }); + + /** + * Compiler for riot custom tags + * @version v3.5.2 + */ + + // istanbul ignore next + function safeRegex (re) { + var arguments$1 = arguments; + + var src = re.source; + var opt = re.global ? 'g' : ''; + + if (re.ignoreCase) { opt += 'i'; } + if (re.multiline) { opt += 'm'; } + + for (var i = 1; i < arguments.length; i++) { + src = src.replace('@', '\\' + arguments$1[i]); + } + + return new RegExp(src, opt) + } + + /** + * @module parsers + */ + var parsers = (function (win) { + + var _p = {}; + + function _r (name) { + var parser = win[name]; + + if (parser) { return parser } + + throw new Error('Parser "' + name + '" not loaded.') + } + + function _req (name) { + var parts = name.split('.'); + + if (parts.length !== 2) { throw new Error('Bad format for parsers._req') } + + var parser = _p[parts[0]][parts[1]]; + if (parser) { return parser } + + throw new Error('Parser "' + name + '" not found.') + } + + function extend (obj, props) { + if (props) { + for (var prop in props) { + /* istanbul ignore next */ + if (props.hasOwnProperty(prop)) { + obj[prop] = props[prop]; + } + } + } + return obj + } + + function renderPug (compilerName, html, opts, url) { + opts = extend({ + pretty: true, + filename: url, + doctype: 'html' + }, opts); + return _r(compilerName).render(html, opts) + } + + _p.html = { + jade: function (html, opts, url) { + /* eslint-disable */ + console.log('DEPRECATION WARNING: jade was renamed "pug" - The jade parser will be removed in riot@3.0.0!'); + /* eslint-enable */ + return renderPug('jade', html, opts, url) + }, + pug: function (html, opts, url) { + return renderPug('pug', html, opts, url) + } + }; + _p.css = { + less: function (tag, css, opts, url) { + var ret; + + opts = extend({ + sync: true, + syncImport: true, + filename: url + }, opts); + _r('less').render(css, opts, function (err, result) { + // istanbul ignore next + if (err) { throw err } + ret = result.css; + }); + return ret + } + }; + _p.js = { + + es6: function (js, opts, url) { // eslint-disable-line no-unused-vars + return _r('Babel').transform( // eslint-disable-line + js, + extend({ + plugins: [ + ['transform-es2015-template-literals', { loose: true }], + 'transform-es2015-literals', + 'transform-es2015-function-name', + 'transform-es2015-arrow-functions', + 'transform-es2015-block-scoped-functions', + ['transform-es2015-classes', { loose: true }], + 'transform-es2015-object-super', + 'transform-es2015-shorthand-properties', + 'transform-es2015-duplicate-keys', + ['transform-es2015-computed-properties', { loose: true }], + ['transform-es2015-for-of', { loose: true }], + 'transform-es2015-sticky-regex', + 'transform-es2015-unicode-regex', + 'check-es2015-constants', + ['transform-es2015-spread', { loose: true }], + 'transform-es2015-parameters', + ['transform-es2015-destructuring', { loose: true }], + 'transform-es2015-block-scoping', + 'transform-es2015-typeof-symbol', + ['transform-es2015-modules-commonjs', { allowTopLevelThis: true }], + ['transform-regenerator', { async: false, asyncGenerators: false }] + ] + }, + opts + )).code + }, + buble: function (js, opts, url) { + opts = extend({ + source: url, + modules: false + }, opts); + return _r('buble').transform(js, opts).code + }, + coffee: function (js, opts) { + return _r('CoffeeScript').compile(js, extend({ bare: true }, opts)) + }, + livescript: function (js, opts) { + return _r('livescript').compile(js, extend({ bare: true, header: false }, opts)) + }, + typescript: function (js, opts) { + return _r('typescript')(js, opts) + }, + none: function (js) { + return js + } + }; + _p.js.javascript = _p.js.none; + _p.js.coffeescript = _p.js.coffee; + _p._req = _req; + _p.utils = { + extend: extend + }; + + return _p + + })(window || global); + + var S_SQ_STR = /'[^'\n\r\\]*(?:\\(?:\r\n?|[\S\s])[^'\n\r\\]*)*'/.source; + + var S_R_SRC1 = [ + /\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//.source, + '//.*', + S_SQ_STR, + S_SQ_STR.replace(/'/g, '"'), + '([/`])' + ].join('|'); + + var S_R_SRC2 = (S_R_SRC1.slice(0, -2)) + "{}])"; + + function skipES6str (code, start, stack) { + + var re = /[`$\\]/g; + + re.lastIndex = start; + while (re.exec(code)) { + var end = re.lastIndex; + var c = code[end - 1]; + + if (c === '`') { + return end + } + if (c === '$' && code[end] === '{') { + stack.push('`', '}'); + return end + 1 + } + re.lastIndex++; + } + + throw new Error('Unclosed ES6 template') + } + + function jsSplitter (code, start) { + + var re1 = new RegExp(S_R_SRC1, 'g'); + var re2; + + /* istanbul ignore next */ + var skipRegex = brackets.skipRegex; + var offset = start | 0; + var result = [[]]; + var stack = []; + var re = re1; + + var lastPos = re.lastIndex = offset; + var str, ch, idx, end, match; + + while ((match = re.exec(code))) { + idx = match.index; + end = re.lastIndex; + str = ''; + ch = match[1]; + + if (ch) { + + if (ch === '{') { + stack.push('}'); + + } else if (ch === '}') { + if (stack.pop() !== ch) { + throw new Error("Unexpected '}'") + + } else if (stack[stack.length - 1] === '`') { + ch = stack.pop(); + } + + } else if (ch === '/') { + end = skipRegex(code, idx); + + if (end > idx + 1) { + str = code.slice(idx, end); + } + } + + if (ch === '`') { + end = skipES6str(code, end, stack); + str = code.slice(idx, end); + + if (stack.length) { + re = re2 || (re2 = new RegExp(S_R_SRC2, 'g')); + } else { + re = re1; + } + } + + } else { + + str = match[0]; + + if (str[0] === '/') { + str = str[1] === '*' ? ' ' : ''; + code = code.slice(offset, idx) + str + code.slice(end); + end = idx + str.length; + str = ''; + + } else if (str.length === 2) { + str = ''; + } + } + + if (str) { + result[0].push(code.slice(lastPos, idx)); + result.push(str); + lastPos = end; + } + + re.lastIndex = end; + } + + result[0].push(code.slice(lastPos)); + + return result + } + + /** + * @module compiler + */ + + var extend$1 = parsers.utils.extend; + /* eslint-enable */ + + var S_LINESTR = /"[^"\n\\]*(?:\\[\S\s][^"\n\\]*)*"|'[^'\n\\]*(?:\\[\S\s][^'\n\\]*)*'/.source; + + var S_STRINGS = brackets.R_STRINGS.source; + + var HTML_ATTRS = / *([-\w:\xA0-\xFF]+) ?(?:= ?('[^']*'|"[^"]*"|\S+))?/g; + + var HTML_COMMS = RegExp(//.source + '|' + S_LINESTR, 'g'); + + var HTML_TAGS = /<(-?[A-Za-z][-\w\xA0-\xFF]*)(?:\s+([^"'/>]*(?:(?:"[^"]*"|'[^']*'|\/[^>])[^'"/>]*)*)|\s*)(\/?)>/g; + + var HTML_PACK = />[ \t]+<(-?[A-Za-z]|\/[-A-Za-z])/g; + + var RIOT_ATTRS = ['style', 'src', 'd', 'value']; + + var VOID_TAGS = /^(?:input|img|br|wbr|hr|area|base|col|embed|keygen|link|meta|param|source|track)$/; + + var PRE_TAGS = /]*|"[^"]*")*)?>([\S\s]+?)<\/pre\s*>/gi; + + var SPEC_TYPES = /^"(?:number|date(?:time)?|time|month|email|color)\b/i; + + var IMPORT_STATEMENT = /^\s*import(?!\w|(\s)?\()(?:(?:\s|[^\s'"])*)['|"].*\n?/gm; + + var TRIM_TRAIL = /[ \t]+$/gm; + + var + RE_HASEXPR = safeRegex(/@#\d/, 'x01'), + RE_REPEXPR = safeRegex(/@#(\d+)/g, 'x01'), + CH_IDEXPR = '\x01#', + CH_DQCODE = '\u2057', + DQ = '"', + SQ = "'"; + + function cleanSource (src) { + var + mm, + re = HTML_COMMS; + + if (src.indexOf('\r') !== 1) { + src = src.replace(/\r\n?/g, '\n'); + } + + re.lastIndex = 0; + while ((mm = re.exec(src))) { + if (mm[0][0] === '<') { + src = RegExp.leftContext + RegExp.rightContext; + re.lastIndex = mm[3] + 1; + } + } + return src + } + + function parseAttribs (str, pcex) { + var + list = [], + match, + type, vexp; + + HTML_ATTRS.lastIndex = 0; + + str = str.replace(/\s+/g, ' '); + + while ((match = HTML_ATTRS.exec(str))) { + var + k = match[1].toLowerCase(), + v = match[2]; + + if (!v) { + list.push(k); + } else { + + if (v[0] !== DQ) { + v = DQ + (v[0] === SQ ? v.slice(1, -1) : v) + DQ; + } + + if (k === 'type' && SPEC_TYPES.test(v)) { + type = v; + } else { + if (RE_HASEXPR.test(v)) { + + if (k === 'value') { vexp = 1; } + if (RIOT_ATTRS.indexOf(k) !== -1) { k = 'riot-' + k; } + } + + list.push(k + '=' + v); + } + } + } + + if (type) { + if (vexp) { type = DQ + pcex._bp[0] + SQ + type.slice(1, -1) + SQ + pcex._bp[1] + DQ; } + list.push('type=' + type); + } + return list.join(' ') + } + + function splitHtml (html, opts, pcex) { + var _bp = pcex._bp; + + if (html && _bp[4].test(html)) { + var + jsfn = opts.expr && (opts.parser || opts.type) ? _compileJS : 0, + list = brackets.split(html, 0, _bp), + expr; + + for (var i = 1; i < list.length; i += 2) { + expr = list[i]; + if (expr[0] === '^') { + expr = expr.slice(1); + } else if (jsfn) { + expr = jsfn(expr, opts).trim(); + if (expr.slice(-1) === ';') { expr = expr.slice(0, -1); } + } + list[i] = CH_IDEXPR + (pcex.push(expr) - 1) + _bp[1]; + } + html = list.join(''); + } + return html + } + + function restoreExpr (html, pcex) { + if (pcex.length) { + html = html.replace(RE_REPEXPR, function (_, d) { + + return pcex._bp[0] + pcex[d].trim().replace(/[\r\n]+/g, ' ').replace(/"/g, CH_DQCODE) + }); + } + return html + } + + function _compileHTML (html, opts, pcex) { + if (!/\S/.test(html)) { return '' } + + html = splitHtml(html, opts, pcex) + .replace(HTML_TAGS, function (_, name, attr, ends) { + + name = name.toLowerCase(); + + ends = ends && !VOID_TAGS.test(name) ? '>' + }); + + if (!opts.whitespace) { + var p = []; + + if (/]/.test(html)) { + html = html.replace(PRE_TAGS, function (q) { + p.push(q); + return '\u0002' + }); + } + + html = html.trim().replace(/\s+/g, ' '); + + if (p.length) { html = html.replace(/\u0002/g, function () { return p.shift() }); } // eslint-disable-line + } + + if (opts.compact) { html = html.replace(HTML_PACK, '><$1'); } + + return restoreExpr(html, pcex).replace(TRIM_TRAIL, '') + } + + function compileHTML (html, opts, pcex) { + + if (Array.isArray(opts)) { + pcex = opts; + opts = {}; + } else { + if (!pcex) { pcex = []; } + if (!opts) { opts = {}; } + } + + pcex._bp = brackets.array(opts.brackets); + + return _compileHTML(cleanSource(html), opts, pcex) + } + + var JS_ES6SIGN = /^[ \t]*(((?:async|\*)\s*)?([$_A-Za-z][$\w]*))\s*\([^()]*\)\s*{/m; + + function riotjs (js) { + var + parts = [], + match, + toes5, + pos, + method, + prefix, + name, + RE = RegExp; + + var src = jsSplitter(js); + js = src.shift().join('<%>'); + + while ((match = js.match(JS_ES6SIGN))) { + + parts.push(RE.leftContext); + js = RE.rightContext; + pos = skipBody(js); + + method = match[1]; + prefix = match[2] || ''; + name = match[3]; + + toes5 = !/^(?:if|while|for|switch|catch|function)$/.test(name); + + if (toes5) { + name = match[0].replace(method, 'this.' + name + ' =' + prefix + ' function'); + } else { + name = match[0]; + } + + parts.push(name, js.slice(0, pos)); + js = js.slice(pos); + + if (toes5 && !/^\s*.\s*bind\b/.test(js)) { parts.push('.bind(this)'); } + } + + if (parts.length) { + js = parts.join('') + js; + } + + if (src.length) { + js = js.replace(/<%>/g, function () { + return src.shift() + }); + } + + return js + + function skipBody (s) { + var r = /[{}]/g; + var i = 1; + + while (i && r.exec(s)) { + if (s[r.lastIndex - 1] === '{') { ++i; } + else { --i; } + } + return i ? s.length : r.lastIndex + } + } + + function _compileJS (js, opts, type, parserOpts, url) { + if (!/\S/.test(js)) { return '' } + if (!type) { type = opts.type; } + + var parser = opts.parser || type && parsers._req('js.' + type, true) || riotjs; + + return parser(js, parserOpts, url).replace(/\r\n?/g, '\n').replace(TRIM_TRAIL, '') + } + + function compileJS (js, opts, type, userOpts) { + if (typeof opts === 'string') { + userOpts = type; + type = opts; + opts = {}; + } + if (type && typeof type === 'object') { + userOpts = type; + type = ''; + } + if (!userOpts) { userOpts = {}; } + + return _compileJS(js, opts || {}, type, userOpts.parserOptions, userOpts.url) + } + + var CSS_SELECTOR = RegExp('([{}]|^)[; ]*((?:[^@ ;{}][^{}]*)?[^@ ;{}:] ?)(?={)|' + S_LINESTR, 'g'); + + function scopedCSS (tag, css) { + var scope = ':scope'; + + return css.replace(CSS_SELECTOR, function (m, p1, p2) { + + if (!p2) { return m } + + p2 = p2.replace(/[^,]+/g, function (sel) { + var s = sel.trim(); + + if (s.indexOf(tag) === 0) { + return sel + } + + if (!s || s === 'from' || s === 'to' || s.slice(-1) === '%') { + return sel + } + + if (s.indexOf(scope) < 0) { + s = tag + ' ' + s + ',[data-is="' + tag + '"] ' + s; + } else { + s = s.replace(scope, tag) + ',' + + s.replace(scope, '[data-is="' + tag + '"]'); + } + return s + }); + + return p1 ? p1 + ' ' + p2 : p2 + }) + } + + function _compileCSS (css, tag, type, opts) { + opts = opts || {}; + + if (type) { + if (type !== 'css') { + + var parser = parsers._req('css.' + type, true); + css = parser(tag, css, opts.parserOpts || {}, opts.url); + } + } + + css = css.replace(brackets.R_MLCOMMS, '').replace(/\s+/g, ' ').trim(); + if (tag) { css = scopedCSS(tag, css); } + + return css + } + + function compileCSS (css, type, opts) { + if (type && typeof type === 'object') { + opts = type; + type = ''; + } else if (!opts) { opts = {}; } + + return _compileCSS(css, opts.tagName, type, opts) + } + + var TYPE_ATTR = /\stype\s*=\s*(?:(['"])(.+?)\1|(\S+))/i; + + var MISC_ATTR = '\\s*=\\s*(' + S_STRINGS + '|{[^}]+}|\\S+)'; + + var END_TAGS = /\/>\n|^<(?:\/?-?[A-Za-z][-\w\xA0-\xFF]*\s*|-?[A-Za-z][-\w\xA0-\xFF]*\s+[-\w:\xA0-\xFF][\S\s]*?)>\n/; + + function _q (s, r) { + if (!s) { return "''" } + s = SQ + s.replace(/\\/g, '\\\\').replace(/'/g, "\\'") + SQ; + return r && s.indexOf('\n') !== -1 ? s.replace(/\n/g, '\\n') : s + } + + function mktag (name, html, css, attr, js, imports, opts) { + var + c = opts.debug ? ',\n ' : ', ', + s = '});'; + + if (js && js.slice(-1) !== '\n') { s = '\n' + s; } + + return imports + 'riot.tag2(\'' + name + SQ + + c + _q(html, 1) + + c + _q(css) + + c + _q(attr) + ', function(opts) {\n' + js + s + } + + function splitBlocks (str) { + if (/<[-\w]/.test(str)) { + var + m, + k = str.lastIndexOf('<'), + n = str.length; + + while (k !== -1) { + m = str.slice(k, n).match(END_TAGS); + if (m) { + k += m.index + m[0].length; + m = str.slice(0, k); + if (m.slice(-5) === '<-/>\n') { m = m.slice(0, -5); } + return [m, str.slice(k)] + } + n = k; + k = str.lastIndexOf('<', k - 1); + } + } + return ['', str] + } + + function getType (attribs) { + if (attribs) { + var match = attribs.match(TYPE_ATTR); + + match = match && (match[2] || match[3]); + if (match) { + return match.replace('text/', '') + } + } + return '' + } + + function getAttrib (attribs, name) { + if (attribs) { + var match = attribs.match(RegExp('\\s' + name + MISC_ATTR, 'i')); + + match = match && match[1]; + if (match) { + return (/^['"]/).test(match) ? match.slice(1, -1) : match + } + } + return '' + } + + function unescapeHTML (str) { + return str + .replace(/&/g, '&') + .replace(/</g, '<') + .replace(/>/g, '>') + .replace(/"/g, '"') + .replace(/'/g, '\'') + } + + function getParserOptions (attribs) { + var opts = unescapeHTML(getAttrib(attribs, 'options')); + + return opts ? JSON.parse(opts) : null + } + + function getCode (code, opts, attribs, base) { + var + type = getType(attribs), + src = getAttrib(attribs, 'src'), + jsParserOptions = extend$1({}, opts.parserOptions.js); + + if (src) { return false } + + return _compileJS( + code, + opts, + type, + extend$1(jsParserOptions, getParserOptions(attribs)), + base + ) + } + + function cssCode (code, opts, attribs, url, tag) { + var + parserStyleOptions = extend$1({}, opts.parserOptions.style), + extraOpts = { + parserOpts: extend$1(parserStyleOptions, getParserOptions(attribs)), + url: url + }; + + return _compileCSS(code, tag, getType(attribs) || opts.style, extraOpts) + } + + function compileTemplate (html, url, lang, opts) { + + var parser = parsers._req('html.' + lang, true); + return parser(html, opts, url) + } + + var + + CUST_TAG = RegExp(/^([ \t]*)<(-?[A-Za-z][-\w\xA0-\xFF]*)(?:\s+([^'"/>]+(?:(?:@|\/[^>])[^'"/>]*)*)|\s*)?(?:\/>|>[ \t]*\n?([\S\s]*)^\1<\/\2\s*>|>(.*)<\/\2\s*>)/ + .source.replace('@', S_STRINGS), 'gim'), + + SCRIPTS = /]*)?>\n?([\S\s]*?)<\/script\s*>/gi, + + STYLES = /]*)?>\n?([\S\s]*?)<\/style\s*>/gi; + + function compile (src, opts, url) { + var + parts = [], + included, + output = src, + defaultParserptions = { + + template: {}, + js: {}, + style: {} + }; + + if (!opts) { opts = {}; } + + opts.parserOptions = extend$1(defaultParserptions, opts.parserOptions || {}); + + included = opts.exclude + ? function (s) { return opts.exclude.indexOf(s) < 0 } : function () { return 1 }; + + if (!url) { url = ''; } + + var _bp = brackets.array(opts.brackets); + + if (opts.template) { + output = compileTemplate(output, url, opts.template, opts.parserOptions.template); + } + + output = cleanSource(output) + .replace(CUST_TAG, function (_, indent, tagName, attribs, body, body2) { + var + jscode = '', + styles = '', + html = '', + imports = '', + pcex = []; + + pcex._bp = _bp; + + tagName = tagName.toLowerCase(); + + attribs = attribs && included('attribs') + ? restoreExpr( + parseAttribs( + splitHtml(attribs, opts, pcex), + pcex), + pcex) : ''; + + if ((body || (body = body2)) && /\S/.test(body)) { + + if (body2) { + + if (included('html')) { html = _compileHTML(body2, opts, pcex); } + } else { + + body = body.replace(RegExp('^' + indent, 'gm'), ''); + + body = body.replace(SCRIPTS, function (_m, _attrs, _script) { + if (included('js')) { + var code = getCode(_script, opts, _attrs, url); + + if (code) { jscode += (jscode ? '\n' : '') + code; } + } + return '' + }); + + body = body.replace(STYLES, function (_m, _attrs, _style) { + if (included('css')) { + styles += (styles ? ' ' : '') + cssCode(_style, opts, _attrs, url, tagName); + } + return '' + }); + + var blocks = splitBlocks(body.replace(TRIM_TRAIL, '')); + + if (included('html')) { + html = _compileHTML(blocks[0], opts, pcex); + } + + if (included('js')) { + body = _compileJS(blocks[1], opts, null, null, url); + if (body) { jscode += (jscode ? '\n' : '') + body; } + jscode = jscode.replace(IMPORT_STATEMENT, function (s) { + imports += s.trim() + '\n'; + return '' + }); + } + } + } + + jscode = /\S/.test(jscode) ? jscode.replace(/\n{3,}/g, '\n\n') : ''; + + if (opts.entities) { + parts.push({ + tagName: tagName, + html: html, + css: styles, + attribs: attribs, + js: jscode, + imports: imports + }); + return '' + } + + return mktag(tagName, html, styles, attribs, jscode, imports, opts) + }); + + if (opts.entities) { return parts } + + return output + } + + var version$2 = 'v3.5.2'; + + var compiler = { + compile: compile, + compileHTML: compileHTML, + compileCSS: compileCSS, + compileJS: compileJS, + parsers: parsers, + version: version$2 + }; + + var + promise, // emits the 'ready' event and runs the first callback + ready; // all the scripts were compiled? + + // gets the source of an external tag with an async call + function GET (url, fn, opts) { + var req = new XMLHttpRequest(); + + req.onreadystatechange = function () { + if (req.readyState === 4) { + if (req.status === 200 || !req.status && req.responseText.length) { + fn(req.responseText, opts, url); + } else { + compile$1.error(("\"" + url + "\" not found")); + } + } + }; + + req.onerror = function (e) { return compile$1.error(e); }; + + req.open('GET', url, true); + req.send(''); + } + + // evaluates a compiled tag within the global context + function globalEval (js, url) { + if (typeof js === T_STRING) { + var + node = makeElement('script'), + root = document.documentElement; + + // make the source available in the "(no domain)" tab + // of Chrome DevTools, with a .js extension + if (url) { js += '\n//# sourceURL=' + url + '.js'; } + + node.text = js; + root.appendChild(node); + root.removeChild(node); + } + } + + // compiles all the internal and external tags on the page + function compileScripts (fn, xopt) { + var + scripts = $$('script[type="riot/tag"]'), + scriptsAmount = scripts.length; + + function done() { + promise.trigger('ready'); + ready = true; + if (fn) { fn(); } + } + + function compileTag (src, opts, url) { + var code = compiler.compile(src, opts, url); + + globalEval(code, url); + if (!--scriptsAmount) { done(); } + } + + if (!scriptsAmount) { done(); } + else { + for (var i = 0; i < scripts.length; ++i) { + var + script = scripts[i], + opts = extend({template: getAttribute(script, 'template')}, xopt), + url = getAttribute(script, 'src') || getAttribute(script, 'data-src'); + + url ? GET(url, compileTag, opts) : compileTag(script.innerHTML, opts); + } + } + } + + var parsers$1 = compiler.parsers; + + /* + Compilation for the browser + */ + function compile$1 (arg, fn, opts) { + + if (typeof arg === T_STRING) { + + // 2nd parameter is optional, but can be null + if (isObject(fn)) { + opts = fn; + fn = false; + } + + // `riot.compile(tag [, callback | true][, options])` + if (/^\s* this.maxIterations) { + throw new Error('Infinite loop detected - reached max iterations') + } + }; + + function getGlobal (str) { + var ctx = (typeof window !== 'undefined' ? window : typeof commonjsGlobal !== 'undefined' ? commonjsGlobal : this); + return typeof str !== 'undefined' ? ctx[str] : ctx + } + + var names = ['Object', 'String', 'Boolean', 'Number', 'RegExp', 'Date', 'Array']; + var immutable = { string: 'String', boolean: 'Boolean', number: 'Number' }; + + var primitives = names.map(getGlobal); + var protos = primitives.map(getProto); + + function Primitives (context) { + var this$1 = this; + + if (this instanceof Primitives) { + this.context = context; + for (var i = 0; i < names.length; i++) { + if (!this$1.context[names[i]]) { + this$1.context[names[i]] = wrap(primitives[i]); + } + } + } else { + return new Primitives(context) + } + } + + Primitives.prototype.replace = function (value) { + var primIndex = primitives.indexOf(value), + protoIndex = protos.indexOf(value), + name; + + if (~primIndex) { + name = names[primIndex]; + return this.context[name] + } else if (~protoIndex) { + name = names[protoIndex]; + return this.context[name].prototype + } + + return value + }; + + Primitives.prototype.getPropertyObject = function (object, property) { + if (immutable[typeof object]) { + return this.getPrototypeOf(object) + } + return object + }; + + Primitives.prototype.isPrimitive = function (value) { + return !!~primitives.indexOf(value) || !!~protos.indexOf(value) + }; + + Primitives.prototype.getPrototypeOf = function (value) { + if (value == null) { // handle null and undefined + return value + } + + var immutableType = immutable[typeof value], + proto; + + if (immutableType) { + proto = this.context[immutableType].prototype; + } else { + proto = Object.getPrototypeOf(value); + } + + if (!proto || proto === Object.prototype) { + return null + } + + var replacement = this.replace(proto); + + if (replacement === value) { + replacement = this.replace(Object.prototype); + } + return replacement + + }; + + Primitives.prototype.applyNew = function (func, args) { + if (func.wrapped) { + var prim = Object.getPrototypeOf(func); + var instance = new (Function.prototype.bind.apply(prim, arguments)); + + setProto(instance, func.prototype); + return instance + } + + return new (Function.prototype.bind.apply(func, arguments)) + + }; + + function getProto (func) { + return func.prototype + } + + function setProto (obj, proto) { + obj.__proto__ = proto; // eslint-disable-line + } + + function wrap (prim) { + var proto = Object.create(prim.prototype); + + var result = function () { + if (this instanceof result) { + prim.apply(this, arguments); + } else { + var instance = prim.apply(null, arguments); + + setProto(instance, proto); + return instance + } + }; + + setProto(result, prim); + result.prototype = proto; + result.wrapped = true; + return result + } + + var commonjsGlobal$$1 = typeof window !== 'undefined' ? window : typeof commonjsGlobal !== 'undefined' ? commonjsGlobal : typeof self !== 'undefined' ? self : {}; + + + + + + function createCommonjsModule$$1(fn, module) { + return module = { exports: {} }, fn(module, module.exports), module.exports; + } + + var esprima = createCommonjsModule$$1(function (module, exports) { + (function webpackUniversalModuleDefinition(root, factory) { + /* istanbul ignore next */ + module.exports = factory(); + })(commonjsGlobal$$1, function() { + return /******/ (function(modules) { // webpackBootstrap + /******/ // The module cache + /******/ var installedModules = {}; + + /******/ // The require function + /******/ function __webpack_require__(moduleId) { + + /******/ // Check if module is in cache + /* istanbul ignore if */ + /******/ if(installedModules[moduleId]) + /******/ { return installedModules[moduleId].exports; } + + /******/ // Create a new module (and put it into the cache) + /******/ var module = installedModules[moduleId] = { + /******/ exports: {}, + /******/ id: moduleId, + /******/ loaded: false + /******/ }; + + /******/ // Execute the module function + /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); + + /******/ // Flag the module as loaded + /******/ module.loaded = true; + + /******/ // Return the exports of the module + /******/ return module.exports; + /******/ } + + + /******/ // expose the modules object (__webpack_modules__) + /******/ __webpack_require__.m = modules; + + /******/ // expose the module cache + /******/ __webpack_require__.c = installedModules; + + /******/ // __webpack_public_path__ + /******/ __webpack_require__.p = ""; + + /******/ // Load entry module and return exports + /******/ return __webpack_require__(0); + /******/ }) + /************************************************************************/ + /******/ ([ + /* 0 */ + /***/ function(module, exports, __webpack_require__) { + var comment_handler_1 = __webpack_require__(1); + var parser_1 = __webpack_require__(3); + var jsx_parser_1 = __webpack_require__(11); + var tokenizer_1 = __webpack_require__(15); + function parse(code, options, delegate) { + var commentHandler = null; + var proxyDelegate = function (node, metadata) { + if (delegate) { + delegate(node, metadata); + } + if (commentHandler) { + commentHandler.visit(node, metadata); + } + }; + var parserDelegate = (typeof delegate === 'function') ? proxyDelegate : null; + var collectComment = false; + if (options) { + collectComment = (typeof options.comment === 'boolean' && options.comment); + var attachComment = (typeof options.attachComment === 'boolean' && options.attachComment); + if (collectComment || attachComment) { + commentHandler = new comment_handler_1.CommentHandler(); + commentHandler.attach = attachComment; + options.comment = true; + parserDelegate = proxyDelegate; + } + } + var parser; + if (options && typeof options.jsx === 'boolean' && options.jsx) { + parser = new jsx_parser_1.JSXParser(code, options, parserDelegate); + } + else { + parser = new parser_1.Parser(code, options, parserDelegate); + } + var ast = (parser.parseProgram()); + if (collectComment) { + ast.comments = commentHandler.comments; + } + if (parser.config.tokens) { + ast.tokens = parser.tokens; + } + if (parser.config.tolerant) { + ast.errors = parser.errorHandler.errors; + } + return ast; + } + exports.parse = parse; + function tokenize(code, options, delegate) { + var tokenizer = new tokenizer_1.Tokenizer(code, options); + var tokens; + tokens = []; + try { + while (true) { + var token = tokenizer.getNextToken(); + if (!token) { + break; + } + if (delegate) { + token = delegate(token); + } + tokens.push(token); + } + } + catch (e) { + tokenizer.errorHandler.tolerate(e); + } + if (tokenizer.errorHandler.tolerant) { + tokens.errors = tokenizer.errors(); + } + return tokens; + } + exports.tokenize = tokenize; + var syntax_1 = __webpack_require__(2); + exports.Syntax = syntax_1.Syntax; + // Sync with *.json manifests. + exports.version = '3.1.3'; + + + /***/ }, + /* 1 */ + /***/ function(module, exports, __webpack_require__) { + var syntax_1 = __webpack_require__(2); + var CommentHandler = (function () { + function CommentHandler() { + this.attach = false; + this.comments = []; + this.stack = []; + this.leading = []; + this.trailing = []; + } + CommentHandler.prototype.insertInnerComments = function (node, metadata) { + var this$1 = this; + + // innnerComments for properties empty block + // `function a() {/** comments **\/}` + if (node.type === syntax_1.Syntax.BlockStatement && node.body.length === 0) { + var innerComments = []; + for (var i = this.leading.length - 1; i >= 0; --i) { + var entry = this$1.leading[i]; + if (metadata.end.offset >= entry.start) { + innerComments.unshift(entry.comment); + this$1.leading.splice(i, 1); + this$1.trailing.splice(i, 1); + } + } + if (innerComments.length) { + node.innerComments = innerComments; + } + } + }; + CommentHandler.prototype.findTrailingComments = function (node, metadata) { + var this$1 = this; + + var trailingComments = []; + if (this.trailing.length > 0) { + for (var i = this.trailing.length - 1; i >= 0; --i) { + var entry_1 = this$1.trailing[i]; + if (entry_1.start >= metadata.end.offset) { + trailingComments.unshift(entry_1.comment); + } + } + this.trailing.length = 0; + return trailingComments; + } + var entry = this.stack[this.stack.length - 1]; + if (entry && entry.node.trailingComments) { + var firstComment = entry.node.trailingComments[0]; + if (firstComment && firstComment.range[0] >= metadata.end.offset) { + trailingComments = entry.node.trailingComments; + delete entry.node.trailingComments; + } + } + return trailingComments; + }; + CommentHandler.prototype.findLeadingComments = function (node, metadata) { + var this$1 = this; + + var leadingComments = []; + var target; + while (this.stack.length > 0) { + var entry = this$1.stack[this$1.stack.length - 1]; + if (entry && entry.start >= metadata.start.offset) { + target = this$1.stack.pop().node; + } + else { + break; + } + } + if (target) { + var count = target.leadingComments ? target.leadingComments.length : 0; + for (var i = count - 1; i >= 0; --i) { + var comment = target.leadingComments[i]; + if (comment.range[1] <= metadata.start.offset) { + leadingComments.unshift(comment); + target.leadingComments.splice(i, 1); + } + } + if (target.leadingComments && target.leadingComments.length === 0) { + delete target.leadingComments; + } + return leadingComments; + } + for (var i = this.leading.length - 1; i >= 0; --i) { + var entry = this$1.leading[i]; + if (entry.start <= metadata.start.offset) { + leadingComments.unshift(entry.comment); + this$1.leading.splice(i, 1); + } + } + return leadingComments; + }; + CommentHandler.prototype.visitNode = function (node, metadata) { + if (node.type === syntax_1.Syntax.Program && node.body.length > 0) { + return; + } + this.insertInnerComments(node, metadata); + var trailingComments = this.findTrailingComments(node, metadata); + var leadingComments = this.findLeadingComments(node, metadata); + if (leadingComments.length > 0) { + node.leadingComments = leadingComments; + } + if (trailingComments.length > 0) { + node.trailingComments = trailingComments; + } + this.stack.push({ + node: node, + start: metadata.start.offset + }); + }; + CommentHandler.prototype.visitComment = function (node, metadata) { + var type = (node.type[0] === 'L') ? 'Line' : 'Block'; + var comment = { + type: type, + value: node.value + }; + if (node.range) { + comment.range = node.range; + } + if (node.loc) { + comment.loc = node.loc; + } + this.comments.push(comment); + if (this.attach) { + var entry = { + comment: { + type: type, + value: node.value, + range: [metadata.start.offset, metadata.end.offset] + }, + start: metadata.start.offset + }; + if (node.loc) { + entry.comment.loc = node.loc; + } + node.type = type; + this.leading.push(entry); + this.trailing.push(entry); + } + }; + CommentHandler.prototype.visit = function (node, metadata) { + if (node.type === 'LineComment') { + this.visitComment(node, metadata); + } + else if (node.type === 'BlockComment') { + this.visitComment(node, metadata); + } + else if (this.attach) { + this.visitNode(node, metadata); + } + }; + return CommentHandler; + }()); + exports.CommentHandler = CommentHandler; + + + /***/ }, + /* 2 */ + /***/ function(module, exports) { + exports.Syntax = { + AssignmentExpression: 'AssignmentExpression', + AssignmentPattern: 'AssignmentPattern', + ArrayExpression: 'ArrayExpression', + ArrayPattern: 'ArrayPattern', + ArrowFunctionExpression: 'ArrowFunctionExpression', + BlockStatement: 'BlockStatement', + BinaryExpression: 'BinaryExpression', + BreakStatement: 'BreakStatement', + CallExpression: 'CallExpression', + CatchClause: 'CatchClause', + ClassBody: 'ClassBody', + ClassDeclaration: 'ClassDeclaration', + ClassExpression: 'ClassExpression', + ConditionalExpression: 'ConditionalExpression', + ContinueStatement: 'ContinueStatement', + DoWhileStatement: 'DoWhileStatement', + DebuggerStatement: 'DebuggerStatement', + EmptyStatement: 'EmptyStatement', + ExportAllDeclaration: 'ExportAllDeclaration', + ExportDefaultDeclaration: 'ExportDefaultDeclaration', + ExportNamedDeclaration: 'ExportNamedDeclaration', + ExportSpecifier: 'ExportSpecifier', + ExpressionStatement: 'ExpressionStatement', + ForStatement: 'ForStatement', + ForOfStatement: 'ForOfStatement', + ForInStatement: 'ForInStatement', + FunctionDeclaration: 'FunctionDeclaration', + FunctionExpression: 'FunctionExpression', + Identifier: 'Identifier', + IfStatement: 'IfStatement', + ImportDeclaration: 'ImportDeclaration', + ImportDefaultSpecifier: 'ImportDefaultSpecifier', + ImportNamespaceSpecifier: 'ImportNamespaceSpecifier', + ImportSpecifier: 'ImportSpecifier', + Literal: 'Literal', + LabeledStatement: 'LabeledStatement', + LogicalExpression: 'LogicalExpression', + MemberExpression: 'MemberExpression', + MetaProperty: 'MetaProperty', + MethodDefinition: 'MethodDefinition', + NewExpression: 'NewExpression', + ObjectExpression: 'ObjectExpression', + ObjectPattern: 'ObjectPattern', + Program: 'Program', + Property: 'Property', + RestElement: 'RestElement', + ReturnStatement: 'ReturnStatement', + SequenceExpression: 'SequenceExpression', + SpreadElement: 'SpreadElement', + Super: 'Super', + SwitchCase: 'SwitchCase', + SwitchStatement: 'SwitchStatement', + TaggedTemplateExpression: 'TaggedTemplateExpression', + TemplateElement: 'TemplateElement', + TemplateLiteral: 'TemplateLiteral', + ThisExpression: 'ThisExpression', + ThrowStatement: 'ThrowStatement', + TryStatement: 'TryStatement', + UnaryExpression: 'UnaryExpression', + UpdateExpression: 'UpdateExpression', + VariableDeclaration: 'VariableDeclaration', + VariableDeclarator: 'VariableDeclarator', + WhileStatement: 'WhileStatement', + WithStatement: 'WithStatement', + YieldExpression: 'YieldExpression' + }; + + + /***/ }, + /* 3 */ + /***/ function(module, exports, __webpack_require__) { + var assert_1 = __webpack_require__(4); + var messages_1 = __webpack_require__(5); + var error_handler_1 = __webpack_require__(6); + var token_1 = __webpack_require__(7); + var scanner_1 = __webpack_require__(8); + var syntax_1 = __webpack_require__(2); + var Node = __webpack_require__(10); + var ArrowParameterPlaceHolder = 'ArrowParameterPlaceHolder'; + var Parser = (function () { + function Parser(code, options, delegate) { + if (options === void 0) { options = {}; } + this.config = { + range: (typeof options.range === 'boolean') && options.range, + loc: (typeof options.loc === 'boolean') && options.loc, + source: null, + tokens: (typeof options.tokens === 'boolean') && options.tokens, + comment: (typeof options.comment === 'boolean') && options.comment, + tolerant: (typeof options.tolerant === 'boolean') && options.tolerant + }; + if (this.config.loc && options.source && options.source !== null) { + this.config.source = String(options.source); + } + this.delegate = delegate; + this.errorHandler = new error_handler_1.ErrorHandler(); + this.errorHandler.tolerant = this.config.tolerant; + this.scanner = new scanner_1.Scanner(code, this.errorHandler); + this.scanner.trackComment = this.config.comment; + this.operatorPrecedence = { + ')': 0, + ';': 0, + ',': 0, + '=': 0, + ']': 0, + '||': 1, + '&&': 2, + '|': 3, + '^': 4, + '&': 5, + '==': 6, + '!=': 6, + '===': 6, + '!==': 6, + '<': 7, + '>': 7, + '<=': 7, + '>=': 7, + '<<': 8, + '>>': 8, + '>>>': 8, + '+': 9, + '-': 9, + '*': 11, + '/': 11, + '%': 11 + }; + this.sourceType = (options && options.sourceType === 'module') ? 'module' : 'script'; + this.lookahead = null; + this.hasLineTerminator = false; + this.context = { + allowIn: true, + allowYield: true, + firstCoverInitializedNameError: null, + isAssignmentTarget: false, + isBindingElement: false, + inFunctionBody: false, + inIteration: false, + inSwitch: false, + labelSet: {}, + strict: (this.sourceType === 'module') + }; + this.tokens = []; + this.startMarker = { + index: 0, + lineNumber: this.scanner.lineNumber, + lineStart: 0 + }; + this.lastMarker = { + index: 0, + lineNumber: this.scanner.lineNumber, + lineStart: 0 + }; + this.nextToken(); + this.lastMarker = { + index: this.scanner.index, + lineNumber: this.scanner.lineNumber, + lineStart: this.scanner.lineStart + }; + } + Parser.prototype.throwError = function (messageFormat) { + var arguments$1 = arguments; + + var values = []; + for (var _i = 1; _i < arguments.length; _i++) { + values[_i - 1] = arguments$1[_i]; + } + var args = Array.prototype.slice.call(arguments, 1); + var msg = messageFormat.replace(/%(\d)/g, function (whole, idx) { + assert_1.assert(idx < args.length, 'Message reference must be in range'); + return args[idx]; + }); + var index = this.lastMarker.index; + var line = this.lastMarker.lineNumber; + var column = this.lastMarker.index - this.lastMarker.lineStart + 1; + throw this.errorHandler.createError(index, line, column, msg); + }; + Parser.prototype.tolerateError = function (messageFormat) { + var arguments$1 = arguments; + + var values = []; + for (var _i = 1; _i < arguments.length; _i++) { + values[_i - 1] = arguments$1[_i]; + } + var args = Array.prototype.slice.call(arguments, 1); + var msg = messageFormat.replace(/%(\d)/g, function (whole, idx) { + assert_1.assert(idx < args.length, 'Message reference must be in range'); + return args[idx]; + }); + var index = this.lastMarker.index; + var line = this.scanner.lineNumber; + var column = this.lastMarker.index - this.lastMarker.lineStart + 1; + this.errorHandler.tolerateError(index, line, column, msg); + }; + // Throw an exception because of the token. + Parser.prototype.unexpectedTokenError = function (token, message) { + var msg = message || messages_1.Messages.UnexpectedToken; + var value; + if (token) { + if (!message) { + msg = (token.type === token_1.Token.EOF) ? messages_1.Messages.UnexpectedEOS : + (token.type === token_1.Token.Identifier) ? messages_1.Messages.UnexpectedIdentifier : + (token.type === token_1.Token.NumericLiteral) ? messages_1.Messages.UnexpectedNumber : + (token.type === token_1.Token.StringLiteral) ? messages_1.Messages.UnexpectedString : + (token.type === token_1.Token.Template) ? messages_1.Messages.UnexpectedTemplate : + messages_1.Messages.UnexpectedToken; + if (token.type === token_1.Token.Keyword) { + if (this.scanner.isFutureReservedWord(token.value)) { + msg = messages_1.Messages.UnexpectedReserved; + } + else if (this.context.strict && this.scanner.isStrictModeReservedWord(token.value)) { + msg = messages_1.Messages.StrictReservedWord; + } + } + } + value = (token.type === token_1.Token.Template) ? token.value.raw : token.value; + } + else { + value = 'ILLEGAL'; + } + msg = msg.replace('%0', value); + if (token && typeof token.lineNumber === 'number') { + var index = token.start; + var line = token.lineNumber; + var column = token.start - this.lastMarker.lineStart + 1; + return this.errorHandler.createError(index, line, column, msg); + } + else { + var index = this.lastMarker.index; + var line = this.lastMarker.lineNumber; + var column = index - this.lastMarker.lineStart + 1; + return this.errorHandler.createError(index, line, column, msg); + } + }; + Parser.prototype.throwUnexpectedToken = function (token, message) { + throw this.unexpectedTokenError(token, message); + }; + Parser.prototype.tolerateUnexpectedToken = function (token, message) { + this.errorHandler.tolerate(this.unexpectedTokenError(token, message)); + }; + Parser.prototype.collectComments = function () { + var this$1 = this; + + if (!this.config.comment) { + this.scanner.scanComments(); + } + else { + var comments = this.scanner.scanComments(); + if (comments.length > 0 && this.delegate) { + for (var i = 0; i < comments.length; ++i) { + var e = comments[i]; + var node = void 0; + node = { + type: e.multiLine ? 'BlockComment' : 'LineComment', + value: this$1.scanner.source.slice(e.slice[0], e.slice[1]) + }; + if (this$1.config.range) { + node.range = e.range; + } + if (this$1.config.loc) { + node.loc = e.loc; + } + var metadata = { + start: { + line: e.loc.start.line, + column: e.loc.start.column, + offset: e.range[0] + }, + end: { + line: e.loc.end.line, + column: e.loc.end.column, + offset: e.range[1] + } + }; + this$1.delegate(node, metadata); + } + } + } + }; + // From internal representation to an external structure + Parser.prototype.getTokenRaw = function (token) { + return this.scanner.source.slice(token.start, token.end); + }; + Parser.prototype.convertToken = function (token) { + var t; + t = { + type: token_1.TokenName[token.type], + value: this.getTokenRaw(token) + }; + if (this.config.range) { + t.range = [token.start, token.end]; + } + if (this.config.loc) { + t.loc = { + start: { + line: this.startMarker.lineNumber, + column: this.startMarker.index - this.startMarker.lineStart + }, + end: { + line: this.scanner.lineNumber, + column: this.scanner.index - this.scanner.lineStart + } + }; + } + if (token.regex) { + t.regex = token.regex; + } + return t; + }; + Parser.prototype.nextToken = function () { + var token = this.lookahead; + this.lastMarker.index = this.scanner.index; + this.lastMarker.lineNumber = this.scanner.lineNumber; + this.lastMarker.lineStart = this.scanner.lineStart; + this.collectComments(); + this.startMarker.index = this.scanner.index; + this.startMarker.lineNumber = this.scanner.lineNumber; + this.startMarker.lineStart = this.scanner.lineStart; + var next; + next = this.scanner.lex(); + this.hasLineTerminator = (token && next) ? (token.lineNumber !== next.lineNumber) : false; + if (next && this.context.strict && next.type === token_1.Token.Identifier) { + if (this.scanner.isStrictModeReservedWord(next.value)) { + next.type = token_1.Token.Keyword; + } + } + this.lookahead = next; + if (this.config.tokens && next.type !== token_1.Token.EOF) { + this.tokens.push(this.convertToken(next)); + } + return token; + }; + Parser.prototype.nextRegexToken = function () { + this.collectComments(); + var token = this.scanner.scanRegExp(); + if (this.config.tokens) { + // Pop the previous token, '/' or '/=' + // This is added from the lookahead token. + this.tokens.pop(); + this.tokens.push(this.convertToken(token)); + } + // Prime the next lookahead. + this.lookahead = token; + this.nextToken(); + return token; + }; + Parser.prototype.createNode = function () { + return { + index: this.startMarker.index, + line: this.startMarker.lineNumber, + column: this.startMarker.index - this.startMarker.lineStart + }; + }; + Parser.prototype.startNode = function (token) { + return { + index: token.start, + line: token.lineNumber, + column: token.start - token.lineStart + }; + }; + Parser.prototype.finalize = function (meta, node) { + if (this.config.range) { + node.range = [meta.index, this.lastMarker.index]; + } + if (this.config.loc) { + node.loc = { + start: { + line: meta.line, + column: meta.column + }, + end: { + line: this.lastMarker.lineNumber, + column: this.lastMarker.index - this.lastMarker.lineStart + } + }; + if (this.config.source) { + node.loc.source = this.config.source; + } + } + if (this.delegate) { + var metadata = { + start: { + line: meta.line, + column: meta.column, + offset: meta.index + }, + end: { + line: this.lastMarker.lineNumber, + column: this.lastMarker.index - this.lastMarker.lineStart, + offset: this.lastMarker.index + } + }; + this.delegate(node, metadata); + } + return node; + }; + // Expect the next token to match the specified punctuator. + // If not, an exception will be thrown. + Parser.prototype.expect = function (value) { + var token = this.nextToken(); + if (token.type !== token_1.Token.Punctuator || token.value !== value) { + this.throwUnexpectedToken(token); + } + }; + // Quietly expect a comma when in tolerant mode, otherwise delegates to expect(). + Parser.prototype.expectCommaSeparator = function () { + if (this.config.tolerant) { + var token = this.lookahead; + if (token.type === token_1.Token.Punctuator && token.value === ',') { + this.nextToken(); + } + else if (token.type === token_1.Token.Punctuator && token.value === ';') { + this.nextToken(); + this.tolerateUnexpectedToken(token); + } + else { + this.tolerateUnexpectedToken(token, messages_1.Messages.UnexpectedToken); + } + } + else { + this.expect(','); + } + }; + // Expect the next token to match the specified keyword. + // If not, an exception will be thrown. + Parser.prototype.expectKeyword = function (keyword) { + var token = this.nextToken(); + if (token.type !== token_1.Token.Keyword || token.value !== keyword) { + this.throwUnexpectedToken(token); + } + }; + // Return true if the next token matches the specified punctuator. + Parser.prototype.match = function (value) { + return this.lookahead.type === token_1.Token.Punctuator && this.lookahead.value === value; + }; + // Return true if the next token matches the specified keyword + Parser.prototype.matchKeyword = function (keyword) { + return this.lookahead.type === token_1.Token.Keyword && this.lookahead.value === keyword; + }; + // Return true if the next token matches the specified contextual keyword + // (where an identifier is sometimes a keyword depending on the context) + Parser.prototype.matchContextualKeyword = function (keyword) { + return this.lookahead.type === token_1.Token.Identifier && this.lookahead.value === keyword; + }; + // Return true if the next token is an assignment operator + Parser.prototype.matchAssign = function () { + if (this.lookahead.type !== token_1.Token.Punctuator) { + return false; + } + var op = this.lookahead.value; + return op === '=' || + op === '*=' || + op === '**=' || + op === '/=' || + op === '%=' || + op === '+=' || + op === '-=' || + op === '<<=' || + op === '>>=' || + op === '>>>=' || + op === '&=' || + op === '^=' || + op === '|='; + }; + // Cover grammar support. + // + // When an assignment expression position starts with an left parenthesis, the determination of the type + // of the syntax is to be deferred arbitrarily long until the end of the parentheses pair (plus a lookahead) + // or the first comma. This situation also defers the determination of all the expressions nested in the pair. + // + // There are three productions that can be parsed in a parentheses pair that needs to be determined + // after the outermost pair is closed. They are: + // + // 1. AssignmentExpression + // 2. BindingElements + // 3. AssignmentTargets + // + // In order to avoid exponential backtracking, we use two flags to denote if the production can be + // binding element or assignment target. + // + // The three productions have the relationship: + // + // BindingElements ⊆ AssignmentTargets ⊆ AssignmentExpression + // + // with a single exception that CoverInitializedName when used directly in an Expression, generates + // an early error. Therefore, we need the third state, firstCoverInitializedNameError, to track the + // first usage of CoverInitializedName and report it when we reached the end of the parentheses pair. + // + // isolateCoverGrammar function runs the given parser function with a new cover grammar context, and it does not + // effect the current flags. This means the production the parser parses is only used as an expression. Therefore + // the CoverInitializedName check is conducted. + // + // inheritCoverGrammar function runs the given parse function with a new cover grammar context, and it propagates + // the flags outside of the parser. This means the production the parser parses is used as a part of a potential + // pattern. The CoverInitializedName check is deferred. + Parser.prototype.isolateCoverGrammar = function (parseFunction) { + var previousIsBindingElement = this.context.isBindingElement; + var previousIsAssignmentTarget = this.context.isAssignmentTarget; + var previousFirstCoverInitializedNameError = this.context.firstCoverInitializedNameError; + this.context.isBindingElement = true; + this.context.isAssignmentTarget = true; + this.context.firstCoverInitializedNameError = null; + var result = parseFunction.call(this); + if (this.context.firstCoverInitializedNameError !== null) { + this.throwUnexpectedToken(this.context.firstCoverInitializedNameError); + } + this.context.isBindingElement = previousIsBindingElement; + this.context.isAssignmentTarget = previousIsAssignmentTarget; + this.context.firstCoverInitializedNameError = previousFirstCoverInitializedNameError; + return result; + }; + Parser.prototype.inheritCoverGrammar = function (parseFunction) { + var previousIsBindingElement = this.context.isBindingElement; + var previousIsAssignmentTarget = this.context.isAssignmentTarget; + var previousFirstCoverInitializedNameError = this.context.firstCoverInitializedNameError; + this.context.isBindingElement = true; + this.context.isAssignmentTarget = true; + this.context.firstCoverInitializedNameError = null; + var result = parseFunction.call(this); + this.context.isBindingElement = this.context.isBindingElement && previousIsBindingElement; + this.context.isAssignmentTarget = this.context.isAssignmentTarget && previousIsAssignmentTarget; + this.context.firstCoverInitializedNameError = previousFirstCoverInitializedNameError || this.context.firstCoverInitializedNameError; + return result; + }; + Parser.prototype.consumeSemicolon = function () { + if (this.match(';')) { + this.nextToken(); + } + else if (!this.hasLineTerminator) { + if (this.lookahead.type !== token_1.Token.EOF && !this.match('}')) { + this.throwUnexpectedToken(this.lookahead); + } + this.lastMarker.index = this.startMarker.index; + this.lastMarker.lineNumber = this.startMarker.lineNumber; + this.lastMarker.lineStart = this.startMarker.lineStart; + } + }; + // ECMA-262 12.2 Primary Expressions + Parser.prototype.parsePrimaryExpression = function () { + var node = this.createNode(); + var expr; + var value, token, raw; + switch (this.lookahead.type) { + case token_1.Token.Identifier: + if (this.sourceType === 'module' && this.lookahead.value === 'await') { + this.tolerateUnexpectedToken(this.lookahead); + } + expr = this.finalize(node, new Node.Identifier(this.nextToken().value)); + break; + case token_1.Token.NumericLiteral: + case token_1.Token.StringLiteral: + if (this.context.strict && this.lookahead.octal) { + this.tolerateUnexpectedToken(this.lookahead, messages_1.Messages.StrictOctalLiteral); + } + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + token = this.nextToken(); + raw = this.getTokenRaw(token); + expr = this.finalize(node, new Node.Literal(token.value, raw)); + break; + case token_1.Token.BooleanLiteral: + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + token = this.nextToken(); + token.value = (token.value === 'true'); + raw = this.getTokenRaw(token); + expr = this.finalize(node, new Node.Literal(token.value, raw)); + break; + case token_1.Token.NullLiteral: + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + token = this.nextToken(); + token.value = null; + raw = this.getTokenRaw(token); + expr = this.finalize(node, new Node.Literal(token.value, raw)); + break; + case token_1.Token.Template: + expr = this.parseTemplateLiteral(); + break; + case token_1.Token.Punctuator: + value = this.lookahead.value; + switch (value) { + case '(': + this.context.isBindingElement = false; + expr = this.inheritCoverGrammar(this.parseGroupExpression); + break; + case '[': + expr = this.inheritCoverGrammar(this.parseArrayInitializer); + break; + case '{': + expr = this.inheritCoverGrammar(this.parseObjectInitializer); + break; + case '/': + case '/=': + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + this.scanner.index = this.startMarker.index; + token = this.nextRegexToken(); + raw = this.getTokenRaw(token); + expr = this.finalize(node, new Node.RegexLiteral(token.value, raw, token.regex)); + break; + default: + this.throwUnexpectedToken(this.nextToken()); + } + break; + case token_1.Token.Keyword: + if (!this.context.strict && this.context.allowYield && this.matchKeyword('yield')) { + expr = this.parseIdentifierName(); + } + else if (!this.context.strict && this.matchKeyword('let')) { + expr = this.finalize(node, new Node.Identifier(this.nextToken().value)); + } + else { + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + if (this.matchKeyword('function')) { + expr = this.parseFunctionExpression(); + } + else if (this.matchKeyword('this')) { + this.nextToken(); + expr = this.finalize(node, new Node.ThisExpression()); + } + else if (this.matchKeyword('class')) { + expr = this.parseClassExpression(); + } + else { + this.throwUnexpectedToken(this.nextToken()); + } + } + break; + default: + this.throwUnexpectedToken(this.nextToken()); + } + return expr; + }; + // ECMA-262 12.2.5 Array Initializer + Parser.prototype.parseSpreadElement = function () { + var node = this.createNode(); + this.expect('...'); + var arg = this.inheritCoverGrammar(this.parseAssignmentExpression); + return this.finalize(node, new Node.SpreadElement(arg)); + }; + Parser.prototype.parseArrayInitializer = function () { + var this$1 = this; + + var node = this.createNode(); + var elements = []; + this.expect('['); + while (!this.match(']')) { + if (this$1.match(',')) { + this$1.nextToken(); + elements.push(null); + } + else if (this$1.match('...')) { + var element = this$1.parseSpreadElement(); + if (!this$1.match(']')) { + this$1.context.isAssignmentTarget = false; + this$1.context.isBindingElement = false; + this$1.expect(','); + } + elements.push(element); + } + else { + elements.push(this$1.inheritCoverGrammar(this$1.parseAssignmentExpression)); + if (!this$1.match(']')) { + this$1.expect(','); + } + } + } + this.expect(']'); + return this.finalize(node, new Node.ArrayExpression(elements)); + }; + // ECMA-262 12.2.6 Object Initializer + Parser.prototype.parsePropertyMethod = function (params) { + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + var previousStrict = this.context.strict; + var body = this.isolateCoverGrammar(this.parseFunctionSourceElements); + if (this.context.strict && params.firstRestricted) { + this.tolerateUnexpectedToken(params.firstRestricted, params.message); + } + if (this.context.strict && params.stricted) { + this.tolerateUnexpectedToken(params.stricted, params.message); + } + this.context.strict = previousStrict; + return body; + }; + Parser.prototype.parsePropertyMethodFunction = function () { + var isGenerator = false; + var node = this.createNode(); + var previousAllowYield = this.context.allowYield; + this.context.allowYield = false; + var params = this.parseFormalParameters(); + var method = this.parsePropertyMethod(params); + this.context.allowYield = previousAllowYield; + return this.finalize(node, new Node.FunctionExpression(null, params.params, method, isGenerator)); + }; + Parser.prototype.parseObjectPropertyKey = function () { + var node = this.createNode(); + var token = this.nextToken(); + var key = null; + switch (token.type) { + case token_1.Token.StringLiteral: + case token_1.Token.NumericLiteral: + if (this.context.strict && token.octal) { + this.tolerateUnexpectedToken(token, messages_1.Messages.StrictOctalLiteral); + } + var raw = this.getTokenRaw(token); + key = this.finalize(node, new Node.Literal(token.value, raw)); + break; + case token_1.Token.Identifier: + case token_1.Token.BooleanLiteral: + case token_1.Token.NullLiteral: + case token_1.Token.Keyword: + key = this.finalize(node, new Node.Identifier(token.value)); + break; + case token_1.Token.Punctuator: + if (token.value === '[') { + key = this.isolateCoverGrammar(this.parseAssignmentExpression); + this.expect(']'); + } + else { + this.throwUnexpectedToken(token); + } + break; + default: + this.throwUnexpectedToken(token); + } + return key; + }; + Parser.prototype.isPropertyKey = function (key, value) { + return (key.type === syntax_1.Syntax.Identifier && key.name === value) || + (key.type === syntax_1.Syntax.Literal && key.value === value); + }; + Parser.prototype.parseObjectProperty = function (hasProto) { + var node = this.createNode(); + var token = this.lookahead; + var kind; + var key; + var value; + var computed = false; + var method = false; + var shorthand = false; + if (token.type === token_1.Token.Identifier) { + this.nextToken(); + key = this.finalize(node, new Node.Identifier(token.value)); + } + else if (this.match('*')) { + this.nextToken(); + } + else { + computed = this.match('['); + key = this.parseObjectPropertyKey(); + } + var lookaheadPropertyKey = this.qualifiedPropertyName(this.lookahead); + if (token.type === token_1.Token.Identifier && token.value === 'get' && lookaheadPropertyKey) { + kind = 'get'; + computed = this.match('['); + key = this.parseObjectPropertyKey(); + this.context.allowYield = false; + value = this.parseGetterMethod(); + } + else if (token.type === token_1.Token.Identifier && token.value === 'set' && lookaheadPropertyKey) { + kind = 'set'; + computed = this.match('['); + key = this.parseObjectPropertyKey(); + value = this.parseSetterMethod(); + } + else if (token.type === token_1.Token.Punctuator && token.value === '*' && lookaheadPropertyKey) { + kind = 'init'; + computed = this.match('['); + key = this.parseObjectPropertyKey(); + value = this.parseGeneratorMethod(); + method = true; + } + else { + if (!key) { + this.throwUnexpectedToken(this.lookahead); + } + kind = 'init'; + if (this.match(':')) { + if (!computed && this.isPropertyKey(key, '__proto__')) { + if (hasProto.value) { + this.tolerateError(messages_1.Messages.DuplicateProtoProperty); + } + hasProto.value = true; + } + this.nextToken(); + value = this.inheritCoverGrammar(this.parseAssignmentExpression); + } + else if (this.match('(')) { + value = this.parsePropertyMethodFunction(); + method = true; + } + else if (token.type === token_1.Token.Identifier) { + var id = this.finalize(node, new Node.Identifier(token.value)); + if (this.match('=')) { + this.context.firstCoverInitializedNameError = this.lookahead; + this.nextToken(); + shorthand = true; + var init = this.isolateCoverGrammar(this.parseAssignmentExpression); + value = this.finalize(node, new Node.AssignmentPattern(id, init)); + } + else { + shorthand = true; + value = id; + } + } + else { + this.throwUnexpectedToken(this.nextToken()); + } + } + return this.finalize(node, new Node.Property(kind, key, computed, value, method, shorthand)); + }; + Parser.prototype.parseObjectInitializer = function () { + var this$1 = this; + + var node = this.createNode(); + this.expect('{'); + var properties = []; + var hasProto = { value: false }; + while (!this.match('}')) { + properties.push(this$1.parseObjectProperty(hasProto)); + if (!this$1.match('}')) { + this$1.expectCommaSeparator(); + } + } + this.expect('}'); + return this.finalize(node, new Node.ObjectExpression(properties)); + }; + // ECMA-262 12.2.9 Template Literals + Parser.prototype.parseTemplateHead = function () { + assert_1.assert(this.lookahead.head, 'Template literal must start with a template head'); + var node = this.createNode(); + var token = this.nextToken(); + var value = { + raw: token.value.raw, + cooked: token.value.cooked + }; + return this.finalize(node, new Node.TemplateElement(value, token.tail)); + }; + Parser.prototype.parseTemplateElement = function () { + if (this.lookahead.type !== token_1.Token.Template) { + this.throwUnexpectedToken(); + } + var node = this.createNode(); + var token = this.nextToken(); + var value = { + raw: token.value.raw, + cooked: token.value.cooked + }; + return this.finalize(node, new Node.TemplateElement(value, token.tail)); + }; + Parser.prototype.parseTemplateLiteral = function () { + var this$1 = this; + + var node = this.createNode(); + var expressions = []; + var quasis = []; + var quasi = this.parseTemplateHead(); + quasis.push(quasi); + while (!quasi.tail) { + expressions.push(this$1.parseExpression()); + quasi = this$1.parseTemplateElement(); + quasis.push(quasi); + } + return this.finalize(node, new Node.TemplateLiteral(quasis, expressions)); + }; + // ECMA-262 12.2.10 The Grouping Operator + Parser.prototype.reinterpretExpressionAsPattern = function (expr) { + var this$1 = this; + + switch (expr.type) { + case syntax_1.Syntax.Identifier: + case syntax_1.Syntax.MemberExpression: + case syntax_1.Syntax.RestElement: + case syntax_1.Syntax.AssignmentPattern: + break; + case syntax_1.Syntax.SpreadElement: + expr.type = syntax_1.Syntax.RestElement; + this.reinterpretExpressionAsPattern(expr.argument); + break; + case syntax_1.Syntax.ArrayExpression: + expr.type = syntax_1.Syntax.ArrayPattern; + for (var i = 0; i < expr.elements.length; i++) { + if (expr.elements[i] !== null) { + this$1.reinterpretExpressionAsPattern(expr.elements[i]); + } + } + break; + case syntax_1.Syntax.ObjectExpression: + expr.type = syntax_1.Syntax.ObjectPattern; + for (var i = 0; i < expr.properties.length; i++) { + this$1.reinterpretExpressionAsPattern(expr.properties[i].value); + } + break; + case syntax_1.Syntax.AssignmentExpression: + expr.type = syntax_1.Syntax.AssignmentPattern; + delete expr.operator; + this.reinterpretExpressionAsPattern(expr.left); + break; + default: + // Allow other node type for tolerant parsing. + break; + } + }; + Parser.prototype.parseGroupExpression = function () { + var this$1 = this; + + var expr; + this.expect('('); + if (this.match(')')) { + this.nextToken(); + if (!this.match('=>')) { + this.expect('=>'); + } + expr = { + type: ArrowParameterPlaceHolder, + params: [] + }; + } + else { + var startToken = this.lookahead; + var params = []; + if (this.match('...')) { + expr = this.parseRestElement(params); + this.expect(')'); + if (!this.match('=>')) { + this.expect('=>'); + } + expr = { + type: ArrowParameterPlaceHolder, + params: [expr] + }; + } + else { + var arrow = false; + this.context.isBindingElement = true; + expr = this.inheritCoverGrammar(this.parseAssignmentExpression); + if (this.match(',')) { + var expressions = []; + this.context.isAssignmentTarget = false; + expressions.push(expr); + while (this.startMarker.index < this.scanner.length) { + if (!this$1.match(',')) { + break; + } + this$1.nextToken(); + if (this$1.match('...')) { + if (!this$1.context.isBindingElement) { + this$1.throwUnexpectedToken(this$1.lookahead); + } + expressions.push(this$1.parseRestElement(params)); + this$1.expect(')'); + if (!this$1.match('=>')) { + this$1.expect('=>'); + } + this$1.context.isBindingElement = false; + for (var i = 0; i < expressions.length; i++) { + this$1.reinterpretExpressionAsPattern(expressions[i]); + } + arrow = true; + expr = { + type: ArrowParameterPlaceHolder, + params: expressions + }; + } + else { + expressions.push(this$1.inheritCoverGrammar(this$1.parseAssignmentExpression)); + } + if (arrow) { + break; + } + } + if (!arrow) { + expr = this.finalize(this.startNode(startToken), new Node.SequenceExpression(expressions)); + } + } + if (!arrow) { + this.expect(')'); + if (this.match('=>')) { + if (expr.type === syntax_1.Syntax.Identifier && expr.name === 'yield') { + arrow = true; + expr = { + type: ArrowParameterPlaceHolder, + params: [expr] + }; + } + if (!arrow) { + if (!this.context.isBindingElement) { + this.throwUnexpectedToken(this.lookahead); + } + if (expr.type === syntax_1.Syntax.SequenceExpression) { + for (var i = 0; i < expr.expressions.length; i++) { + this$1.reinterpretExpressionAsPattern(expr.expressions[i]); + } + } + else { + this.reinterpretExpressionAsPattern(expr); + } + var params_1 = (expr.type === syntax_1.Syntax.SequenceExpression ? expr.expressions : [expr]); + expr = { + type: ArrowParameterPlaceHolder, + params: params_1 + }; + } + } + this.context.isBindingElement = false; + } + } + } + return expr; + }; + // ECMA-262 12.3 Left-Hand-Side Expressions + Parser.prototype.parseArguments = function () { + var this$1 = this; + + this.expect('('); + var args = []; + if (!this.match(')')) { + while (true) { + var expr = this$1.match('...') ? this$1.parseSpreadElement() : + this$1.isolateCoverGrammar(this$1.parseAssignmentExpression); + args.push(expr); + if (this$1.match(')')) { + break; + } + this$1.expectCommaSeparator(); + } + } + this.expect(')'); + return args; + }; + Parser.prototype.isIdentifierName = function (token) { + return token.type === token_1.Token.Identifier || + token.type === token_1.Token.Keyword || + token.type === token_1.Token.BooleanLiteral || + token.type === token_1.Token.NullLiteral; + }; + Parser.prototype.parseIdentifierName = function () { + var node = this.createNode(); + var token = this.nextToken(); + if (!this.isIdentifierName(token)) { + this.throwUnexpectedToken(token); + } + return this.finalize(node, new Node.Identifier(token.value)); + }; + Parser.prototype.parseNewExpression = function () { + var node = this.createNode(); + var id = this.parseIdentifierName(); + assert_1.assert(id.name === 'new', 'New expression must start with `new`'); + var expr; + if (this.match('.')) { + this.nextToken(); + if (this.lookahead.type === token_1.Token.Identifier && this.context.inFunctionBody && this.lookahead.value === 'target') { + var property = this.parseIdentifierName(); + expr = new Node.MetaProperty(id, property); + } + else { + this.throwUnexpectedToken(this.lookahead); + } + } + else { + var callee = this.isolateCoverGrammar(this.parseLeftHandSideExpression); + var args = this.match('(') ? this.parseArguments() : []; + expr = new Node.NewExpression(callee, args); + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + } + return this.finalize(node, expr); + }; + Parser.prototype.parseLeftHandSideExpressionAllowCall = function () { + var this$1 = this; + + var startToken = this.lookahead; + var previousAllowIn = this.context.allowIn; + this.context.allowIn = true; + var expr; + if (this.matchKeyword('super') && this.context.inFunctionBody) { + expr = this.createNode(); + this.nextToken(); + expr = this.finalize(expr, new Node.Super()); + if (!this.match('(') && !this.match('.') && !this.match('[')) { + this.throwUnexpectedToken(this.lookahead); + } + } + else { + expr = this.inheritCoverGrammar(this.matchKeyword('new') ? this.parseNewExpression : this.parsePrimaryExpression); + } + while (true) { + if (this$1.match('.')) { + this$1.context.isBindingElement = false; + this$1.context.isAssignmentTarget = true; + this$1.expect('.'); + var property = this$1.parseIdentifierName(); + expr = this$1.finalize(this$1.startNode(startToken), new Node.StaticMemberExpression(expr, property)); + } + else if (this$1.match('(')) { + this$1.context.isBindingElement = false; + this$1.context.isAssignmentTarget = false; + var args = this$1.parseArguments(); + expr = this$1.finalize(this$1.startNode(startToken), new Node.CallExpression(expr, args)); + } + else if (this$1.match('[')) { + this$1.context.isBindingElement = false; + this$1.context.isAssignmentTarget = true; + this$1.expect('['); + var property = this$1.isolateCoverGrammar(this$1.parseExpression); + this$1.expect(']'); + expr = this$1.finalize(this$1.startNode(startToken), new Node.ComputedMemberExpression(expr, property)); + } + else if (this$1.lookahead.type === token_1.Token.Template && this$1.lookahead.head) { + var quasi = this$1.parseTemplateLiteral(); + expr = this$1.finalize(this$1.startNode(startToken), new Node.TaggedTemplateExpression(expr, quasi)); + } + else { + break; + } + } + this.context.allowIn = previousAllowIn; + return expr; + }; + Parser.prototype.parseSuper = function () { + var node = this.createNode(); + this.expectKeyword('super'); + if (!this.match('[') && !this.match('.')) { + this.throwUnexpectedToken(this.lookahead); + } + return this.finalize(node, new Node.Super()); + }; + Parser.prototype.parseLeftHandSideExpression = function () { + var this$1 = this; + + assert_1.assert(this.context.allowIn, 'callee of new expression always allow in keyword.'); + var node = this.startNode(this.lookahead); + var expr = (this.matchKeyword('super') && this.context.inFunctionBody) ? this.parseSuper() : + this.inheritCoverGrammar(this.matchKeyword('new') ? this.parseNewExpression : this.parsePrimaryExpression); + while (true) { + if (this$1.match('[')) { + this$1.context.isBindingElement = false; + this$1.context.isAssignmentTarget = true; + this$1.expect('['); + var property = this$1.isolateCoverGrammar(this$1.parseExpression); + this$1.expect(']'); + expr = this$1.finalize(node, new Node.ComputedMemberExpression(expr, property)); + } + else if (this$1.match('.')) { + this$1.context.isBindingElement = false; + this$1.context.isAssignmentTarget = true; + this$1.expect('.'); + var property = this$1.parseIdentifierName(); + expr = this$1.finalize(node, new Node.StaticMemberExpression(expr, property)); + } + else if (this$1.lookahead.type === token_1.Token.Template && this$1.lookahead.head) { + var quasi = this$1.parseTemplateLiteral(); + expr = this$1.finalize(node, new Node.TaggedTemplateExpression(expr, quasi)); + } + else { + break; + } + } + return expr; + }; + // ECMA-262 12.4 Update Expressions + Parser.prototype.parseUpdateExpression = function () { + var expr; + var startToken = this.lookahead; + if (this.match('++') || this.match('--')) { + var node = this.startNode(startToken); + var token = this.nextToken(); + expr = this.inheritCoverGrammar(this.parseUnaryExpression); + if (this.context.strict && expr.type === syntax_1.Syntax.Identifier && this.scanner.isRestrictedWord(expr.name)) { + this.tolerateError(messages_1.Messages.StrictLHSPrefix); + } + if (!this.context.isAssignmentTarget) { + this.tolerateError(messages_1.Messages.InvalidLHSInAssignment); + } + var prefix = true; + expr = this.finalize(node, new Node.UpdateExpression(token.value, expr, prefix)); + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + } + else { + expr = this.inheritCoverGrammar(this.parseLeftHandSideExpressionAllowCall); + if (!this.hasLineTerminator && this.lookahead.type === token_1.Token.Punctuator) { + if (this.match('++') || this.match('--')) { + if (this.context.strict && expr.type === syntax_1.Syntax.Identifier && this.scanner.isRestrictedWord(expr.name)) { + this.tolerateError(messages_1.Messages.StrictLHSPostfix); + } + if (!this.context.isAssignmentTarget) { + this.tolerateError(messages_1.Messages.InvalidLHSInAssignment); + } + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + var operator = this.nextToken().value; + var prefix = false; + expr = this.finalize(this.startNode(startToken), new Node.UpdateExpression(operator, expr, prefix)); + } + } + } + return expr; + }; + // ECMA-262 12.5 Unary Operators + Parser.prototype.parseUnaryExpression = function () { + var expr; + if (this.match('+') || this.match('-') || this.match('~') || this.match('!') || + this.matchKeyword('delete') || this.matchKeyword('void') || this.matchKeyword('typeof')) { + var node = this.startNode(this.lookahead); + var token = this.nextToken(); + expr = this.inheritCoverGrammar(this.parseUnaryExpression); + expr = this.finalize(node, new Node.UnaryExpression(token.value, expr)); + if (this.context.strict && expr.operator === 'delete' && expr.argument.type === syntax_1.Syntax.Identifier) { + this.tolerateError(messages_1.Messages.StrictDelete); + } + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + } + else { + expr = this.parseUpdateExpression(); + } + return expr; + }; + Parser.prototype.parseExponentiationExpression = function () { + var startToken = this.lookahead; + var expr = this.inheritCoverGrammar(this.parseUnaryExpression); + if (expr.type !== syntax_1.Syntax.UnaryExpression && this.match('**')) { + this.nextToken(); + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + var left = expr; + var right = this.isolateCoverGrammar(this.parseExponentiationExpression); + expr = this.finalize(this.startNode(startToken), new Node.BinaryExpression('**', left, right)); + } + return expr; + }; + // ECMA-262 12.6 Exponentiation Operators + // ECMA-262 12.7 Multiplicative Operators + // ECMA-262 12.8 Additive Operators + // ECMA-262 12.9 Bitwise Shift Operators + // ECMA-262 12.10 Relational Operators + // ECMA-262 12.11 Equality Operators + // ECMA-262 12.12 Binary Bitwise Operators + // ECMA-262 12.13 Binary Logical Operators + Parser.prototype.binaryPrecedence = function (token) { + var op = token.value; + var precedence; + if (token.type === token_1.Token.Punctuator) { + precedence = this.operatorPrecedence[op] || 0; + } + else if (token.type === token_1.Token.Keyword) { + precedence = (op === 'instanceof' || (this.context.allowIn && op === 'in')) ? 7 : 0; + } + else { + precedence = 0; + } + return precedence; + }; + Parser.prototype.parseBinaryExpression = function () { + var this$1 = this; + + var startToken = this.lookahead; + var expr = this.inheritCoverGrammar(this.parseExponentiationExpression); + var token = this.lookahead; + var prec = this.binaryPrecedence(token); + if (prec > 0) { + this.nextToken(); + token.prec = prec; + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + var markers = [startToken, this.lookahead]; + var left = expr; + var right = this.isolateCoverGrammar(this.parseExponentiationExpression); + var stack = [left, token, right]; + while (true) { + prec = this$1.binaryPrecedence(this$1.lookahead); + if (prec <= 0) { + break; + } + // Reduce: make a binary expression from the three topmost entries. + while ((stack.length > 2) && (prec <= stack[stack.length - 2].prec)) { + right = stack.pop(); + var operator = stack.pop().value; + left = stack.pop(); + markers.pop(); + var node = this$1.startNode(markers[markers.length - 1]); + stack.push(this$1.finalize(node, new Node.BinaryExpression(operator, left, right))); + } + // Shift. + token = this$1.nextToken(); + token.prec = prec; + stack.push(token); + markers.push(this$1.lookahead); + stack.push(this$1.isolateCoverGrammar(this$1.parseExponentiationExpression)); + } + // Final reduce to clean-up the stack. + var i = stack.length - 1; + expr = stack[i]; + markers.pop(); + while (i > 1) { + var node = this$1.startNode(markers.pop()); + expr = this$1.finalize(node, new Node.BinaryExpression(stack[i - 1].value, stack[i - 2], expr)); + i -= 2; + } + } + return expr; + }; + // ECMA-262 12.14 Conditional Operator + Parser.prototype.parseConditionalExpression = function () { + var startToken = this.lookahead; + var expr = this.inheritCoverGrammar(this.parseBinaryExpression); + if (this.match('?')) { + this.nextToken(); + var previousAllowIn = this.context.allowIn; + this.context.allowIn = true; + var consequent = this.isolateCoverGrammar(this.parseAssignmentExpression); + this.context.allowIn = previousAllowIn; + this.expect(':'); + var alternate = this.isolateCoverGrammar(this.parseAssignmentExpression); + expr = this.finalize(this.startNode(startToken), new Node.ConditionalExpression(expr, consequent, alternate)); + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + } + return expr; + }; + // ECMA-262 12.15 Assignment Operators + Parser.prototype.checkPatternParam = function (options, param) { + var this$1 = this; + + switch (param.type) { + case syntax_1.Syntax.Identifier: + this.validateParam(options, param, param.name); + break; + case syntax_1.Syntax.RestElement: + this.checkPatternParam(options, param.argument); + break; + case syntax_1.Syntax.AssignmentPattern: + this.checkPatternParam(options, param.left); + break; + case syntax_1.Syntax.ArrayPattern: + for (var i = 0; i < param.elements.length; i++) { + if (param.elements[i] !== null) { + this$1.checkPatternParam(options, param.elements[i]); + } + } + break; + case syntax_1.Syntax.YieldExpression: + break; + default: + assert_1.assert(param.type === syntax_1.Syntax.ObjectPattern, 'Invalid type'); + for (var i = 0; i < param.properties.length; i++) { + this$1.checkPatternParam(options, param.properties[i].value); + } + break; + } + }; + Parser.prototype.reinterpretAsCoverFormalsList = function (expr) { + var this$1 = this; + + var params = [expr]; + var options; + switch (expr.type) { + case syntax_1.Syntax.Identifier: + break; + case ArrowParameterPlaceHolder: + params = expr.params; + break; + default: + return null; + } + options = { + paramSet: {} + }; + for (var i = 0; i < params.length; ++i) { + var param = params[i]; + if (param.type === syntax_1.Syntax.AssignmentPattern) { + if (param.right.type === syntax_1.Syntax.YieldExpression) { + if (param.right.argument) { + this$1.throwUnexpectedToken(this$1.lookahead); + } + param.right.type = syntax_1.Syntax.Identifier; + param.right.name = 'yield'; + delete param.right.argument; + delete param.right.delegate; + } + } + this$1.checkPatternParam(options, param); + params[i] = param; + } + if (this.context.strict || !this.context.allowYield) { + for (var i = 0; i < params.length; ++i) { + var param = params[i]; + if (param.type === syntax_1.Syntax.YieldExpression) { + this$1.throwUnexpectedToken(this$1.lookahead); + } + } + } + if (options.message === messages_1.Messages.StrictParamDupe) { + var token = this.context.strict ? options.stricted : options.firstRestricted; + this.throwUnexpectedToken(token, options.message); + } + return { + params: params, + stricted: options.stricted, + firstRestricted: options.firstRestricted, + message: options.message + }; + }; + Parser.prototype.parseAssignmentExpression = function () { + var expr; + if (!this.context.allowYield && this.matchKeyword('yield')) { + expr = this.parseYieldExpression(); + } + else { + var startToken = this.lookahead; + var token = startToken; + expr = this.parseConditionalExpression(); + if (expr.type === ArrowParameterPlaceHolder || this.match('=>')) { + // ECMA-262 14.2 Arrow Function Definitions + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + var list = this.reinterpretAsCoverFormalsList(expr); + if (list) { + if (this.hasLineTerminator) { + this.tolerateUnexpectedToken(this.lookahead); + } + this.context.firstCoverInitializedNameError = null; + var previousStrict = this.context.strict; + var previousAllowYield = this.context.allowYield; + this.context.allowYield = true; + var node = this.startNode(startToken); + this.expect('=>'); + var body = this.match('{') ? this.parseFunctionSourceElements() : + this.isolateCoverGrammar(this.parseAssignmentExpression); + var expression = body.type !== syntax_1.Syntax.BlockStatement; + if (this.context.strict && list.firstRestricted) { + this.throwUnexpectedToken(list.firstRestricted, list.message); + } + if (this.context.strict && list.stricted) { + this.tolerateUnexpectedToken(list.stricted, list.message); + } + expr = this.finalize(node, new Node.ArrowFunctionExpression(list.params, body, expression)); + this.context.strict = previousStrict; + this.context.allowYield = previousAllowYield; + } + } + else { + if (this.matchAssign()) { + if (!this.context.isAssignmentTarget) { + this.tolerateError(messages_1.Messages.InvalidLHSInAssignment); + } + if (this.context.strict && expr.type === syntax_1.Syntax.Identifier) { + var id = (expr); + if (this.scanner.isRestrictedWord(id.name)) { + this.tolerateUnexpectedToken(token, messages_1.Messages.StrictLHSAssignment); + } + if (this.scanner.isStrictModeReservedWord(id.name)) { + this.tolerateUnexpectedToken(token, messages_1.Messages.StrictReservedWord); + } + } + if (!this.match('=')) { + this.context.isAssignmentTarget = false; + this.context.isBindingElement = false; + } + else { + this.reinterpretExpressionAsPattern(expr); + } + token = this.nextToken(); + var right = this.isolateCoverGrammar(this.parseAssignmentExpression); + expr = this.finalize(this.startNode(startToken), new Node.AssignmentExpression(token.value, expr, right)); + this.context.firstCoverInitializedNameError = null; + } + } + } + return expr; + }; + // ECMA-262 12.16 Comma Operator + Parser.prototype.parseExpression = function () { + var this$1 = this; + + var startToken = this.lookahead; + var expr = this.isolateCoverGrammar(this.parseAssignmentExpression); + if (this.match(',')) { + var expressions = []; + expressions.push(expr); + while (this.startMarker.index < this.scanner.length) { + if (!this$1.match(',')) { + break; + } + this$1.nextToken(); + expressions.push(this$1.isolateCoverGrammar(this$1.parseAssignmentExpression)); + } + expr = this.finalize(this.startNode(startToken), new Node.SequenceExpression(expressions)); + } + return expr; + }; + // ECMA-262 13.2 Block + Parser.prototype.parseStatementListItem = function () { + var statement = null; + this.context.isAssignmentTarget = true; + this.context.isBindingElement = true; + if (this.lookahead.type === token_1.Token.Keyword) { + switch (this.lookahead.value) { + case 'export': + if (this.sourceType !== 'module') { + this.tolerateUnexpectedToken(this.lookahead, messages_1.Messages.IllegalExportDeclaration); + } + statement = this.parseExportDeclaration(); + break; + case 'import': + if (this.sourceType !== 'module') { + this.tolerateUnexpectedToken(this.lookahead, messages_1.Messages.IllegalImportDeclaration); + } + statement = this.parseImportDeclaration(); + break; + case 'const': + statement = this.parseLexicalDeclaration({ inFor: false }); + break; + case 'function': + statement = this.parseFunctionDeclaration(); + break; + case 'class': + statement = this.parseClassDeclaration(); + break; + case 'let': + statement = this.isLexicalDeclaration() ? this.parseLexicalDeclaration({ inFor: false }) : this.parseStatement(); + break; + default: + statement = this.parseStatement(); + break; + } + } + else { + statement = this.parseStatement(); + } + return statement; + }; + Parser.prototype.parseBlock = function () { + var this$1 = this; + + var node = this.createNode(); + this.expect('{'); + var block = []; + while (true) { + if (this$1.match('}')) { + break; + } + block.push(this$1.parseStatementListItem()); + } + this.expect('}'); + return this.finalize(node, new Node.BlockStatement(block)); + }; + // ECMA-262 13.3.1 Let and Const Declarations + Parser.prototype.parseLexicalBinding = function (kind, options) { + var node = this.createNode(); + var params = []; + var id = this.parsePattern(params, kind); + // ECMA-262 12.2.1 + if (this.context.strict && id.type === syntax_1.Syntax.Identifier) { + if (this.scanner.isRestrictedWord((id).name)) { + this.tolerateError(messages_1.Messages.StrictVarName); + } + } + var init = null; + if (kind === 'const') { + if (!this.matchKeyword('in') && !this.matchContextualKeyword('of')) { + this.expect('='); + init = this.isolateCoverGrammar(this.parseAssignmentExpression); + } + } + else if ((!options.inFor && id.type !== syntax_1.Syntax.Identifier) || this.match('=')) { + this.expect('='); + init = this.isolateCoverGrammar(this.parseAssignmentExpression); + } + return this.finalize(node, new Node.VariableDeclarator(id, init)); + }; + Parser.prototype.parseBindingList = function (kind, options) { + var this$1 = this; + + var list = [this.parseLexicalBinding(kind, options)]; + while (this.match(',')) { + this$1.nextToken(); + list.push(this$1.parseLexicalBinding(kind, options)); + } + return list; + }; + Parser.prototype.isLexicalDeclaration = function () { + var previousIndex = this.scanner.index; + var previousLineNumber = this.scanner.lineNumber; + var previousLineStart = this.scanner.lineStart; + this.collectComments(); + var next = this.scanner.lex(); + this.scanner.index = previousIndex; + this.scanner.lineNumber = previousLineNumber; + this.scanner.lineStart = previousLineStart; + return (next.type === token_1.Token.Identifier) || + (next.type === token_1.Token.Punctuator && next.value === '[') || + (next.type === token_1.Token.Punctuator && next.value === '{') || + (next.type === token_1.Token.Keyword && next.value === 'let') || + (next.type === token_1.Token.Keyword && next.value === 'yield'); + }; + Parser.prototype.parseLexicalDeclaration = function (options) { + var node = this.createNode(); + var kind = this.nextToken().value; + assert_1.assert(kind === 'let' || kind === 'const', 'Lexical declaration must be either let or const'); + var declarations = this.parseBindingList(kind, options); + this.consumeSemicolon(); + return this.finalize(node, new Node.VariableDeclaration(declarations, kind)); + }; + // ECMA-262 13.3.3 Destructuring Binding Patterns + Parser.prototype.parseBindingRestElement = function (params, kind) { + var node = this.createNode(); + this.expect('...'); + var arg = this.parsePattern(params, kind); + return this.finalize(node, new Node.RestElement(arg)); + }; + Parser.prototype.parseArrayPattern = function (params, kind) { + var this$1 = this; + + var node = this.createNode(); + this.expect('['); + var elements = []; + while (!this.match(']')) { + if (this$1.match(',')) { + this$1.nextToken(); + elements.push(null); + } + else { + if (this$1.match('...')) { + elements.push(this$1.parseBindingRestElement(params, kind)); + break; + } + else { + elements.push(this$1.parsePatternWithDefault(params, kind)); + } + if (!this$1.match(']')) { + this$1.expect(','); + } + } + } + this.expect(']'); + return this.finalize(node, new Node.ArrayPattern(elements)); + }; + Parser.prototype.parsePropertyPattern = function (params, kind) { + var node = this.createNode(); + var computed = false; + var shorthand = false; + var method = false; + var key; + var value; + if (this.lookahead.type === token_1.Token.Identifier) { + var keyToken = this.lookahead; + key = this.parseVariableIdentifier(); + var init = this.finalize(node, new Node.Identifier(keyToken.value)); + if (this.match('=')) { + params.push(keyToken); + shorthand = true; + this.nextToken(); + var expr = this.parseAssignmentExpression(); + value = this.finalize(this.startNode(keyToken), new Node.AssignmentPattern(init, expr)); + } + else if (!this.match(':')) { + params.push(keyToken); + shorthand = true; + value = init; + } + else { + this.expect(':'); + value = this.parsePatternWithDefault(params, kind); + } + } + else { + computed = this.match('['); + key = this.parseObjectPropertyKey(); + this.expect(':'); + value = this.parsePatternWithDefault(params, kind); + } + return this.finalize(node, new Node.Property('init', key, computed, value, method, shorthand)); + }; + Parser.prototype.parseObjectPattern = function (params, kind) { + var this$1 = this; + + var node = this.createNode(); + var properties = []; + this.expect('{'); + while (!this.match('}')) { + properties.push(this$1.parsePropertyPattern(params, kind)); + if (!this$1.match('}')) { + this$1.expect(','); + } + } + this.expect('}'); + return this.finalize(node, new Node.ObjectPattern(properties)); + }; + Parser.prototype.parsePattern = function (params, kind) { + var pattern; + if (this.match('[')) { + pattern = this.parseArrayPattern(params, kind); + } + else if (this.match('{')) { + pattern = this.parseObjectPattern(params, kind); + } + else { + if (this.matchKeyword('let') && (kind === 'const' || kind === 'let')) { + this.tolerateUnexpectedToken(this.lookahead, messages_1.Messages.UnexpectedToken); + } + params.push(this.lookahead); + pattern = this.parseVariableIdentifier(kind); + } + return pattern; + }; + Parser.prototype.parsePatternWithDefault = function (params, kind) { + var startToken = this.lookahead; + var pattern = this.parsePattern(params, kind); + if (this.match('=')) { + this.nextToken(); + var previousAllowYield = this.context.allowYield; + this.context.allowYield = true; + var right = this.isolateCoverGrammar(this.parseAssignmentExpression); + this.context.allowYield = previousAllowYield; + pattern = this.finalize(this.startNode(startToken), new Node.AssignmentPattern(pattern, right)); + } + return pattern; + }; + // ECMA-262 13.3.2 Variable Statement + Parser.prototype.parseVariableIdentifier = function (kind) { + var node = this.createNode(); + var token = this.nextToken(); + if (token.type === token_1.Token.Keyword && token.value === 'yield') { + if (this.context.strict) { + this.tolerateUnexpectedToken(token, messages_1.Messages.StrictReservedWord); + } + if (!this.context.allowYield) { + this.throwUnexpectedToken(token); + } + } + else if (token.type !== token_1.Token.Identifier) { + if (this.context.strict && token.type === token_1.Token.Keyword && this.scanner.isStrictModeReservedWord(token.value)) { + this.tolerateUnexpectedToken(token, messages_1.Messages.StrictReservedWord); + } + else { + if (this.context.strict || token.value !== 'let' || kind !== 'var') { + this.throwUnexpectedToken(token); + } + } + } + else if (this.sourceType === 'module' && token.type === token_1.Token.Identifier && token.value === 'await') { + this.tolerateUnexpectedToken(token); + } + return this.finalize(node, new Node.Identifier(token.value)); + }; + Parser.prototype.parseVariableDeclaration = function (options) { + var node = this.createNode(); + var params = []; + var id = this.parsePattern(params, 'var'); + // ECMA-262 12.2.1 + if (this.context.strict && id.type === syntax_1.Syntax.Identifier) { + if (this.scanner.isRestrictedWord((id).name)) { + this.tolerateError(messages_1.Messages.StrictVarName); + } + } + var init = null; + if (this.match('=')) { + this.nextToken(); + init = this.isolateCoverGrammar(this.parseAssignmentExpression); + } + else if (id.type !== syntax_1.Syntax.Identifier && !options.inFor) { + this.expect('='); + } + return this.finalize(node, new Node.VariableDeclarator(id, init)); + }; + Parser.prototype.parseVariableDeclarationList = function (options) { + var this$1 = this; + + var opt = { inFor: options.inFor }; + var list = []; + list.push(this.parseVariableDeclaration(opt)); + while (this.match(',')) { + this$1.nextToken(); + list.push(this$1.parseVariableDeclaration(opt)); + } + return list; + }; + Parser.prototype.parseVariableStatement = function () { + var node = this.createNode(); + this.expectKeyword('var'); + var declarations = this.parseVariableDeclarationList({ inFor: false }); + this.consumeSemicolon(); + return this.finalize(node, new Node.VariableDeclaration(declarations, 'var')); + }; + // ECMA-262 13.4 Empty Statement + Parser.prototype.parseEmptyStatement = function () { + var node = this.createNode(); + this.expect(';'); + return this.finalize(node, new Node.EmptyStatement()); + }; + // ECMA-262 13.5 Expression Statement + Parser.prototype.parseExpressionStatement = function () { + var node = this.createNode(); + var expr = this.parseExpression(); + this.consumeSemicolon(); + return this.finalize(node, new Node.ExpressionStatement(expr)); + }; + // ECMA-262 13.6 If statement + Parser.prototype.parseIfStatement = function () { + var node = this.createNode(); + var consequent; + var alternate = null; + this.expectKeyword('if'); + this.expect('('); + var test = this.parseExpression(); + if (!this.match(')') && this.config.tolerant) { + this.tolerateUnexpectedToken(this.nextToken()); + consequent = this.finalize(this.createNode(), new Node.EmptyStatement()); + } + else { + this.expect(')'); + consequent = this.parseStatement(); + if (this.matchKeyword('else')) { + this.nextToken(); + alternate = this.parseStatement(); + } + } + return this.finalize(node, new Node.IfStatement(test, consequent, alternate)); + }; + // ECMA-262 13.7.2 The do-while Statement + Parser.prototype.parseDoWhileStatement = function () { + var node = this.createNode(); + this.expectKeyword('do'); + var previousInIteration = this.context.inIteration; + this.context.inIteration = true; + var body = this.parseStatement(); + this.context.inIteration = previousInIteration; + this.expectKeyword('while'); + this.expect('('); + var test = this.parseExpression(); + this.expect(')'); + if (this.match(';')) { + this.nextToken(); + } + return this.finalize(node, new Node.DoWhileStatement(body, test)); + }; + // ECMA-262 13.7.3 The while Statement + Parser.prototype.parseWhileStatement = function () { + var node = this.createNode(); + var body; + this.expectKeyword('while'); + this.expect('('); + var test = this.parseExpression(); + if (!this.match(')') && this.config.tolerant) { + this.tolerateUnexpectedToken(this.nextToken()); + body = this.finalize(this.createNode(), new Node.EmptyStatement()); + } + else { + this.expect(')'); + var previousInIteration = this.context.inIteration; + this.context.inIteration = true; + body = this.parseStatement(); + this.context.inIteration = previousInIteration; + } + return this.finalize(node, new Node.WhileStatement(test, body)); + }; + // ECMA-262 13.7.4 The for Statement + // ECMA-262 13.7.5 The for-in and for-of Statements + Parser.prototype.parseForStatement = function () { + var this$1 = this; + + var init = null; + var test = null; + var update = null; + var forIn = true; + var left, right; + var node = this.createNode(); + this.expectKeyword('for'); + this.expect('('); + if (this.match(';')) { + this.nextToken(); + } + else { + if (this.matchKeyword('var')) { + init = this.createNode(); + this.nextToken(); + var previousAllowIn = this.context.allowIn; + this.context.allowIn = false; + var declarations = this.parseVariableDeclarationList({ inFor: true }); + this.context.allowIn = previousAllowIn; + if (declarations.length === 1 && this.matchKeyword('in')) { + var decl = declarations[0]; + if (decl.init && (decl.id.type === syntax_1.Syntax.ArrayPattern || decl.id.type === syntax_1.Syntax.ObjectPattern || this.context.strict)) { + this.tolerateError(messages_1.Messages.ForInOfLoopInitializer, 'for-in'); + } + init = this.finalize(init, new Node.VariableDeclaration(declarations, 'var')); + this.nextToken(); + left = init; + right = this.parseExpression(); + init = null; + } + else if (declarations.length === 1 && declarations[0].init === null && this.matchContextualKeyword('of')) { + init = this.finalize(init, new Node.VariableDeclaration(declarations, 'var')); + this.nextToken(); + left = init; + right = this.parseAssignmentExpression(); + init = null; + forIn = false; + } + else { + init = this.finalize(init, new Node.VariableDeclaration(declarations, 'var')); + this.expect(';'); + } + } + else if (this.matchKeyword('const') || this.matchKeyword('let')) { + init = this.createNode(); + var kind = this.nextToken().value; + if (!this.context.strict && this.lookahead.value === 'in') { + init = this.finalize(init, new Node.Identifier(kind)); + this.nextToken(); + left = init; + right = this.parseExpression(); + init = null; + } + else { + var previousAllowIn = this.context.allowIn; + this.context.allowIn = false; + var declarations = this.parseBindingList(kind, { inFor: true }); + this.context.allowIn = previousAllowIn; + if (declarations.length === 1 && declarations[0].init === null && this.matchKeyword('in')) { + init = this.finalize(init, new Node.VariableDeclaration(declarations, kind)); + this.nextToken(); + left = init; + right = this.parseExpression(); + init = null; + } + else if (declarations.length === 1 && declarations[0].init === null && this.matchContextualKeyword('of')) { + init = this.finalize(init, new Node.VariableDeclaration(declarations, kind)); + this.nextToken(); + left = init; + right = this.parseAssignmentExpression(); + init = null; + forIn = false; + } + else { + this.consumeSemicolon(); + init = this.finalize(init, new Node.VariableDeclaration(declarations, kind)); + } + } + } + else { + var initStartToken = this.lookahead; + var previousAllowIn = this.context.allowIn; + this.context.allowIn = false; + init = this.inheritCoverGrammar(this.parseAssignmentExpression); + this.context.allowIn = previousAllowIn; + if (this.matchKeyword('in')) { + if (!this.context.isAssignmentTarget || init.type === syntax_1.Syntax.AssignmentExpression) { + this.tolerateError(messages_1.Messages.InvalidLHSInForIn); + } + this.nextToken(); + this.reinterpretExpressionAsPattern(init); + left = init; + right = this.parseExpression(); + init = null; + } + else if (this.matchContextualKeyword('of')) { + if (!this.context.isAssignmentTarget || init.type === syntax_1.Syntax.AssignmentExpression) { + this.tolerateError(messages_1.Messages.InvalidLHSInForLoop); + } + this.nextToken(); + this.reinterpretExpressionAsPattern(init); + left = init; + right = this.parseAssignmentExpression(); + init = null; + forIn = false; + } + else { + if (this.match(',')) { + var initSeq = [init]; + while (this.match(',')) { + this$1.nextToken(); + initSeq.push(this$1.isolateCoverGrammar(this$1.parseAssignmentExpression)); + } + init = this.finalize(this.startNode(initStartToken), new Node.SequenceExpression(initSeq)); + } + this.expect(';'); + } + } + } + if (typeof left === 'undefined') { + if (!this.match(';')) { + test = this.parseExpression(); + } + this.expect(';'); + if (!this.match(')')) { + update = this.parseExpression(); + } + } + var body; + if (!this.match(')') && this.config.tolerant) { + this.tolerateUnexpectedToken(this.nextToken()); + body = this.finalize(this.createNode(), new Node.EmptyStatement()); + } + else { + this.expect(')'); + var previousInIteration = this.context.inIteration; + this.context.inIteration = true; + body = this.isolateCoverGrammar(this.parseStatement); + this.context.inIteration = previousInIteration; + } + return (typeof left === 'undefined') ? + this.finalize(node, new Node.ForStatement(init, test, update, body)) : + forIn ? this.finalize(node, new Node.ForInStatement(left, right, body)) : + this.finalize(node, new Node.ForOfStatement(left, right, body)); + }; + // ECMA-262 13.8 The continue statement + Parser.prototype.parseContinueStatement = function () { + var node = this.createNode(); + this.expectKeyword('continue'); + var label = null; + if (this.lookahead.type === token_1.Token.Identifier && !this.hasLineTerminator) { + label = this.parseVariableIdentifier(); + var key = '$' + label.name; + if (!Object.prototype.hasOwnProperty.call(this.context.labelSet, key)) { + this.throwError(messages_1.Messages.UnknownLabel, label.name); + } + } + this.consumeSemicolon(); + if (label === null && !this.context.inIteration) { + this.throwError(messages_1.Messages.IllegalContinue); + } + return this.finalize(node, new Node.ContinueStatement(label)); + }; + // ECMA-262 13.9 The break statement + Parser.prototype.parseBreakStatement = function () { + var node = this.createNode(); + this.expectKeyword('break'); + var label = null; + if (this.lookahead.type === token_1.Token.Identifier && !this.hasLineTerminator) { + label = this.parseVariableIdentifier(); + var key = '$' + label.name; + if (!Object.prototype.hasOwnProperty.call(this.context.labelSet, key)) { + this.throwError(messages_1.Messages.UnknownLabel, label.name); + } + } + this.consumeSemicolon(); + if (label === null && !this.context.inIteration && !this.context.inSwitch) { + this.throwError(messages_1.Messages.IllegalBreak); + } + return this.finalize(node, new Node.BreakStatement(label)); + }; + // ECMA-262 13.10 The return statement + Parser.prototype.parseReturnStatement = function () { + if (!this.context.inFunctionBody) { + this.tolerateError(messages_1.Messages.IllegalReturn); + } + var node = this.createNode(); + this.expectKeyword('return'); + var hasArgument = !this.match(';') && !this.match('}') && + !this.hasLineTerminator && this.lookahead.type !== token_1.Token.EOF; + var argument = hasArgument ? this.parseExpression() : null; + this.consumeSemicolon(); + return this.finalize(node, new Node.ReturnStatement(argument)); + }; + // ECMA-262 13.11 The with statement + Parser.prototype.parseWithStatement = function () { + if (this.context.strict) { + this.tolerateError(messages_1.Messages.StrictModeWith); + } + var node = this.createNode(); + this.expectKeyword('with'); + this.expect('('); + var object = this.parseExpression(); + this.expect(')'); + var body = this.parseStatement(); + return this.finalize(node, new Node.WithStatement(object, body)); + }; + // ECMA-262 13.12 The switch statement + Parser.prototype.parseSwitchCase = function () { + var this$1 = this; + + var node = this.createNode(); + var test; + if (this.matchKeyword('default')) { + this.nextToken(); + test = null; + } + else { + this.expectKeyword('case'); + test = this.parseExpression(); + } + this.expect(':'); + var consequent = []; + while (true) { + if (this$1.match('}') || this$1.matchKeyword('default') || this$1.matchKeyword('case')) { + break; + } + consequent.push(this$1.parseStatementListItem()); + } + return this.finalize(node, new Node.SwitchCase(test, consequent)); + }; + Parser.prototype.parseSwitchStatement = function () { + var this$1 = this; + + var node = this.createNode(); + this.expectKeyword('switch'); + this.expect('('); + var discriminant = this.parseExpression(); + this.expect(')'); + var previousInSwitch = this.context.inSwitch; + this.context.inSwitch = true; + var cases = []; + var defaultFound = false; + this.expect('{'); + while (true) { + if (this$1.match('}')) { + break; + } + var clause = this$1.parseSwitchCase(); + if (clause.test === null) { + if (defaultFound) { + this$1.throwError(messages_1.Messages.MultipleDefaultsInSwitch); + } + defaultFound = true; + } + cases.push(clause); + } + this.expect('}'); + this.context.inSwitch = previousInSwitch; + return this.finalize(node, new Node.SwitchStatement(discriminant, cases)); + }; + // ECMA-262 13.13 Labelled Statements + Parser.prototype.parseLabelledStatement = function () { + var node = this.createNode(); + var expr = this.parseExpression(); + var statement; + if ((expr.type === syntax_1.Syntax.Identifier) && this.match(':')) { + this.nextToken(); + var id = (expr); + var key = '$' + id.name; + if (Object.prototype.hasOwnProperty.call(this.context.labelSet, key)) { + this.throwError(messages_1.Messages.Redeclaration, 'Label', id.name); + } + this.context.labelSet[key] = true; + var labeledBody = this.parseStatement(); + delete this.context.labelSet[key]; + statement = new Node.LabeledStatement(id, labeledBody); + } + else { + this.consumeSemicolon(); + statement = new Node.ExpressionStatement(expr); + } + return this.finalize(node, statement); + }; + // ECMA-262 13.14 The throw statement + Parser.prototype.parseThrowStatement = function () { + var node = this.createNode(); + this.expectKeyword('throw'); + if (this.hasLineTerminator) { + this.throwError(messages_1.Messages.NewlineAfterThrow); + } + var argument = this.parseExpression(); + this.consumeSemicolon(); + return this.finalize(node, new Node.ThrowStatement(argument)); + }; + // ECMA-262 13.15 The try statement + Parser.prototype.parseCatchClause = function () { + var this$1 = this; + + var node = this.createNode(); + this.expectKeyword('catch'); + this.expect('('); + if (this.match(')')) { + this.throwUnexpectedToken(this.lookahead); + } + var params = []; + var param = this.parsePattern(params); + var paramMap = {}; + for (var i = 0; i < params.length; i++) { + var key = '$' + params[i].value; + if (Object.prototype.hasOwnProperty.call(paramMap, key)) { + this$1.tolerateError(messages_1.Messages.DuplicateBinding, params[i].value); + } + paramMap[key] = true; + } + if (this.context.strict && param.type === syntax_1.Syntax.Identifier) { + if (this.scanner.isRestrictedWord((param).name)) { + this.tolerateError(messages_1.Messages.StrictCatchVariable); + } + } + this.expect(')'); + var body = this.parseBlock(); + return this.finalize(node, new Node.CatchClause(param, body)); + }; + Parser.prototype.parseFinallyClause = function () { + this.expectKeyword('finally'); + return this.parseBlock(); + }; + Parser.prototype.parseTryStatement = function () { + var node = this.createNode(); + this.expectKeyword('try'); + var block = this.parseBlock(); + var handler = this.matchKeyword('catch') ? this.parseCatchClause() : null; + var finalizer = this.matchKeyword('finally') ? this.parseFinallyClause() : null; + if (!handler && !finalizer) { + this.throwError(messages_1.Messages.NoCatchOrFinally); + } + return this.finalize(node, new Node.TryStatement(block, handler, finalizer)); + }; + // ECMA-262 13.16 The debugger statement + Parser.prototype.parseDebuggerStatement = function () { + var node = this.createNode(); + this.expectKeyword('debugger'); + this.consumeSemicolon(); + return this.finalize(node, new Node.DebuggerStatement()); + }; + // ECMA-262 13 Statements + Parser.prototype.parseStatement = function () { + var statement = null; + switch (this.lookahead.type) { + case token_1.Token.BooleanLiteral: + case token_1.Token.NullLiteral: + case token_1.Token.NumericLiteral: + case token_1.Token.StringLiteral: + case token_1.Token.Template: + case token_1.Token.RegularExpression: + statement = this.parseExpressionStatement(); + break; + case token_1.Token.Punctuator: + var value = this.lookahead.value; + if (value === '{') { + statement = this.parseBlock(); + } + else if (value === '(') { + statement = this.parseExpressionStatement(); + } + else if (value === ';') { + statement = this.parseEmptyStatement(); + } + else { + statement = this.parseExpressionStatement(); + } + break; + case token_1.Token.Identifier: + statement = this.parseLabelledStatement(); + break; + case token_1.Token.Keyword: + switch (this.lookahead.value) { + case 'break': + statement = this.parseBreakStatement(); + break; + case 'continue': + statement = this.parseContinueStatement(); + break; + case 'debugger': + statement = this.parseDebuggerStatement(); + break; + case 'do': + statement = this.parseDoWhileStatement(); + break; + case 'for': + statement = this.parseForStatement(); + break; + case 'function': + statement = this.parseFunctionDeclaration(); + break; + case 'if': + statement = this.parseIfStatement(); + break; + case 'return': + statement = this.parseReturnStatement(); + break; + case 'switch': + statement = this.parseSwitchStatement(); + break; + case 'throw': + statement = this.parseThrowStatement(); + break; + case 'try': + statement = this.parseTryStatement(); + break; + case 'var': + statement = this.parseVariableStatement(); + break; + case 'while': + statement = this.parseWhileStatement(); + break; + case 'with': + statement = this.parseWithStatement(); + break; + default: + statement = this.parseExpressionStatement(); + break; + } + break; + default: + this.throwUnexpectedToken(this.lookahead); + } + return statement; + }; + // ECMA-262 14.1 Function Definition + Parser.prototype.parseFunctionSourceElements = function () { + var this$1 = this; + + var node = this.createNode(); + this.expect('{'); + var body = this.parseDirectivePrologues(); + var previousLabelSet = this.context.labelSet; + var previousInIteration = this.context.inIteration; + var previousInSwitch = this.context.inSwitch; + var previousInFunctionBody = this.context.inFunctionBody; + this.context.labelSet = {}; + this.context.inIteration = false; + this.context.inSwitch = false; + this.context.inFunctionBody = true; + while (this.startMarker.index < this.scanner.length) { + if (this$1.match('}')) { + break; + } + body.push(this$1.parseStatementListItem()); + } + this.expect('}'); + this.context.labelSet = previousLabelSet; + this.context.inIteration = previousInIteration; + this.context.inSwitch = previousInSwitch; + this.context.inFunctionBody = previousInFunctionBody; + return this.finalize(node, new Node.BlockStatement(body)); + }; + Parser.prototype.validateParam = function (options, param, name) { + var key = '$' + name; + if (this.context.strict) { + if (this.scanner.isRestrictedWord(name)) { + options.stricted = param; + options.message = messages_1.Messages.StrictParamName; + } + if (Object.prototype.hasOwnProperty.call(options.paramSet, key)) { + options.stricted = param; + options.message = messages_1.Messages.StrictParamDupe; + } + } + else if (!options.firstRestricted) { + if (this.scanner.isRestrictedWord(name)) { + options.firstRestricted = param; + options.message = messages_1.Messages.StrictParamName; + } + else if (this.scanner.isStrictModeReservedWord(name)) { + options.firstRestricted = param; + options.message = messages_1.Messages.StrictReservedWord; + } + else if (Object.prototype.hasOwnProperty.call(options.paramSet, key)) { + options.stricted = param; + options.message = messages_1.Messages.StrictParamDupe; + } + } + /* istanbul ignore next */ + if (typeof Object.defineProperty === 'function') { + Object.defineProperty(options.paramSet, key, { value: true, enumerable: true, writable: true, configurable: true }); + } + else { + options.paramSet[key] = true; + } + }; + Parser.prototype.parseRestElement = function (params) { + var node = this.createNode(); + this.expect('...'); + var arg = this.parsePattern(params); + if (this.match('=')) { + this.throwError(messages_1.Messages.DefaultRestParameter); + } + if (!this.match(')')) { + this.throwError(messages_1.Messages.ParameterAfterRestParameter); + } + return this.finalize(node, new Node.RestElement(arg)); + }; + Parser.prototype.parseFormalParameter = function (options) { + var this$1 = this; + + var params = []; + var param = this.match('...') ? this.parseRestElement(params) : this.parsePatternWithDefault(params); + for (var i = 0; i < params.length; i++) { + this$1.validateParam(options, params[i], params[i].value); + } + options.params.push(param); + return !this.match(')'); + }; + Parser.prototype.parseFormalParameters = function (firstRestricted) { + var this$1 = this; + + var options; + options = { + params: [], + firstRestricted: firstRestricted + }; + this.expect('('); + if (!this.match(')')) { + options.paramSet = {}; + while (this.startMarker.index < this.scanner.length) { + if (!this$1.parseFormalParameter(options)) { + break; + } + this$1.expect(','); + } + } + this.expect(')'); + return { + params: options.params, + stricted: options.stricted, + firstRestricted: options.firstRestricted, + message: options.message + }; + }; + Parser.prototype.parseFunctionDeclaration = function (identifierIsOptional) { + var node = this.createNode(); + this.expectKeyword('function'); + var isGenerator = this.match('*'); + if (isGenerator) { + this.nextToken(); + } + var message; + var id = null; + var firstRestricted = null; + if (!identifierIsOptional || !this.match('(')) { + var token = this.lookahead; + id = this.parseVariableIdentifier(); + if (this.context.strict) { + if (this.scanner.isRestrictedWord(token.value)) { + this.tolerateUnexpectedToken(token, messages_1.Messages.StrictFunctionName); + } + } + else { + if (this.scanner.isRestrictedWord(token.value)) { + firstRestricted = token; + message = messages_1.Messages.StrictFunctionName; + } + else if (this.scanner.isStrictModeReservedWord(token.value)) { + firstRestricted = token; + message = messages_1.Messages.StrictReservedWord; + } + } + } + var previousAllowYield = this.context.allowYield; + this.context.allowYield = !isGenerator; + var formalParameters = this.parseFormalParameters(firstRestricted); + var params = formalParameters.params; + var stricted = formalParameters.stricted; + firstRestricted = formalParameters.firstRestricted; + if (formalParameters.message) { + message = formalParameters.message; + } + var previousStrict = this.context.strict; + var body = this.parseFunctionSourceElements(); + if (this.context.strict && firstRestricted) { + this.throwUnexpectedToken(firstRestricted, message); + } + if (this.context.strict && stricted) { + this.tolerateUnexpectedToken(stricted, message); + } + this.context.strict = previousStrict; + this.context.allowYield = previousAllowYield; + return this.finalize(node, new Node.FunctionDeclaration(id, params, body, isGenerator)); + }; + Parser.prototype.parseFunctionExpression = function () { + var node = this.createNode(); + this.expectKeyword('function'); + var isGenerator = this.match('*'); + if (isGenerator) { + this.nextToken(); + } + var message; + var id = null; + var firstRestricted; + var previousAllowYield = this.context.allowYield; + this.context.allowYield = !isGenerator; + if (!this.match('(')) { + var token = this.lookahead; + id = (!this.context.strict && !isGenerator && this.matchKeyword('yield')) ? this.parseIdentifierName() : this.parseVariableIdentifier(); + if (this.context.strict) { + if (this.scanner.isRestrictedWord(token.value)) { + this.tolerateUnexpectedToken(token, messages_1.Messages.StrictFunctionName); + } + } + else { + if (this.scanner.isRestrictedWord(token.value)) { + firstRestricted = token; + message = messages_1.Messages.StrictFunctionName; + } + else if (this.scanner.isStrictModeReservedWord(token.value)) { + firstRestricted = token; + message = messages_1.Messages.StrictReservedWord; + } + } + } + var formalParameters = this.parseFormalParameters(firstRestricted); + var params = formalParameters.params; + var stricted = formalParameters.stricted; + firstRestricted = formalParameters.firstRestricted; + if (formalParameters.message) { + message = formalParameters.message; + } + var previousStrict = this.context.strict; + var body = this.parseFunctionSourceElements(); + if (this.context.strict && firstRestricted) { + this.throwUnexpectedToken(firstRestricted, message); + } + if (this.context.strict && stricted) { + this.tolerateUnexpectedToken(stricted, message); + } + this.context.strict = previousStrict; + this.context.allowYield = previousAllowYield; + return this.finalize(node, new Node.FunctionExpression(id, params, body, isGenerator)); + }; + // ECMA-262 14.1.1 Directive Prologues + Parser.prototype.parseDirective = function () { + var token = this.lookahead; + var directive = null; + var node = this.createNode(); + var expr = this.parseExpression(); + if (expr.type === syntax_1.Syntax.Literal) { + directive = this.getTokenRaw(token).slice(1, -1); + } + this.consumeSemicolon(); + return this.finalize(node, directive ? new Node.Directive(expr, directive) : + new Node.ExpressionStatement(expr)); + }; + Parser.prototype.parseDirectivePrologues = function () { + var this$1 = this; + + var firstRestricted = null; + var body = []; + while (true) { + var token = this$1.lookahead; + if (token.type !== token_1.Token.StringLiteral) { + break; + } + var statement = this$1.parseDirective(); + body.push(statement); + var directive = statement.directive; + if (typeof directive !== 'string') { + break; + } + if (directive === 'use strict') { + this$1.context.strict = true; + if (firstRestricted) { + this$1.tolerateUnexpectedToken(firstRestricted, messages_1.Messages.StrictOctalLiteral); + } + } + else { + if (!firstRestricted && token.octal) { + firstRestricted = token; + } + } + } + return body; + }; + // ECMA-262 14.3 Method Definitions + Parser.prototype.qualifiedPropertyName = function (token) { + switch (token.type) { + case token_1.Token.Identifier: + case token_1.Token.StringLiteral: + case token_1.Token.BooleanLiteral: + case token_1.Token.NullLiteral: + case token_1.Token.NumericLiteral: + case token_1.Token.Keyword: + return true; + case token_1.Token.Punctuator: + return token.value === '['; + } + return false; + }; + Parser.prototype.parseGetterMethod = function () { + var node = this.createNode(); + this.expect('('); + this.expect(')'); + var isGenerator = false; + var params = { + params: [], + stricted: null, + firstRestricted: null, + message: null + }; + var previousAllowYield = this.context.allowYield; + this.context.allowYield = false; + var method = this.parsePropertyMethod(params); + this.context.allowYield = previousAllowYield; + return this.finalize(node, new Node.FunctionExpression(null, params.params, method, isGenerator)); + }; + Parser.prototype.parseSetterMethod = function () { + var node = this.createNode(); + var options = { + params: [], + firstRestricted: null, + paramSet: {} + }; + var isGenerator = false; + var previousAllowYield = this.context.allowYield; + this.context.allowYield = false; + this.expect('('); + if (this.match(')')) { + this.tolerateUnexpectedToken(this.lookahead); + } + else { + this.parseFormalParameter(options); + } + this.expect(')'); + var method = this.parsePropertyMethod(options); + this.context.allowYield = previousAllowYield; + return this.finalize(node, new Node.FunctionExpression(null, options.params, method, isGenerator)); + }; + Parser.prototype.parseGeneratorMethod = function () { + var node = this.createNode(); + var isGenerator = true; + var previousAllowYield = this.context.allowYield; + this.context.allowYield = true; + var params = this.parseFormalParameters(); + this.context.allowYield = false; + var method = this.parsePropertyMethod(params); + this.context.allowYield = previousAllowYield; + return this.finalize(node, new Node.FunctionExpression(null, params.params, method, isGenerator)); + }; + // ECMA-262 14.4 Generator Function Definitions + Parser.prototype.isStartOfExpression = function () { + var start = true; + var value = this.lookahead.value; + switch (this.lookahead.type) { + case token_1.Token.Punctuator: + start = (value === '[') || (value === '(') || (value === '{') || + (value === '+') || (value === '-') || + (value === '!') || (value === '~') || + (value === '++') || (value === '--') || + (value === '/') || (value === '/='); // regular expression literal + break; + case token_1.Token.Keyword: + start = (value === 'class') || (value === 'delete') || + (value === 'function') || (value === 'let') || (value === 'new') || + (value === 'super') || (value === 'this') || (value === 'typeof') || + (value === 'void') || (value === 'yield'); + break; + default: + break; + } + return start; + }; + Parser.prototype.parseYieldExpression = function () { + var node = this.createNode(); + this.expectKeyword('yield'); + var argument = null; + var delegate = false; + if (!this.hasLineTerminator) { + var previousAllowYield = this.context.allowYield; + this.context.allowYield = false; + delegate = this.match('*'); + if (delegate) { + this.nextToken(); + argument = this.parseAssignmentExpression(); + } + else if (this.isStartOfExpression()) { + argument = this.parseAssignmentExpression(); + } + this.context.allowYield = previousAllowYield; + } + return this.finalize(node, new Node.YieldExpression(argument, delegate)); + }; + // ECMA-262 14.5 Class Definitions + Parser.prototype.parseClassElement = function (hasConstructor) { + var token = this.lookahead; + var node = this.createNode(); + var kind; + var key; + var value; + var computed = false; + var method = false; + var isStatic = false; + if (this.match('*')) { + this.nextToken(); + } + else { + computed = this.match('['); + key = this.parseObjectPropertyKey(); + var id = key; + if (id.name === 'static' && (this.qualifiedPropertyName(this.lookahead) || this.match('*'))) { + token = this.lookahead; + isStatic = true; + computed = this.match('['); + if (this.match('*')) { + this.nextToken(); + } + else { + key = this.parseObjectPropertyKey(); + } + } + } + var lookaheadPropertyKey = this.qualifiedPropertyName(this.lookahead); + if (token.type === token_1.Token.Identifier) { + if (token.value === 'get' && lookaheadPropertyKey) { + kind = 'get'; + computed = this.match('['); + key = this.parseObjectPropertyKey(); + this.context.allowYield = false; + value = this.parseGetterMethod(); + } + else if (token.value === 'set' && lookaheadPropertyKey) { + kind = 'set'; + computed = this.match('['); + key = this.parseObjectPropertyKey(); + value = this.parseSetterMethod(); + } + } + else if (token.type === token_1.Token.Punctuator && token.value === '*' && lookaheadPropertyKey) { + kind = 'init'; + computed = this.match('['); + key = this.parseObjectPropertyKey(); + value = this.parseGeneratorMethod(); + method = true; + } + if (!kind && key && this.match('(')) { + kind = 'init'; + value = this.parsePropertyMethodFunction(); + method = true; + } + if (!kind) { + this.throwUnexpectedToken(this.lookahead); + } + if (kind === 'init') { + kind = 'method'; + } + if (!computed) { + if (isStatic && this.isPropertyKey(key, 'prototype')) { + this.throwUnexpectedToken(token, messages_1.Messages.StaticPrototype); + } + if (!isStatic && this.isPropertyKey(key, 'constructor')) { + if (kind !== 'method' || !method || value.generator) { + this.throwUnexpectedToken(token, messages_1.Messages.ConstructorSpecialMethod); + } + if (hasConstructor.value) { + this.throwUnexpectedToken(token, messages_1.Messages.DuplicateConstructor); + } + else { + hasConstructor.value = true; + } + kind = 'constructor'; + } + } + return this.finalize(node, new Node.MethodDefinition(key, computed, value, kind, isStatic)); + }; + Parser.prototype.parseClassElementList = function () { + var this$1 = this; + + var body = []; + var hasConstructor = { value: false }; + this.expect('{'); + while (!this.match('}')) { + if (this$1.match(';')) { + this$1.nextToken(); + } + else { + body.push(this$1.parseClassElement(hasConstructor)); + } + } + this.expect('}'); + return body; + }; + Parser.prototype.parseClassBody = function () { + var node = this.createNode(); + var elementList = this.parseClassElementList(); + return this.finalize(node, new Node.ClassBody(elementList)); + }; + Parser.prototype.parseClassDeclaration = function (identifierIsOptional) { + var node = this.createNode(); + var previousStrict = this.context.strict; + this.context.strict = true; + this.expectKeyword('class'); + var id = (identifierIsOptional && (this.lookahead.type !== token_1.Token.Identifier)) ? null : this.parseVariableIdentifier(); + var superClass = null; + if (this.matchKeyword('extends')) { + this.nextToken(); + superClass = this.isolateCoverGrammar(this.parseLeftHandSideExpressionAllowCall); + } + var classBody = this.parseClassBody(); + this.context.strict = previousStrict; + return this.finalize(node, new Node.ClassDeclaration(id, superClass, classBody)); + }; + Parser.prototype.parseClassExpression = function () { + var node = this.createNode(); + var previousStrict = this.context.strict; + this.context.strict = true; + this.expectKeyword('class'); + var id = (this.lookahead.type === token_1.Token.Identifier) ? this.parseVariableIdentifier() : null; + var superClass = null; + if (this.matchKeyword('extends')) { + this.nextToken(); + superClass = this.isolateCoverGrammar(this.parseLeftHandSideExpressionAllowCall); + } + var classBody = this.parseClassBody(); + this.context.strict = previousStrict; + return this.finalize(node, new Node.ClassExpression(id, superClass, classBody)); + }; + // ECMA-262 15.1 Scripts + // ECMA-262 15.2 Modules + Parser.prototype.parseProgram = function () { + var this$1 = this; + + var node = this.createNode(); + var body = this.parseDirectivePrologues(); + while (this.startMarker.index < this.scanner.length) { + body.push(this$1.parseStatementListItem()); + } + return this.finalize(node, new Node.Program(body, this.sourceType)); + }; + // ECMA-262 15.2.2 Imports + Parser.prototype.parseModuleSpecifier = function () { + var node = this.createNode(); + if (this.lookahead.type !== token_1.Token.StringLiteral) { + this.throwError(messages_1.Messages.InvalidModuleSpecifier); + } + var token = this.nextToken(); + var raw = this.getTokenRaw(token); + return this.finalize(node, new Node.Literal(token.value, raw)); + }; + // import {} ...; + Parser.prototype.parseImportSpecifier = function () { + var node = this.createNode(); + var imported; + var local; + if (this.lookahead.type === token_1.Token.Identifier) { + imported = this.parseVariableIdentifier(); + local = imported; + if (this.matchContextualKeyword('as')) { + this.nextToken(); + local = this.parseVariableIdentifier(); + } + } + else { + imported = this.parseIdentifierName(); + local = imported; + if (this.matchContextualKeyword('as')) { + this.nextToken(); + local = this.parseVariableIdentifier(); + } + else { + this.throwUnexpectedToken(this.nextToken()); + } + } + return this.finalize(node, new Node.ImportSpecifier(local, imported)); + }; + // {foo, bar as bas} + Parser.prototype.parseNamedImports = function () { + var this$1 = this; + + this.expect('{'); + var specifiers = []; + while (!this.match('}')) { + specifiers.push(this$1.parseImportSpecifier()); + if (!this$1.match('}')) { + this$1.expect(','); + } + } + this.expect('}'); + return specifiers; + }; + // import ...; + Parser.prototype.parseImportDefaultSpecifier = function () { + var node = this.createNode(); + var local = this.parseIdentifierName(); + return this.finalize(node, new Node.ImportDefaultSpecifier(local)); + }; + // import <* as foo> ...; + Parser.prototype.parseImportNamespaceSpecifier = function () { + var node = this.createNode(); + this.expect('*'); + if (!this.matchContextualKeyword('as')) { + this.throwError(messages_1.Messages.NoAsAfterImportNamespace); + } + this.nextToken(); + var local = this.parseIdentifierName(); + return this.finalize(node, new Node.ImportNamespaceSpecifier(local)); + }; + Parser.prototype.parseImportDeclaration = function () { + if (this.context.inFunctionBody) { + this.throwError(messages_1.Messages.IllegalImportDeclaration); + } + var node = this.createNode(); + this.expectKeyword('import'); + var src; + var specifiers = []; + if (this.lookahead.type === token_1.Token.StringLiteral) { + // import 'foo'; + src = this.parseModuleSpecifier(); + } + else { + if (this.match('{')) { + // import {bar} + specifiers = specifiers.concat(this.parseNamedImports()); + } + else if (this.match('*')) { + // import * as foo + specifiers.push(this.parseImportNamespaceSpecifier()); + } + else if (this.isIdentifierName(this.lookahead) && !this.matchKeyword('default')) { + // import foo + specifiers.push(this.parseImportDefaultSpecifier()); + if (this.match(',')) { + this.nextToken(); + if (this.match('*')) { + // import foo, * as foo + specifiers.push(this.parseImportNamespaceSpecifier()); + } + else if (this.match('{')) { + // import foo, {bar} + specifiers = specifiers.concat(this.parseNamedImports()); + } + else { + this.throwUnexpectedToken(this.lookahead); + } + } + } + else { + this.throwUnexpectedToken(this.nextToken()); + } + if (!this.matchContextualKeyword('from')) { + var message = this.lookahead.value ? messages_1.Messages.UnexpectedToken : messages_1.Messages.MissingFromClause; + this.throwError(message, this.lookahead.value); + } + this.nextToken(); + src = this.parseModuleSpecifier(); + } + this.consumeSemicolon(); + return this.finalize(node, new Node.ImportDeclaration(specifiers, src)); + }; + // ECMA-262 15.2.3 Exports + Parser.prototype.parseExportSpecifier = function () { + var node = this.createNode(); + var local = this.parseIdentifierName(); + var exported = local; + if (this.matchContextualKeyword('as')) { + this.nextToken(); + exported = this.parseIdentifierName(); + } + return this.finalize(node, new Node.ExportSpecifier(local, exported)); + }; + Parser.prototype.parseExportDeclaration = function () { + var this$1 = this; + + if (this.context.inFunctionBody) { + this.throwError(messages_1.Messages.IllegalExportDeclaration); + } + var node = this.createNode(); + this.expectKeyword('export'); + var exportDeclaration; + if (this.matchKeyword('default')) { + // export default ... + this.nextToken(); + if (this.matchKeyword('function')) { + // export default function foo () {} + // export default function () {} + var declaration = this.parseFunctionDeclaration(true); + exportDeclaration = this.finalize(node, new Node.ExportDefaultDeclaration(declaration)); + } + else if (this.matchKeyword('class')) { + // export default class foo {} + var declaration = this.parseClassDeclaration(true); + exportDeclaration = this.finalize(node, new Node.ExportDefaultDeclaration(declaration)); + } + else { + if (this.matchContextualKeyword('from')) { + this.throwError(messages_1.Messages.UnexpectedToken, this.lookahead.value); + } + // export default {}; + // export default []; + // export default (1 + 2); + var declaration = this.match('{') ? this.parseObjectInitializer() : + this.match('[') ? this.parseArrayInitializer() : this.parseAssignmentExpression(); + this.consumeSemicolon(); + exportDeclaration = this.finalize(node, new Node.ExportDefaultDeclaration(declaration)); + } + } + else if (this.match('*')) { + // export * from 'foo'; + this.nextToken(); + if (!this.matchContextualKeyword('from')) { + var message = this.lookahead.value ? messages_1.Messages.UnexpectedToken : messages_1.Messages.MissingFromClause; + this.throwError(message, this.lookahead.value); + } + this.nextToken(); + var src = this.parseModuleSpecifier(); + this.consumeSemicolon(); + exportDeclaration = this.finalize(node, new Node.ExportAllDeclaration(src)); + } + else if (this.lookahead.type === token_1.Token.Keyword) { + // export var f = 1; + var declaration = void 0; + switch (this.lookahead.value) { + case 'let': + case 'const': + declaration = this.parseLexicalDeclaration({ inFor: false }); + break; + case 'var': + case 'class': + case 'function': + declaration = this.parseStatementListItem(); + break; + default: + this.throwUnexpectedToken(this.lookahead); + } + exportDeclaration = this.finalize(node, new Node.ExportNamedDeclaration(declaration, [], null)); + } + else { + var specifiers = []; + var source = null; + var isExportFromIdentifier = false; + this.expect('{'); + while (!this.match('}')) { + isExportFromIdentifier = isExportFromIdentifier || this$1.matchKeyword('default'); + specifiers.push(this$1.parseExportSpecifier()); + if (!this$1.match('}')) { + this$1.expect(','); + } + } + this.expect('}'); + if (this.matchContextualKeyword('from')) { + // export {default} from 'foo'; + // export {foo} from 'foo'; + this.nextToken(); + source = this.parseModuleSpecifier(); + this.consumeSemicolon(); + } + else if (isExportFromIdentifier) { + // export {default}; // missing fromClause + var message = this.lookahead.value ? messages_1.Messages.UnexpectedToken : messages_1.Messages.MissingFromClause; + this.throwError(message, this.lookahead.value); + } + else { + // export {foo}; + this.consumeSemicolon(); + } + exportDeclaration = this.finalize(node, new Node.ExportNamedDeclaration(null, specifiers, source)); + } + return exportDeclaration; + }; + return Parser; + }()); + exports.Parser = Parser; + + + /***/ }, + /* 4 */ + /***/ function(module, exports) { + function assert(condition, message) { + /* istanbul ignore if */ + if (!condition) { + throw new Error('ASSERT: ' + message); + } + } + exports.assert = assert; + + + /***/ }, + /* 5 */ + /***/ function(module, exports) { + // Error messages should be identical to V8. + exports.Messages = { + UnexpectedToken: 'Unexpected token %0', + UnexpectedTokenIllegal: 'Unexpected token ILLEGAL', + UnexpectedNumber: 'Unexpected number', + UnexpectedString: 'Unexpected string', + UnexpectedIdentifier: 'Unexpected identifier', + UnexpectedReserved: 'Unexpected reserved word', + UnexpectedTemplate: 'Unexpected quasi %0', + UnexpectedEOS: 'Unexpected end of input', + NewlineAfterThrow: 'Illegal newline after throw', + InvalidRegExp: 'Invalid regular expression', + UnterminatedRegExp: 'Invalid regular expression: missing /', + InvalidLHSInAssignment: 'Invalid left-hand side in assignment', + InvalidLHSInForIn: 'Invalid left-hand side in for-in', + InvalidLHSInForLoop: 'Invalid left-hand side in for-loop', + MultipleDefaultsInSwitch: 'More than one default clause in switch statement', + NoCatchOrFinally: 'Missing catch or finally after try', + UnknownLabel: 'Undefined label \'%0\'', + Redeclaration: '%0 \'%1\' has already been declared', + IllegalContinue: 'Illegal continue statement', + IllegalBreak: 'Illegal break statement', + IllegalReturn: 'Illegal return statement', + StrictModeWith: 'Strict mode code may not include a with statement', + StrictCatchVariable: 'Catch variable may not be eval or arguments in strict mode', + StrictVarName: 'Variable name may not be eval or arguments in strict mode', + StrictParamName: 'Parameter name eval or arguments is not allowed in strict mode', + StrictParamDupe: 'Strict mode function may not have duplicate parameter names', + StrictFunctionName: 'Function name may not be eval or arguments in strict mode', + StrictOctalLiteral: 'Octal literals are not allowed in strict mode.', + StrictDelete: 'Delete of an unqualified identifier in strict mode.', + StrictLHSAssignment: 'Assignment to eval or arguments is not allowed in strict mode', + StrictLHSPostfix: 'Postfix increment/decrement may not have eval or arguments operand in strict mode', + StrictLHSPrefix: 'Prefix increment/decrement may not have eval or arguments operand in strict mode', + StrictReservedWord: 'Use of future reserved word in strict mode', + TemplateOctalLiteral: 'Octal literals are not allowed in template strings.', + ParameterAfterRestParameter: 'Rest parameter must be last formal parameter', + DefaultRestParameter: 'Unexpected token =', + DuplicateProtoProperty: 'Duplicate __proto__ fields are not allowed in object literals', + ConstructorSpecialMethod: 'Class constructor may not be an accessor', + DuplicateConstructor: 'A class may only have one constructor', + StaticPrototype: 'Classes may not have static property named prototype', + MissingFromClause: 'Unexpected token', + NoAsAfterImportNamespace: 'Unexpected token', + InvalidModuleSpecifier: 'Unexpected token', + IllegalImportDeclaration: 'Unexpected token', + IllegalExportDeclaration: 'Unexpected token', + DuplicateBinding: 'Duplicate binding %0', + ForInOfLoopInitializer: '%0 loop variable declaration may not have an initializer' + }; + + + /***/ }, + /* 6 */ + /***/ function(module, exports) { + var ErrorHandler = (function () { + function ErrorHandler() { + this.errors = []; + this.tolerant = false; + } + + ErrorHandler.prototype.recordError = function (error) { + this.errors.push(error); + }; + + ErrorHandler.prototype.tolerate = function (error) { + if (this.tolerant) { + this.recordError(error); + } + else { + throw error; + } + }; + + ErrorHandler.prototype.constructError = function (msg, column) { + var error = new Error(msg); + try { + throw error; + } + catch (base) { + /* istanbul ignore else */ + if (Object.create && Object.defineProperty) { + error = Object.create(base); + Object.defineProperty(error, 'column', { value: column }); + } + } + finally { + return error; + } + }; + + ErrorHandler.prototype.createError = function (index, line, col, description) { + var msg = 'Line ' + line + ': ' + description; + var error = this.constructError(msg, col); + error.index = index; + error.lineNumber = line; + error.description = description; + return error; + }; + + ErrorHandler.prototype.throwError = function (index, line, col, description) { + throw this.createError(index, line, col, description); + }; + + ErrorHandler.prototype.tolerateError = function (index, line, col, description) { + var error = this.createError(index, line, col, description); + if (this.tolerant) { + this.recordError(error); + } + else { + throw error; + } + }; + + return ErrorHandler; + }()); + exports.ErrorHandler = ErrorHandler; + + + /***/ }, + /* 7 */ + /***/ function(module, exports) { + (function (Token) { + Token[Token["BooleanLiteral"] = 1] = "BooleanLiteral"; + Token[Token["EOF"] = 2] = "EOF"; + Token[Token["Identifier"] = 3] = "Identifier"; + Token[Token["Keyword"] = 4] = "Keyword"; + Token[Token["NullLiteral"] = 5] = "NullLiteral"; + Token[Token["NumericLiteral"] = 6] = "NumericLiteral"; + Token[Token["Punctuator"] = 7] = "Punctuator"; + Token[Token["StringLiteral"] = 8] = "StringLiteral"; + Token[Token["RegularExpression"] = 9] = "RegularExpression"; + Token[Token["Template"] = 10] = "Template"; + })(exports.Token || (exports.Token = {})); + var Token = exports.Token; + + exports.TokenName = {}; + exports.TokenName[Token.BooleanLiteral] = 'Boolean'; + exports.TokenName[Token.EOF] = ''; + exports.TokenName[Token.Identifier] = 'Identifier'; + exports.TokenName[Token.Keyword] = 'Keyword'; + exports.TokenName[Token.NullLiteral] = 'Null'; + exports.TokenName[Token.NumericLiteral] = 'Numeric'; + exports.TokenName[Token.Punctuator] = 'Punctuator'; + exports.TokenName[Token.StringLiteral] = 'String'; + exports.TokenName[Token.RegularExpression] = 'RegularExpression'; + exports.TokenName[Token.Template] = 'Template'; + + + /***/ }, + /* 8 */ + /***/ function(module, exports, __webpack_require__) { + var assert_1 = __webpack_require__(4); + var messages_1 = __webpack_require__(5); + var character_1 = __webpack_require__(9); + var token_1 = __webpack_require__(7); + function hexValue(ch) { + return '0123456789abcdef'.indexOf(ch.toLowerCase()); + } + function octalValue(ch) { + return '01234567'.indexOf(ch); + } + var Scanner = (function () { + function Scanner(code, handler) { + this.source = code; + this.errorHandler = handler; + this.trackComment = false; + this.length = code.length; + this.index = 0; + this.lineNumber = (code.length > 0) ? 1 : 0; + this.lineStart = 0; + this.curlyStack = []; + } + + Scanner.prototype.eof = function () { + return this.index >= this.length; + }; + + Scanner.prototype.throwUnexpectedToken = function (message) { + if (message === void 0) { message = messages_1.Messages.UnexpectedTokenIllegal; } + this.errorHandler.throwError(this.index, this.lineNumber, this.index - this.lineStart + 1, message); + }; + + Scanner.prototype.tolerateUnexpectedToken = function () { + this.errorHandler.tolerateError(this.index, this.lineNumber, this.index - this.lineStart + 1, messages_1.Messages.UnexpectedTokenIllegal); + }; + + // ECMA-262 11.4 Comments + Scanner.prototype.skipSingleLineComment = function (offset) { + var this$1 = this; + + var comments; + var start, loc; + if (this.trackComment) { + comments = []; + start = this.index - offset; + loc = { + start: { + line: this.lineNumber, + column: this.index - this.lineStart - offset + }, + end: {} + }; + } + while (!this.eof()) { + var ch = this$1.source.charCodeAt(this$1.index); + ++this$1.index; + if (character_1.Character.isLineTerminator(ch)) { + if (this$1.trackComment) { + loc.end = { + line: this$1.lineNumber, + column: this$1.index - this$1.lineStart - 1 + }; + var entry = { + multiLine: false, + slice: [start + offset, this$1.index - 1], + range: [start, this$1.index - 1], + loc: loc + }; + comments.push(entry); + } + if (ch === 13 && this$1.source.charCodeAt(this$1.index) === 10) { + ++this$1.index; + } + ++this$1.lineNumber; + this$1.lineStart = this$1.index; + return comments; + } + } + if (this.trackComment) { + loc.end = { + line: this.lineNumber, + column: this.index - this.lineStart + }; + var entry = { + multiLine: false, + slice: [start + offset, this.index], + range: [start, this.index], + loc: loc + }; + comments.push(entry); + } + return comments; + }; + + Scanner.prototype.skipMultiLineComment = function () { + var this$1 = this; + + var comments; + var start, loc; + if (this.trackComment) { + comments = []; + start = this.index - 2; + loc = { + start: { + line: this.lineNumber, + column: this.index - this.lineStart - 2 + }, + end: {} + }; + } + while (!this.eof()) { + var ch = this$1.source.charCodeAt(this$1.index); + if (character_1.Character.isLineTerminator(ch)) { + if (ch === 0x0D && this$1.source.charCodeAt(this$1.index + 1) === 0x0A) { + ++this$1.index; + } + ++this$1.lineNumber; + ++this$1.index; + this$1.lineStart = this$1.index; + } + else if (ch === 0x2A) { + // Block comment ends with '*/'. + if (this$1.source.charCodeAt(this$1.index + 1) === 0x2F) { + this$1.index += 2; + if (this$1.trackComment) { + loc.end = { + line: this$1.lineNumber, + column: this$1.index - this$1.lineStart + }; + var entry = { + multiLine: true, + slice: [start + 2, this$1.index - 2], + range: [start, this$1.index], + loc: loc + }; + comments.push(entry); + } + return comments; + } + ++this$1.index; + } + else { + ++this$1.index; + } + } + // Ran off the end of the file - the whole thing is a comment + if (this.trackComment) { + loc.end = { + line: this.lineNumber, + column: this.index - this.lineStart + }; + var entry = { + multiLine: true, + slice: [start + 2, this.index], + range: [start, this.index], + loc: loc + }; + comments.push(entry); + } + this.tolerateUnexpectedToken(); + return comments; + }; + + Scanner.prototype.scanComments = function () { + var this$1 = this; + + var comments; + if (this.trackComment) { + comments = []; + } + var start = (this.index === 0); + while (!this.eof()) { + var ch = this$1.source.charCodeAt(this$1.index); + if (character_1.Character.isWhiteSpace(ch)) { + ++this$1.index; + } + else if (character_1.Character.isLineTerminator(ch)) { + ++this$1.index; + if (ch === 0x0D && this$1.source.charCodeAt(this$1.index) === 0x0A) { + ++this$1.index; + } + ++this$1.lineNumber; + this$1.lineStart = this$1.index; + start = true; + } + else if (ch === 0x2F) { + ch = this$1.source.charCodeAt(this$1.index + 1); + if (ch === 0x2F) { + this$1.index += 2; + var comment = this$1.skipSingleLineComment(2); + if (this$1.trackComment) { + comments = comments.concat(comment); + } + start = true; + } + else if (ch === 0x2A) { + this$1.index += 2; + var comment = this$1.skipMultiLineComment(); + if (this$1.trackComment) { + comments = comments.concat(comment); + } + } + else { + break; + } + } + else if (start && ch === 0x2D) { + // U+003E is '>' + if ((this$1.source.charCodeAt(this$1.index + 1) === 0x2D) && (this$1.source.charCodeAt(this$1.index + 2) === 0x3E)) { + // '-->' is a single-line comment + this$1.index += 3; + var comment = this$1.skipSingleLineComment(3); + if (this$1.trackComment) { + comments = comments.concat(comment); + } + } + else { + break; + } + } + else if (ch === 0x3C) { + if (this$1.source.slice(this$1.index + 1, this$1.index + 4) === '!--') { + this$1.index += 4; // ` + + + { dbname } + + + + + { lastSample.nbQueries } + + + + + { formatElapsed } +
+
+ { query } +
+
+
+ + + + +
+ + ADDED public/riot-3.13.2/test/performance/db-monster/dbmon.tag Index: public/riot-3.13.2/test/performance/db-monster/dbmon.tag ================================================================== --- public/riot-3.13.2/test/performance/db-monster/dbmon.tag +++ public/riot-3.13.2/test/performance/db-monster/dbmon.tag @@ -0,0 +1,44 @@ + +
+ + + + + + + + + + + +
+ { dbname } + + + { lastSample.nbQueries } + + + { formatElapsed } +
+
+ { query } +
+
+
+
+
+ +
ADDED public/riot-3.13.2/test/performance/db-monster/index.html Index: public/riot-3.13.2/test/performance/db-monster/index.html ================================================================== --- public/riot-3.13.2/test/performance/db-monster/index.html +++ public/riot-3.13.2/test/performance/db-monster/index.html @@ -0,0 +1,18 @@ + + + + + + + dbmon (riot) + + + + + + + + + + + ADDED public/riot-3.13.2/test/performance/db-monster/memory-stats.js Index: public/riot-3.13.2/test/performance/db-monster/memory-stats.js ================================================================== --- public/riot-3.13.2/test/performance/db-monster/memory-stats.js +++ public/riot-3.13.2/test/performance/db-monster/memory-stats.js @@ -0,0 +1,101 @@ +/** + * @author mrdoob / http://mrdoob.com/ + * @author jetienne / http://jetienne.com/ + * @author paulirish / http://paulirish.com/ + */ +var MemoryStats = function (){ + + var msMin = 100; + var msMax = 0; + + var container = document.createElement( 'div' ); + container.id = 'stats'; + container.style.cssText = 'width:80px;opacity:0.9;cursor:pointer'; + + var msDiv = document.createElement( 'div' ); + msDiv.id = 'ms'; + msDiv.style.cssText = 'padding:0 0 3px 3px;text-align:left;background-color:#020;'; + container.appendChild( msDiv ); + + var msText = document.createElement( 'div' ); + msText.id = 'msText'; + msText.style.cssText = 'color:#0f0;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px'; + msText.innerHTML= 'Memory'; + msDiv.appendChild( msText ); + + var msGraph = document.createElement( 'div' ); + msGraph.id = 'msGraph'; + msGraph.style.cssText = 'position:relative;width:74px;height:30px;background-color:#0f0'; + msDiv.appendChild( msGraph ); + + while ( msGraph.children.length < 74 ) { + + var bar = document.createElement( 'span' ); + bar.style.cssText = 'width:1px;height:30px;float:left;background-color:#131'; + msGraph.appendChild( bar ); + + } + + var updateGraph = function ( dom, height, color ) { + + var child = dom.appendChild( dom.firstChild ); + child.style.height = height + 'px'; + if( color ) child.style.backgroundColor = color; + + } + + var perf = window.performance || {}; + // polyfill usedJSHeapSize + if (!perf && !perf.memory){ + perf.memory = { usedJSHeapSize : 0 }; + } + if (perf && !perf.memory){ + perf.memory = { usedJSHeapSize : 0 }; + } + + // support of the API? + if( perf.memory.totalJSHeapSize === 0 ){ + console.warn('totalJSHeapSize === 0... performance.memory is only available in Chrome .') + } + + // TODO, add a sanity check to see if values are bucketed. + // If so, reminde user to adopt the --enable-precise-memory-info flag. + // open -a "/Applications/Google Chrome.app" --args --enable-precise-memory-info + + var lastTime = Date.now(); + var lastUsedHeap= perf.memory.usedJSHeapSize; + return { + domElement: container, + + update: function () { + + // refresh only 30time per second + if( Date.now() - lastTime < 1000/30 ) return; + lastTime = Date.now() + + var delta = perf.memory.usedJSHeapSize - lastUsedHeap; + lastUsedHeap = perf.memory.usedJSHeapSize; + var color = delta < 0 ? '#830' : '#131'; + + var ms = perf.memory.usedJSHeapSize; + msMin = Math.min( msMin, ms ); + msMax = Math.max( msMax, ms ); + msText.textContent = "Mem: " + bytesToSize(ms, 2); + + var normValue = ms / (30*1024*1024); + var height = Math.min( 30, 30 - normValue * 30 ); + updateGraph( msGraph, height, color); + + function bytesToSize( bytes, nFractDigit ){ + var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']; + if (bytes == 0) return 'n/a'; + nFractDigit = nFractDigit !== undefined ? nFractDigit : 0; + var precision = Math.pow(10, nFractDigit); + var i = Math.floor(Math.log(bytes) / Math.log(1024)); + return Math.round(bytes*precision / Math.pow(1024, i))/precision + ' ' + sizes[i]; + }; + } + + } + +}; ADDED public/riot-3.13.2/test/performance/db-monster/monitor.js Index: public/riot-3.13.2/test/performance/db-monster/monitor.js ================================================================== --- public/riot-3.13.2/test/performance/db-monster/monitor.js +++ public/riot-3.13.2/test/performance/db-monster/monitor.js @@ -0,0 +1,60 @@ +var Monitoring = Monitoring || (function() { + + var stats = new MemoryStats(); + stats.domElement.style.position = 'fixed'; + stats.domElement.style.right = '0px'; + stats.domElement.style.bottom = '0px'; + document.body.appendChild( stats.domElement ); + requestAnimationFrame(function rAFloop(){ + stats.update(); + requestAnimationFrame(rAFloop); + }); + + var RenderRate = function () { + var container = document.createElement( 'div' ); + container.id = 'stats'; + container.style.cssText = 'width:150px;opacity:0.9;cursor:pointer;position:fixed;right:80px;bottom:0px;'; + + var msDiv = document.createElement( 'div' ); + msDiv.id = 'ms'; + msDiv.style.cssText = 'padding:0 0 3px 3px;text-align:left;background-color:#020;'; + container.appendChild( msDiv ); + + var msText = document.createElement( 'div' ); + msText.id = 'msText'; + msText.style.cssText = 'color:#0f0;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px'; + msText.innerHTML= 'Repaint rate: 0/sec'; + msDiv.appendChild( msText ); + + var bucketSize = 20; + var bucket = []; + var lastTime = Date.now(); + return { + domElement: container, + ping: function () { + var start = lastTime; + var stop = Date.now(); + var rate = 1000 / (stop - start); + bucket.push(rate); + if (bucket.length > bucketSize) { + bucket.shift(); + } + var sum = 0; + for (var i = 0; i < bucket.length; i++) { + sum = sum + bucket[i]; + } + msText.textContent = "Repaint rate: " + (sum / bucket.length).toFixed(2) + "/sec"; + lastTime = stop; + } + } + }; + + var renderRate = new RenderRate(); + document.body.appendChild( renderRate.domElement ); + + return { + memoryStats: stats, + renderRate: renderRate + }; + +})(); ADDED public/riot-3.13.2/test/performance/db-monster/no-reorder.html Index: public/riot-3.13.2/test/performance/db-monster/no-reorder.html ================================================================== --- public/riot-3.13.2/test/performance/db-monster/no-reorder.html +++ public/riot-3.13.2/test/performance/db-monster/no-reorder.html @@ -0,0 +1,18 @@ + + + + + + + dbmon (riot) + + + + + + + + + + + ADDED public/riot-3.13.2/test/performance/db-monster/styles.css Index: public/riot-3.13.2/test/performance/db-monster/styles.css ================================================================== --- public/riot-3.13.2/test/performance/db-monster/styles.css +++ public/riot-3.13.2/test/performance/db-monster/styles.css @@ -0,0 +1,10 @@ +.Query { + position: relative; +} + +.Query:hover .popover { + left: -100%; + width: 100%; + display: block; +} + ADDED public/riot-3.13.2/test/performance/loop.html Index: public/riot-3.13.2/test/performance/loop.html ================================================================== --- public/riot-3.13.2/test/performance/loop.html +++ public/riot-3.13.2/test/performance/loop.html @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + ADDED public/riot-3.13.2/test/performance/memory/index.js Index: public/riot-3.13.2/test/performance/memory/index.js ================================================================== --- public/riot-3.13.2/test/performance/memory/index.js +++ public/riot-3.13.2/test/performance/memory/index.js @@ -0,0 +1,105 @@ +/** + * + * You can check the live example on here http://jsfiddle.net/gianlucaguarini/ftoLgfg3/ + * + */ + +var riot = require('../../../dist/riot/riot'), + jsdom = require('jsdom').JSDOM, + myComponent = 'my-component', + myComponentHTML = ` + '

{ opts.title }

', + '

{ opts.description }

', + '' + `, + result, + myListItem = 'my-list-item', + myListItemHTML = ` + '', + 'I am active' + ` + + +/** + * Helper function to generate custom array + * @param { int } amount amount of entries in the array + * @param { * } data + * @return array + */ + + +function generateItems (amount) { + var items = [] + while (--amount) { + items.push({ + isActive: false + }) + } + return items +} + +/** + * Check the memory usage analizing the heap + * @param { function } fn + * @return { array } memory used + duration + */ + +function measure(fn) { + var startTime = Date.now() + fn() + global.gc() + return [process.memoryUsage().heapUsed, Date.now() - startTime] +} + +/** + * Adding the custom tags to the riot internal cache + */ + +function setupTags() { + riot.tag(myComponent, myComponentHTML, function(opts) { + var self = this + function loop () { + opts.items = generateItems(1000, { + isActive: false + }) + result = measure(self.update.bind(self)) + console.log( + (result[0] / 1024 / 1024).toFixed(2) + ' MiB', + result[1] + ' ms' + ) + setTimeout(loop, 50) + } + loop() + }) + riot.tag(myListItem, myListItemHTML, function (opts) { + this.onChange = function (e) { + opts.isActive = e.target.checked + } + }) +} + +/** + * + * Mount the custom tags passing some fake values + * + */ + +function mount() { + riot.mount(myComponent, { + title: 'hello world', + description: 'mad world', + items: generateItems(1000, { + isActive: false + }) + }) +} + + +// Initialize the test +var doc = new jsdom(`<${myComponent}/>`) +global.window = doc.defaultView +global.document = doc.window.document + +setupTags() +mount() + ADDED public/riot-3.13.2/test/performance/riot.2.6.1.js Index: public/riot-3.13.2/test/performance/riot.2.6.1.js ================================================================== --- public/riot-3.13.2/test/performance/riot.2.6.1.js +++ public/riot-3.13.2/test/performance/riot.2.6.1.js @@ -0,0 +1,2669 @@ +/* Riot v2.6.1, @license MIT */ + +;(function(window, undefined) { + 'use strict'; +var riot = { version: 'v2.6.1', settings: {} }, + // be aware, internal usage + // ATTENTION: prefix the global dynamic variables with `__` + + // counter to give a unique id to all the Tag instances + __uid = 0, + // tags instances cache + __virtualDom = [], + // tags implementation cache + __tagImpl = {}, + + /** + * Const + */ + GLOBAL_MIXIN = '__global_mixin', + + // riot specific prefixes + RIOT_PREFIX = 'riot-', + RIOT_TAG = RIOT_PREFIX + 'tag', + RIOT_TAG_IS = 'data-is', + + // for typeof == '' comparisons + T_STRING = 'string', + T_OBJECT = 'object', + T_UNDEF = 'undefined', + T_FUNCTION = 'function', + XLINK_NS = 'http://www.w3.org/1999/xlink', + XLINK_REGEX = /^xlink:(\w+)/, + // special native tags that cannot be treated like the others + SPECIAL_TAGS_REGEX = /^(?:t(?:body|head|foot|[rhd])|caption|col(?:group)?|opt(?:ion|group))$/, + RESERVED_WORDS_BLACKLIST = /^(?:_(?:item|id|parent)|update|root|(?:un)?mount|mixin|is(?:Mounted|Loop)|tags|parent|opts|trigger|o(?:n|ff|ne))$/, + // SVG tags list https://www.w3.org/TR/SVG/attindex.html#PresentationAttributes + SVG_TAGS_LIST = ['altGlyph', 'animate', 'animateColor', 'circle', 'clipPath', 'defs', 'ellipse', 'feBlend', 'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feFlood', 'feGaussianBlur', 'feImage', 'feMerge', 'feMorphology', 'feOffset', 'feSpecularLighting', 'feTile', 'feTurbulence', 'filter', 'font', 'foreignObject', 'g', 'glyph', 'glyphRef', 'image', 'line', 'linearGradient', 'marker', 'mask', 'missing-glyph', 'path', 'pattern', 'polygon', 'polyline', 'radialGradient', 'rect', 'stop', 'svg', 'switch', 'symbol', 'text', 'textPath', 'tref', 'tspan', 'use'], + + // version# for IE 8-11, 0 for others + IE_VERSION = (window && window.document || {}).documentMode | 0, + + // detect firefox to fix #1374 + FIREFOX = window && !!window.InstallTrigger +/* istanbul ignore next */ +riot.observable = function(el) { + + /** + * Extend the original object or create a new empty one + * @type { Object } + */ + + el = el || {} + + /** + * Private variables + */ + var callbacks = {}, + slice = Array.prototype.slice + + /** + * Private Methods + */ + + /** + * Helper function needed to get and loop all the events in a string + * @param { String } e - event string + * @param {Function} fn - callback + */ + function onEachEvent(e, fn) { + var es = e.split(' '), l = es.length, i = 0 + for (; i < l; i++) { + var name = es[i] + if (name) fn(name, i) + } + } + + /** + * Public Api + */ + + // extend the el object adding the observable methods + Object.defineProperties(el, { + /** + * Listen to the given space separated list of `events` and + * execute the `callback` each time an event is triggered. + * @param { String } events - events ids + * @param { Function } fn - callback function + * @returns { Object } el + */ + on: { + value: function(events, fn) { + if (typeof fn != 'function') return el + + onEachEvent(events, function(name, pos) { + (callbacks[name] = callbacks[name] || []).push(fn) + fn.typed = pos > 0 + }) + + return el + }, + enumerable: false, + writable: false, + configurable: false + }, + + /** + * Removes the given space separated list of `events` listeners + * @param { String } events - events ids + * @param { Function } fn - callback function + * @returns { Object } el + */ + off: { + value: function(events, fn) { + if (events == '*' && !fn) callbacks = {} + else { + onEachEvent(events, function(name, pos) { + if (fn) { + var arr = callbacks[name] + for (var i = 0, cb; cb = arr && arr[i]; ++i) { + if (cb == fn) arr.splice(i--, 1) + } + } else delete callbacks[name] + }) + } + return el + }, + enumerable: false, + writable: false, + configurable: false + }, + + /** + * Listen to the given space separated list of `events` and + * execute the `callback` at most once + * @param { String } events - events ids + * @param { Function } fn - callback function + * @returns { Object } el + */ + one: { + value: function(events, fn) { + function on() { + el.off(events, on) + fn.apply(el, arguments) + } + return el.on(events, on) + }, + enumerable: false, + writable: false, + configurable: false + }, + + /** + * Execute all callback functions that listen to + * the given space separated list of `events` + * @param { String } events - events ids + * @returns { Object } el + */ + trigger: { + value: function(events) { + + // getting the arguments + var arglen = arguments.length - 1, + args = new Array(arglen), + fns + + for (var i = 0; i < arglen; i++) { + args[i] = arguments[i + 1] // skip first argument + } + + onEachEvent(events, function(name, pos) { + + fns = slice.call(callbacks[name] || [], 0) + + for (var i = 0, fn; fn = fns[i]; ++i) { + if (fn.busy) continue + fn.busy = 1 + fn.apply(el, fn.typed ? [name].concat(args) : args) + if (fns[i] !== fn) { i-- } + fn.busy = 0 + } + + if (callbacks['*'] && name != '*') + el.trigger.apply(el, ['*', name].concat(args)) + + }) + + return el + }, + enumerable: false, + writable: false, + configurable: false + } + }) + + return el + +} +/* istanbul ignore next */ +;(function(riot) { + +/** + * Simple client-side router + * @module riot-route + */ + + +var RE_ORIGIN = /^.+?\/\/+[^\/]+/, + EVENT_LISTENER = 'EventListener', + REMOVE_EVENT_LISTENER = 'remove' + EVENT_LISTENER, + ADD_EVENT_LISTENER = 'add' + EVENT_LISTENER, + HAS_ATTRIBUTE = 'hasAttribute', + REPLACE = 'replace', + POPSTATE = 'popstate', + HASHCHANGE = 'hashchange', + TRIGGER = 'trigger', + MAX_EMIT_STACK_LEVEL = 3, + win = typeof window != 'undefined' && window, + doc = typeof document != 'undefined' && document, + hist = win && history, + loc = win && (hist.location || win.location), // see html5-history-api + prot = Router.prototype, // to minify more + clickEvent = doc && doc.ontouchstart ? 'touchstart' : 'click', + started = false, + central = riot.observable(), + routeFound = false, + debouncedEmit, + base, current, parser, secondParser, emitStack = [], emitStackLevel = 0 + +/** + * Default parser. You can replace it via router.parser method. + * @param {string} path - current path (normalized) + * @returns {array} array + */ +function DEFAULT_PARSER(path) { + return path.split(/[/?#]/) +} + +/** + * Default parser (second). You can replace it via router.parser method. + * @param {string} path - current path (normalized) + * @param {string} filter - filter string (normalized) + * @returns {array} array + */ +function DEFAULT_SECOND_PARSER(path, filter) { + var re = new RegExp('^' + filter[REPLACE](/\*/g, '([^/?#]+?)')[REPLACE](/\.\./, '.*') + '$'), + args = path.match(re) + + if (args) return args.slice(1) +} + +/** + * Simple/cheap debounce implementation + * @param {function} fn - callback + * @param {number} delay - delay in seconds + * @returns {function} debounced function + */ +function debounce(fn, delay) { + var t + return function () { + clearTimeout(t) + t = setTimeout(fn, delay) + } +} + +/** + * Set the window listeners to trigger the routes + * @param {boolean} autoExec - see route.start + */ +function start(autoExec) { + debouncedEmit = debounce(emit, 1) + win[ADD_EVENT_LISTENER](POPSTATE, debouncedEmit) + win[ADD_EVENT_LISTENER](HASHCHANGE, debouncedEmit) + doc[ADD_EVENT_LISTENER](clickEvent, click) + if (autoExec) emit(true) +} + +/** + * Router class + */ +function Router() { + this.$ = [] + riot.observable(this) // make it observable + central.on('stop', this.s.bind(this)) + central.on('emit', this.e.bind(this)) +} + +function normalize(path) { + return path[REPLACE](/^\/|\/$/, '') +} + +function isString(str) { + return typeof str == 'string' +} + +/** + * Get the part after domain name + * @param {string} href - fullpath + * @returns {string} path from root + */ +function getPathFromRoot(href) { + return (href || loc.href)[REPLACE](RE_ORIGIN, '') +} + +/** + * Get the part after base + * @param {string} href - fullpath + * @returns {string} path from base + */ +function getPathFromBase(href) { + return base[0] == '#' + ? (href || loc.href || '').split(base)[1] || '' + : (loc ? getPathFromRoot(href) : href || '')[REPLACE](base, '') +} + +function emit(force) { + // the stack is needed for redirections + var isRoot = emitStackLevel == 0, first + if (MAX_EMIT_STACK_LEVEL <= emitStackLevel) return + + emitStackLevel++ + emitStack.push(function() { + var path = getPathFromBase() + if (force || path != current) { + central[TRIGGER]('emit', path) + current = path + } + }) + if (isRoot) { + while (first = emitStack.shift()) first() // stack increses within this call + emitStackLevel = 0 + } +} + +function click(e) { + if ( + e.which != 1 // not left click + || e.metaKey || e.ctrlKey || e.shiftKey // or meta keys + || e.defaultPrevented // or default prevented + ) return + + var el = e.target + while (el && el.nodeName != 'A') el = el.parentNode + + if ( + !el || el.nodeName != 'A' // not A tag + || el[HAS_ATTRIBUTE]('download') // has download attr + || !el[HAS_ATTRIBUTE]('href') // has no href attr + || el.target && el.target != '_self' // another window or frame + || el.href.indexOf(loc.href.match(RE_ORIGIN)[0]) == -1 // cross origin + ) return + + if (el.href != loc.href + && ( + el.href.split('#')[0] == loc.href.split('#')[0] // internal jump + || base[0] != '#' && getPathFromRoot(el.href).indexOf(base) !== 0 // outside of base + || base[0] == '#' && el.href.split(base)[0] != loc.href.split(base)[0] // outside of #base + || !go(getPathFromBase(el.href), el.title || doc.title) // route not found + )) return + + e.preventDefault() +} + +/** + * Go to the path + * @param {string} path - destination path + * @param {string} title - page title + * @param {boolean} shouldReplace - use replaceState or pushState + * @returns {boolean} - route not found flag + */ +function go(path, title, shouldReplace) { + // Server-side usage: directly execute handlers for the path + if (!hist) return central[TRIGGER]('emit', getPathFromBase(path)) + + path = base + normalize(path) + title = title || doc.title + // browsers ignores the second parameter `title` + shouldReplace + ? hist.replaceState(null, title, path) + : hist.pushState(null, title, path) + // so we need to set it manually + doc.title = title + routeFound = false + emit() + return routeFound +} + +/** + * Go to path or set action + * a single string: go there + * two strings: go there with setting a title + * two strings and boolean: replace history with setting a title + * a single function: set an action on the default route + * a string/RegExp and a function: set an action on the route + * @param {(string|function)} first - path / action / filter + * @param {(string|RegExp|function)} second - title / action + * @param {boolean} third - replace flag + */ +prot.m = function(first, second, third) { + if (isString(first) && (!second || isString(second))) go(first, second, third || false) + else if (second) this.r(first, second) + else this.r('@', first) +} + +/** + * Stop routing + */ +prot.s = function() { + this.off('*') + this.$ = [] +} + +/** + * Emit + * @param {string} path - path + */ +prot.e = function(path) { + this.$.concat('@').some(function(filter) { + var args = (filter == '@' ? parser : secondParser)(normalize(path), normalize(filter)) + if (typeof args != 'undefined') { + this[TRIGGER].apply(null, [filter].concat(args)) + return routeFound = true // exit from loop + } + }, this) +} + +/** + * Register route + * @param {string} filter - filter for matching to url + * @param {function} action - action to register + */ +prot.r = function(filter, action) { + if (filter != '@') { + filter = '/' + normalize(filter) + this.$.push(filter) + } + this.on(filter, action) +} + +var mainRouter = new Router() +var route = mainRouter.m.bind(mainRouter) + +/** + * Create a sub router + * @returns {function} the method of a new Router object + */ +route.create = function() { + var newSubRouter = new Router() + // assign sub-router's main method + var router = newSubRouter.m.bind(newSubRouter) + // stop only this sub-router + router.stop = newSubRouter.s.bind(newSubRouter) + return router +} + +/** + * Set the base of url + * @param {(str|RegExp)} arg - a new base or '#' or '#!' + */ +route.base = function(arg) { + base = arg || '#' + current = getPathFromBase() // recalculate current path +} + +/** Exec routing right now **/ +route.exec = function() { + emit(true) +} + +/** + * Replace the default router to yours + * @param {function} fn - your parser function + * @param {function} fn2 - your secondParser function + */ +route.parser = function(fn, fn2) { + if (!fn && !fn2) { + // reset parser for testing... + parser = DEFAULT_PARSER + secondParser = DEFAULT_SECOND_PARSER + } + if (fn) parser = fn + if (fn2) secondParser = fn2 +} + +/** + * Helper function to get url query as an object + * @returns {object} parsed query + */ +route.query = function() { + var q = {} + var href = loc.href || current + href[REPLACE](/[?&](.+?)=([^&]*)/g, function(_, k, v) { q[k] = v }) + return q +} + +/** Stop routing **/ +route.stop = function () { + if (started) { + if (win) { + win[REMOVE_EVENT_LISTENER](POPSTATE, debouncedEmit) + win[REMOVE_EVENT_LISTENER](HASHCHANGE, debouncedEmit) + doc[REMOVE_EVENT_LISTENER](clickEvent, click) + } + central[TRIGGER]('stop') + started = false + } +} + +/** + * Start routing + * @param {boolean} autoExec - automatically exec after starting if true + */ +route.start = function (autoExec) { + if (!started) { + if (win) { + if (document.readyState == 'complete') start(autoExec) + // the timeout is needed to solve + // a weird safari bug https://github.com/riot/route/issues/33 + else win[ADD_EVENT_LISTENER]('load', function() { + setTimeout(function() { start(autoExec) }, 1) + }) + } + started = true + } +} + +/** Prepare the router **/ +route.base() +route.parser() + +riot.route = route +})(riot) +/* istanbul ignore next */ + +/** + * The riot template engine + * @version v2.4.1 + */ +/** + * riot.util.brackets + * + * - `brackets ` - Returns a string or regex based on its parameter + * - `brackets.set` - Change the current riot brackets + * + * @module + */ + +var brackets = (function (UNDEF) { + + var + REGLOB = 'g', + + R_MLCOMMS = /\/\*[^*]*\*+(?:[^*\/][^*]*\*+)*\//g, + + R_STRINGS = /"[^"\\]*(?:\\[\S\s][^"\\]*)*"|'[^'\\]*(?:\\[\S\s][^'\\]*)*'/g, + + S_QBLOCKS = R_STRINGS.source + '|' + + /(?:\breturn\s+|(?:[$\w\)\]]|\+\+|--)\s*(\/)(?![*\/]))/.source + '|' + + /\/(?=[^*\/])[^[\/\\]*(?:(?:\[(?:\\.|[^\]\\]*)*\]|\\.)[^[\/\\]*)*?(\/)[gim]*/.source, + + UNSUPPORTED = RegExp('[\\' + 'x00-\\x1F<>a-zA-Z0-9\'",;\\\\]'), + + NEED_ESCAPE = /(?=[[\]()*+?.^$|])/g, + + FINDBRACES = { + '(': RegExp('([()])|' + S_QBLOCKS, REGLOB), + '[': RegExp('([[\\]])|' + S_QBLOCKS, REGLOB), + '{': RegExp('([{}])|' + S_QBLOCKS, REGLOB) + }, + + DEFAULT = '{ }' + + var _pairs = [ + '{', '}', + '{', '}', + /{[^}]*}/, + /\\([{}])/g, + /\\({)|{/g, + RegExp('\\\\(})|([[({])|(})|' + S_QBLOCKS, REGLOB), + DEFAULT, + /^\s*{\^?\s*([$\w]+)(?:\s*,\s*(\S+))?\s+in\s+(\S.*)\s*}/, + /(^|[^\\]){=[\S\s]*?}/ + ] + + var + cachedBrackets = UNDEF, + _regex, + _cache = [], + _settings + + function _loopback (re) { return re } + + function _rewrite (re, bp) { + if (!bp) bp = _cache + return new RegExp( + re.source.replace(/{/g, bp[2]).replace(/}/g, bp[3]), re.global ? REGLOB : '' + ) + } + + function _create (pair) { + if (pair === DEFAULT) return _pairs + + var arr = pair.split(' ') + + if (arr.length !== 2 || UNSUPPORTED.test(pair)) { + throw new Error('Unsupported brackets "' + pair + '"') + } + arr = arr.concat(pair.replace(NEED_ESCAPE, '\\').split(' ')) + + arr[4] = _rewrite(arr[1].length > 1 ? /{[\S\s]*?}/ : _pairs[4], arr) + arr[5] = _rewrite(pair.length > 3 ? /\\({|})/g : _pairs[5], arr) + arr[6] = _rewrite(_pairs[6], arr) + arr[7] = RegExp('\\\\(' + arr[3] + ')|([[({])|(' + arr[3] + ')|' + S_QBLOCKS, REGLOB) + arr[8] = pair + return arr + } + + function _brackets (reOrIdx) { + return reOrIdx instanceof RegExp ? _regex(reOrIdx) : _cache[reOrIdx] + } + + _brackets.split = function split (str, tmpl, _bp) { + // istanbul ignore next: _bp is for the compiler + if (!_bp) _bp = _cache + + var + parts = [], + match, + isexpr, + start, + pos, + re = _bp[6] + + isexpr = start = re.lastIndex = 0 + + while ((match = re.exec(str))) { + + pos = match.index + + if (isexpr) { + + if (match[2]) { + re.lastIndex = skipBraces(str, match[2], re.lastIndex) + continue + } + if (!match[3]) { + continue + } + } + + if (!match[1]) { + unescapeStr(str.slice(start, pos)) + start = re.lastIndex + re = _bp[6 + (isexpr ^= 1)] + re.lastIndex = start + } + } + + if (str && start < str.length) { + unescapeStr(str.slice(start)) + } + + return parts + + function unescapeStr (s) { + if (tmpl || isexpr) { + parts.push(s && s.replace(_bp[5], '$1')) + } else { + parts.push(s) + } + } + + function skipBraces (s, ch, ix) { + var + match, + recch = FINDBRACES[ch] + + recch.lastIndex = ix + ix = 1 + while ((match = recch.exec(s))) { + if (match[1] && + !(match[1] === ch ? ++ix : --ix)) break + } + return ix ? s.length : recch.lastIndex + } + } + + _brackets.hasExpr = function hasExpr (str) { + return _cache[4].test(str) + } + + _brackets.loopKeys = function loopKeys (expr) { + var m = expr.match(_cache[9]) + + return m + ? { key: m[1], pos: m[2], val: _cache[0] + m[3].trim() + _cache[1] } + : { val: expr.trim() } + } + + _brackets.array = function array (pair) { + return pair ? _create(pair) : _cache + } + + function _reset (pair) { + if ((pair || (pair = DEFAULT)) !== _cache[8]) { + _cache = _create(pair) + _regex = pair === DEFAULT ? _loopback : _rewrite + _cache[9] = _regex(_pairs[9]) + } + cachedBrackets = pair + } + + function _setSettings (o) { + var b + + o = o || {} + b = o.brackets + Object.defineProperty(o, 'brackets', { + set: _reset, + get: function () { return cachedBrackets }, + enumerable: true + }) + _settings = o + _reset(b) + } + + Object.defineProperty(_brackets, 'settings', { + set: _setSettings, + get: function () { return _settings } + }) + + /* istanbul ignore next: in the browser riot is always in the scope */ + _brackets.settings = typeof riot !== 'undefined' && riot.settings || {} + _brackets.set = _reset + + _brackets.R_STRINGS = R_STRINGS + _brackets.R_MLCOMMS = R_MLCOMMS + _brackets.S_QBLOCKS = S_QBLOCKS + + return _brackets + +})() + +/** + * @module tmpl + * + * tmpl - Root function, returns the template value, render with data + * tmpl.hasExpr - Test the existence of a expression inside a string + * tmpl.loopKeys - Get the keys for an 'each' loop (used by `_each`) + */ + +var tmpl = (function () { + + var _cache = {} + + function _tmpl (str, data) { + if (!str) return str + + return (_cache[str] || (_cache[str] = _create(str))).call(data, _logErr) + } + + _tmpl.haveRaw = brackets.hasRaw + + _tmpl.hasExpr = brackets.hasExpr + + _tmpl.loopKeys = brackets.loopKeys + + // istanbul ignore next + _tmpl.clearCache = function () { _cache = {} } + + _tmpl.errorHandler = null + + function _logErr (err, ctx) { + + if (_tmpl.errorHandler) { + + err.riotData = { + tagName: ctx && ctx.root && ctx.root.tagName, + _riot_id: ctx && ctx._riot_id //eslint-disable-line camelcase + } + _tmpl.errorHandler(err) + } + } + + function _create (str) { + var expr = _getTmpl(str) + + if (expr.slice(0, 11) !== 'try{return ') expr = 'return ' + expr + + return new Function('E', expr + ';') // eslint-disable-line no-new-func + } + + var + CH_IDEXPR = '\u2057', + RE_CSNAME = /^(?:(-?[_A-Za-z\xA0-\xFF][-\w\xA0-\xFF]*)|\u2057(\d+)~):/, + RE_QBLOCK = RegExp(brackets.S_QBLOCKS, 'g'), + RE_DQUOTE = /\u2057/g, + RE_QBMARK = /\u2057(\d+)~/g + + function _getTmpl (str) { + var + qstr = [], + expr, + parts = brackets.split(str.replace(RE_DQUOTE, '"'), 1) + + if (parts.length > 2 || parts[0]) { + var i, j, list = [] + + for (i = j = 0; i < parts.length; ++i) { + + expr = parts[i] + + if (expr && (expr = i & 1 + + ? _parseExpr(expr, 1, qstr) + + : '"' + expr + .replace(/\\/g, '\\\\') + .replace(/\r\n?|\n/g, '\\n') + .replace(/"/g, '\\"') + + '"' + + )) list[j++] = expr + + } + + expr = j < 2 ? list[0] + : '[' + list.join(',') + '].join("")' + + } else { + + expr = _parseExpr(parts[1], 0, qstr) + } + + if (qstr[0]) { + expr = expr.replace(RE_QBMARK, function (_, pos) { + return qstr[pos] + .replace(/\r/g, '\\r') + .replace(/\n/g, '\\n') + }) + } + return expr + } + + var + RE_BREND = { + '(': /[()]/g, + '[': /[[\]]/g, + '{': /[{}]/g + } + + function _parseExpr (expr, asText, qstr) { + + expr = expr + .replace(RE_QBLOCK, function (s, div) { + return s.length > 2 && !div ? CH_IDEXPR + (qstr.push(s) - 1) + '~' : s + }) + .replace(/\s+/g, ' ').trim() + .replace(/\ ?([[\({},?\.:])\ ?/g, '$1') + + if (expr) { + var + list = [], + cnt = 0, + match + + while (expr && + (match = expr.match(RE_CSNAME)) && + !match.index + ) { + var + key, + jsb, + re = /,|([[{(])|$/g + + expr = RegExp.rightContext + key = match[2] ? qstr[match[2]].slice(1, -1).trim().replace(/\s+/g, ' ') : match[1] + + while (jsb = (match = re.exec(expr))[1]) skipBraces(jsb, re) + + jsb = expr.slice(0, match.index) + expr = RegExp.rightContext + + list[cnt++] = _wrapExpr(jsb, 1, key) + } + + expr = !cnt ? _wrapExpr(expr, asText) + : cnt > 1 ? '[' + list.join(',') + '].join(" ").trim()' : list[0] + } + return expr + + function skipBraces (ch, re) { + var + mm, + lv = 1, + ir = RE_BREND[ch] + + ir.lastIndex = re.lastIndex + while (mm = ir.exec(expr)) { + if (mm[0] === ch) ++lv + else if (!--lv) break + } + re.lastIndex = lv ? expr.length : ir.lastIndex + } + } + + // istanbul ignore next: not both + var // eslint-disable-next-line max-len + JS_CONTEXT = '"in this?this:' + (typeof window !== 'object' ? 'global' : 'window') + ').', + JS_VARNAME = /[,{][$\w]+(?=:)|(^ *|[^$\w\.])(?!(?:typeof|true|false|null|undefined|in|instanceof|is(?:Finite|NaN)|void|NaN|new|Date|RegExp|Math)(?![$\w]))([$_A-Za-z][$\w]*)/g, + JS_NOPROPS = /^(?=(\.[$\w]+))\1(?:[^.[(]|$)/ + + function _wrapExpr (expr, asText, key) { + var tb + + expr = expr.replace(JS_VARNAME, function (match, p, mvar, pos, s) { + if (mvar) { + pos = tb ? 0 : pos + match.length + + if (mvar !== 'this' && mvar !== 'global' && mvar !== 'window') { + match = p + '("' + mvar + JS_CONTEXT + mvar + if (pos) tb = (s = s[pos]) === '.' || s === '(' || s === '[' + } else if (pos) { + tb = !JS_NOPROPS.test(s.slice(pos)) + } + } + return match + }) + + if (tb) { + expr = 'try{return ' + expr + '}catch(e){E(e,this)}' + } + + if (key) { + + expr = (tb + ? 'function(){' + expr + '}.call(this)' : '(' + expr + ')' + ) + '?"' + key + '":""' + + } else if (asText) { + + expr = 'function(v){' + (tb + ? expr.replace('return ', 'v=') : 'v=(' + expr + ')' + ) + ';return v||v===0?v:""}.call(this)' + } + + return expr + } + + _tmpl.version = brackets.version = 'v2.4.1' + + return _tmpl + +})() + +/* + lib/browser/tag/mkdom.js + + Includes hacks needed for the Internet Explorer version 9 and below + See: http://kangax.github.io/compat-table/es5/#ie8 + http://codeplanet.io/dropping-ie8/ +*/ +var mkdom = (function _mkdom() { + var + reHasYield = /|>([\S\s]*?)<\/yield\s*>|>)/ig, + reYieldSrc = /]*)['"]\s*>([\S\s]*?)<\/yield\s*>/ig, + reYieldDest = /|>([\S\s]*?)<\/yield\s*>)/ig + var + rootEls = { tr: 'tbody', th: 'tr', td: 'tr', col: 'colgroup' }, + tblTags = IE_VERSION && IE_VERSION < 10 + ? SPECIAL_TAGS_REGEX : /^(?:t(?:body|head|foot|[rhd])|caption|col(?:group)?)$/ + + /** + * Creates a DOM element to wrap the given content. Normally an `DIV`, but can be + * also a `TABLE`, `SELECT`, `TBODY`, `TR`, or `COLGROUP` element. + * + * @param {string} templ - The template coming from the custom tag definition + * @param {string} [html] - HTML content that comes from the DOM element where you + * will mount the tag, mostly the original tag in the page + * @returns {HTMLElement} DOM element with _templ_ merged through `YIELD` with the _html_. + */ + function _mkdom(templ, html) { + var + match = templ && templ.match(/^\s*<([-\w]+)/), + tagName = match && match[1].toLowerCase(), + el = mkEl('div', isSVGTag(tagName)) + + // replace all the yield tags with the tag inner html + templ = replaceYield(templ, html) + + /* istanbul ignore next */ + if (tblTags.test(tagName)) + el = specialTags(el, templ, tagName) + else + setInnerHTML(el, templ) + + el.stub = true + + return el + } + + /* + Creates the root element for table or select child elements: + tr/th/td/thead/tfoot/tbody/caption/col/colgroup/option/optgroup + */ + function specialTags(el, templ, tagName) { + var + select = tagName[0] === 'o', + parent = select ? 'select>' : 'table>' + + // trim() is important here, this ensures we don't have artifacts, + // so we can check if we have only one element inside the parent + el.innerHTML = '<' + parent + templ.trim() + ' j) { + t = tags[--i] + tags.splice(i, 1) + t.unmount() + } +} + +/** + * Move the nested custom tags in non custom loop tags + * @param { Object } child - non custom loop tag + * @param { Number } i - current position of the loop tag + */ +function moveNestedTags(child, i) { + Object.keys(child.tags).forEach(function(tagName) { + var tag = child.tags[tagName] + if (isArray(tag)) + each(tag, function (t) { + moveChildTag(t, tagName, i) + }) + else + moveChildTag(tag, tagName, i) + }) +} + +/** + * Adds the elements for a virtual tag + * @param { Tag } tag - the tag whose root's children will be inserted or appended + * @param { Node } src - the node that will do the inserting or appending + * @param { Tag } target - only if inserting, insert before this tag's first child + */ +function addVirtual(tag, src, target) { + var el = tag._root, sib + tag._virts = [] + while (el) { + sib = el.nextSibling + if (target) + src.insertBefore(el, target._root) + else + src.appendChild(el) + + tag._virts.push(el) // hold for unmounting + el = sib + } +} + +/** + * Move virtual tag and all child nodes + * @param { Tag } tag - first child reference used to start move + * @param { Node } src - the node that will do the inserting + * @param { Tag } target - insert before this tag's first child + * @param { Number } len - how many child nodes to move + */ +function moveVirtual(tag, src, target, len) { + var el = tag._root, sib, i = 0 + for (; i < len; i++) { + sib = el.nextSibling + src.insertBefore(el, target._root) + el = sib + } +} + + +/** + * Manage tags having the 'each' + * @param { Object } dom - DOM node we need to loop + * @param { Tag } parent - parent tag instance where the dom node is contained + * @param { String } expr - string contained in the 'each' attribute + */ +function _each(dom, parent, expr) { + + // remove the each property from the original tag + remAttr(dom, 'each') + + var mustReorder = typeof getAttr(dom, 'no-reorder') !== T_STRING || remAttr(dom, 'no-reorder'), + tagName = getTagName(dom), + impl = __tagImpl[tagName] || { tmpl: getOuterHTML(dom) }, + useRoot = SPECIAL_TAGS_REGEX.test(tagName), + root = dom.parentNode, + ref = document.createTextNode(''), + child = getTag(dom), + isOption = tagName.toLowerCase() === 'option', // the option tags must be treated differently + tags = [], + oldItems = [], + hasKeys, + isVirtual = dom.tagName == 'VIRTUAL' + + // parse the each expression + expr = tmpl.loopKeys(expr) + + // insert a marked where the loop tags will be injected + root.insertBefore(ref, dom) + + // clean template code + parent.one('before-mount', function () { + + // remove the original DOM node + dom.parentNode.removeChild(dom) + if (root.stub) root = parent.root + + }).on('update', function () { + // get the new items collection + var items = tmpl(expr.val, parent), + // create a fragment to hold the new DOM nodes to inject in the parent tag + frag = document.createDocumentFragment() + + // object loop. any changes cause full redraw + if (!isArray(items)) { + hasKeys = items || false + items = hasKeys ? + Object.keys(items).map(function (key) { + return mkitem(expr, key, items[key]) + }) : [] + } + + // loop all the new items + var i = 0, + itemsLength = items.length + + for (; i < itemsLength; i++) { + // reorder only if the items are objects + var + item = items[i], + _mustReorder = mustReorder && typeof item == T_OBJECT && !hasKeys, + oldPos = oldItems.indexOf(item), + pos = ~oldPos && _mustReorder ? oldPos : i, + // does a tag exist in this position? + tag = tags[pos] + + item = !hasKeys && expr.key ? mkitem(expr, item, i) : item + + // new tag + if ( + !_mustReorder && !tag // with no-reorder we just update the old tags + || + _mustReorder && !~oldPos || !tag // by default we always try to reorder the DOM elements + ) { + + tag = new Tag(impl, { + parent: parent, + isLoop: true, + hasImpl: !!__tagImpl[tagName], + root: useRoot ? root : dom.cloneNode(), + item: item + }, dom.innerHTML) + + tag.mount() + + if (isVirtual) tag._root = tag.root.firstChild // save reference for further moves or inserts + // this tag must be appended + if (i == tags.length || !tags[i]) { // fix 1581 + if (isVirtual) + addVirtual(tag, frag) + else frag.appendChild(tag.root) + } + // this tag must be insert + else { + if (isVirtual) + addVirtual(tag, root, tags[i]) + else root.insertBefore(tag.root, tags[i].root) // #1374 some browsers reset selected here + oldItems.splice(i, 0, item) + } + + tags.splice(i, 0, tag) + pos = i // handled here so no move + } else tag.update(item, true) + + // reorder the tag if it's not located in its previous position + if ( + pos !== i && _mustReorder && + tags[i] // fix 1581 unable to reproduce it in a test! + ) { + // update the DOM + if (isVirtual) + moveVirtual(tag, root, tags[i], dom.childNodes.length) + else if (tags[i].root.parentNode) root.insertBefore(tag.root, tags[i].root) + // update the position attribute if it exists + if (expr.pos) + tag[expr.pos] = i + // move the old tag instance + tags.splice(i, 0, tags.splice(pos, 1)[0]) + // move the old item + oldItems.splice(i, 0, oldItems.splice(pos, 1)[0]) + // if the loop tags are not custom + // we need to move all their custom tags into the right position + if (!child && tag.tags) moveNestedTags(tag, i) + } + + // cache the original item to use it in the events bound to this node + // and its children + tag._item = item + // cache the real parent tag internally + defineProperty(tag, '_parent', parent) + } + + // remove the redundant tags + unmountRedundant(items, tags) + + // insert the new nodes + root.insertBefore(frag, ref) + if (isOption) { + + // #1374 FireFox bug in