diff --git a/.eslintrc.yml b/.eslintrc.yml index c34ee971..7add1b28 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -2,7 +2,7 @@ env: es6: true node: true parserOptions: - ecmaVersion: 2017 + ecmaVersion: 2018 extends: 'eslint:recommended' rules: indent: off diff --git a/.travis.yml b/.travis.yml index da143493..44b1ad38 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,9 +8,6 @@ addons: node_js: - '10' before_install: -- mkdir cvc4/ -- wget https://almond-static.stanford.edu/test-data/cvc4-1.6-x86_64-linux-opt -O cvc4/cvc4 -- chmod +x cvc4/cvc4 - mkdir geckodriver/ - wget https://github.com/mozilla/geckodriver/releases/download/v0.22.0/geckodriver-v0.22.0-linux64.tar.gz - tar xvf geckodriver-v0.22.0-linux64.tar.gz -C geckodriver/ diff --git a/COPYING b/COPYING deleted file mode 100644 index d159169d..00000000 --- a/COPYING +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. diff --git a/LICENSE b/LICENSE index 0f7589ba..d6456956 100644 --- a/LICENSE +++ b/LICENSE @@ -1,50 +1,202 @@ -The overall Almond is - -Copyright 2015-2018 The Board of Trustees of the Leland Stanford Junior University - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -This package is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - -In addition, as a special exception, the copyright holders give -permission to link the code of portions of this program with the -OpenSSL library, and distribute linked combinations -including the two. - -You must obey the GNU General Public License in all respects -for all of the code used other than OpenSSL. If you modify -file(s) with this exception, you may extend this exception to your -version of the file(s), but you are not obligated to do so. If you -do not wish to do so, delete this exception statement from your -version. If you delete this exception statement from all source -files in the program, then also delete it here. - -=================================================================== - -This package depends on various third-party node.js modules. Those -modules are copyright of their respective authors, and the license -to each module is included in the module folder. - -This package also includes the cmu_us_slt voice file -(data/cmu_us_slt.flitevox) -This was obtained from the mimic project, which in turn obtained it -from the flite project. -This file is copyright 1999-2014 Language Technologies Institute, Carnegie Mellon University -It is licensed under the flite project license. - -=================================================================== - -This product includes software developed by the OpenSSL Project -for use in the OpenSSL Toolkit (http://www.openssl.org/). -This product includes cryptographic software written by Eric Young -(eay@cryptsoft.com). This product includes software written by Tim -Hudson (tjh@cryptsoft.com). + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md index b925bfc8..32ff8e5c 100644 --- a/README.md +++ b/README.md @@ -19,10 +19,9 @@ the container to run as your regular user (and thus access PulseAudio from your To run, use the command: ```bash -podman run -p 3000:3000 --uidmap keep-id \ +podman run --name almond -p 3000:3000 --uidmap keep-id \ -v /dev/shm:/dev/shm \ -v $XDG_RUNTIME_DIR/pulse:/run/pulse \ - -v ${XDG_CONFIG_HOME:-$HOME/.config}/almond-server:/var/lib/almond-server \ stanfordoval/almond-server ``` @@ -33,13 +32,9 @@ You can now navigate to [127.0.0.1:3000](http://127.0.0.1:3000) to access Almond Voice support is only available on Linux. On Mac or Windows, you can use the following docker command: ```bash -docker run -p 3000:3000 \ - -v $HOME/.almond-server:/var/lib/almond-server \ - stanfordoval/almond-server:latest-portable +docker run --name almond -p 3000:3000 stanfordoval/almond-server:latest-portable ``` -Change the `-v` line to a different path to save the almond-server configuration files in a different directory than `$HOME/.almond-server`. - ## Development setup To develop almond-server, you should clone this repository, then install the dependencies with: diff --git a/config.js b/config.js index c81a031e..d660cc7e 100644 --- a/config.js +++ b/config.js @@ -2,11 +2,21 @@ // // This file is part of Almond // -// Copyright 2016 The Board of Trustees of the Leland Stanford Junior University +// Copyright 2017-2020 The Board of Trustees of the Leland Stanford Junior University // -// Author: Giovanni Campagna +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 // -// See COPYING for details +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Author: Giovanni Campagna "use strict"; /** @@ -56,8 +66,9 @@ module.exports.HOST_BASED_AUTHENTICATION = process.env.THINGENGINE_HOST_BASED_AU module.exports.ENABLE_DB_ENCRYPTION = false; -module.exports.SEMPRE_URL = process.env.THINGENGINE_NLP_URL || 'https://almond-nl.stanford.edu'; -module.exports.THINGPEDIA_URL = process.env.THINGPEDIA_URL || 'https://thingpedia.stanford.edu/thingpedia'; +module.exports.SEMPRE_URL = process.env.THINGENGINE_NLP_URL || 'https://nlp-staging.almond.stanford.edu'; +module.exports.THINGPEDIA_URL = process.env.THINGPEDIA_URL || 'https://almond-dev.stanford.edu/thingpedia'; +module.exports.CLOUD_SYNC_URL = process.env.THINGENGINE_CLOUD_SYNC_URL || 'https://almond-dev.stanford.edu'; module.exports.MS_SPEECH_RECOGNITION_PRIMARY_KEY = 'de1f02817356494483ba502b2ce95f6f'; module.exports.MS_SPEECH_RECOGNITION_SECONDARY_KEY = '3dc6ce0b832940f0b0c984a1517c457e'; diff --git a/main.js b/main.js index 4400eeb7..21d1a5ec 100644 --- a/main.js +++ b/main.js @@ -2,26 +2,43 @@ // // This file is part of Almond // -// Copyright 2015 The Board of Trustees of the Leland Stanford Junior University +// Copyright 2016-2020 The Board of Trustees of the Leland Stanford Junior University // -// Author: Giovanni Campagna +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. // -// See COPYING for details +// Author: Giovanni Campagna "use strict"; const Q = require('q'); Q.longStackSupport = true; process.on('unhandledRejection', (up) => { throw up; }); -const Engine = require('thingengine-core'); +const child_process = require('child_process'); +let canberra; +try { + canberra = require('canberra'); +} catch(e) { + canberra = null; +} + +const Genie = require('genie-toolkit'); const WebFrontend = require('./service/frontend'); -const AssistantDispatcher = require('./service/assistant'); const Config = require('./config'); let _stopped = false; let _running = false; -let _engine, _frontend, _ad; +let _engine, _frontend; function handleStop() { if (_running) @@ -31,15 +48,68 @@ function handleStop() { } const DEBUG = false; +const LOCAL_USER = { + id: process.getuid ? process.getuid() : 0, + account: '', //pwnam.name; + name: '', //pwnam.gecos; +}; +const HOTWORD_DETECTED_ID = 1; async function init(platform) { - _engine = new Engine(platform, { thingpediaUrl: Config.THINGPEDIA_URL }); + _engine = new Genie.AssistantEngine(platform, { + cloudSyncUrl: Config.CLOUD_SYNC_URL, + thingpediaUrl: Config.THINGPEDIA_URL, + nluModelUrl: Config.SEMPRE_URL, + }); _frontend.setEngine(_engine); - _ad = new AssistantDispatcher(_engine); - platform.setAssistant(_ad); await _engine.open(); - await _ad.start(); + + const conversation = _engine.assistant.openConversation('main', LOCAL_USER, { + showWelcome: true, + debug: true, + deleteWhenInactive: false, + inactivityTimeout: 30000, // pick a low inactivity timeout to turn off the microphone + contextResetTimeout: 600000, // but only reset the timeout after 10 minutes (the default) + }); + + if (platform.hasCapability('sound')) { + const speech = new Genie.SpeechHandler(conversation, platform, { + subscriptionKey: Config.MS_SPEECH_RECOGNITION_PRIMARY_KEY + }); + + speech.on('wakeword', (hotword) => { + child_process.spawn('xset', ['dpms', 'force', 'on']).on('error', (err) => { + console.error(`Failed to wake up the screen: ${err.message}`); + }); + }); + + if (canberra) { + const eventSoundCtx = new canberra.Context({ + [canberra.Property.APPLICATION_ID]: 'edu.stanford.Almond', + }); + try { + eventSoundCtx.cache({ + 'media.role': 'voice-assistant', + [canberra.Property.EVENT_ID]: 'message-new-instant' + }); + } catch (e) { + console.error(`Failed to cache event sound: ${e.message}`); + } + + speech.on('wakeword', (hotword) => { + eventSoundCtx.play(HOTWORD_DETECTED_ID, { + 'media.role': 'voice-assistant', + [canberra.Property.EVENT_ID]: 'message-new-instant' + }).catch((e) => { + console.error(`Failed to play hotword detection sound: ${e.message}`); + }); + }); + } + + speech.start(); + } + await conversation.start(); } async function main() { @@ -71,12 +141,10 @@ async function main() { console.log('Ready'); if (!_stopped) { _running = true; - await _ad.startConversation(); await _engine.run(); } } finally { try { - await _ad.stop(); await _engine.close(); } catch(error) { console.log('Exception during stop: ' + error.message); diff --git a/package.json b/package.json index 77d0895f..5eed4cf4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,7 @@ { - "name": "thingengine-server", + "name": "almond-server", "version": "1.8.0", + "license": "Apache-2.0", "private": true, "scripts": { "start": "node main.js", @@ -11,7 +12,6 @@ }, "resolutions": {}, "dependencies": { - "almond-dialog-agent": "~1.8.0", "body-parser": "^1.17.2", "color-scheme": "^1.0.0", "connect-flash": "^0.1.1", @@ -22,6 +22,7 @@ "express": "^4.15.3", "express-session": "^1.17.1", "express-ws": "^4.0.0", + "genie-toolkit": "^0.7.0-beta.4", "gm": "^1.23.1", "morgan": "^1.8.2", "node-gettext": "^3.0.0", @@ -30,18 +31,16 @@ "pug": "^3.0.0", "q": "^1.5.0", "serve-favicon": "^2.4.3", - "smtlib": "^0.1.1", "sqlite3": "^5.0.0", - "thingengine-core": "~1.8.0", - "thingpedia": "~2.7.0", + "thingpedia": "~2.8.0-beta.2", "thingpedia-discovery": "^1.0.0", - "thingtalk": "~1.10.0", + "thingtalk": "~1.11.0-beta.2", "uuid": "^8.2.0", "ws": "^7.3.1" }, "optionalDependencies": { "canberra": "^0.1.2", - "pulseaudio2": "^0.3.2", + "pulseaudio2": "^0.3.3", "snowboy": "^1.3.1" }, "devDependencies": { diff --git a/public/javascripts/conversation.js b/public/javascripts/conversation.js index ebb296ee..a784a78f 100644 --- a/public/javascripts/conversation.js +++ b/public/javascripts/conversation.js @@ -215,6 +215,8 @@ $(function() { console.log('received ' + event.data); switch (parsed.type) { case 'text': + case 'result': + // FIXME: support more type of results textMessage(parsed.text, parsed.icon); currentGrid = null; break; @@ -229,12 +231,6 @@ $(function() { currentGrid = null; break; - case 'result': - // FIXME: support more type of results - textMessage(parsed.fallback, parsed.icon); - currentGrid = null; - break; - case 'choice': choice(parsed.idx, parsed.title); break; @@ -261,7 +257,7 @@ $(function() { case 'command': $('#input').val(''); collapseButtons(); - appendUserMessage(parsed.text); + appendUserMessage(parsed.command); break; } diff --git a/routes/api.js b/routes/api.js index 83d3d67a..5d5ec1bc 100644 --- a/routes/api.js +++ b/routes/api.js @@ -2,15 +2,26 @@ // // This file is part of Almond // -// Copyright 2015 The Board of Trustees of the Leland Stanford Junior University +// Copyright 2016-2020 The Board of Trustees of the Leland Stanford Junior University // -// Author: Giovanni Campagna +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. // -// See COPYING for details +// Author: Giovanni Campagna "use strict"; const express = require('express'); const crypto = require('crypto'); +const ThingTalk = require('thingtalk'); const user = require('../util/user'); const errorHandling = require('../util/error_handling'); @@ -33,25 +44,6 @@ router.use('/', (req, res, next) => { next(); }, user.requireLogIn); -router.get('/parse', (req, res, next) => { - let query = req.query.q || null; - if (!query) { - res.status(400).json({error:'Missing query'}); - return; - } - - const engine = req.app.engine; - const assistant = engine.platform.getCapability('assistant'); - Promise.resolve().then(() => { - return assistant.parse(query); - }).then((result) => { - res.json(result); - }).catch((e) => { - console.error(e.stack); - res.status(500).json({error:e.message}); - }); -}); - router.post('/converse', (req, res, next) => { const command = req.body.command; if (!command) { @@ -60,31 +52,18 @@ router.post('/converse', (req, res, next) => { } const engine = req.app.engine; - const assistant = engine.platform.getCapability('assistant'); + const assistant = engine.assistant; Promise.resolve().then(() => { return assistant.converse(command); }).then((result) => { res.json(result); - }).catch((e) => { - console.error(e.stack); - res.status(500).json({error:e.message}); - }); + }).catch(next); }); -function describeDevice(d, req) { - return { - uniqueId: d.uniqueId, - name: d.name || req._("Unknown device"), - description: d.description || req._("Description not available"), - kind: d.kind, - ownerTier: d.ownerTier - }; -} - router.get('/devices/list', (req, res, next) => { const engine = req.app.engine; Promise.resolve().then(() => { - const result = engine.devices.getAllDevices().map((d) => describeDevice(d, req)); + const result = engine.getDeviceInfos(); // sort by name to provide a deterministic result result.sort((a, b) => a.name.localeCompare(b.name)); res.json(result); @@ -95,199 +74,207 @@ router.post('/devices/create', (req, res, next) => { const engine = req.app.engine; Promise.resolve().then(async () => { const device = await engine.devices.addSerialized(req.body); - res.json(describeDevice(device, req)); + res.json(engine.getDeviceInfo(device.uniqueId)); }).catch(next); }); -function describeApp(app) { +async function createAppAndReturnResults(engine, data) { + const app = await engine.createApp(data.code); + const results = []; + const errors = []; + + const formatter = new ThingTalk.Formatter(engine.platform.locale, engine.platform.timezone, engine.schemas); + for await (const value of app.mainOutput) { + if (value instanceof Error) { + errors.push(value); + } else { + const messages = await formatter.formatForType(value.outputType, value.outputValue, 'messages'); + results.push({ raw: value.outputValue, type: value.outputType, formatted: messages }); + } + } + return { uniqueId: app.uniqueId, description: app.description, - error: app.error, code: app.code, - icon: app.icon ? Config.THINGPEDIA_URL + '/api/devices/icon/' + app.icon : null + icon: app.icon ? Config.THINGPEDIA_URL + '/api/devices/icon/' + app.icon : app.icon, + results, errors }; } router.post('/apps/create', (req, res, next) => { const engine = req.app.engine; - const assistant = engine.platform.getCapability('assistant'); - Promise.resolve().then(() => { - return assistant.createApp(req.body); + return createAppAndReturnResults(engine, req.body); }).then((result) => { if (result.error) res.status(400); res.json(result); - }).catch((e) => { - console.error(e.stack); - res.status(500).json({error:e.message}); - }); + }).catch(next); }); router.get('/apps/list', (req, res, next) => { const engine = req.app.engine; Promise.resolve().then(() => { - return engine.apps.getAllApps(); - }).then((apps) => { - res.json(apps.map(describeApp)); - }).catch((e) => { - console.error(e.stack); - res.status(500).json({error:e.message}); - }); + res.json(engine.getAppInfo()); + }).catch(next); }); router.get('/apps/get/:appId', (req, res, next) => { const engine = req.app.engine; Promise.resolve().then(() => { - return engine.apps.getApp(req.params.appId); + return engine.getAppInfo(req.params.appId, false); }).then((app) => { if (!app) { res.status(404); - return { error: 'No such app' }; + res.json({ error: 'No such app' }); } else { - return describeApp(app); + res.json(app); } - }).then((result) => { - res.json(result); - }).catch((e) => { - console.error(e.stack); - res.status(500).json({error:e.message}); - }); + }).catch(next); }); router.post('/apps/delete/:appId', (req, res, next) => { const engine = req.app.engine; Promise.resolve().then(() => { - return engine.apps.getApp(req.params.appId); - }).then((app) => { - if (!app) { + return engine.deleteApp(req.params.appId); + }).then((deleted) => { + if (!deleted) { res.status(404); - return { error: 'No such app' }; + return res.json({ error: 'No such app' }); } else { - return Promise.resolve(engine.apps.removeApp(app)).then(() => ({status:'ok'})); + return res.json({ status:'ok' }); } - }).then((result) => { - res.json(result); - }).catch((e) => { - console.error(e.stack); - res.status(500).json({error:e.message}); - }); + }).catch(next); }); + +class NotificationWrapper { + constructor(engine, ws) { + this._dispatcher = engine.assistant; + this._ws = ws; + this._formatter = new ThingTalk.Formatter(engine.platform.locale, engine.platform.timezone, engine.schemas); + this._dispatcher.addNotificationOutput(this); + } + + destroy() { + this._dispatcher.removeNotificationOutput(this); + } + + async notify(appId, icon, outputType, outputValue) { + const messages = await this._formatter.formatForType(outputType, outputValue, 'messages'); + await this._ws.send(JSON.stringify({ + result: { + appId: appId, + icon: icon ? Config.THINGPEDIA_URL + '/api/devices/icon/' + icon : null, + raw: outputValue, + type: outputType, + formatted: messages + } + })); + } + + async notifyError(appId, icon, error) { + await this._ws.send(JSON.stringify({ + error: { + appId: appId, + icon: icon ? Config.THINGPEDIA_URL + '/api/devices/icon/' + icon : null, + error: error + } + })); + } +} + router.ws('/results', (ws, req, next) => { const engine = req.app.engine; - const assistant = engine.platform.getCapability('assistant'); Promise.resolve().then(() => { + const wrapper = new NotificationWrapper(engine, ws); ws.on('close', () => { - assistant.removeOutput(ws); + wrapper.destroy(ws); }); ws.on('ping', (data) => ws.pong(data)); - - return assistant.addOutput(ws); }).catch((error) => { console.error('Error in API websocket: ' + error.message); ws.close(); }); }); + class WebsocketAssistantDelegate { constructor(ws) { this._ws = ws; } - send(text, icon) { - return this._ws.send(JSON.stringify({ type: 'text', text: text, icon: icon })); - } - - sendPicture(url, icon) { - return this._ws.send(JSON.stringify({ type: 'picture', url: url, icon: icon })); - } - - sendRDL(rdl, icon) { - return this._ws.send(JSON.stringify({ type: 'rdl', rdl: rdl, icon: icon })); - } - - sendChoice(idx, what, title, text) { - return this._ws.send(JSON.stringify({ type: 'choice', idx: idx, title: title, text: text })); + setHypothesis() { + // voice doesn't go through SpeechHandler, hence hypotheses don't go through here! } - sendButton(title, json) { - return this._ws.send(JSON.stringify({ type: 'button', title: title, json: json })); + setExpected(what) { + this._ws.send(JSON.stringify({ type: 'askSpecial', ask: what })); } - sendLink(title, url) { - return this._ws.send(JSON.stringify({ type: 'link', title: title, url: url })); - } - - sendAskSpecial(what) { - return this._ws.send(JSON.stringify({ type: 'askSpecial', ask: what })); - } - - sendHypothesis(hypothesis) { - return this._ws.send(JSON.stringify({ type: 'hypothesis', hypothesis: hypothesis })); - } - - sendCommand(command) { - return this._ws.send(JSON.stringify({ type: 'command', text: command })); + addMessage(msg) { + this._ws.send(JSON.stringify(msg)); } } +const LOCAL_USER = { + id: process.getuid ? process.getuid() : 0, + account: '', //pwnam.name; + name: '', //pwnam.gecos; +}; + router.ws('/conversation', (ws, req, next) => { - const engine = req.app.engine; - const assistant = engine.platform.getCapability('assistant'); + Promise.resolve().then(async () => { + const engine = req.app.engine; - const delegate = new WebsocketAssistantDelegate(ws); - const isMain = req.host === '127.0.0.1'; + const delegate = new WebsocketAssistantDelegate(ws); + const isMain = req.host === '127.0.0.1'; - let opened = false; - const id = 'web-' + makeRandom(16); - ws.on('error', (err) => { - console.error(err); - ws.close(); - }); - ws.on('close', () => { - if (opened) { - if (isMain) + let opened = false; + const conversationId = isMain ? 'main' : (req.query.conversationId || 'web-' + makeRandom(16)); + ws.on('error', (err) => { + console.error(err); + ws.close(); + }); + ws.on('close', () => { + if (opened) conversation.removeOutput(delegate); - else - assistant.closeConversation(id); - } - opened = false; - }); + opened = false; + }); - let conversation; - if (isMain) { - conversation = assistant.getConversation('main'); - conversation.addOutput(delegate); - opened = true; - } else { - conversation = assistant.openConversation(id, delegate); + const conversation = await engine.assistant.getOrOpenConversation(conversationId, LOCAL_USER, { + showWelcome: true, + debug: true, + }); + await conversation.addOutput(delegate, true); opened = true; - conversation.start(); - } - ws.on('message', (data) => { - Promise.resolve().then(() => { - const parsed = JSON.parse(data); - switch(parsed.type) { - case 'command': - return conversation.handleCommand(parsed.text); - case 'parsed': - return conversation.handleParsedCommand(parsed.json, parsed.title); - case 'tt': - return conversation.handleThingTalk(parsed.code); - default: - throw new Error('Invalid command type ' + parsed.type); - } - }).catch((e) => { - console.error(e.stack); - ws.send(JSON.stringify({ type: 'error', error:e.message })); + ws.on('message', (data) => { + Promise.resolve().then(() => { + const parsed = JSON.parse(data); + switch(parsed.type) { + case 'command': + return conversation.handleCommand(parsed.text); + case 'parsed': + return conversation.handleParsedCommand(parsed.json, parsed.title); + case 'tt': + return conversation.handleThingTalk(parsed.code); + default: + throw new Error('Invalid command type ' + parsed.type); + } + }).catch((e) => { + console.error(e.stack); + ws.send(JSON.stringify({ type: 'error', error:e.message })); + }); }); + }).catch((e) => { + console.error('Error in API websocket: ' + e.message); + ws.close(); }); }); diff --git a/routes/apps.js b/routes/apps.js index a9911968..252f744e 100644 --- a/routes/apps.js +++ b/routes/apps.js @@ -2,11 +2,21 @@ // // This file is part of Almond // -// Copyright 2015 The Board of Trustees of the Leland Stanford Junior University +// Copyright 2016-2020 The Board of Trustees of the Leland Stanford Junior University // -// Author: Giovanni Campagna +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 // -// See COPYING for details +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Author: Giovanni Campagna "use strict"; const express = require('express'); @@ -15,50 +25,30 @@ var router = express.Router(); const user = require('../util/user'); const Config = require('../config'); -function appsList(req, res, next, message) { - var engine = req.app.engine; - - var apps = engine.apps.getAllApps(); - var info = apps.map((a) => { - return { uniqueId: a.uniqueId, name: a.name || "Some app", description: a.description, - running: a.isRunning, enabled: a.isEnabled, - currentTier: a.currentTier }; - }); +router.get('/', user.redirectLogIn, (req, res, next) => { + const engine = req.app.engine; res.render('apps_list', { page_title: 'Almond - My Rules', - message: message, + message: '', csrfToken: req.csrfToken(), - apps: info }); -} - -router.get('/', user.redirectLogIn, (req, res, next) => { - appsList(req, res, next, ''); + apps: engine.getAppInfos() }); }); router.post('/delete', user.requireLogIn, (req, res, next) => { - try { - var engine = req.app.engine; + Promise.resolve().then(async () => { + const engine = req.app.engine; - var id = req.body.id; - var app = engine.apps.getApp(id); - if (app === undefined) { + const id = req.body.id; + const deleted = await engine.deleteApp(id); + if (!deleted) { res.status(404).render('error', { page_title: "Almond - Error", message: "Not found." }); return; } - engine.apps.removeApp(app).then(() => { - req.flash('app-message', "Rule successfully stopped"); - res.redirect(303, Config.BASE_URL + '/apps'); - }).catch((e) => { - res.status(400).render('error', { page_title: "Almond - Error", - message: e.message + '\n' + e.stack }); - }).catch(next); - } catch(e) { - res.status(400).render('error', { page_title: "Almond - Error", - message: e.message + '\n' + e.stack }); - - } + req.flash('app-message', "Rule successfully stopped"); + res.redirect(303, Config.BASE_URL + '/apps'); + }).catch(next); }); module.exports = router; diff --git a/routes/config.js b/routes/config.js index 7ec5ed66..02f3f97f 100644 --- a/routes/config.js +++ b/routes/config.js @@ -2,26 +2,36 @@ // // This file is part of Almond // -// Copyright 2015 The Board of Trustees of the Leland Stanford Junior University +// Copyright 2016-2020 The Board of Trustees of the Leland Stanford Junior University // -// Author: Giovanni Campagna +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. // -// See COPYING for details +// Author: Giovanni Campagna "use strict"; const Q = require('q'); const express = require('express'); -var router = express.Router(); +const Genie = require('genie-toolkit'); -// FIXME -const ipAddress = require('thingengine-core/lib/util/ip_address'); const user = require('../util/user'); const platform = require('../service/platform'); const Config = require('../config'); +const router = express.Router(); + function config(req, res, next, userData, cloudData) { - return ipAddress.getServerName().then((host) => { + return Genie.IpAddressUtils.getServerName().then((host) => { var port = res.app.get('port'); var serverAddress = 'http://' + (host.indexOf(':') >= 0 ? '[' + host + ']' : host) @@ -34,7 +44,7 @@ function config(req, res, next, userData, cloudData) { var qrcodeTarget = 'https://thingengine.stanford.edu/qrcode/' + host + '/' + port + '/' + authToken; - var ipAddresses = ipAddress.getServerAddresses(host); + var ipAddresses = Genie.IpAddressUtils.getServerAddresses(host); res.render('config', { page_title: "Configure Almond", csrfToken: req.csrfToken(), @@ -80,7 +90,7 @@ router.post('/set-server-password', user.requireLogIn, (req, res, next) => { if (typeof req.body['password'] !== 'string' || req.body['password'].length < 8 || req.body['password'].length > 255) - throw new Error("You must specifiy a valid password (of at least 8 characters)"); + throw new Error("You must specify a valid password (of at least 8 characters)"); if (req.body['confirm-password'] !== req.body['password']) throw new Error("The password and the confirmation do not match"); diff --git a/routes/devices.js b/routes/devices.js index 4f014142..6f3e55d3 100644 --- a/routes/devices.js +++ b/routes/devices.js @@ -2,11 +2,21 @@ // // This file is part of Almond // -// Copyright 2015 The Board of Trustees of the Leland Stanford Junior University +// Copyright 2016-2020 The Board of Trustees of the Leland Stanford Junior University // -// Author: Giovanni Campagna +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. // -// See COPYING for details +// Author: Giovanni Campagna "use strict"; const express = require('express'); @@ -15,24 +25,9 @@ var router = express.Router(); const user = require('../util/user'); const Config = require('../config'); -function getAllDevices(req, engine) { - return engine.devices.getAllDevices().map((d) => { - return { uniqueId: d.uniqueId, name: d.name || req._("Unknown device"), - description: d.description || req._("Description not available"), - kind: d.kind, - ownerTier: d.ownerTier, - available: d.available, - isTransient: d.isTransient, - isOnlineAccount: d.hasKind('online-account'), - isDataSource: d.hasKind('data-source'), - isPhysical: !d.hasKind('online-account') && !d.hasKind('data-source'), - isThingEngine: d.hasKind('thingengine-system') }; - }).filter((d) => !d.isThingEngine); -} - router.get('/', user.redirectLogIn, (req, res, next) => { res.render('devices_list', { page_title: 'Almond - My Goods', - devices: getAllDevices(req, req.app.engine) }); + devices: req.app.engine.getDeviceInfos() }); }); router.get('/create', user.redirectLogIn, (req, res, next) => { @@ -63,41 +58,29 @@ router.post('/create', user.requireLogIn, (req, res, next) => { } else { res.redirect(303, Config.BASE_URL + '/devices'); } - }).catch((e) => { - res.status(400).render('error', { page_title: "Almond - Error", - message: e.message }); - }); + }).catch(next); }); router.post('/delete', user.requireLogIn, (req, res, next) => { - var engine = req.app.engine; - var id = req.body.id; - var device; - try { - if (!engine.devices.hasDevice(id)) - device = undefined; - else - device = engine.devices.getDevice(id); + const engine = req.app.engine; + Promise.resolve().then(async () => { + const id = req.body.id; + const removed = await engine.deleteDevice(id); - if (device === undefined) { + if (!removed) { res.status(404).render('error', { page_title: "Almond - Error", message: "Not found." }); return; } - - engine.devices.removeDevice(device); res.redirect(Config.BASE_URL + '/devices'); - } catch(e) { - res.status(400).render('error', { page_title: "Almond - Error", - message: e.message }); - } + }).catch(next); }); router.get('/oauth2/:kind', user.redirectLogIn, (req, res, next) => { const kind = req.params.kind; const engine = req.app.engine; Promise.resolve().then(async () => { - const result = await engine.devices.addFromOAuth(kind); + const result = await engine.startOAuth(kind); if (result !== null) { const [redirect, session] = result; for (let key in session) @@ -106,18 +89,14 @@ router.get('/oauth2/:kind', user.redirectLogIn, (req, res, next) => { } else { res.redirect(Config.BASE_URL + '/devices?class=online'); } - }).catch((e) => { - console.log(e.stack); - res.status(400).render('error', { page_title: "Almond - Error", - message: e.message }); - }); + }).catch(next); }); router.get('/oauth2/callback/:kind', user.redirectLogIn, (req, res, next) => { const kind = req.params.kind; const engine = req.app.engine; Promise.resolve().then(async () => { - await engine.devices.completeOAuth(kind, req.url, req.session); + await engine.completeOAuth(kind, req.url, req.session); res.redirect(Config.BASE_URL + '/devices?class=online'); }).catch((e) => { console.log(e.stack); diff --git a/routes/index.js b/routes/index.js index fd81f95b..f5a5f4b7 100644 --- a/routes/index.js +++ b/routes/index.js @@ -2,24 +2,34 @@ // // This file is part of Almond // -// Copyright 2015 The Board of Trustees of the Leland Stanford Junior University +// Copyright 2016-2020 The Board of Trustees of the Leland Stanford Junior University // -// Author: Giovanni Campagna +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. // -// See COPYING for details +// Author: Giovanni Campagna "use strict"; const os = require('os'); const express = require('express'); -var router = express.Router(); +const Genie = require('genie-toolkit'); -// FIXME -const ipAddress = require('thingengine-core/lib/util/ip_address'); const user = require('../util/user'); const platform = require('../service/platform'); +const router = express.Router(); + router.get('/', user.redirectLogIn, (req, res, next) => { - ipAddress.getServerName().then((host) => { + Genie.IpAddressUtils.getServerName().then((host) => { var port = res.app.get('port'); var prefs = platform.getSharedPreferences(); diff --git a/routes/user.js b/routes/user.js index 933aed02..685ce1ae 100644 --- a/routes/user.js +++ b/routes/user.js @@ -2,11 +2,21 @@ // // This file is part of Almond // -// Copyright 2015 The Board of Trustees of the Leland Stanford Junior University +// Copyright 2016-2019 The Board of Trustees of the Leland Stanford Junior University // -// Author: Giovanni Campagna +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 // -// See COPYING for details +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Author: Giovanni Campagna "use strict"; const Q = require('q'); diff --git a/service/almond_api.js b/service/almond_api.js deleted file mode 100644 index 62139be2..00000000 --- a/service/almond_api.js +++ /dev/null @@ -1,403 +0,0 @@ -// -*- mode: js; indent-tabs-mode: nil; js-basic-offset: 4 -*- -// -// This file is part of Almond -// -// Copyright 2017 The Board of Trustees of the Leland Stanford Junior University -// -// Author: Giovanni Campagna -// -// See COPYING for details -"use strict"; - -const ThingTalk = require('thingtalk'); -const Ast = ThingTalk.Ast; -const Formatter = ThingTalk.Formatter; -const { ParserClient } = require('almond-dialog-agent'); - -const Config = require('../config'); - -module.exports = class AlmondApi { - constructor(engine) { - this._engine = engine; - this._parser = new ParserClient(Config.SEMPRE_URL, engine.platform.locale, engine.platform.getSharedPreferences()); - this._formatter = new Formatter(this._engine.platform.locale, this._engine.platform.timezone, this._engine.schemas); - - this._outputs = new Set; - } - - _sendWs(obj) { - let str = JSON.stringify(obj); - for (let out of this._outputs) { - try { - out.send(str); - } catch(e) { - // ignore errors if the connection was closed, while still sending to other connections - } - } - } - addOutput(out) { - this._outputs.add(out); - } - removeOutput(out) { - this._outputs.delete(out); - } - - sendCommand(command) { - this._sendWs({ - command: command - }); - } - sendHypothesis(hyp) { - this._sendWs({ - hypothesis: hyp - }); - } - - notify(appId, icon, outputType, outputValue) { - return Promise.resolve(this._formatter.formatForType(outputType, outputValue, 'messages')).then((messages) => { - this._sendWs({ result: { - appId: appId, - icon: icon ? Config.THINGPEDIA_URL + '/api/devices/icon/' + icon : null, - raw: outputValue, - type: outputType, - formatted: messages - }}); - }); - } - - notifyError(appId, icon, error) { - this._sendWs({ error: { - appId: appId, - icon: icon ? Config.THINGPEDIA_URL + '/api/devices/icon/' + icon : null, - error: error - }}); - } - - async _doCreateApp(code, locations) { - const program = await ThingTalk.Grammar.parseAndTypecheck(code, this._engine.schemas, true); - for (let slot of program.iterateSlots2()) { - if (slot instanceof Ast.Selector) { - if (slot.isBuiltin) - continue; - if (typeof slot.id !== 'string') - throw new TypeError(`must select a device for @${slot.kind}`); - continue; - } - const value = slot.get(); - if (value.isLocation && value.value.isRelative) { - let relativeTag = value.value.relativeTag; - if (relativeTag === 'current_location') - slot.set(locations['current_location'] ? Ast.Value.fromJSON(ThingTalk.Type.Location, locations['current_location']) : null); - else - slot.set(this._resolveUserContext('$context.location.' + relativeTag)); - if (!slot.get()) - throw new TypeError(`missing location ${relativeTag}`); - } - if (value.isTime && value.value.isRelative) { - let relativeTag = value.value.relativeTag; - slot.set(this._resolveUserContext('$context.time.' + relativeTag)); - if (!slot.get()) - throw new TypeError(`missing time ${relativeTag}`); - } - } - - let icon = null; - for (let [, prim] of program.iteratePrimitives()) { - if (prim.selector.isBuiltin) - continue; - if (prim.selector.kind !== 'org.thingpedia.builtin.thingengine.remote' && - !prim.selector.kind.startsWith('__dyn') - && prim.selector.id) { - let device = this._engine.devices.getDevice(prim.selector.id); - icon = device ? device.kind : null; - if (icon) break; - } - } - - let options = { icon }; - return this._engine.apps.createApp(program, options); - } - - async _doDrainApp(app) { - // drain the queue of results from the app - let results = []; - let errors = []; - if (!app) - return [results, errors]; - - for (;;) { - let { item: next, resolve, reject } = await app.mainOutput.next(); - - if (next.isDone) { - resolve(); - break; - } - - if (next.isNotification) { - try { - const messages = await this._formatter.formatForType(next.outputType, next.outputValue, 'messages'); - results.push({ raw: next.outputValue, type: next.outputType, formatted: messages }); - resolve(); - } catch (e) { - reject(e); - } - } else if (next.isError) { - errors.push(next.error); - resolve(); - } else if (next.isQuestion) { - let e = new Error('User cancelled'); - e.code = 'ECANCELLED'; - reject(e); - } - } - - return [results, errors]; - } - - async createApp(data) { - let code = data.code; - let locations = data.locations || {}; - let times = data.times || {}; - - let sharedPrefs = this._engine.platform.getSharedPreferences(); - for (let loc in locations) { - if (loc === 'home' || loc === 'work') { - let location = Ast.Value.fromJSON(ThingTalk.Type.Location, locations[loc]); - sharedPrefs.set('context-$context.location.' + loc, location.toJS()); - } - } - for (let time in times) { - if (time === 'morning' || time === 'evening') { - let time = Ast.Value.fromJSON(ThingTalk.Type.Time, times[time]); - sharedPrefs.set('context-$context.time.' + time, time.toJS()); - } - } - if (!code) - return { error: 'Missing program' }; - - try { - const app = await this._doCreateApp(code, locations); - const [results, errors] = await this._doDrainApp(app); - - return { - uniqueId: app.uniqueId, - description: app.description, - code: app.code, - icon: Config.CDN_HOST + '/icons/' + app.icon + '.png', - results, errors - }; - } catch (e) { - console.error(e.stack); - if (e instanceof TypeError) - return { error: e.message }; - else - throw e; - } - } - - _doParse(sentence) { - return this._parser.sendUtterance(sentence, null, null); - } - - parse(sentence, target) { - return Promise.resolve().then(() => { - if (target) { - return { entities: target.entities, - candidates: [{ score: 'Infinity', code: target.code }] }; - } else { - return this._doParse(sentence); - } - }).then((analyzed) => { - return Promise.all(analyzed.candidates.map((candidate) => { - return this._processCandidate(candidate, analyzed); - })).then((programs) => { - return programs.filter((r) => r !== null); - }).then((programs) => { - return { - tokens: analyzed.tokens, - entities: analyzed.entities, - candidates: programs.slice(0, 3) - }; - }); - }); - } - - _tryConfigureDevice(kind) { - return this._engine.thingpedia.getDeviceSetup([kind]).then((factories) => { - var factory = factories[kind]; - if (!factory) { - // something funky happened or thingpedia did not recognize the kind - return [null, null]; - } - - if (factory.type === 'none') { - return this._engine.devices.addSerialized({ kind: factory.kind }).then((device) => { - return [device, null]; - }); - } else { - let copy = {}; - Object.assign(copy, factory); - return [null, copy]; - } - }); - } - - _chooseDevice(selector, primId, devMap) { - function describeDevice(device) { - return { - uniqueId: device.uniqueId, - name: device.name, - description: device.description, - kind: device.kind, - icon: Config.THINGPEDIA_URL + '/api/devices/icon/' + device.kind, - }; - } - - let kind = selector.kind; - if (selector.id !== null) { - if (this._engine.devices.hasDevice(selector.id)) { - devMap[primId] = [describeDevice(this._engine.devices.getDevice(selector.id))]; - return Promise.resolve(true); - } else { - return Promise.resolve(false); - } - } - - let devices = this._engine.devices.getAllDevicesOfKind(kind); - - if (devices.length === 0) { - return this._tryConfigureDevice(kind).then(([device, factory]) => { - if (device) { - selector.device = device; - selector.id = device.uniqueId; - devMap[primId] = [describeDevice(device)]; - return true; - } else if (factory) { - devMap[primId] = factory; - return true; - } else { - return true; - } - }); - } else { - if (devices.length === 1) { - selector.device = devices[0]; - selector.id = devices[0].uniqueId; - } - - devMap[primId] = devices.map((dev) => describeDevice(dev)); - return Promise.resolve(true); - } - } - - _resolveUserContext(variable) { - let sharedPrefs = this._engine.platform.getSharedPreferences(); - - switch (variable) { - case '$context.location.current_location': - return null; - case '$context.location.home': - case '$context.location.work': { - let value = sharedPrefs.get('context-' + variable); - if (value !== undefined) - return Ast.Value.fromJSON(ThingTalk.Type.Location, value); - else - return null; - } - case '$context.time.morning': - case '$context.time.evening': { - let value = sharedPrefs.get('context-' + variable); - if (value !== undefined) - return Ast.Value.fromJSON(ThingTalk.Type.Time, value); - else - return null; - } - default: - throw new TypeError('Invalid variable ' + variable); - } - } - - _processPrimitives(program, primMap, result) { - let primitives = Array.from(program.iteratePrimitives()); - return Promise.all(primitives.map(([, prim]) => { - if (prim.selector.isBuiltin) - return true; - const primId = `p_${primMap.size}`; - primMap.set(prim, primId); - - return this._chooseDevice(prim.selector, primId, result.devices); - })).then((res) => { - if (primMap.size === 1) { - let rule = program.rules[0]; - if (rule.stream) - result.commandClass = 'trigger'; - else if (rule.table) - result.commandClass = 'query'; - else - result.commandClass = 'action'; - } - - return res.every((x) => x); - }); - } - - _slotFill(program, result) { - for (const [, slot, ,] of program.iterateSlots()) { - if (slot instanceof Ast.Selector) - continue; - if (slot.value.isUndefined && slot.value.local) - continue; - if (slot.value.isLocation && slot.value.value.isRelative) { - let value = this._resolveUserContext('$context.location.' + slot.value.value.relativeTag); - if (value !== null) { - slot.value.value = value; - result.locations[slot.value.value.relativeTag] = true; - } else { - result.locations[slot.value.value.relativeTag] = false; - } - } - if (slot.value.isTime && slot.value.value.isRelative) { - let value = this._resolveUserContext('$context.time.' + slot.value.value.relativeTag); - if (value !== null) { - slot.value.value = value; - result.times[slot.value.value.relativeTag] = true; - } else { - result.times[slot.value.value.relativeTag] = false; - } - } - } - } - - async _processCandidate(candidate, analyzed) { - if (candidate.code[0] === 'bookkeeping') // not a thingtalk program - return null; - - let program; - try { - program = ThingTalk.NNSyntax.fromNN(candidate.code, analyzed.entities); - await program.typecheck(this._engine.schemas, true); - } catch(e) { - console.error('Failed to analyze ' + candidate.code.join(' ') + ' : ' + e.message); - return null; - } - if (!program || !program.isProgram) - return null; - - const primitives = new Map; - - const result = { - score: candidate.score, - code: null, - commandClass: 'rule', - devices: {}, - locations: {}, - times: {}, - }; - const ok = await this._processPrimitives(program, primitives, result); - if (!ok) - return null; - this._slotFill(program, result); - result.code = program.prettyprint(true); - return result; - } -}; diff --git a/service/assistant.js b/service/assistant.js deleted file mode 100644 index 811a8568..00000000 --- a/service/assistant.js +++ /dev/null @@ -1,458 +0,0 @@ -// -*- mode: js; indent-tabs-mode: nil; js-basic-offset: 4 -*- -// -// This file is part of Almond -// -// Copyright 2016 The Board of Trustees of the Leland Stanford Junior University -// -// Author: Giovanni Campagna -// -// See COPYING for details -"use strict"; - -const assert = require('assert'); -const events = require('events'); -const child_process = require('child_process'); -let canberra; -try { - canberra = require('canberra'); -} catch(e) { - canberra = null; -} - -const Almond = require('almond-dialog-agent'); -let SpeechHandler; -try { - SpeechHandler = require('./speech_handler'); -} catch(e) { - SpeechHandler = null; -} -const AlmondApi = require('./almond_api'); - -const Config = require('../config'); - -class LocalUser { - constructor() { - - this.id = process.getuid ? process.getuid() : 0; - this.account = '';//pwnam.name; - this.name = '';//pwnam.gecos; - } -} - -const MessageType = { - TEXT: 0, - PICTURE: 1, - CHOICE: 2, - LINK: 3, - BUTTON: 4, - ASK_SPECIAL: 5, - RDL: 6, - MAX: 6 -}; - -class MainConversationDelegate { - constructor(platform, speechHandler) { - this._speechSynth = platform.getCapability('text-to-speech'); - this._outputs = new Set; - - this._speechHandler = speechHandler; - this._history = []; - } - - clearSpeechQueue() { - if (this._speechSynth) - this._speechSynth.clearQueue(); - } - setConversation(conversation) { - this._conversation = conversation; - } - - sendHypothesis(hypothesis) { - for (let out of this._outputs) - out.sendHypothesis(hypothesis); - } - - addOutput(out) { - this._outputs.add(out); - for (let [,msg] of this._history) // replay the history - msg(out); - } - removeOutput(out) { - this._outputs.delete(out); - } - - _emit(msg) { - for (let out of this._outputs) - msg(out); - } - - collapseButtons() { - for (let i = this._history.length-1; i >= 0; i--) { - let [type,] = this._history[i]; - if (type === MessageType.ASK_SPECIAL || type === MessageType.CHOICE || type === MessageType.BUTTON) - this._history.pop(); - else - break; - } - } - - _addMessage(type, msg) { - this._history.push([type, msg]); - if (this._history.length > 30) - this._history.shift(); - this._emit(msg); - } - - addCommandToHistory(msg) { - this._addMessage(MessageType.TEXT, (out) => out.sendCommand(msg)); - } - - send(text, icon) { - if (this._speechSynth) - this._speechSynth.say(text); - this._addMessage(MessageType.TEXT, (out) => out.send(text, icon)); - } - - sendPicture(url, icon) { - this._addMessage(MessageType.PICTURE, (out) => out.sendPicture(url, icon)); - } - - sendChoice(idx, what, title, text) { - if (this._speechSynth) - this._speechSynth.say(title); - this._addMessage(MessageType.CHOICE, (out) => out.sendChoice(idx, what, title, text)); - } - - sendLink(title, url) { - this._addMessage(MessageType.LINK, (out) => out.sendLink(title, url)); - } - - sendButton(title, json) { - if (this._speechSynth) - this._speechSynth.say(title); - this._addMessage(MessageType.BUTTON, (out) => out.sendButton(title, json)); - } - - sendAskSpecial(what) { - this._addMessage(MessageType.ASK_SPECIAL, (out) => out.sendAskSpecial(what)); - } - - sendRDL(rdl, icon) { - if (this._speechSynth) - this._speechSynth.say(rdl.displayTitle); - this._addMessage(MessageType.RDL, (out) => out.sendRDL(rdl, icon)); - } -} - -class MainConversation extends Almond { - constructor(engine, speechHandler, options) { - super(engine, 'main', new LocalUser(), new MainConversationDelegate(engine.platform, speechHandler), options); - this._delegate.setConversation(this); - } - - sendHypothesis(hypothesis) { - this._delegate.sendHypothesis(hypothesis); - } - - addOutput(out) { - this._delegate.addOutput(out); - } - removeOutput(out) { - this._delegate.removeOutput(out); - } - - handleCommand(command) { - this._delegate.clearSpeechQueue(); - this._delegate.collapseButtons(); - this._delegate.addCommandToHistory(command); - return super.handleCommand.apply(this, arguments); - } - - handleParsedCommand(json, title) { - this._delegate.clearSpeechQueue(); - this._delegate.collapseButtons(); - this._delegate.addCommandToHistory(title); - return super.handleParsedCommand.apply(this, arguments); - } - - handleThingTalk(code) { - this._delegate.clearSpeechQueue(); - this._delegate.collapseButtons(); - this._delegate.addCommandToHistory("\\t " + code); - return super.handleThingTalk.apply(this, arguments); - } - - presentExample() { - this._delegate.clearSpeechQueue(); - this._delegate.collapseButtons(); - return super.presentExample.apply(this, arguments); - } -} - -class OtherConversation extends Almond { - - handleCommand(command) { - this._delegate.sendCommand(command); - return super.handleCommand(command); - } - - handleParsedCommand(json, title) { - this._delegate.sendCommand(title); - return super.handleParsedCommand(json); - } - - handleThingTalk(code) { - this._delegate.sendCommand("\\t " + code); - return super.handleThingTalk(code); - } -} - -class StatelessConversationDelegate { - constructor(locale) { - this._locale = locale; - this._buffer = []; - this._askSpecial = null; - } - - flush() { - const buffer = this._buffer; - const askSpecial = this._askSpecial; - this._buffer = []; - this._askSpecial = null; - return { - messages: buffer, - askSpecial: askSpecial - }; - } - - send(text, icon) { - this._buffer.push({ type: 'text', text, icon }); - } - - sendPicture(url, icon) { - this._buffer.push({ type: 'picture', url, icon }); - } - - sendChoice(idx, what, title, text) { - this._buffer.push({ type: 'choice', idx, title, text }); - } - - sendLink(title, url) { - this._buffer.push({ type: 'link', title, url }); - } - - sendButton(title, json) { - this._buffer.push({ type: 'button', title, json }); - } - - sendRDL(rdl, icon) { - this._buffer.push({ type: 'rdl', rdl, icon }); - } - - sendResult(message, icon) { - this._buffer.push({ - type: 'result', - result: message, - - fallback: message.toLocaleString(this._locale), - icon - }); - } - - sendAskSpecial(what) { - assert(this._askSpecial === null); - this._askSpecial = what; - } -} - -const HOTWORD_DETECTED_ID = 1; - -module.exports = class Assistant extends events.EventEmitter { - constructor(engine) { - super(); - - this._engine = engine; - this._platform = engine.platform; - this._api = new AlmondApi(this._engine); - - if (SpeechHandler && this._platform.hasCapability('pulseaudio')) - this._speechHandler = new SpeechHandler(engine.platform); - else - this._speechHandler = null; - this._speechSynth = this._platform.getCapability('text-to-speech'); - try { - if (canberra) { - this._eventSoundCtx = new canberra.Context({ - [canberra.Property.APPLICATION_ID]: 'edu.stanford.Almond', - }); - this._eventSoundCtx.cache({ - [canberra.Property.EVENT_ID]: 'message-new-instant' - }); - } else { - this._eventSoundCtx = null; - } - } catch(e) { - this._eventSoundCtx = null; - console.error(`Failed to initialize libcanberra: ${e.message}`); - } - this._mainConversation = new MainConversation(engine, this._speechHandler, { - sempreUrl: Config.SEMPRE_URL, - showWelcome: true - }); - this._mainConversationInitialized = false; - this._statelessConversation = new Almond(engine, 'stateless', new LocalUser(), new StatelessConversationDelegate(this._platform.locale), { - sempreUrl: Config.SEMPRE_URL, - showWelcome: false - }); - - if (this._speechHandler) { - this._speechHandler.on('hypothesis', (hypothesis) => { - //this._api.sendHypothesis(hypothesis); - this._mainConversation.sendHypothesis(hypothesis); - }); - this._speechHandler.on('hotword', async (hotword) => { - child_process.spawn('xset', ['dpms', 'force', 'on']).on('error', (err) => { - console.error(`Failed to wake up the screen: ${err.message}`); - }); - if (!this._eventSoundCtx) - return; - try { - await this._eventSoundCtx.play(HOTWORD_DETECTED_ID, { - [canberra.Property.EVENT_ID]: 'message-new-instant' - }); - } catch(e) { - console.error(`Failed to play hotword detection sound: ${e.message}`); - } - }); - this._speechHandler.on('utterance', (utterance) => { - //this._api.sendCommand(utterance); - this._mainConversation.handleCommand(utterance); - }); - this._speechHandler.on('error', (error) => { - console.log('Error in speech recognition: ' + error.message); - this._speechSynth.say("Sorry, I had an error understanding your speech: " + error.message); - }); - } - - this._conversations = { - api: this._api, - main: this._mainConversation, - stateless: this._statelessConversation - }; - this._lastConversation = this._mainConversation; - } - - async converse(command) { - const conversation = this._conversations.stateless; - const delegate = conversation._delegate; - - switch (command.type) { - case 'command': - await conversation.handleCommand(command.text); - break; - case 'parsed': - await conversation.handleParsedCommand(command.json, command.title || ''); - break; - case 'tt': - await conversation.handleThingTalk(command.code); - break; - default: - throw new Error('Invalid command type ' + command.type); - } - - const result = delegate.flush(); - result.conversationId = conversation.id; - return result; - } - - hotword() { - if (!this._speechHandler) - return; - this._speechHandler.hotword(); - } - - parse(sentence, target) { - return this._api.parse(sentence, target); - } - createApp(data) { - return this._api.createApp(data); - } - addOutput(out) { - this._api.addOutput(out); - } - removeOutput(out) { - this._api.removeOutput(out); - } - - async start() { - if (this._speechSynth) - await this._speechSynth.start(); - if (this._speechHandler) - await this._speechHandler.start(); - } - - async startConversation() { - if (this._speechHandler) { - this._mainConversationInitialized = true; - await this._mainConversation.start(); - } - - await this._statelessConversation.start(); - } - - stop() { - if (this._speechSynth) - this._speechSynth.stop(); - if (this._speechHandler) - this._speechHandler.stop(); - } - - notifyAll(...data) { - return Promise.all(Object.keys(this._conversations).map((id) => { - if (id === 'stateless') - return Promise.resolve(); - return this._conversations[id].notify(...data); - })); - } - - notifyErrorAll(...data) { - return Promise.all(Object.keys(this._conversations).map((id) => { - if (id === 'stateless') - return Promise.resolve(); - return this._conversations[id].notifyError(...data); - })); - } - - getConversation(id) { - if (id === 'main' && !this._mainConversationInitialized) { - this._mainConversationInitialized = true; - this._mainConversation.start(); - } - - if (id !== undefined && this._conversations[id]) - return this._conversations[id]; - else if (this._lastConversation) - return this._lastConversation; - else - return this._mainConversation; - } - - openConversation(feedId, delegate) { - if (this._conversations[feedId]) - delete this._conversations[feedId]; - var conv = new OtherConversation(this._engine, feedId, new LocalUser(), delegate, { - sempreUrl: Config.SEMPRE_URL, - showWelcome: true - }); - conv.on('active', () => this._lastConversation = conv); - this._lastConversation = conv; - this._conversations[feedId] = conv; - return conv; - } - - closeConversation(feedId) { - if (this._conversations[feedId] === this._lastConversation) - this._lastConversation = null; - delete this._conversations[feedId]; - } -}; diff --git a/service/frontend.js b/service/frontend.js index bec2cd4b..c37c8398 100644 --- a/service/frontend.js +++ b/service/frontend.js @@ -1,7 +1,20 @@ - -/** - * Module dependencies. - */ +// -*- mode: js; indent-tabs-mode: nil; js-basic-offset: 4 -*- +// +// This file is part of Almond +// +// Copyright 2017-2019 The Board of Trustees of the Leland Stanford Junior University +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. "use strict"; const Q = require('q'); diff --git a/service/platform/bluez.js b/service/platform/bluez.js index 27662d78..ace2bc4a 100644 --- a/service/platform/bluez.js +++ b/service/platform/bluez.js @@ -2,11 +2,21 @@ // // This file is part of Almond // -// Copyright 2015 The Board of Trustees of the Leland Stanford Junior University +// Copyright 2019 The Board of Trustees of the Leland Stanford Junior University // -// Author: Giovanni Campagna +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 // -// See COPYING for details +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Author: Giovanni Campagna "use strict"; // Linux platform implementation of Bluetooth API, using BlueZ diff --git a/service/platform/contacts.js b/service/platform/contacts.js deleted file mode 100644 index 20d10030..00000000 --- a/service/platform/contacts.js +++ /dev/null @@ -1,82 +0,0 @@ -// -*- mode: js; indent-tabs-mode: nil; js-basic-offset: 4 -*- -// -// Copyright 2018 Google LLC -// -// Author: Giovanni Campagna -// -// See COPYING for details -"use strict"; - -// demo magic! -const MOCK_ADDRESS_BOOK_DATA = [ - { displayName: 'Bob', alternativeDisplayName: 'Doctor', - isPrimary: true, starred: false, timesContacted: 0, type: 'home', - email_address: 'elvzhang@stanford.edu', phone_number: '+1555BBOBSON', - speakerId: 'cc52eb7a-179d-49d8-b01d-96bd3c297b5d' /* giovanni */ }, - { - displayName: 'Ricky', alternativeDisplayName: 'Patient freaky riki rikis reekis reekes', - isPrimary: true, starred: false, timesContacted: 0, type: 'home', - email_address: 'elviszhang0606@gmail.com', phone_number: null, - speakerId: 'f83882d6-795a-45f6-a9a4-6cd75731d960' /* silei */ - }, - { - displayName: 'Alice Bobson', alternativeDisplayName: 'Mom', - isPrimary: true, starred: true, timesContacted: 0, type: 'home', - email_address: 'alice@bobson.com', phone_number: null, - speakerId: 'c8fe4497-89ce-4132-86fe-e833a9d9dd15' /* monica */, - }, - { - displayName: 'Chris Bobson', alternativeDisplayName: 'Older Son', - isPrimary: true, starred: false, timesContacted: 0, type: 'home', - email_address: 'chris@bobson.com', phone_number: '+1555CBOBSON', - speakerId: '0b46936a-033d-429b-b7d4-218c053e961c' // rakesh - } -]; - -module.exports = class UserRegistry { - constructor() { - } - - getOwnerContact() { - return MOCK_ADDRESS_BOOK_DATA[0]; - } - - async getAllSpeakerIds() { - return MOCK_ADDRESS_BOOK_DATA.map((c) => c.speakerId) - .filter((id) => id !== null); - } - - async lookup(item, key) { - return MOCK_ADDRESS_BOOK_DATA.map((el) => { - const clone = {}; - Object.assign(clone, el); - if (item === 'contact') { - //clone.value = 'speaker:' + clone.speakerId; - /*if (clone.phone_number !== null) - clone.value = 'phone:' + clone.phone_number; - else */if (clone.email_address !== null) - clone.value = 'email:' + clone.email_address; - else - clone.value = null; - } else { - clone.value = clone[item]; - } - if (clone.value) - return clone; - else - return null; - }); - } - - async lookupPrincipal(principal) { - return MOCK_ADDRESS_BOOK_DATA.find((contact) => { - if (principal.startsWith('speaker:')) - return contact.speakerId === principal.substr('speaker:'.length); - if (principal.startsWith('phone:')) - return contact.phone_number === principal.substr('phone:'.length); - if (principal.startsWith('email:')) - return contact.email_address === principal.substr('email:'.length); - return contact; - }) || null; - } -}; diff --git a/service/platform/graphics.js b/service/platform/graphics.js index 50ae6c28..5c690816 100644 --- a/service/platform/graphics.js +++ b/service/platform/graphics.js @@ -2,11 +2,21 @@ // // This file is part of Almond // -// Copyright 2016 The Board of Trustees of the Leland Stanford Junior University +// Copyright 2019 The Board of Trustees of the Leland Stanford Junior University // -// Author: Giovanni Campagna +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 // -// See COPYING for details +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Author: Giovanni Campagna "use strict"; // Graphics API abstraction, based on nodejs-gm diff --git a/service/platform/index.js b/service/platform/index.js index 8a6a1531..d2f26ab1 100644 --- a/service/platform/index.js +++ b/service/platform/index.js @@ -2,11 +2,21 @@ // // This file is part of Almond // -// Copyright 2015-2018 The Board of Trustees of the Leland Stanford Junior University +// Copyright 2019-2020 The Board of Trustees of the Leland Stanford Junior University // -// Author: Giovanni Campagna +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. // -// See COPYING for details +// Author: Giovanni Campagna "use strict"; // Server platform @@ -24,18 +34,17 @@ try { } catch(e) { PulseAudio = null; } -const CVC4Solver = require('smtlib').LocalCVC4Solver; const BluezBluetooth = require('./bluez'); -let SpeechSynthesizer; +const MediaPlayer = require('./media_player'); +const _graphicsApi = require('./graphics'); + +let WakeWordDetector; try { - SpeechSynthesizer = require('./speech_synthesizer'); + WakeWordDetector = require('../wake-word/snowboy'); } catch(e) { - SpeechSynthesizer = null; + WakeWordDetector = null; } -const MediaPlayer = require('./media_player'); -const Contacts = require('./contacts'); -const _graphicsApi = require('./graphics'); var _unzipApi = { unzip(zipPath, dir) { @@ -75,7 +84,6 @@ const _contentApi = { }); } } -const _contactApi = JavaAPI.makeJavaAPI('Contacts', ['lookup'], [], []); const _telephoneApi = JavaAPI.makeJavaAPI('Telephone', ['call', 'callEmergency'], [], []); */ @@ -158,13 +166,12 @@ class ServerPlatform extends Tp.BasePlatform { constructor() { super(); - this._assistant = null; - this._gettext = new Gettext(); this._filesDir = getFilesDir(); safeMkdirSync(this._filesDir); - this._locale = process.env.LC_ALL || process.env.LC_MESSAGES || process.env.LANG || 'en-US'; + // TODO support other locales + this._locale = 'en-US'; // normalize this._locale to something that Intl can grok this._locale = this._locale.split(/[-_.@]/).slice(0,2).join('-'); @@ -179,31 +186,25 @@ class ServerPlatform extends Tp.BasePlatform { this._dbusSystem = DBus.systemBus(); else this._dbusSystem = null; + this._btApi = null; + this._wakeWordDetector = null; if (PulseAudio) { this._pulse = new PulseAudio({ - client: "thingengine-platform-server" + client: "almond-server" }); - if (SpeechSynthesizer) - this._tts = new SpeechSynthesizer(this); - else - this._tts = null; + if (WakeWordDetector) + this._wakeWordDetector = new WakeWordDetector(); } else { this._pulse = null; - this._tts = null; } this._media = new MediaPlayer(); - this._contacts = new Contacts(); this._sqliteKey = null; this._origin = null; } - setAssistant(ad) { - this._assistant = ad; - } - get type() { return 'server'; } @@ -225,13 +226,7 @@ class ServerPlatform extends Tp.BasePlatform { // (eg we don't need discovery on the cloud, and we don't need graphdb, // messaging or the apps on the phone client) hasFeature(feature) { - switch(feature) { - case 'ui': - return false; - - default: - return true; - } + return true; } getPlatformDevice() { @@ -254,8 +249,6 @@ class ServerPlatform extends Tp.BasePlatform { return this._dbusSession !== null; case 'dbus-system': return this._dbusSystem !== null; - case 'text-to-speech': - return this._tts !== null; case 'bluetooth': return this._dbusSystem !== null; @@ -263,8 +256,12 @@ class ServerPlatform extends Tp.BasePlatform { case 'media-player': return true; - case'pulseaudio': + case 'pulseaudio': + case 'sound': return this._pulse !== null; + + case 'wakeword-detector': + return this._wakeWordDetector !== null; /* // We can use the phone capabilities case 'notify': @@ -280,10 +277,8 @@ class ServerPlatform extends Tp.BasePlatform { */ case 'gps': case 'graphics-api': - case 'contacts': case 'content-api': case 'assistant': - case 'smt-solver': return true; case 'gettext': @@ -308,26 +303,23 @@ class ServerPlatform extends Tp.BasePlatform { return this._dbusSession; case 'dbus-system': return this._dbusSystem; - case 'text-to-speech': - return this._tts; case 'bluetooth': if (this._dbusSystem === null) return null; if (!this._btApi) this._btApi = new BluezBluetooth(this); return this._btApi; - case 'pulseaudio': + case 'sound': + case 'pulseaudio': // legacy name for "sound" return this._pulse; + case 'wakeword-detector': + return this._wakeWordDetector; case 'media-player': return this._media; case 'content-api': return _contentApi; case 'graphics-api': return _graphicsApi; - case 'contacts': - return this._contacts; - case 'smt-solver': - return CVC4Solver; case 'gps': return _gpsApi; @@ -358,9 +350,6 @@ class ServerPlatform extends Tp.BasePlatform { return _telephoneApi; */ - case 'assistant': - return this._assistant; - case 'gettext': return this._gettext; diff --git a/service/platform/media_player.js b/service/platform/media_player.js index 2a6e9928..bde4debc 100644 --- a/service/platform/media_player.js +++ b/service/platform/media_player.js @@ -2,11 +2,21 @@ // // This file is part of Almond // -// Copyright 2018 The Board of Trustees of the Leland Stanford Junior University +// Copyright 2019 The Board of Trustees of the Leland Stanford Junior University // -// Author: Giovanni Campagna +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 // -// See COPYING for details +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Author: Giovanni Campagna "use strict"; const util = require('util'); diff --git a/service/platform/speech_synthesizer.js b/service/platform/speech_synthesizer.js deleted file mode 100644 index c0807189..00000000 --- a/service/platform/speech_synthesizer.js +++ /dev/null @@ -1,161 +0,0 @@ -// -*- mode: js; indent-tabs-mode: nil; js-basic-offset: 4 -*- -// -// Copyright 2017 The Board of Trustees of the Leland Stanford Junior University -// -// Author: Giovanni Campagna -// -// See COPYING for details -"use strict"; - -const Tp = require('thingpedia'); -const assert = require('assert'); - -class CancelledError extends Error { - constructor() { - super("Cancelled"); - this.code = 'ECANCELLED'; - } -} - -const Config = require('../../config'); - -module.exports = class SpeechSynthesizer { - constructor(platform) { - this._locale = platform.locale; - this._pulseCtx = platform.getCapability('pulseaudio'); - - this._queue = []; - this._speaking = false; - - this._outputStream = null; - this._closeTimeout = null; - } - - start() { - } - stop() { - } - - clearQueue() { - if (this._outputStream) - this._outputStream.discard(); - - const err = new CancelledError(); - for (const q of this._queue) { - if (typeof q.reject === 'function') - q.reject(err); - } - this._queue.length = 0; - } - - async _synth(text) { - const [buffer,] = await Tp.Helpers.Http.post(Config.SEMPRE_URL + '/' + this._locale + '/voice/tts', JSON.stringify({ - text - }), { - dataContentType: 'application/json', - raw: true - }); - - const numChannels = buffer.readInt16LE(22); - const sampleRate = buffer.readInt32LE(24); - // check bytes per sample (we only support S16LE format, which is what everybody uses anyway) - assert.strictEqual(buffer.readInt16LE(32), 2); - - console.log(this._numChannels, this._sampleRate); - - // remove the wav header (44 bytes) - const sliced = buffer.slice(44, buffer.length); - console.log(buffer.length, sliced.length); - - return { buffer: sliced, sampleRate, numChannels, text }; - } - - say(text) { - if (this._currentFrame !== this._nextFrame) { - this.clearQueue(); - this._currentFrame = this._nextFrame; - } - - this._queue.push(this._synth(text)); - if (!this._speaking) - this._sayNext(); - } - endFrame() { - const callbacks = {}; - const promise = new Promise((resolve, reject) => { - callbacks.resolve = resolve; - callbacks.reject = reject; - }); - - this._queue.push(callbacks); - if (!this._speaking) - this._sayNext(); - - return promise; - } - - _silence() { - // force flush the buffer with 0.15 second of silence - // this also causes a pause between the utterances, which sounds natural - // and slows down the pace - let bufferLength = 0.15 * this._sampleRate * this._numChannels * 2; - this._outputStream.write(Buffer.alloc(bufferLength)); - return 1000; - } - - _ensureOutputStream(result) { - if (this._closeTimeout) - clearTimeout(this._closeTimeout); - this._closeTimeout = setTimeout(() => { - this._outputStream.end(); - this._outputStream = null; - this._closeTimeout = null; - }, 60000); - - if (this._outputStream && this._sampleRate === result.sampleRate - && this._numChannels === result.numChannels) - return; - if (this._outputStream) - this._outputStream.end(); - this._sampleRate = result.sampleRate; - this._numChannels = result.numChannels; - this._outputStream = this._pulseCtx.createPlaybackStream({ - format: 'S16LE', // signed 16 bit little endian - rate: this._sampleRate, - channels: this._numChannels, - stream: 'thingengine-voice-output', - latency: 100000, // us (= 0.1 s) - properties: { - 'filter.want': 'echo-cancel', - } - }); - } - - async _sayNext() { - if (this._queue.length === 0) { - this._speaking = false; - return; - } - this._speaking = true; - - const qitem = this._queue.shift(); - try { - if (typeof qitem.resolve === 'function') { - qitem.resolve(); - } else { - const result = await qitem; - this._ensureOutputStream(result); - - let duration = result.buffer.length /2 / - result.sampleRate / result.numChannels * 1000; - console.log('outputstream write for ' + result.text + ', delay of ' + duration); - this._outputStream.write(result.buffer); - duration += this._silence(); - } - } catch (e) { - console.error('Failed to speak: ' + e); - } - - process.nextTick(() => this._sayNext()); - } -}; diff --git a/service/platform/utils.js b/service/platform/utils.js index 022b6979..7e42d68c 100644 --- a/service/platform/utils.js +++ b/service/platform/utils.js @@ -4,9 +4,19 @@ // // Copyright 2019 The Board of Trustees of the Leland Stanford Junior University // -// Author: Giovanni Campagna +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 // -// See COPYING for details +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Author: Giovanni Campagna "use strict"; function ninvoke(obj, method, ...args) { diff --git a/service/speech_handler.js b/service/speech_handler.js deleted file mode 100644 index 880de6a4..00000000 --- a/service/speech_handler.js +++ /dev/null @@ -1,96 +0,0 @@ -// -*- mode: js; indent-tabs-mode: nil; js-basic-offset: 4 -*- -// -// Copyright 2017 The Board of Trustees of the Leland Stanford Junior University -// -// Author: Giovanni Campagna -// -// See COPYING for details -"use strict"; - -const events = require('events'); - -const SpeechRecognizer = require('./speech_recognizer'); -const WakeWordDetector = require('./wake-word/snowboy'); - -module.exports = class SpeechHandler extends events.EventEmitter { - constructor(platform) { - super(); - this._platform = platform; - this._pulse = platform.getCapability('pulseaudio'); - - this._recognizer = new SpeechRecognizer({ locale: this._platform.locale }); - this._recognizer.on('error', (e) => { - this.emit('error', e); - }); - - this._hotwordDetected = false; - this._autoTrigger = false; - } - - setAutoTrigger(autoTrigger) { - console.log('setAutoTrigger', autoTrigger); - this._autoTrigger = autoTrigger; - } - - hotword() { - this.emit('hotword'); - this._onDetected(); - } - - _onDetected() { - let req = this._recognizer.request(this._stream); - req.on('hypothesis', (hypothesis) => this.emit('hypothesis', hypothesis)); - req.on('done', (status, utterance) => { - if (status === 'Success') { - console.log('Recognized as "' + utterance + '"'); - this._detector.autoTrigger = false; - this.emit('utterance', utterance); - } else if (status === 'NoMatch') { - this.emit('no-match'); - } else if (status === 'InitialSilenceTimeout') { - this.emit('silence'); - } else { - console.log('Recognition error: ' + status); - } - }); - } - - start() { - this._stream = this._pulse.createRecordStream({ - format: 'S16LE', - rate: 16000, - channels: 1, - properties: { - 'filter.want': 'echo-cancel', - } - }); - - this._stream.on('state', (state) => { - console.log('Record stream is now ' + state); - if (state === 'ready') - this.emit('ready'); - }); - this._stream.on('error', (e) => this.emit('error', e)); - - this._detector = new WakeWordDetector(); - this._detector.on('sound', () => { - if (this._autoTrigger) - this._onDetected(); - }); - this._detector.on('hotword', (hotword) => { - console.log('Hotword ' + hotword + ' detected'); - this.emit('hotword', hotword); - this._onDetected(); - }); - this._stream.pipe(this._detector); - } - - stop() { - if (!this._stream) - return; - this._stream.end(); - this._stream = null; - this._recognizer.close(); - this._detector.destroy(); - } -}; diff --git a/service/speech_recognizer.js b/service/speech_recognizer.js deleted file mode 100644 index 7fa95717..00000000 --- a/service/speech_recognizer.js +++ /dev/null @@ -1,360 +0,0 @@ -// -*- mode: js; indent-tabs-mode: nil; js-basic-offset: 4 -*- -// -// Copyright 2017 The Board of Trustees of the Leland Stanford Junior University -// -// Author: Giovanni Campagna -// -// See COPYING for details -"use strict"; - -const events = require('events'); -const Stream = require('stream'); -const https = require('https'); -const Url = require('url'); - -const uuid = require('uuid'); -const WebSocket = require('ws'); - -const Config = require('../config'); - -function encodeHeaders(path, contentType, requestId) { - let headers = { - 'path': path, - 'x-timestamp': (new Date).toISOString(), - 'content-type': contentType - }; - if (requestId) - headers['x-requestid'] = requestId; - let str = ''; - for (let name in headers) - str += name + ': ' + headers[name] + '\r\n'; - return str; -} - -class SpeechRequest extends Stream.Writable { - constructor(stream) { - // this is important, as the protocol does not allow chunks larger than 8192 bytes - super({ highWaterMark: 8192 }); - - this._stream = stream; - - this._requestId = uuid.v4().replace(/-/g, ''); - this._endDetected = false; - this._ended = false; - this._started = false; - this._sentRIFFHeader = false; - - //this._debugFile = fs.createWriteStream('out_' + process.pid + '_' + (i++) + '.wav'); - - this._startTime = (new Date).toISOString(); - this._stream.pipe(this); - this._piped = true; - - // all chunks received before the connection is ready are buffered here - this._bufferedMessages = []; - - this.on('error', () => { - if (!this._piped) - return; - this._piped = false; - this._stream.unpipe(this); - }); - } - - start(connection, connectionTelemetry) { - this._started = true; - this._connection = connection; - this._endTimeout = setTimeout(() => this.end(), 150000); - - this._listener = this._handleMessage.bind(this); - this._connection.on('message', this._listener); - - this._receivedMessages = {}; - this._connectionTelemetry = connectionTelemetry; - - for (let message of this._bufferedMessages) - this._connection.send(message, { binary: true }); - this._bufferedMessages = []; - } - - _finish(callback) { - // readable stream ended - this._piped = false; - this.end(); - callback(); - } - - end() { - if (this._piped) { - this._piped = false; - this._stream.unpipe(this); - } - - if (this._ended) - return; - - // end() before start() indicates an error connecting to the server (e.g. - // access token error) - if (!this._started) { - this._ended = true; - return; - } - - clearTimeout(this._endTimeout); - this._endTime = (new Date).toISOString(); - - let receivedMessages = []; - for (let path in this._receivedMessages) { - if (this._receivedMessages[path].length === 1) - receivedMessages.push({ [path]: this._receivedMessages[path][0] }); - else - receivedMessages.push({ [path]: this._receivedMessages[path] }); - } - this._sendTextMessage('telemetry', 'application/json', JSON.stringify({ - ReceivedMessages: receivedMessages, - Metrics: [ - this._connectionTelemetry, - { - Name: 'Microphone', - Start: this._startTime, - End: this._endTime - } - ] - })); - this._ended = true; - - //this._debugFile.end(); - } - - _handleMessage(msg) { - //console.log('Received message'); - //console.log(msg); - let lines = msg.toString('utf8').split('\r\n'); - let headers = {}; - let body; - for (let i = 0; i < lines.length; i++) { - let line = lines[i]; - if (line.length === 0) { - body = lines.slice(i+1).join('\r\n'); - break; - } - let tokens = line.split(':', 2); - headers[tokens[0].trim().toLowerCase()] = tokens[1].trim(); - } - - if (this._requestId !== headers['x-requestid']) - return; - - let json = JSON.parse(body); - let path = headers['path']; - if (!this._receivedMessages[path]) - this._receivedMessages[path] = []; - this._receivedMessages[path].push((new Date).toISOString()); - - if (path === 'speech.hypothesis') - this.emit('hypothesis', json.Text); - else if (path === 'speech.phrase') - this.emit('done', json.RecognitionStatus, json.DisplayText); - else if (path === 'speech.endDetected') - this._endDetected = true; - else if (path === 'turn.end') - this.end(); - } - - _write(chunk, encoding, callback) { - if (this._ended || this._endDetected) { - callback(); - return; - } - //console.log('Sending chunk of length ' + chunk.length); - - let header = Buffer.from(encodeHeaders('audio', 'audio/x-wav', this._requestId), 'utf8'); - let message; - if (!this._sentRIFFHeader) - message = Buffer.alloc(2 + header.length + 44 + chunk.length); - else - message = Buffer.alloc(2 + header.length + chunk.length); - message.writeInt16BE(header.length, 0); - header.copy(message, 2); - if (!this._sentRIFFHeader) { - let riffHeader = Buffer.alloc(44); - // the size of the chunks are chosen based on what GStreamer produces by default - riffHeader.write('RIFF', 0); - riffHeader.writeInt32LE(0x7fff0024, 4); - riffHeader.write('WAVE', 8); - riffHeader.write('fmt ', 12); - riffHeader.writeInt32LE(16, 16); // fmt pkt size - riffHeader.writeInt16LE(1, 20); // format (1 = PCM) - riffHeader.writeInt16LE(1, 22); // number of channels - riffHeader.writeInt32LE(16000, 24); // sample rate - riffHeader.writeInt32LE((16000 * 16 * 1)/8, 28); // byterate - riffHeader.writeInt16LE((16 * 1)/8, 32); // byte per sample - riffHeader.writeInt16LE(16, 34); // bits per sample - riffHeader.write('data', 36); - riffHeader.writeInt32LE(0x7fff0000, 40); - //this._debugFile.write(riffHeader); - riffHeader.copy(message, 2 + header.length); - //this._debugFile.write(chunk); - chunk.copy(message, 2 + 44 + header.length); - this._sentRIFFHeader = true; - } else { - //this._debugFile.write(chunk); - chunk.copy(message, 2 + header.length); - } - - if (this._connection && this._connection.readyState === 1) { - // OPEN - this._connection.send(message, { binary: true }, (err) => callback(err)); - } else { - this._bufferedMessages.push(message); - callback(); - } - } - - _sendTextMessage(path, contentType, body) { - let header = encodeHeaders(path, contentType, this._requestId); - let msg = header + '\r\n' + body; - //console.log(msg); - if (this._connection.readyState === 1) // OPEN - this._connection.send(msg, { binary: false }); - } -} - -module.exports = class SpeechRecognizer extends events.EventEmitter { - constructor(options = {}) { - super(); - this._language = options.locale || 'en-US'; - this._connection = null; - } - - close() { - if (!this._connection) - return; - this._connection.close(); - this._connection = null; - } - - _obtainAccessToken() { - let url = Url.parse('https://api.cognitive.microsoft.com/sts/v1.0/issueToken'); - url.method = 'POST'; - url.headers = { - 'Content-type': 'application/x-www-form-urlencoded', - 'Ocp-Apim-Subscription-Key': Config.MS_SPEECH_RECOGNITION_PRIMARY_KEY, - 'Content-Length': '0' - }; - return new Promise((callback, errback) => { - var req = https.request(url, (res) => { - if (res.statusCode !== 200) { - errback(new Error(res.statusMessage)); - return; - } - let buf =''; - res.on('data', (d) => buf += d); - res.on('error', errback); - res.on('end', () => callback(buf)); - }); - req.on('error', errback); - req.end(); - }); - } - - _ensureAccessToken() { - let now = (new Date).getTime(); - if (this._accessToken && this._accessTokenExpires >= now) - return Promise.resolve(this._accessToken); - return this._obtainAccessToken().then((token) => { - console.log('Obtained access token ' + token); - this._accessToken = token; - // access tokens last for 10 minutes - // make them 9 minutes to be safe - this._accessTokenExpires = (new Date).getTime() + 9 * 3600 * 1000; - return token; - }); - } - - _doConnect(accessToken) { - let startTime = (new Date).toISOString(); - let connectionId = uuid.v4().replace(/-/g, ''); - - let url = 'wss://speech.platform.bing.com/speech/recognition/interactive/cognitiveservices/v1?language=' + this._language; - this._connectionTelemetry = { - Name: 'Connection', - Id: connectionId, - Start: startTime - }; - let connection = new WebSocket(url, { - perMessageDeflate: true, - headers: { - 'Authorization': 'Bearer ' + accessToken, - 'Ocp-Apim-Subscription-Key': Config.MS_SPEECH_RECOGNITION_SECONDARY_KEY, - 'X-ConnectionId': connectionId - } - }); - return new Promise((callback, errback) => { - connection.on('unexpected-response', (req, res) => { - errback(new Error(res.statusMessage)); - }); - connection.on('open', () => { - //console.log('Connection opened'); - this._connectionTelemetry.End = (new Date).toISOString(); - - // connection telemetry confuses the server, and apparently - // we don't need it - /*let msg = encodeHeaders('speech.config', 'application/json; charset=utf-8') + '\r\n' - + JSON.stringify({ - context: { - system: { - version: '1.0.0', - }, - os: { - platform: 'Linux', - name: 'Debian', - version: '9.0.0', - }, - device: { - manufacturer: 'Unknown', - model: 'Unknown', - version: '1.0.0' - } - } - }); - console.log(msg); - this._connection.send(msg);*/ - - this._connection = connection; - callback(connection); - }); - connection.on('close', (code, reason) => { - if (code !== 1000) // 1000 = normal closure (eg timeout, or we closed on our side) - console.log('Connection to MS Speech Recognizer service closed: ' + code + ' ' + reason); - this._connection = null; - }); - connection.on('error', (e) => { - this._connection = null; - if (e.code === 'ECONNRESET') - console.log('Error on MS Speech Recognizer: Connection Reset'); - else - this.emit('error', e); - }); - }); - } - - _ensureConnection() { - if (this._connection) - return Promise.resolve(this._connection); - else - return this._ensureAccessToken().then((token) => this._doConnect(token)); - } - - request(stream) { - let req = new SpeechRequest(stream); - this._ensureConnection().then((connection) => { - req.start(connection, this._connectionTelemetry); - }).catch((e) => { - req.end(); - this.emit('error', e); - }); - req.on('error', (e) => this.emit('error', e)); - return req; - } -}; diff --git a/service/wake-word/mycroft_precise.js b/service/wake-word/mycroft_precise.js index ea6e3bee..7b14a851 100644 --- a/service/wake-word/mycroft_precise.js +++ b/service/wake-word/mycroft_precise.js @@ -1,10 +1,22 @@ // -*- mode: js; indent-tabs-mode: nil; js-basic-offset: 4 -*- // -// Copyright 2017 The Board of Trustees of the Leland Stanford Junior University +// This file is part of Almond // -// Author: Giovanni Campagna +// Copyright 2019 The Board of Trustees of the Leland Stanford Junior University // -// See COPYING for details +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Author: Giovanni Campagna "use strict"; const stream = require('stream'); diff --git a/service/wake-word/snowboy.js b/service/wake-word/snowboy.js index 63902be9..973f5e72 100644 --- a/service/wake-word/snowboy.js +++ b/service/wake-word/snowboy.js @@ -1,10 +1,22 @@ // -*- mode: js; indent-tabs-mode: nil; js-basic-offset: 4 -*- // -// Copyright 2017 The Board of Trustees of the Leland Stanford Junior University +// This file is part of Almond // -// Author: Giovanni Campagna +// Copyright 2020 The Board of Trustees of the Leland Stanford Junior University +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 // -// See COPYING for details +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Author: Giovanni Campagna "use strict"; const stream = require('stream'); @@ -36,7 +48,7 @@ module.exports = class SnowboyDetectorStream extends stream.Writable { this.emit('sound'); }); this._detector.on('hotword', (index, hotword, buffer) => { - this.emit('hotword', hotword); + this.emit('wakeword', hotword); }); } diff --git a/tests/linkcheck.js b/tests/linkcheck.js index bcaa6590..a5df9bc6 100644 --- a/tests/linkcheck.js +++ b/tests/linkcheck.js @@ -1,12 +1,22 @@ // -*- mode: js; indent-tabs-mode: nil; js-basic-offset: 4 -*- // -// This file is part of Almond Cloud +// This file is part of Almond // -// Copyright 2018 The Board of Trustees of the Leland Stanford Junior University +// Copyright 2019 The Board of Trustees of the Leland Stanford Junior University // -// Author: Giovanni Campagna +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 // -// See COPYING for details +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Author: Giovanni Campagna "use strict"; // load thingpedia to initialize the polyfill diff --git a/tests/manual/test_record.js b/tests/manual/test_record.js deleted file mode 100644 index f2441afe..00000000 --- a/tests/manual/test_record.js +++ /dev/null @@ -1,42 +0,0 @@ - -const fs = require('fs'); -const PulseAudio = require('pulseaudio2'); - -function main() { - let pulseCtx = new PulseAudio(); - let stream = pulseCtx.createRecordStream({ format: 'S16LE', rate: 16000, channels: 1 }); - stream.on('state', (state) => { - if (state === 'ready') - console.log('Speak now...'); - }); - - let output = fs.createWriteStream('output.wav'); - let riffHeader = Buffer.alloc(44); - // the size of the chunks are chosen based on what GStreamer produces by default - riffHeader.write('RIFF', 0); - riffHeader.writeInt32LE(0x7fff0024, 4); - riffHeader.write('WAVE', 8); - riffHeader.write('fmt ', 12); - riffHeader.writeInt32LE(16, 16); // fmt pkt size - riffHeader.writeInt16LE(1, 20); // format (1 = PCM) - riffHeader.writeInt16LE(1, 22); // number of channels - riffHeader.writeInt32LE(16000, 24); // sample rate - riffHeader.writeInt32LE((16000 * 16 * 1)/8, 28); // byterate - riffHeader.writeInt16LE((16 * 1)/8, 32); // byte per sample - riffHeader.writeInt16LE(16, 34); // bits per sample - riffHeader.write('data', 36); - riffHeader.writeInt32LE(0x7fff0000, 40); - output.write(riffHeader); - //stream.pipe(output); - stream.on('data', (chunk) => { - console.log('Chunk of size ' + chunk.length); - output.write(chunk) - }); - stream.on('end', () => output.end()); - - process.on('SIGINT', () => { - stream.end(); - pulseCtx.end(); - }); -} -main(); diff --git a/tests/manual/test_speech_handler.js b/tests/manual/test_speech_handler.js deleted file mode 100644 index 7fc9bb2b..00000000 --- a/tests/manual/test_speech_handler.js +++ /dev/null @@ -1,31 +0,0 @@ -// -*- mode: js; indent-tabs-mode: nil; js-basic-offset: 4 -*- -// -// Copyright 2017 The Board of Trustees of the Leland Stanford Junior University -// -// Author: Giovanni Campagna -// -// See COPYING for details -"use strict"; - -const SpeechHandler = require('../service/speech_handler'); -const platform = require('../service/platform'); - -function main() { - platform.init(); - let handler = new SpeechHandler(platform); - - handler.on('ready', () => { - console.log('Speak now...'); - }); - handler.on('hypothesis', (hypothesis) => { - console.log('Hypothesis: ' + hypothesis); - }); - handler.on('utterance', (utterance) => { - console.log('Utterance: ' + utterance); - }); - handler.on('error', (e) => { - console.error('Error', e); - }); - handler.start(); -} -main(); diff --git a/tests/manual/test_speech_recognizer.js b/tests/manual/test_speech_recognizer.js deleted file mode 100644 index 534e8f9e..00000000 --- a/tests/manual/test_speech_recognizer.js +++ /dev/null @@ -1,75 +0,0 @@ -// -*- mode: js; indent-tabs-mode: nil; js-basic-offset: 4 -*- -// -// Copyright 2017 The Board of Trustees of the Leland Stanford Junior University -// -// Author: Giovanni Campagna -// -// See COPYING for details -"use strict"; - -const PulseAudio = require('pulseaudio2'); - -const SpeechRecognizer = require('../service/speech_recognizer'); -const readline = require('readline'); - -function main() { - let recognizer = new SpeechRecognizer({ - locale: 'en-US' - }); - let pulseCtx = new PulseAudio(); - - function makeRequest() { - return new Promise((callback, errback) => { - let stream = pulseCtx.createRecordStream({ format: 'S16LE', rate: 16000, channels: 1 }); - stream.on('state', (state) => { - if (state === 'ready') - console.log('Speak now...'); - }); - - let request = recognizer.request(null, stream); - request.on('ready', () => console.log('Speak now...')); - request.on('hypothesis', (hyp) => console.log('Hypothesis: ' + hyp)); - request.on('done', (status, phrase) => { - console.log('Done: ' + status); - if (status === 'Success') - console.log(phrase); - callback(); - }); - }); - } - - var rl = readline.createInterface({ input: process.stdin, output: process.stdout }); - - rl.setPrompt('$ '); - - function help() { - console.log('Available console commands:'); - console.log('\\q: quit'); - console.log('\\s: speak'); - console.log('\\? or \\h: this help'); - rl.prompt(); - } - function quit() { - recognizer.close(); - pulseCtx.end(); - rl.close(); - } - - rl.on('line', function(line) { - if (line.trim().length === 0) { - rl.prompt(); - return; - } - if (line === '\\q') - quit(); - else if (line === '\\h' || line === '\\?') - help(); - else if (line === '\\s') - return makeRequest().then(() => rl.prompt()); - else - console.log('Unknown command ' + line); - rl.prompt(); - }); - rl.prompt(); -} -main(); diff --git a/tests/test_website_selenium.js b/tests/test_website_selenium.js index 43111870..93bf0606 100644 --- a/tests/test_website_selenium.js +++ b/tests/test_website_selenium.js @@ -1,12 +1,22 @@ // -*- mode: js; indent-tabs-mode: nil; js-basic-offset: 4 -*- // -// This file is part of Almond Cloud +// This file is part of Almond // -// Copyright 2018 The Board of Trustees of the Leland Stanford Junior University +// Copyright 2019 The Board of Trustees of the Leland Stanford Junior University // -// Author: Giovanni Campagna +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. // -// See COPYING for details +// Author: Giovanni Campagna "use strict"; // load thingpedia to initialize the polyfill @@ -94,6 +104,17 @@ async function testHomepage(driver) { assert.strictEqual(await title.getText(), 'It works!'); } +// there is some randomness in what message we pick +const WELCOME_MESSAGES = [ + `Hi, what can I do for you?`, + `Hi, how can I help you?`, + `Hello, what can I do for you?`, + `Hello, how can I help you?`, + `Hi! What can I do for you?`, + `Hi! How can I help you?`, + `Hello! What can I do for you?`, + `Hello! How can I help you?`, +]; async function testMyConversation(driver) { await driver.get(BASE_URL + '/conversation'); @@ -108,8 +129,9 @@ async function testMyConversation(driver) { let messages = await driver.findElements(WD.By.css('.message')); assert.strictEqual(messages.length, 1); - assert.strictEqual(await messages[0].getText(), `Welcome back!`); + assert(WELCOME_MESSAGES.includes(await messages[0].getText())); + // todo: use a better test await inputEntry.sendKeys('no', WD.Key.ENTER); const ourInput = await driver.wait( @@ -119,20 +141,8 @@ async function testMyConversation(driver) { const response = await driver.wait( WD.until.elementLocated(WD.By.css('.from-almond:nth-child(3) .message')), - 10000); - assert.strictEqual(await response.getText(), 'No way!'); - - /*await inputEntry.sendKeys('hello', WD.Key.ENTER); - - const ourInput2 = await driver.wait( - WD.until.elementLocated(WD.By.css('.message.from-user:nth-child(3)')), - 10000); - assert.strictEqual(await ourInput2.getText(), 'hello'); - - const response2 = await driver.wait( - WD.until.elementLocated(WD.By.css('.from-almond:nth-child(4) .message')), - 10000); - assert.strictEqual(await response2.getText(), 'Hi!');*/ + 60000); + assert.strictEqual(await response.getText(), 'Sorry, I did not understand that. Can you rephrase it?'); } async function main() { diff --git a/tests/unit/index.js b/tests/unit/index.js index 287da646..deb54a42 100644 --- a/tests/unit/index.js +++ b/tests/unit/index.js @@ -1,3 +1,20 @@ +// -*- mode: js; indent-tabs-mode: nil; js-basic-offset: 4 -*- +// +// This file is part of Almond +// +// Copyright 2019 The Board of Trustees of the Leland Stanford Junior University +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. "use strict"; process.on('unhandledRejection', (up) => { throw up; }); diff --git a/tests/util/csrf.js b/tests/util/csrf.js index 576771e3..db85e159 100644 --- a/tests/util/csrf.js +++ b/tests/util/csrf.js @@ -1,12 +1,22 @@ // -*- mode: js; indent-tabs-mode: nil; js-basic-offset: 4 -*- // -// This file is part of Almond Cloud +// This file is part of Almond // -// Copyright 2018 The Board of Trustees of the Leland Stanford Junior University +// Copyright 2019 The Board of Trustees of the Leland Stanford Junior University // -// Author: Giovanni Campagna +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 // -// See COPYING for details +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Author: Giovanni Campagna "use strict"; const minidom = require('./minidom'); diff --git a/tests/util/minidom.js b/tests/util/minidom.js index b703a15b..4d7d785a 100644 --- a/tests/util/minidom.js +++ b/tests/util/minidom.js @@ -1,12 +1,22 @@ // -*- mode: js; indent-tabs-mode: nil; js-basic-offset: 4 -*- // -// This file is part of Almond Cloud +// This file is part of Almond // -// Copyright 2018 The Board of Trustees of the Leland Stanford Junior University +// Copyright 2019 The Board of Trustees of the Leland Stanford Junior University // -// Author: Giovanni Campagna +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 // -// See COPYING for details +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Author: Giovanni Campagna "use strict"; const parse5 = require('parse5'); diff --git a/util/error_handling.js b/util/error_handling.js index aecd7187..ddd87bce 100644 --- a/util/error_handling.js +++ b/util/error_handling.js @@ -1,12 +1,22 @@ // -*- mode: js; indent-tabs-mode: nil; js-basic-offset: 4 -*- // -// This file is part of Thingpedia +// This file is part of Almond // // Copyright 2019 The Board of Trustees of the Leland Stanford Junior University // -// Author: Giovanni Campagna +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 // -// See COPYING for details +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Author: Giovanni Campagna "use strict"; const Tp = require('thingpedia'); diff --git a/util/errors.js b/util/errors.js index 8b173f1d..40a59c1d 100644 --- a/util/errors.js +++ b/util/errors.js @@ -4,9 +4,19 @@ // // Copyright 2019 The Board of Trustees of the Leland Stanford Junior University // -// Author: Giovanni Campagna +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 // -// See COPYING for details +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Author: Giovanni Campagna "use strict"; class HTTPError extends Error { diff --git a/util/secret_key.js b/util/secret_key.js index 5a7a7203..73916950 100644 --- a/util/secret_key.js +++ b/util/secret_key.js @@ -2,11 +2,21 @@ // // This file is part of Almond // -// Copyright 2015 The Board of Trustees of the Leland Stanford Junior University +// Copyright 2016-2019 The Board of Trustees of the Leland Stanford Junior University // -// Author: Giovanni Campagna +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 // -// See COPYING for details +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Author: Giovanni Campagna "use strict"; const crypto = require('crypto'); diff --git a/util/user.js b/util/user.js index ab4193b6..a75c8c58 100644 --- a/util/user.js +++ b/util/user.js @@ -2,11 +2,21 @@ // // This file is part of Almond // -// Copyright 2015 The Board of Trustees of the Leland Stanford Junior University +// Copyright 2016-2019 The Board of Trustees of the Leland Stanford Junior University // -// Author: Giovanni Campagna +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 // -// See COPYING for details +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Author: Giovanni Campagna "use strict"; const crypto = require('crypto'); diff --git a/views/devices_list.pug b/views/devices_list.pug index 78e7b348..86f55043 100644 --- a/views/devices_list.pug +++ b/views/devices_list.pug @@ -35,27 +35,9 @@ block content img(src=THINGPEDIA_URL + '/api/devices/icon/' + dev.kind, alt="Icon for " + dev.name) p= dev.description - if dev.isPhysical - if dev.ownerTier !== 'cloud' && dev.ownerTier !== 'global' - p= _("This device is owned by your %s.").format(dev.ownerTier) - - if dev.available == 0 - p= _("The device is not available. It might be powered off or disconnected.") - else if dev.available == 1 - p= _("The device is available and working.") - else if dev.available == 2 - if dev.ownerTier === 'server' - p= _("The device is not available because your server is disconnected.") - = _(" Make sure that it is powered on and correctly configured.") - else if dev.ownerTier === 'phone' - p= _("The device is not available because your phone is disconnected.") - = _(" Make sure that it is powered on and connected to the network.") - else - p= _("The device is not available because Cloud Almond cannot be reached.") - = _(" There might be a temporary service outage.") - else - p= _("It was not possible to verify if the device is available.") - = _("Please check it is powered on and correctly configured.") + if dev.class === 'physical' + if dev.ownerTier !== 'cloud' && dev.ownerTier !== 'global' + p= _("This device is owned by your %s.").format(dev.ownerTier) div.panel-footer div.row if !dev.isTransient diff --git a/webview/main.js b/webview/main.js index e6cda7c6..ae8d7c8c 100644 --- a/webview/main.js +++ b/webview/main.js @@ -4,9 +4,19 @@ // // Copyright 2018 The Board of Trustees of the Leland Stanford Junior University // -// Author: Giovanni Campagna +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 // -// See COPYING for details +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Author: Giovanni Campagna "use strict"; const System = imports.system; @@ -14,7 +24,6 @@ const GObject = imports.gi.GObject; const GLib = imports.gi.GLib; const Gio = imports.gi.Gio; const Gtk = imports.gi.Gtk; -const Gdk = imports.gi.Gdk; const WebKit = imports.gi.WebKit2; const BrowserWindow = GObject.registerClass(class BrowserWindow extends Gtk.ApplicationWindow { diff --git a/yarn.lock b/yarn.lock index eecf7388..46b4b016 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,207 +2,188 @@ # yarn lockfile v1 -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.8.3.tgz#33e25903d7481181534e12ec0a25f16b6fcf419e" - integrity sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g== +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a" + integrity sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg== dependencies: - "@babel/highlight" "^7.8.3" + "@babel/highlight" "^7.10.4" "@babel/core@^7.7.5": - version "7.9.0" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.9.0.tgz#ac977b538b77e132ff706f3b8a4dbad09c03c56e" - integrity sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w== - dependencies: - "@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" + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.11.0.tgz#73b9c33f1658506887f767c26dae07798b30df76" + integrity sha512-mkLq8nwaXmDtFmRkQ8ED/eA2CnVw4zr7dCztKalZXBvdK5EeNUAesrrwUqjQEzFgomJssayzB0aqlOsP1vGLqg== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/generator" "^7.11.0" + "@babel/helper-module-transforms" "^7.11.0" + "@babel/helpers" "^7.10.4" + "@babel/parser" "^7.11.0" + "@babel/template" "^7.10.4" + "@babel/traverse" "^7.11.0" + "@babel/types" "^7.11.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" + lodash "^4.17.19" resolve "^1.3.2" semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@^7.9.0": - version "7.9.4" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.9.4.tgz#12441e90c3b3c4159cdecf312075bf1a8ce2dbce" - integrity sha512-rjP8ahaDy/ouhrvCoU1E5mqaitWrxwuNGU+dy1EpaoK48jZay4MdkskKGIMHLZNewg8sAsqpGSREJwP0zH3YQA== +"@babel/generator@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.11.0.tgz#4b90c78d8c12825024568cbe83ee6c9af193585c" + integrity sha512-fEm3Uzw7Mc9Xi//qU20cBKatTfs2aOtKqmvy/Vm7RkJEGFQ4xc9myCfbXxqK//ZS8MR/ciOHw6meGASJuKmDfQ== dependencies: - "@babel/types" "^7.9.0" + "@babel/types" "^7.11.0" jsesc "^2.5.1" - lodash "^4.17.13" source-map "^0.5.0" -"@babel/helper-function-name@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz#eeeb665a01b1f11068e9fb86ad56a1cb1a824cca" - integrity sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA== - dependencies: - "@babel/helper-get-function-arity" "^7.8.3" - "@babel/template" "^7.8.3" - "@babel/types" "^7.8.3" - -"@babel/helper-get-function-arity@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz#b894b947bd004381ce63ea1db9f08547e920abd5" - integrity sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA== - dependencies: - "@babel/types" "^7.8.3" - -"@babel/helper-member-expression-to-functions@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz#659b710498ea6c1d9907e0c73f206eee7dadc24c" - integrity sha512-fO4Egq88utkQFjbPrSHGmGLFqmrshs11d46WI+WZDESt7Wu7wN2G2Iu+NMMZJFDOVRHAMIkB5SNh30NtwCA7RA== - dependencies: - "@babel/types" "^7.8.3" - -"@babel/helper-module-imports@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz#7fe39589b39c016331b6b8c3f441e8f0b1419498" - integrity sha512-R0Bx3jippsbAEtzkpZ/6FIiuzOURPcMjHp+Z6xPe6DtApDJx+w7UYyOLanZqO8+wKR9G10s/FmHXvxaMd9s6Kg== - dependencies: - "@babel/types" "^7.8.3" - -"@babel/helper-module-transforms@^7.9.0": - version "7.9.0" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.9.0.tgz#43b34dfe15961918707d247327431388e9fe96e5" - integrity sha512-0FvKyu0gpPfIQ8EkxlrAydOWROdHpBmiCiRwLkUiBGhCUPRRbVD2/tm3sFr/c/GWFrQ/ffutGUAnx7V0FzT2wA== - dependencies: - "@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" - -"@babel/helper-optimise-call-expression@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz#7ed071813d09c75298ef4f208956006b6111ecb9" - integrity sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ== - dependencies: - "@babel/types" "^7.8.3" - -"@babel/helper-replace-supers@^7.8.6": - version "7.8.6" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.8.6.tgz#5ada744fd5ad73203bf1d67459a27dcba67effc8" - integrity sha512-PeMArdA4Sv/Wf4zXwBKPqVj7n9UF/xg6slNRtZW84FM7JpE1CbG8B612FyM4cxrf4fMAMGO0kR7voy1ForHHFA== - dependencies: - "@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" - -"@babel/helper-simple-access@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz#7f8109928b4dab4654076986af575231deb639ae" - integrity sha512-VNGUDjx5cCWg4vvCTR8qQ7YJYZ+HBjxOgXEl7ounz+4Sn7+LMD3CFrCTEU6/qXKbA2nKg21CwhhBzO0RpRbdCw== - dependencies: - "@babel/template" "^7.8.3" - "@babel/types" "^7.8.3" - -"@babel/helper-split-export-declaration@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz#31a9f30070f91368a7182cf05f831781065fc7a9" - integrity sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA== - dependencies: - "@babel/types" "^7.8.3" - -"@babel/helper-validator-identifier@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.1.tgz#5770b0c1a826c4f53f5ede5e153163e0318e94b5" - integrity sha512-5vW/JXLALhczRCWP0PnFDMCJAchlBvM7f4uk/jXritBnIa6E1KmqmtrS3yn1LAnxFBypQ3eneLuXjsnfQsgILw== - -"@babel/helper-validator-identifier@^7.9.0": - version "7.9.0" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.0.tgz#ad53562a7fc29b3b9a91bbf7d10397fd146346ed" - integrity sha512-6G8bQKjOh+of4PV/ThDm/rRqlU7+IGoJuofpagU5GlEl29Vv0RGqqt86ZGRV8ZuSOY3o+8yXl5y782SMcG7SHw== - -"@babel/helpers@^7.9.0": - version "7.9.2" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.9.2.tgz#b42a81a811f1e7313b88cba8adc66b3d9ae6c09f" - integrity sha512-JwLvzlXVPjO8eU9c/wF9/zOIN7X6h8DYf7mG4CiFRZRvZNKEF5dQ3H3V+ASkHoIB3mWhatgl5ONhyqHRI6MppA== - dependencies: - "@babel/template" "^7.8.3" - "@babel/traverse" "^7.9.0" - "@babel/types" "^7.9.0" - -"@babel/highlight@^7.8.3": - version "7.9.0" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.9.0.tgz#4e9b45ccb82b79607271b2979ad82c7b68163079" - integrity sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ== - dependencies: - "@babel/helper-validator-identifier" "^7.9.0" +"@babel/helper-function-name@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz#d2d3b20c59ad8c47112fa7d2a94bc09d5ef82f1a" + integrity sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ== + dependencies: + "@babel/helper-get-function-arity" "^7.10.4" + "@babel/template" "^7.10.4" + "@babel/types" "^7.10.4" + +"@babel/helper-get-function-arity@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz#98c1cbea0e2332f33f9a4661b8ce1505b2c19ba2" + integrity sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A== + dependencies: + "@babel/types" "^7.10.4" + +"@babel/helper-member-expression-to-functions@^7.10.4": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.11.0.tgz#ae69c83d84ee82f4b42f96e2a09410935a8f26df" + integrity sha512-JbFlKHFntRV5qKw3YC0CvQnDZ4XMwgzzBbld7Ly4Mj4cbFy3KywcR8NtNctRToMWJOVvLINJv525Gd6wwVEx/Q== + dependencies: + "@babel/types" "^7.11.0" + +"@babel/helper-module-imports@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz#4c5c54be04bd31670a7382797d75b9fa2e5b5620" + integrity sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw== + dependencies: + "@babel/types" "^7.10.4" + +"@babel/helper-module-transforms@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.11.0.tgz#b16f250229e47211abdd84b34b64737c2ab2d359" + integrity sha512-02EVu8COMuTRO1TAzdMtpBPbe6aQ1w/8fePD2YgQmxZU4gpNWaL9gK3Jp7dxlkUlUCJOTaSeA+Hrm1BRQwqIhg== + dependencies: + "@babel/helper-module-imports" "^7.10.4" + "@babel/helper-replace-supers" "^7.10.4" + "@babel/helper-simple-access" "^7.10.4" + "@babel/helper-split-export-declaration" "^7.11.0" + "@babel/template" "^7.10.4" + "@babel/types" "^7.11.0" + lodash "^4.17.19" + +"@babel/helper-optimise-call-expression@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz#50dc96413d594f995a77905905b05893cd779673" + integrity sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg== + dependencies: + "@babel/types" "^7.10.4" + +"@babel/helper-replace-supers@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz#d585cd9388ea06e6031e4cd44b6713cbead9e6cf" + integrity sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.10.4" + "@babel/helper-optimise-call-expression" "^7.10.4" + "@babel/traverse" "^7.10.4" + "@babel/types" "^7.10.4" + +"@babel/helper-simple-access@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz#0f5ccda2945277a2a7a2d3a821e15395edcf3461" + integrity sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw== + dependencies: + "@babel/template" "^7.10.4" + "@babel/types" "^7.10.4" + +"@babel/helper-split-export-declaration@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz#f8a491244acf6a676158ac42072911ba83ad099f" + integrity sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg== + dependencies: + "@babel/types" "^7.11.0" + +"@babel/helper-validator-identifier@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz#a78c7a7251e01f616512d31b10adcf52ada5e0d2" + integrity sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw== + +"@babel/helpers@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.10.4.tgz#2abeb0d721aff7c0a97376b9e1f6f65d7a475044" + integrity sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA== + dependencies: + "@babel/template" "^7.10.4" + "@babel/traverse" "^7.10.4" + "@babel/types" "^7.10.4" + +"@babel/highlight@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.4.tgz#7d1bdfd65753538fabe6c38596cdb76d9ac60143" + integrity sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA== + dependencies: + "@babel/helper-validator-identifier" "^7.10.4" chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.6.0", "@babel/parser@^7.9.6": - version "7.10.2" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.10.2.tgz#871807f10442b92ff97e4783b9b54f6a0ca812d0" - integrity sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ== - -"@babel/parser@^7.7.5", "@babel/parser@^7.8.6", "@babel/parser@^7.9.0": - version "7.9.4" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.9.4.tgz#68a35e6b0319bbc014465be43828300113f2f2e8" - integrity sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA== - -"@babel/template@^7.7.4", "@babel/template@^7.8.3", "@babel/template@^7.8.6": - version "7.8.6" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.8.6.tgz#86b22af15f828dfb086474f964dcc3e39c43ce2b" - integrity sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg== - dependencies: - "@babel/code-frame" "^7.8.3" - "@babel/parser" "^7.8.6" - "@babel/types" "^7.8.6" - -"@babel/traverse@^7.7.4", "@babel/traverse@^7.8.6", "@babel/traverse@^7.9.0": - version "7.9.0" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.9.0.tgz#d3882c2830e513f4fe4cec9fe76ea1cc78747892" - integrity sha512-jAZQj0+kn4WTHO5dUZkZKhbFrqZE7K5LAQ5JysMnmvGij+wOdr+8lWqPeW0BcF4wFwrEXXtdGO7wcV6YPJcf3w== - dependencies: - "@babel/code-frame" "^7.8.3" - "@babel/generator" "^7.9.0" - "@babel/helper-function-name" "^7.8.3" - "@babel/helper-split-export-declaration" "^7.8.3" - "@babel/parser" "^7.9.0" - "@babel/types" "^7.9.0" +"@babel/parser@^7.10.4", "@babel/parser@^7.11.0", "@babel/parser@^7.6.0", "@babel/parser@^7.9.6": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.0.tgz#a9d7e11aead25d3b422d17b2c6502c8dddef6a5d" + integrity sha512-qvRvi4oI8xii8NllyEc4MDJjuZiNaRzyb7Y7lup1NqJV8TZHF4O27CcP+72WPn/k1zkgJ6WJfnIbk4jTsVAZHw== + +"@babel/template@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.4.tgz#3251996c4200ebc71d1a8fc405fba940f36ba278" + integrity sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/parser" "^7.10.4" + "@babel/types" "^7.10.4" + +"@babel/traverse@^7.10.4", "@babel/traverse@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.11.0.tgz#9b996ce1b98f53f7c3e4175115605d56ed07dd24" + integrity sha512-ZB2V+LskoWKNpMq6E5UUCrjtDUh5IOTAyIl0dTjIEoXum/iKWkoIEKIRDnUucO6f+2FzNkE0oD4RLKoPIufDtg== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/generator" "^7.11.0" + "@babel/helper-function-name" "^7.10.4" + "@babel/helper-split-export-declaration" "^7.11.0" + "@babel/parser" "^7.11.0" + "@babel/types" "^7.11.0" debug "^4.1.0" globals "^11.1.0" - lodash "^4.17.13" - -"@babel/types@^7.6.1", "@babel/types@^7.9.6": - version "7.10.2" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.10.2.tgz#30283be31cad0dbf6fb00bd40641ca0ea675172d" - integrity sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng== - dependencies: - "@babel/helper-validator-identifier" "^7.10.1" - lodash "^4.17.13" - to-fast-properties "^2.0.0" + lodash "^4.17.19" -"@babel/types@^7.8.3", "@babel/types@^7.8.6", "@babel/types@^7.9.0": - version "7.9.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.9.0.tgz#00b064c3df83ad32b2dbf5ff07312b15c7f1efb5" - integrity sha512-BS9JKfXkzzJl8RluW4JGknzpiUV7ZrvTayM6yfqLTVBEnFtyowVIOu6rqxRd5cVO6yGoWf4T8u8dgK9oB+GCng== +"@babel/types@^7.10.4", "@babel/types@^7.11.0", "@babel/types@^7.6.1", "@babel/types@^7.9.6": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.11.0.tgz#2ae6bf1ba9ae8c3c43824e5861269871b206e90d" + integrity sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA== dependencies: - "@babel/helper-validator-identifier" "^7.9.0" - lodash "^4.17.13" + "@babel/helper-validator-identifier" "^7.10.4" + lodash "^4.17.19" to-fast-properties "^2.0.0" "@istanbuljs/load-nyc-config@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.0.0.tgz#10602de5570baea82f8afbfa2630b24e7a8cfe5b" - integrity sha512-ZR0rq/f/E4f4XcgnDvtMWXCUJpi8eO0rssVhmztsZqLIEFA9UUP9zmpE0VxlM+kv/E1ul2I876Fwil2ayptDVg== + version "1.1.0" + resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" + integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== dependencies: camelcase "^5.3.1" find-up "^4.1.0" + get-package-type "^0.1.0" js-yaml "^3.13.1" resolve-from "^5.0.0" @@ -228,6 +209,14 @@ resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== +JSONStream@^1.3.5: + version "1.3.5" + resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" + integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ== + dependencies: + jsonparse "^1.2.0" + through ">=2.2.7 <3" + abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" @@ -254,12 +243,7 @@ acorn-jsx@^5.2.0: resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.2.0.tgz#4c66069173d6fdd68ed85239fc256226182b2ebe" integrity sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ== -acorn@^7.1.1: - version "7.2.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.2.0.tgz#17ea7e40d7c8640ff54a694c889c26f31704effe" - integrity sha512-apwXVmYVpQ34m/i71vrApRrRKCWQnZZF1+npOD0WV5xZFfwWOmKGQ2RWlfdy9vWITsenisM8M0Qeq8agcFHNiQ== - -acorn@^7.3.1: +acorn@^7.1.1, acorn@^7.3.1: version "7.3.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.3.1.tgz#85010754db53c3fbaf3b9ea3e083aa5c5d147ffd" integrity sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA== @@ -290,34 +274,16 @@ ajv@^4.9.1: co "^4.6.0" json-stable-stringify "^1.0.1" -ajv@^6.10.0, ajv@^6.10.2, ajv@^6.5.5: - version "6.12.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.0.tgz#06d60b96d87b8454a5adaba86e7854da629db4b7" - integrity sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw== +ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.3: + version "6.12.3" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.3.tgz#18c5af38a111ddeb4f2697bd78d68abc1cabd706" + integrity sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA== dependencies: fast-deep-equal "^3.1.1" fast-json-stable-stringify "^2.0.0" json-schema-traverse "^0.4.1" uri-js "^4.2.2" -almond-dialog-agent@~1.8.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/almond-dialog-agent/-/almond-dialog-agent-1.8.0.tgz#0b3e6ea0514c04974a3b243101a5f16d35749b9b" - integrity sha512-Zo/RcG15WJ9bSznD0tUmRNlEPCi9MqmbTKcmSf3WEre4vxaxLf9fwl+NSb4GaUQGTw4zfbkOXQh4rS9m4TNYGQ== - dependencies: - adt "^0.7.2" - consumer-queue "^1.0.0" - qs "^6.7.0" - string-interp "^0.1.0" - thingpedia "~2.7.0" - thingtalk "~1.10.0" - uuid "^7.0.0" - -another-json@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/another-json/-/another-json-0.2.0.tgz#b5f4019c973b6dd5c6506a2d93469cb6d32aeedc" - integrity sha1-tfQBnJc7bdXGUGotk0acttMq7tw= - ansi-align@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.0.tgz#b536b371cf687caaef236c18d3e21fe3797467cb" @@ -325,10 +291,10 @@ ansi-align@^3.0.0: dependencies: string-width "^3.0.0" -ansi-colors@^3.2.1: - version "3.2.4" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf" - integrity sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA== +ansi-colors@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== ansi-regex@^2.0.0: version "2.1.1" @@ -398,7 +364,7 @@ are-we-there-yet@~1.1.2: delegates "^1.0.0" readable-stream "^2.0.6" -argparse@^1.0.7: +argparse@^1.0.10, 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== @@ -472,7 +438,7 @@ asynckit@^0.4.0: resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= -available-typed-arrays@^1.0.0, available-typed-arrays@^1.0.1: +available-typed-arrays@^1.0.0, available-typed-arrays@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz#6b098ca9d8039079ee3f77f7b783c4480ba513f5" integrity sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ== @@ -490,17 +456,9 @@ aws-sign2@~0.7.0: integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= aws4@^1.2.1, aws4@^1.8.0: - version "1.9.1" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.1.tgz#7e33d8f7d449b3f673cd72deb9abdc552dbe528e" - integrity sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug== - -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" + version "1.10.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.10.0.tgz#a17b3a8ea811060e74d47d306122400ad4497ae2" + integrity sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA== babel-walk@3.0.0-canary-5: version "3.0.0-canary-5" @@ -529,9 +487,9 @@ bcrypt-pbkdf@^1.0.0: tweetnacl "^0.14.3" binary-extensions@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.0.0.tgz#23c0df14f6a88077f5f986c0d167ec03c3d5537c" - integrity sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow== + version "2.1.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.1.0.tgz#30fa40c9e7fe07dbc895678cd287024dea241dd9" + integrity sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ== bindings@^1.2.1, bindings@^1.3.1, bindings@~1.5.0: version "1.5.0" @@ -547,12 +505,7 @@ block-stream@*: dependencies: inherits "~2.0.0" -bluebird@^3.5.0: - version "3.7.2" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" - integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== - -body-parser@1.19.0, body-parser@^1.17.2: +body-parser@1.19.0, body-parser@^1.17.2, body-parser@^1.19.0: version "1.19.0" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== @@ -604,11 +557,6 @@ braces@~3.0.2: dependencies: fill-range "^7.0.1" -browser-request@^0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/browser-request/-/browser-request-0.3.3.tgz#9ece5b5aca89a29932242e18bf933def9876cc17" - integrity sha1-ns5bWsqJopkyJC4Yv5M975h2zBc= - byline@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/byline/-/byline-5.0.0.tgz#741c5216468eadc457b03410118ad77de8c1ddb1" @@ -683,9 +631,9 @@ chalk@^3.0.0: supports-color "^7.1.0" chalk@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.0.0.tgz#6e98081ed2d17faab615eb52ac66ec1fe6209e72" - integrity sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A== + version "4.1.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" + integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== dependencies: ansi-styles "^4.1.0" supports-color "^7.1.0" @@ -698,9 +646,9 @@ character-parser@^2.2.0: is-regex "^1.0.3" chokidar@^3.2.2: - version "3.3.1" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.3.1.tgz#c84e5b3d18d9a4d77558fef466b1bf16bbeb3450" - integrity sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg== + version "3.4.1" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.1.tgz#e905bdecf10eaa0a0b1db0c664481cc4cbc22ba1" + integrity sha512-TQTJyr2stihpC4Sya9hs2Xh+O2wf+igjL36Y75xx2WdHuiICcn/XJza46Jwt0eT5hVpQOzo3FpY3cj3RVYLX0g== dependencies: anymatch "~3.1.1" braces "~3.0.2" @@ -708,7 +656,7 @@ chokidar@^3.2.2: is-binary-path "~2.1.0" is-glob "~4.0.1" normalize-path "~3.0.0" - readdirp "~3.3.0" + readdirp "~3.4.0" optionalDependencies: fsevents "~2.1.2" @@ -722,6 +670,11 @@ ci-info@^2.0.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== +cities-list@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/cities-list/-/cities-list-1.0.3.tgz#cb217d19ea1f355fc833d173a752ad9992f1240c" + integrity sha1-yyF9GeofNV/IM9Fzp1KtmZLxJAw= + clean-stack@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" @@ -834,7 +787,7 @@ constantinople@^4.0.1: "@babel/parser" "^7.6.0" "@babel/types" "^7.6.1" -consumer-queue@^1.0.0, consumer-queue@^1.0.1: +consumer-queue@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/consumer-queue/-/consumer-queue-1.0.1.tgz#be0a8efcf9e3aa7e1ab0248d5c07f817c45b5276" integrity sha1-vgqO/Pnjqn4asCSNXAf4F8RbUnY= @@ -846,7 +799,7 @@ content-disposition@0.5.3: dependencies: safe-buffer "5.1.2" -content-type@^1.0.2, content-type@^1.0.4, content-type@~1.0.4: +content-type@^1.0.4, content-type@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== @@ -876,11 +829,6 @@ cookie@0.4.0: resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== -core-js@^2.4.0: - version "2.6.11" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.11.tgz#38831469f9922bded8ee21c9dc46985e0399308c" - integrity sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg== - 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" @@ -945,6 +893,16 @@ csurf@^1.9.0: csrf "3.1.0" http-errors "~1.7.3" +csv-parse@^4.4.5: + version "4.11.1" + resolved "https://registry.yarnpkg.com/csv-parse/-/csv-parse-4.11.1.tgz#3935a7862d7e431020a25538905dec0153fa75bd" + integrity sha512-cH2BG5Gd0u4G8qVI/jGXJSP2+El7Vy91/ZD3ehKALAWids1aIKOPhZ1ZVJzUrs2zTn6aGumVPBlbHsI91kI83A== + +csv-stringify@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/csv-stringify/-/csv-stringify-5.5.0.tgz#0bdeaaf60d6e15b89c752a0eceb4b4c2c8af5a8a" + integrity sha512-G05575DSO/9vFzQxZN+Srh30cNyHk0SM0ePyiTChMD5WVt7GMTVPBQf4rtgMF6mqhNCJUPw4pN8LDe8MF9EYOA== + dashdash@^1.12.0: version "1.14.1" resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" @@ -1000,10 +958,10 @@ decompress-response@^3.3.0: dependencies: mimic-response "^1.0.0" -deep-equal@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.0.2.tgz#e68291e245493ae908ca7190c1deea57a01ed82b" - integrity sha512-kX0bjV7tdMuhrhzKPEnVwqfQCuf+IEfN+4Xqv4eKd75xGRyn8yzdQ9ujPY6a221rgJKyQC4KBu1PibDTpa6m9w== +deep-equal@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.0.3.tgz#cad1c15277ad78a5c01c49c2dee0f54de8a6a7b0" + integrity sha512-Spqdl4H+ky45I9ByyJtXteOm9CaIrPmnIPmOhrkKGNYWeDgCvJ8jNYVCTjChxW4FqGuZnLHADc8EKRMX6+CgvA== dependencies: es-abstract "^1.17.5" es-get-iterator "^1.1.0" @@ -1011,13 +969,14 @@ deep-equal@^2.0.1: is-date-object "^1.0.2" is-regex "^1.0.5" isarray "^2.0.5" - object-is "^1.0.2" + object-is "^1.1.2" object-keys "^1.1.1" + object.assign "^4.1.0" regexp.prototype.flags "^1.3.0" side-channel "^1.0.2" which-boxed-primitive "^1.0.1" which-collection "^1.0.1" - which-typed-array "^1.1.1" + which-typed-array "^1.1.2" deep-extend@^0.6.0: version "0.6.0" @@ -1130,17 +1089,46 @@ emoji-regex@^8.0.0: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== +en-inflectors@^1.0.12, en-inflectors@^1.0.7: + version "1.0.12" + resolved "https://registry.yarnpkg.com/en-inflectors/-/en-inflectors-1.0.12.tgz#fd334776608a021cb4202157f20d52ab934af78a" + integrity sha1-/TNHdmCKAhy0ICFX8g1Sq5NK94o= + dependencies: + en-stemmer "^1.0.2" + +en-lexicon@^1.0.8: + version "1.0.11" + resolved "https://registry.yarnpkg.com/en-lexicon/-/en-lexicon-1.0.11.tgz#3f4da8a9cca9a906f510b8ece11631be3fd1105f" + integrity sha1-P02oqcypqQb1ELjs4RYxvj/REF8= + dependencies: + en-inflectors "^1.0.7" + +en-pos@^1.0.16: + version "1.0.16" + resolved "https://registry.yarnpkg.com/en-pos/-/en-pos-1.0.16.tgz#5b6ee67eed52a8e11267f3d15fa7501101123fb0" + integrity sha1-W27mfu1SqOESZ/PRX6dQEQESP7A= + dependencies: + cities-list "^1.0.3" + en-inflectors "^1.0.7" + en-lexicon "^1.0.8" + humannames "^1.0.5" + +en-stemmer@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/en-stemmer/-/en-stemmer-1.0.3.tgz#2d22fb5db9005a88d6fc58026b38a831c8bc7c19" + integrity sha1-LSL7XbkAWojW/FgCazioMci8fBk= + encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= -encoding@^0.1.12: - version "0.1.12" - resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" - integrity sha1-U4tm8+5izRq1HsMjgp0flIDHS+s= +encoding@^0.1.13: + version "0.1.13" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" + integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== dependencies: - iconv-lite "~0.4.13" + iconv-lite "^0.6.2" end-of-stream@^1.1.0: version "1.4.4" @@ -1150,13 +1138,13 @@ end-of-stream@^1.1.0: once "^1.4.0" enquirer@^2.3.5: - version "2.3.5" - resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.5.tgz#3ab2b838df0a9d8ab9e7dff235b0e8712ef92381" - integrity sha512-BNT1C08P9XD0vNg3J475yIUG+mVdp9T6towYFHUv897X0KoHBjB1shyrNmhmtHWKP17iSWgo7Gqh7BBuzLZMSA== + version "2.3.6" + resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" + integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== dependencies: - ansi-colors "^3.2.1" + ansi-colors "^4.1.1" -errorhandler@^1.5.0: +errorhandler@^1.5.0, errorhandler@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/errorhandler/-/errorhandler-1.5.1.tgz#b9ba5d17cf90744cd1e851357a6e75bf806a9a91" integrity sha512-rcOwbfvP1WTViVoUjcfZicVzjhjTuhSMntHh6mW3IrEiyE6mJyXvsToJUJGlGlw/2xU9P5whlWNGlIDVeCiT4A== @@ -1165,21 +1153,21 @@ errorhandler@^1.5.0: escape-html "~1.0.3" es-abstract@^1.17.0-next.1, es-abstract@^1.17.4, es-abstract@^1.17.5: - version "1.17.5" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.5.tgz#d8c9d1d66c8981fb9200e2251d799eee92774ae9" - integrity sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg== + version "1.17.6" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.6.tgz#9142071707857b2cacc7b89ecb670316c3e2d52a" + integrity sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw== dependencies: 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" + is-callable "^1.2.0" + is-regex "^1.1.0" 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" + string.prototype.trimend "^1.0.1" + string.prototype.trimstart "^1.0.1" es-get-iterator@^1.1.0: version "1.1.0" @@ -1244,9 +1232,9 @@ eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== eslint@^7.5.0: - version "7.5.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.5.0.tgz#9ecbfad62216d223b82ac9ffea7ef3444671d135" - integrity sha512-vlUP10xse9sWt9SGRtcr1LAC67BENcQMFeV+w5EvLEoFe3xJ8cF1Skd0msziRx/VMC+72B4DxreCE+OR12OA6Q== + version "7.6.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.6.0.tgz#522d67cfaea09724d96949c70e7a0550614d64d6" + integrity sha512-QlAManNtqr7sozWm5TF4wIH9gmUm2hE3vNRUvyoYAa4y1l5/jxD/PQStEjBMQtCqZmSep8UxrcecI60hOpe61w== dependencies: "@babel/code-frame" "^7.0.0" ajv "^6.10.0" @@ -1367,7 +1355,7 @@ express-ws@^4.0.0: dependencies: ws "^5.2.0" -express@^4.15.3: +express@^4.15.3, express@^4.17.1: version "4.17.1" resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== @@ -1419,9 +1407,9 @@ extsprintf@^1.2.0: integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= fast-deep-equal@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4" - integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA== + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== fast-json-stable-stringify@^2.0.0: version "2.1.0" @@ -1434,9 +1422,9 @@ fast-levenshtein@^2.0.6: integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= feedparser@^2.2.9: - version "2.2.9" - resolved "https://registry.yarnpkg.com/feedparser/-/feedparser-2.2.9.tgz#9138197dafdae05fcadde0036beeaf6066c2c5e9" - integrity sha1-kTgZfa/a4F/K3eADa+6vYGbCxek= + version "2.2.10" + resolved "https://registry.yarnpkg.com/feedparser/-/feedparser-2.2.10.tgz#d3fa509e7d64761dfa037bbbe563df9d52dfb038" + integrity sha512-WoAOooa61V8/xuKMi2pEtK86qQ3ZH/M72EEGdqlOTxxb3m6ve1NPvZcmPFs3wEDfcBbFLId2GqZ4YjsYi+h1xA== dependencies: addressparser "^1.0.1" array-indexofobject "~0.0.1" @@ -1444,8 +1432,8 @@ feedparser@^2.2.9: lodash.get "^4.4.2" lodash.has "^4.5.2" lodash.uniq "^4.5.0" - mri "^1.1.0" - readable-stream "^2.2.2" + mri "^1.1.5" + readable-stream "^2.3.7" sax "^1.2.4" file-entry-cache@^5.0.1: @@ -1511,6 +1499,11 @@ flatted@^2.0.0: resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== +flex-js@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/flex-js/-/flex-js-1.0.5.tgz#1b9a3fda1d080e83aed217a9caca01a4d33286c0" + integrity sha512-Z5uoLzOGtTB/nzaTVVBbwmxOHBzHovAGJHLXE1TUKsQuN1RRWMOWeA08J9RRKtAl9TH9tkaH6fpjA4sLf0DzQw== + foreach@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" @@ -1563,9 +1556,9 @@ from@^0.1.7: integrity sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4= fromentries@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/fromentries/-/fromentries-1.2.0.tgz#e6aa06f240d6267f913cea422075ef88b63e7897" - integrity sha512-33X7H/wdfO99GdRLLgkjUrD4geAFdq/Uv0kl3HD4da6HDixd2GUg8Mw7dahLCV9r/EARkmtYBB6Tch4EEokFTQ== + version "1.2.1" + resolved "https://registry.yarnpkg.com/fromentries/-/fromentries-1.2.1.tgz#64c31665630479bc993cd800d53387920dc61b4d" + integrity sha512-Xu2Qh8yqYuDhQGOhD5iJGninErSfI9A3FrriD3tjUgV5VbJFeH8vfgZ9HnC6jWN80QDVNQK5vmxRAmEAp7Mevw== fs-minipass@^1.2.5: version "1.2.7" @@ -1580,9 +1573,9 @@ fs.realpath@^1.0.0: integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= fsevents@~2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.2.tgz#4c0a1fb34bc68e543b4b82a9ec392bfbda840805" - integrity sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA== + version "2.1.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" + integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== fstream-ignore@^1.0.5: version "1.0.5" @@ -1627,6 +1620,43 @@ gauge@~2.7.3: strip-ansi "^3.0.1" wide-align "^1.1.0" +genie-toolkit@^0.7.0-beta.4: + version "0.7.0-beta.4" + resolved "https://registry.yarnpkg.com/genie-toolkit/-/genie-toolkit-0.7.0-beta.4.tgz#15181b200bb21009639d2acecd8ce6f82ad38617" + integrity sha512-ZgCMOjDF59xzfHMYZ5AD8NEFli1WIKUi3Mhzko7ta9XbIKGgXCtpFgkYyOUF6JRKa2hFwHwLylrkkZAG4IDaJg== + dependencies: + JSONStream "^1.3.5" + adt "^0.7.2" + argparse "^1.0.10" + body-parser "^1.19.0" + byline "^5.0.0" + consumer-queue "^1.0.0" + csv-parse "^4.4.5" + csv-stringify "^5.3.0" + deep-equal "^2.0.3" + en-inflectors "^1.0.12" + en-pos "^1.0.16" + errorhandler "^1.5.1" + express "^4.17.1" + flex-js "^1.0.5" + ip "^1.1.5" + js-yaml "^3.14.0" + morgan "^1.9.1" + node-gettext "^3.0.0" + q "^1.5.0" + qs "^6.7.0" + query-validation "^0.1.0" + seedrandom "^3.0.0" + sockaddr "^1.0.1" + sqlite3 "^5.0.0" + stemmer "^1.0.5" + string-interp "^0.3.1" + thingpedia "~2.8.0-beta.1" + thingtalk "~1.11.0-beta.2" + thingtalk-units "^0.1.0" + uuid "^8.2.0" + ws "^7.3.0" + gensync@^1.0.0-beta.1: version "1.0.0-beta.1" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269" @@ -1664,14 +1694,14 @@ getpass@^0.1.1: assert-plus "^1.0.0" gettext-parser@^4.0.2: - version "4.0.3" - resolved "https://registry.yarnpkg.com/gettext-parser/-/gettext-parser-4.0.3.tgz#bfb26f22fdd51c080f55c398eb5b0f12328e7353" - integrity sha512-FGzzgAtSJuhFZGKNlV8AGjuBic1MoJXL2hlfS55JlCeMgyvG5XbY/Zje/Cx78gnLh+oO8WMIHp6kh7/j3CLx9A== + version "4.0.4" + resolved "https://registry.yarnpkg.com/gettext-parser/-/gettext-parser-4.0.4.tgz#bd5eb4af282336c8bf83f607d35f0839853b9670" + integrity sha512-VDZEeOIYd0veZXt5iAn0SS3I0Fz14fJw+59avRNa7VIslEDriRLxcfrBd/xeQyOcm6nyS4uuufxm2iw88qirAg== dependencies: content-type "^1.0.4" - encoding "^0.1.12" + encoding "^0.1.13" readable-stream "^3.6.0" - safe-buffer "^5.2.0" + safe-buffer "^5.2.1" glob-parent@^5.0.0, glob-parent@~5.1.0: version "5.1.1" @@ -1739,9 +1769,9 @@ got@^9.6.0: url-parse-lax "^3.0.0" graceful-fs@^4.1.15, graceful-fs@^4.1.2: - version "4.2.3" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" - integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== + version "4.2.4" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" + integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== har-schema@^1.0.5: version "1.0.5" @@ -1762,11 +1792,11 @@ har-validator@~4.2.1: har-schema "^1.0.5" har-validator@~5.1.3: - version "5.1.3" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" - integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== + version "5.1.5" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" + integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== dependencies: - ajv "^6.5.5" + ajv "^6.12.3" har-schema "^2.0.0" has-flag@^3.0.0: @@ -1879,13 +1909,25 @@ http-signature@~1.2.0: jsprim "^1.2.2" sshpk "^1.7.0" -iconv-lite@0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13: +humannames@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/humannames/-/humannames-1.0.5.tgz#a4d60d4168df8737f4b262efd23f2ee32974f1c5" + integrity sha1-pNYNQWjfhzf0smLv0j8u4yl08cU= + +iconv-lite@0.4.24, 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" +iconv-lite@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.2.tgz#ce13d1875b0c3a674bd6a04b7f76b01b1b6ded01" + integrity sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + ignore-by-default@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" @@ -1986,10 +2028,10 @@ is-boolean-object@^1.0.0: resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.0.1.tgz#10edc0900dd127697a92f6f9807c7617d68ac48e" integrity sha512-TqZuVwa/sppcrhUCAYkGBk7w0yxfQQnxq28fjkO53tnK9FQXmdwz2JS5+GjsWQ6RByES1K40nI+yDic5c9/aAQ== -is-callable@^1.1.4, is-callable@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab" - integrity sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q== +is-callable@^1.1.4, is-callable@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.0.tgz#83336560b54a38e35e3a2df7afd0454d691468bb" + integrity sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw== is-ci@^2.0.0: version "2.0.0" @@ -2079,16 +2121,16 @@ is-path-inside@^3.0.1: integrity sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg== is-promise@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" - integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= + version "2.2.2" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.2.2.tgz#39ab959ccbf9a774cf079f7b40c7a26f763135f1" + integrity sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ== -is-regex@^1.0.3, is-regex@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae" - integrity sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ== +is-regex@^1.0.3, is-regex@^1.0.5, is-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.0.tgz#ece38e389e490df0dc21caea2bd596f987f767ff" + integrity sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw== dependencies: - has "^1.0.3" + has-symbols "^1.0.1" is-set@^2.0.1: version "2.0.1" @@ -2180,14 +2222,11 @@ istanbul-lib-hook@^3.0.0: append-transform "^2.0.0" istanbul-lib-instrument@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.1.tgz#61f13ac2c96cfefb076fe7131156cc05907874e6" - integrity sha512-imIchxnodll7pvQBYOqUu88EufLCU56LMeFPZZM/fJZ1irYcYdqroaV+ACK1Ila8ls09iEYArp+nqyC6lW1Vfg== + version "4.0.3" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz#873c6fff897450118222774696a3f28902d77c1d" + integrity sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ== dependencies: "@babel/core" "^7.7.5" - "@babel/parser" "^7.7.5" - "@babel/template" "^7.7.4" - "@babel/traverse" "^7.7.4" "@istanbuljs/schema" "^0.1.2" istanbul-lib-coverage "^3.0.0" semver "^6.3.0" @@ -2241,10 +2280,10 @@ js-tokens@^4.0.0: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-yaml@^3.13.1: - version "3.13.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" - integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== +js-yaml@^3.13.1, js-yaml@^3.14.0: + version "3.14.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.0.tgz#a7a34170f26a21bb162424d8adacb4113a69e482" + integrity sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A== dependencies: argparse "^1.0.7" esprima "^4.0.0" @@ -2292,9 +2331,9 @@ json-stringify-safe@~5.0.1: integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= json5@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.2.tgz#43ef1f0af9835dd624751a6b7fa48874fb2d608e" - integrity sha512-MoUOQ4WdiN3yxhm7NEVJSJrieAo5hNSLQ5sj05OTRHPL9HOBy8u4Bu88jsC1jvqAdN+E1bJmsUcZH+1HQxliqQ== + version "2.1.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43" + integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA== dependencies: minimist "^1.2.5" @@ -2303,6 +2342,11 @@ jsonify@~0.0.0: resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= +jsonparse@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" + integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA= + jsprim@^1.2.2: version "1.4.1" resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" @@ -2322,9 +2366,9 @@ jstransformer@1.0.0: promise "^7.0.1" jszip@^3.2.2: - version "3.3.0" - resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.3.0.tgz#29d72c21a54990fa885b11fc843db320640d5271" - integrity sha512-EJ9k766htB1ZWnsV5ZMDkKLgA+201r/ouFF8R2OigVjVdcm2rurcBrrdXaeqBJbqnUVMko512PYmlncBKE1Huw== + version "3.5.0" + resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.5.0.tgz#b4fd1f368245346658e781fec9675802489e15f6" + integrity sha512-WRtu7TPCmYePR1nazfrtuF216cIVon/3GWOvHS9QR5bIwSbnxtdpma6un3jyGGNhHsKCSzn5Ypk+EkDRvTGiFA== dependencies: lie "~3.3.0" pako "~1.0.2" @@ -2397,7 +2441,7 @@ lodash.uniq@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= -lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.19: +lodash@^4.17.14, lodash@^4.17.19: version "4.17.19" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b" integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ== @@ -2431,9 +2475,9 @@ lru-cache@^4.0.1: yallist "^2.1.2" make-dir@^3.0.0, make-dir@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.0.2.tgz#04a1acbf22221e1d6ef43559f43e05a90dbb4392" - integrity sha512-rYKABKutXa6vXTXhoV18cBE7PaewPXHe/Bdq4v+ZLMhxbWApkFFplT0LcbMW+6BbjnQXzZ/sAvSE/JdguApG5w== + version "3.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== dependencies: semver "^6.0.0" @@ -2442,18 +2486,6 @@ map-stream@0.0.7: resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.0.7.tgz#8a1f07896d82b10926bd3744a2420009f88974a8" integrity sha1-ih8HiW2CsQkmvTdEokIACfiJdKg= -matrix-js-sdk@0.9.2: - version "0.9.2" - resolved "https://registry.yarnpkg.com/matrix-js-sdk/-/matrix-js-sdk-0.9.2.tgz#2a521bddcf637cbefde9138784e627ea43645b77" - integrity sha1-KlIb3c9jfL796ROHhOYn6kNkW3c= - dependencies: - another-json "^0.2.0" - babel-runtime "^6.26.0" - bluebird "^3.5.0" - browser-request "^0.3.3" - content-type "^1.0.2" - request "^2.53.0" - media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" @@ -2469,17 +2501,17 @@ methods@~1.1.2: resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= -mime-db@1.43.0: - version "1.43.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.43.0.tgz#0a12e0502650e473d735535050e7c8f4eb4fae58" - integrity sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ== +mime-db@1.44.0: + version "1.44.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" + integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== mime-types@^2.1.12, mime-types@~2.1.19, mime-types@~2.1.24, mime-types@~2.1.7: - version "2.1.26" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.26.tgz#9c921fc09b7e149a65dfdc0da4d20997200b0a06" - integrity sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ== + version "2.1.27" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" + integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== dependencies: - mime-db "1.43.0" + mime-db "1.44.0" mime@1.6.0: version "1.6.0" @@ -2530,7 +2562,7 @@ minizlib@^1.2.1: dependencies: minimist "^1.2.5" -morgan@^1.8.2: +morgan@^1.8.2, morgan@^1.9.1: version "1.10.0" resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.10.0.tgz#091778abc1fc47cd3509824653dae1faab6b17d7" integrity sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ== @@ -2541,10 +2573,10 @@ morgan@^1.8.2: on-finished "~2.3.0" on-headers "~1.0.2" -mri@^1.1.0: - version "1.1.5" - resolved "https://registry.yarnpkg.com/mri/-/mri-1.1.5.tgz#ce21dba2c69f74a9b7cf8a1ec62307e089e223e0" - integrity sha512-d2RKzMD4JNyHMbnbWnznPaa8vbdlq/4pNZ3IgdaGrVbBhebBsGUUE/6qorTMYNS6TwuH3ilfOlD2bf4Igh8CKg== +mri@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/mri/-/mri-1.1.6.tgz#49952e1044db21dbf90f6cd92bc9c9a777d415a6" + integrity sha512-oi1b3MfbyGa7FJMP9GmLTttni5JoICpYBRlq+x5V16fZbLsnL9N3wFqqIm/nIG43FjUFkFh9Epzp/kzUGUnJxQ== ms@2.0.0: version "2.0.0" @@ -2572,9 +2604,9 @@ natural-compare@^1.4.0: integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= needle@^2.2.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/needle/-/needle-2.4.1.tgz#14af48732463d7475696f937626b1b993247a56a" - integrity sha512-x/gi6ijr4B7fwl6WYL9FwlCvRQKGlUNvnceho8wxkwXqN8jvVmmmATTmZPRRG7b/yC1eode26C2HO9jl78Du9g== + version "2.5.0" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.5.0.tgz#e6fc4b3cc6c25caed7554bd613a5cf0bac8c31c0" + integrity sha512-o/qITSDR0JCyCKEQ1/1bnUXMmznxabbwi/Y4WwJElf+evwJNFNwIDMCCt5IigFVxgeGBJESLohGtIS9gEzo1fA== dependencies: debug "^3.2.6" iconv-lite "^0.4.4" @@ -2801,14 +2833,17 @@ object-assign@^4.1.0, object-assign@^4.1.1: integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= object-inspect@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67" - integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw== + version "1.8.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.8.0.tgz#df807e5ecf53a609cc6bfe93eac3cc7be5b3a9d0" + integrity sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA== -object-is@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.0.2.tgz#6b80eb84fe451498f65007982f035a5b445edec4" - integrity sha512-Epah+btZd5wrrfjkJZq1AOB9O6OxUQto45hzFd7lXGrpHPGE0W1k+426yrZV+k6NJOzLNNW/nVsmZdIWsAqoOQ== +object-is@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.2.tgz#c5d2e87ff9e119f78b7a088441519e2eec1573b6" + integrity sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: version "1.1.1" @@ -2888,9 +2923,9 @@ p-cancelable@^1.0.0: integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== p-limit@^2.2.0: - version "2.2.2" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.2.tgz#61279b67721f5287aa1c13a9a7fbbc48c9291b1e" - integrity sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ== + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== dependencies: p-try "^2.0.0" @@ -2946,9 +2981,9 @@ parent-module@^1.0.0: callsites "^3.0.0" parse5@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.0.tgz#d2ac3448289c84b49947d49a39f7bef6200fa6ba" - integrity sha512-lC0A+4DefTdRr+DLQlEwwZqndL9VzEjiuegI5bj3hp4bnzzwQldSqCpHv7+msRpSOHGJyJvkcCa4q15LMUJ8rg== + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" + integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== parseurl@~1.3.2, parseurl@~1.3.3: version "1.3.3" @@ -3022,7 +3057,7 @@ performance-now@^2.1.0: resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= -picomatch@^2.0.4, picomatch@^2.0.7: +picomatch@^2.0.4, picomatch@^2.2.1: version "2.2.2" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== @@ -3087,9 +3122,9 @@ psl@^1.1.28: integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== pstree.remy@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.7.tgz#c76963a28047ed61542dc361aa26ee55a7fa15f3" - integrity sha512-xsMgrUwRpuGskEzBFkH8NmTimbZ5PcPup0LA8JJkHIm2IMUbQcpo3yeLNWVrufEYjh8YwtSVh0xz6UeWc5Oh5A== + version "1.1.8" + resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.8.tgz#c242224f4a67c21f686839bbdb4ac282b8373d3a" + integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w== pug-attrs@^3.0.0: version "3.0.0" @@ -3194,10 +3229,10 @@ pug@^3.0.0: pug-runtime "^3.0.0" pug-strip-comments "^2.0.0" -pulseaudio2@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/pulseaudio2/-/pulseaudio2-0.3.2.tgz#3d06ad535bbe26286b9a6dcc543df9b66ad8f54e" - integrity sha512-pizI/DyUIQoRW5i/dS/wjrtqzpKYKSaoIUp92TOIu3jQavC6VrdCUIjomGDLhx0LXXu5VdRK3TYn9qaWd8FLjQ== +pulseaudio2@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/pulseaudio2/-/pulseaudio2-0.3.3.tgz#f06c4d306948182318a0faf4b4603f5c212a86f4" + integrity sha512-OLtThHLd6yPPkFg7ysZ7i0xx/8BV+w75/0ZScdBRD1Gvctef4BBXolGJfETGf07TxtlCKQcgLZ6gFSm2oJLXLg== dependencies: bindings "^1.3.1" nan "^2.14.1" @@ -3243,9 +3278,9 @@ qs@6.7.0: integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== qs@^6.7.0: - version "6.9.3" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.3.tgz#bfadcd296c2d549f1dffa560619132c977f5008e" - integrity sha512-EbZYNarm6138UKKq46tdx08Yo/q9ZhFoAXAI1meAFd2GtbRDhbZY2WQSICskT0c5q99aFzLG1D4nvTk9tqfXIw== + version "6.9.4" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.4.tgz#9090b290d1f91728d3c22e54843ca44aea5ab687" + integrity sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ== qs@~6.4.0: version "6.4.0" @@ -3257,6 +3292,13 @@ qs@~6.5.2: resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== +query-validation@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/query-validation/-/query-validation-0.1.0.tgz#c70b787129b115fc44e1dd101afb15d74a46c711" + integrity sha512-YNTJpfr60PHq9uWy++OiJB2Q/9YNU3QF2tXEbkBSrcCbrfst/F5gTI+GCHB/Tn9Bvox70kl4aD3y7ExH8dEOiw== + dependencies: + type-is "^1.6.18" + random-bytes@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/random-bytes/-/random-bytes-1.0.0.tgz#4f68a1dc0ae58bd3fb95848c30324db75d64360b" @@ -3287,7 +3329,7 @@ rc@^1.1.7, rc@^1.2.7, rc@^1.2.8: minimist "^1.2.0" strip-json-comments "~2.0.1" -readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.2.2, readable-stream@~2.3.6: +readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.3.7, readable-stream@~2.3.6: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== @@ -3309,17 +3351,12 @@ readable-stream@^3.6.0: string_decoder "^1.1.1" util-deprecate "^1.0.1" -readdirp@~3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.3.0.tgz#984458d13a1e42e2e9f5841b129e162f369aff17" - integrity sha512-zz0pAkSPOXXm1viEwygWIPSPkcBYjW1xU5j/JBh5t9bGCJwa6f9+BJa6VaB2g+b55yVrmXzqkyLf4xaWYM0IkQ== +readdirp@~3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.4.0.tgz#9fdccdf9e9155805449221ac645e8303ab5b9ada" + integrity sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ== dependencies: - picomatch "^2.0.7" - -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== + picomatch "^2.2.1" regexp.prototype.flags@^1.3.0: version "1.3.0" @@ -3335,9 +3372,9 @@ regexpp@^3.1.0: integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q== registry-auth-token@^4.0.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-4.1.1.tgz#40a33be1e82539460f94328b0f7f0f84c16d9479" - integrity sha512-9bKS7nTl9+/A1s7tnPeGrUpRcVY+LUh7bfFgzpndALdPfXQBfQV77rQVtqgUV3ti4vc/Ik81Ex8UJDWDQ12zQA== + version "4.2.0" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-4.2.0.tgz#1d37dffda72bbecd0f581e4715540213a65eb7da" + integrity sha512-P+lWzPrsgfN+UEpDS3U8AQKg/UjZX6mQSJueZj3EK+vNESoqBSpBUD3gmu4sF9lOsjXWjF11dQKUqemf3veq1w== dependencies: rc "^1.2.8" @@ -3383,7 +3420,7 @@ request@2.81.0: tunnel-agent "^0.6.0" uuid "^3.0.0" -request@^2.53.0, request@^2.87.0, request@^2.88.2: +request@^2.87.0, request@^2.88.2: version "2.88.2" resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== @@ -3429,20 +3466,13 @@ resolve-from@^5.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== -resolve@^1.15.1: +resolve@^1.15.1, resolve@^1.3.2: version "1.17.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== dependencies: path-parse "^1.0.6" -resolve@^1.3.2: - version "1.15.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.1.tgz#27bdcdeffeaf2d6244b95bb0f9f4b4653451f3e8" - integrity sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w== - dependencies: - path-parse "^1.0.6" - responselike@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" @@ -3450,7 +3480,7 @@ responselike@^1.0.2: dependencies: lowercase-keys "^1.0.0" -rimraf@2, rimraf@^2.5.1, rimraf@^2.6.1, rimraf@^2.6.3, rimraf@^2.7.1: +rimraf@2, rimraf@^2.5.1, rimraf@^2.6.1, rimraf@^2.7.1: version "2.7.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== @@ -3486,12 +3516,17 @@ safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@5.2.0, safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: +safe-buffer@5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== -"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: +safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.1, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", 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== @@ -3501,6 +3536,11 @@ sax@>=0.6.0, sax@^1.2.4: resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== +seedrandom@^3.0.0: + version "3.0.5" + resolved "https://registry.yarnpkg.com/seedrandom/-/seedrandom-3.0.5.tgz#54edc85c95222525b0c7a6f6b3543d8e0b3aa0a7" + integrity sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg== + selenium-webdriver@^4.0.0-alpha.5: version "4.0.0-alpha.7" resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-4.0.0-alpha.7.tgz#e3879d8457fd7ad8e4424094b7dc0540d99e6797" @@ -3527,7 +3567,7 @@ semver@^6.0.0, semver@^6.2.0, semver@^6.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -semver@^7.2.1: +semver@^7.2.1, semver@^7.3.2: version "7.3.2" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== @@ -3647,6 +3687,11 @@ sntp@1.x.x: dependencies: hoek "2.x.x" +sockaddr@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sockaddr/-/sockaddr-1.0.1.tgz#6dd525c9122641ff2a083fdc09dfd56e9d1b1854" + integrity sha512-dWExeYQghPJLBI9w7G802J++g+d/9PscIMxzlIbTKsLrgrW8nZPV68z+D3JjOSVkqjc8hVm0oAyt3XUI1g/yqg== + source-map@^0.5.0: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" @@ -3681,14 +3726,6 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= -sqlite3@^4.0.2: - version "4.2.0" - resolved "https://registry.yarnpkg.com/sqlite3/-/sqlite3-4.2.0.tgz#49026d665e9fc4f922e56fb9711ba5b4c85c4901" - integrity sha512-roEOz41hxui2Q7uYnWsjMOTry6TcNUNmp8audCx18gF10P2NknwdpF+E+HKvz/F2NvPKGGBF4NGc+ZPQ+AABwg== - dependencies: - nan "^2.12.1" - node-pre-gyp "^0.11.0" - sqlite3@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/sqlite3/-/sqlite3-5.0.0.tgz#1bfef2151c6bc48a3ab1a6c126088bb8dd233566" @@ -3719,6 +3756,11 @@ sshpk@^1.7.0: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= +stemmer@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/stemmer/-/stemmer-1.0.5.tgz#fd89beaf8bff5d04b6643bfffcaed0fc420deec0" + integrity sha512-SLq7annzSKRDStasOJJoftCSCzBCKmBmH38jC4fDtCunAqOzpTpIm9zmaHmwNJiZ8gLe9qpVdBVbEG2DC5dE2A== + stream-combiner@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.2.2.tgz#aec8cbac177b56b6f4fa479ced8c1912cee52858" @@ -3727,10 +3769,10 @@ stream-combiner@^0.2.2: duplexer "~0.1.1" through "~2.3.4" -string-interp@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/string-interp/-/string-interp-0.1.0.tgz#d1501e268ffcf4723ac15ea9f14486870bed92b7" - integrity sha512-IpdjjxHgiO+AKlhmeUSl4U/M/vLf/Qy5t5MwG/Ij8+l8yNBemLgjgtn13WCKaw78FrKi1DDKrs0gnDJnMiUgBw== +string-interp@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/string-interp/-/string-interp-0.3.1.tgz#27f14d690828e1a88eaa11d6145d234933b84e3c" + integrity sha512-SObZ/Gzoe0YTH3B8tD5/hPyX3SksgUV0Az+MCLl7Pzh40BTAysC1A46rDRzOEdREegU0iTrpFwBhc/Jc0MKyzQ== dependencies: thingtalk-units "^0.1.0" @@ -3769,36 +3811,18 @@ string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.0" -string.prototype.trimend@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.0.tgz#ee497fd29768646d84be2c9b819e292439614373" - integrity sha512-EEJnGqa/xNfIg05SxiPSqRS7S9qwDhYts1TSLR1BQfYUfPe1stofgGKvwERK9+9yf+PpfBMlpBaCHucXGPQfUA== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.5" - -string.prototype.trimleft@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz#4408aa2e5d6ddd0c9a80739b087fbc067c03b3cc" - integrity sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.5" - string.prototype.trimstart "^1.0.0" - -string.prototype.trimright@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz#c76f1cef30f21bbad8afeb8db1511496cfb0f2a3" - integrity sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg== +string.prototype.trimend@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz#85812a6b847ac002270f5808146064c995fb6913" + integrity sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g== dependencies: define-properties "^1.1.3" es-abstract "^1.17.5" - string.prototype.trimend "^1.0.0" -string.prototype.trimstart@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.0.tgz#afe596a7ce9de905496919406c9734845f01a2f2" - integrity sha512-iCP8g01NFYiiBOnwG1Xc3WZLyoo+RuBymwIlWncShXDDJYWN6DbnM3odslBJdgCdRlq94B5s63NWAZlcn2CS4w== +string.prototype.trimstart@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz#14af6d9f34b053f7cfc89b72f8f2ee14b9039a54" + integrity sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw== dependencies: define-properties "^1.1.3" es-abstract "^1.17.5" @@ -3856,9 +3880,9 @@ strip-bom@^4.0.0: integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== strip-json-comments@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.0.tgz#7638d31422129ecf4457440009fba03f9f9ac180" - integrity sha512-e6/d0eBu7gHtdCqFt0xJr642LdToM5/cN4Qb9DbHjVx1CP5RyeM+zH7pbecEmDv/lBqb0QH+6Uqq75rxFPkM0w== + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== strip-json-comments@~2.0.1: version "2.0.1" @@ -3944,25 +3968,6 @@ text-table@^0.2.0: resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= -thingengine-core@~1.8.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/thingengine-core/-/thingengine-core-1.8.0.tgz#b2ad35819e0d67946aee28e8a9c01e9e398daee1" - integrity sha512-34c6lyhYnPZnJe6rgQgt+HoNKhg+CibE9lTDRyMzwzYbSuyrvdrhmq+YI1LvTcLFOmKeuV0kJFDLTJrnlTk7AQ== - dependencies: - adt "^0.7.2" - consumer-queue "^1.0.1" - deep-equal "^2.0.1" - ip "^1.1.5" - matrix-js-sdk "0.9.2" - q "^1.5.0" - sqlite3 "^4.0.2" - string-interp "^0.1.0" - thingpedia "~2.7.0" - thingpedia-discovery "^1.0.0" - thingtalk "~1.10.0" - uuid "^7.0.0" - ws "^7.0.0" - thingpedia-discovery@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/thingpedia-discovery/-/thingpedia-discovery-1.0.1.tgz#8464cdc84cdecc52361440e0085f8f8c24eb77f6" @@ -3970,18 +3975,18 @@ thingpedia-discovery@^1.0.0: dependencies: node-ssdp "^2.7.2" -thingpedia@~2.7.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/thingpedia/-/thingpedia-2.7.0.tgz#36c8a33a714d4e879feda5121f39a86bc4335f3c" - integrity sha512-v1YzGWnlfy/Ej9Aw4ERauiXqlzBs/2T/fT+On+Rhhc7GRJidNtgFHhY+6oRT5QwqMuVYjKDO1QvBmn1CxPKVNA== +thingpedia@~2.8.0-beta.1, thingpedia@~2.8.0-beta.2: + version "2.8.0-beta.2" + resolved "https://registry.yarnpkg.com/thingpedia/-/thingpedia-2.8.0-beta.2.tgz#94c35f7ea83075e6ee3bd426dfbedd70c58e4043" + integrity sha512-5mQHI77/cdBZ3o0E88wdapGaJrPkOfmVsiK5RWb8w5Y2jtoDrdOBqrrfrWcE/ple+6YsuxGTQIcXPQn1vrDgSw== dependencies: feedparser "^2.2.9" gettext-parser "^4.0.2" ip "^1.1.0" oauth "^0.9.14" - string-interp "^0.1.0" - thingtalk "~1.10.0" - tmp "^0.1.0" + string-interp "^0.3.1" + thingtalk "~1.11.0-beta.2" + tmp "^0.2.1" xml2js "^0.4.17" thingtalk-units@^0.1.0: @@ -3989,19 +3994,20 @@ thingtalk-units@^0.1.0: resolved "https://registry.yarnpkg.com/thingtalk-units/-/thingtalk-units-0.1.0.tgz#c3b69bc0c7d0a3ba5bfad3ccf02dc1c291d1abc8" integrity sha512-rV5/jZw9fBk3OgYi/HrA1LsTmD5w0gYDlsc1US3/ePR5szaUxwMUtN8UAPYaUorOiW0Qcjm1plvssOC97EkedQ== -thingtalk@~1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/thingtalk/-/thingtalk-1.10.0.tgz#dd80e80ef6fccf9dd878aa1e7c3f3abad7add700" - integrity sha512-wJbH2GR85shpQHTFF9FN7qjPkK+VXtdFbLJGXOfEkaMKo14dAREw8KGMwAsYhNKW+MlrTJtBPOf+kZaW6HXN2A== +thingtalk@~1.11.0-beta.2: + version "1.11.0-beta.2" + resolved "https://registry.yarnpkg.com/thingtalk/-/thingtalk-1.11.0-beta.2.tgz#9cb76fd952209d37971199107ff9854d8123d61c" + integrity sha512-OPIfUvQqORzYJK7sLpMAMWhW0bDwcBxhiwgTYaypkbs343APqL6gPZjfPtVgYfpv9gk8kS7+73jqYzNsagoH8w== dependencies: adt "~0.7.2" byline "^5.0.0" consumer-queue "^1.0.0" + semver "^7.3.2" smtlib "^0.1.1" - string-interp "^0.1.0" + string-interp "^0.3.1" thingtalk-units "^0.1.0" -through@2, through@^2.3.8, through@~2.3, through@~2.3.4: +through@2, "through@>=2.2.7 <3", through@^2.3.8, through@~2.3, through@~2.3.4: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= @@ -4013,12 +4019,12 @@ tmp@0.0.30: dependencies: os-tmpdir "~1.0.1" -tmp@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.1.0.tgz#ee434a4e22543082e294ba6201dcc6eafefa2877" - integrity sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw== +tmp@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" + integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== dependencies: - rimraf "^2.6.3" + rimraf "^3.0.0" to-fast-properties@^2.0.0: version "2.0.0" @@ -4098,7 +4104,7 @@ type-fest@^0.8.0, type-fest@^0.8.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== -type-is@~1.6.17, type-is@~1.6.18: +type-is@^1.6.18, type-is@~1.6.17, type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== @@ -4192,20 +4198,15 @@ uuid@^3.0.0, uuid@^3.3.2, uuid@^3.3.3: resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== -uuid@^7.0.0: - version "7.0.3" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-7.0.3.tgz#c5c9f2c8cf25dc0a372c4df1441c41f5bd0c680b" - integrity sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg== - uuid@^8.2.0: - version "8.2.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.2.0.tgz#cb10dd6b118e2dada7d0cd9730ba7417c93d920e" - integrity sha512-CYpGiFTUrmI6OBMkAdjSDM0k5h8SkkiTP4WAjQgDgNB1S3Ou9VBEvr6q0Kv2H1mMk7IWfxYGpMH5sd5AvcIV2Q== + version "8.3.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.0.tgz#ab738085ca22dc9a8c92725e459b1d507df5d6ea" + integrity sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ== v8-compile-cache@^2.0.3: - version "2.1.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz#e14de37b31a6d194f5690d67efc4e7f6fc6ab30e" - integrity sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g== + version "2.1.1" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz#54bc3cdd43317bca91e35dcaf305b1a7237de745" + integrity sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ== vary@~1.1.2: version "1.1.2" @@ -4252,13 +4253,14 @@ which-module@^2.0.0: resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= -which-typed-array@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.1.tgz#bff075fd975faedad9ed9355ee0d15452d068794" - integrity sha512-IWlkoJZ4Zdfi4YBn2wnYB8AVox+4A2+Kmr4kHFAraffHYrQZFiTOjgjk9et8e6RSPZOV1QjZOC51PVCK9SkR/A== +which-typed-array@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.2.tgz#e5f98e56bda93e3dac196b01d47c1156679c00b2" + integrity sha512-KT6okrd1tE6JdZAy3o2VhMoYPh3+J6EMZLyrxBQsZflI1QCZIxMrIYLkosd8Twf+YfknVIHmYQPgJt238p8dnQ== dependencies: - available-typed-arrays "^1.0.1" - es-abstract "^1.17.4" + available-typed-arrays "^1.0.2" + es-abstract "^1.17.5" + foreach "^2.0.5" function-bind "^1.1.1" has-symbols "^1.0.1" is-typed-array "^1.1.3" @@ -4349,7 +4351,7 @@ ws@^5.2.0: dependencies: async-limiter "~1.0.0" -ws@^7.0.0, ws@^7.3.1: +ws@^7.3.0, ws@^7.3.1: version "7.3.1" resolved "https://registry.yarnpkg.com/ws/-/ws-7.3.1.tgz#d0547bf67f7ce4f12a72dfe31262c68d7dc551c8" integrity sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA== @@ -4387,18 +4389,18 @@ yallist@^3.0.0, yallist@^3.0.3: resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== -yargs-parser@^18.1.1: - version "18.1.2" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.2.tgz#2f482bea2136dbde0861683abea7756d30b504f1" - integrity sha512-hlIPNR3IzC1YuL1c2UwwDKpXlNFBqD1Fswwh1khz5+d8Cq/8yc/Mn0i+rQXduu8hcrFKvO7Eryk+09NecTQAAQ== +yargs-parser@^18.1.2: + version "18.1.3" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" + integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ== dependencies: camelcase "^5.0.0" decamelize "^1.2.0" yargs@^15.0.2: - version "15.3.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.3.1.tgz#9505b472763963e54afe60148ad27a330818e98b" - integrity sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA== + version "15.4.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8" + integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A== dependencies: cliui "^6.0.0" decamelize "^1.2.0" @@ -4410,4 +4412,4 @@ yargs@^15.0.2: string-width "^4.2.0" which-module "^2.0.0" y18n "^4.0.0" - yargs-parser "^18.1.1" + yargs-parser "^18.1.2"