diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..5f65649 --- /dev/null +++ b/LICENSE @@ -0,0 +1,217 @@ +Copyright 2020 Dennis Gunia + +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. + + + + 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/bin/opentoken-linux b/bin/opentoken-linux index 3511f41..3a73de8 100755 Binary files a/bin/opentoken-linux and b/bin/opentoken-linux differ diff --git a/bin/opentoken-macos b/bin/opentoken-macos index d97ccba..be18494 100755 Binary files a/bin/opentoken-macos and b/bin/opentoken-macos differ diff --git a/bin/opentoken-win.exe b/bin/opentoken-win.exe index c1128f7..73b883d 100644 Binary files a/bin/opentoken-win.exe and b/bin/opentoken-win.exe differ diff --git a/docs/assets/css/main.css b/docs/assets/css/main.css new file mode 100644 index 0000000..3c0dcab --- /dev/null +++ b/docs/assets/css/main.css @@ -0,0 +1 @@ +/*! normalize.css v1.1.3 | MIT License | git.io/normalize */article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none;height:0}[hidden]{display:none}html{font-size:100%;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;font-family:sans-serif}button,input,select,textarea{font-family:sans-serif}body{margin:0}a:focus{outline:thin dotted}a:active,a:hover{outline:0}h1{font-size:2em;margin:.67em 0}h2{font-size:1.5em;margin:.83em 0}h3{font-size:1.17em;margin:1em 0}h4,.tsd-index-panel h3{font-size:1em;margin:1.33em 0}h5{font-size:.83em;margin:1.67em 0}h6{font-size:.67em;margin:2.33em 0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}blockquote{margin:1em 40px}dfn{font-style:italic}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}mark{background:#ff0;color:#000}p,pre{margin:1em 0}code,kbd,pre,samp{font-family:monospace,serif;_font-family:"courier new",monospace;font-size:1em}pre{white-space:pre;white-space:pre-wrap;word-wrap:break-word}q{quotes:none}q:before,q:after{content:"";content:none}small{font-size:80%}sub{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline;top:-0.5em}sub{bottom:-0.25em}dl,menu,ol,ul{margin:1em 0}dd{margin:0 0 0 40px}menu,ol,ul{padding:0 0 0 40px}nav ul,nav ol{list-style:none;list-style-image:none}img{border:0;-ms-interpolation-mode:bicubic}svg:not(:root){overflow:hidden}figure,form{margin:0}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0;white-space:normal;*margin-left:-7px}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,select{text-transform:none}button,html input[type=button]{-webkit-appearance:button;cursor:pointer;*overflow:visible}input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;*overflow:visible}button[disabled],html input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0;*height:13px;*width:13px}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top}table{border-collapse:collapse;border-spacing:0}.hljs{display:inline-block;padding:.5em;background:#fff;color:#000}.hljs-comment,.hljs-annotation,.hljs-template_comment,.diff .hljs-header,.hljs-chunk,.apache .hljs-cbracket{color:green}.hljs-keyword,.hljs-id,.hljs-built_in,.css .smalltalk .hljs-class,.hljs-winutils,.bash .hljs-variable,.tex .hljs-command,.hljs-request,.hljs-status,.nginx .hljs-title{color:blue}.xml .hljs-tag{color:blue}.xml .hljs-tag .hljs-value{color:blue}.hljs-string,.hljs-title,.hljs-parent,.hljs-tag .hljs-value,.hljs-rules .hljs-value{color:#a31515}.ruby .hljs-symbol{color:#a31515}.ruby .hljs-symbol .hljs-string{color:#a31515}.hljs-template_tag,.django .hljs-variable,.hljs-addition,.hljs-flow,.hljs-stream,.apache .hljs-tag,.hljs-date,.tex .hljs-formula,.coffeescript .hljs-attribute{color:#a31515}.ruby .hljs-string,.hljs-decorator,.hljs-filter .hljs-argument,.hljs-localvars,.hljs-array,.hljs-attr_selector,.hljs-pseudo,.hljs-pi,.hljs-doctype,.hljs-deletion,.hljs-envvar,.hljs-shebang,.hljs-preprocessor,.hljs-pragma,.userType,.apache .hljs-sqbracket,.nginx .hljs-built_in,.tex .hljs-special,.hljs-prompt{color:#2b91af}.hljs-phpdoc,.hljs-javadoc,.hljs-xmlDocTag{color:gray}.vhdl .hljs-typename{font-weight:bold}.vhdl .hljs-string{color:#666}.vhdl .hljs-literal{color:#a31515}.vhdl .hljs-attribute{color:#00b0e8}.xml .hljs-attribute{color:red}ul.tsd-descriptions>li>:first-child,.tsd-panel>:first-child,.col>:first-child,.col-11>:first-child,.col-10>:first-child,.col-9>:first-child,.col-8>:first-child,.col-7>:first-child,.col-6>:first-child,.col-5>:first-child,.col-4>:first-child,.col-3>:first-child,.col-2>:first-child,.col-1>:first-child,ul.tsd-descriptions>li>:first-child>:first-child,.tsd-panel>:first-child>:first-child,.col>:first-child>:first-child,.col-11>:first-child>:first-child,.col-10>:first-child>:first-child,.col-9>:first-child>:first-child,.col-8>:first-child>:first-child,.col-7>:first-child>:first-child,.col-6>:first-child>:first-child,.col-5>:first-child>:first-child,.col-4>:first-child>:first-child,.col-3>:first-child>:first-child,.col-2>:first-child>:first-child,.col-1>:first-child>:first-child,ul.tsd-descriptions>li>:first-child>:first-child>:first-child,.tsd-panel>:first-child>:first-child>:first-child,.col>:first-child>:first-child>:first-child,.col-11>:first-child>:first-child>:first-child,.col-10>:first-child>:first-child>:first-child,.col-9>:first-child>:first-child>:first-child,.col-8>:first-child>:first-child>:first-child,.col-7>:first-child>:first-child>:first-child,.col-6>:first-child>:first-child>:first-child,.col-5>:first-child>:first-child>:first-child,.col-4>:first-child>:first-child>:first-child,.col-3>:first-child>:first-child>:first-child,.col-2>:first-child>:first-child>:first-child,.col-1>:first-child>:first-child>:first-child{margin-top:0}ul.tsd-descriptions>li>:last-child,.tsd-panel>:last-child,.col>:last-child,.col-11>:last-child,.col-10>:last-child,.col-9>:last-child,.col-8>:last-child,.col-7>:last-child,.col-6>:last-child,.col-5>:last-child,.col-4>:last-child,.col-3>:last-child,.col-2>:last-child,.col-1>:last-child,ul.tsd-descriptions>li>:last-child>:last-child,.tsd-panel>:last-child>:last-child,.col>:last-child>:last-child,.col-11>:last-child>:last-child,.col-10>:last-child>:last-child,.col-9>:last-child>:last-child,.col-8>:last-child>:last-child,.col-7>:last-child>:last-child,.col-6>:last-child>:last-child,.col-5>:last-child>:last-child,.col-4>:last-child>:last-child,.col-3>:last-child>:last-child,.col-2>:last-child>:last-child,.col-1>:last-child>:last-child,ul.tsd-descriptions>li>:last-child>:last-child>:last-child,.tsd-panel>:last-child>:last-child>:last-child,.col>:last-child>:last-child>:last-child,.col-11>:last-child>:last-child>:last-child,.col-10>:last-child>:last-child>:last-child,.col-9>:last-child>:last-child>:last-child,.col-8>:last-child>:last-child>:last-child,.col-7>:last-child>:last-child>:last-child,.col-6>:last-child>:last-child>:last-child,.col-5>:last-child>:last-child>:last-child,.col-4>:last-child>:last-child>:last-child,.col-3>:last-child>:last-child>:last-child,.col-2>:last-child>:last-child>:last-child,.col-1>:last-child>:last-child>:last-child{margin-bottom:0}.container{max-width:1200px;margin:0 auto;padding:0 40px}@media(max-width: 640px){.container{padding:0 20px}}.container-main{padding-bottom:200px}.row{display:flex;position:relative;margin:0 -10px}.row:after{visibility:hidden;display:block;content:"";clear:both;height:0}.col,.col-11,.col-10,.col-9,.col-8,.col-7,.col-6,.col-5,.col-4,.col-3,.col-2,.col-1{box-sizing:border-box;float:left;padding:0 10px}.col-1{width:8.3333333333%}.offset-1{margin-left:8.3333333333%}.col-2{width:16.6666666667%}.offset-2{margin-left:16.6666666667%}.col-3{width:25%}.offset-3{margin-left:25%}.col-4{width:33.3333333333%}.offset-4{margin-left:33.3333333333%}.col-5{width:41.6666666667%}.offset-5{margin-left:41.6666666667%}.col-6{width:50%}.offset-6{margin-left:50%}.col-7{width:58.3333333333%}.offset-7{margin-left:58.3333333333%}.col-8{width:66.6666666667%}.offset-8{margin-left:66.6666666667%}.col-9{width:75%}.offset-9{margin-left:75%}.col-10{width:83.3333333333%}.offset-10{margin-left:83.3333333333%}.col-11{width:91.6666666667%}.offset-11{margin-left:91.6666666667%}.tsd-kind-icon{display:block;position:relative;padding-left:20px;text-indent:-20px}.tsd-kind-icon:before{content:"";display:inline-block;vertical-align:middle;width:17px;height:17px;margin:0 3px 2px 0;background-image:url(../images/icons.png)}@media(-webkit-min-device-pixel-ratio: 1.5),(min-resolution: 144dpi){.tsd-kind-icon:before{background-image:url(../images/icons@2x.png);background-size:238px 204px}}.tsd-signature.tsd-kind-icon:before{background-position:0 -153px}.tsd-kind-object-literal>.tsd-kind-icon:before{background-position:0px -17px}.tsd-kind-object-literal.tsd-is-protected>.tsd-kind-icon:before{background-position:-17px -17px}.tsd-kind-object-literal.tsd-is-private>.tsd-kind-icon:before{background-position:-34px -17px}.tsd-kind-class>.tsd-kind-icon:before{background-position:0px -34px}.tsd-kind-class.tsd-is-protected>.tsd-kind-icon:before{background-position:-17px -34px}.tsd-kind-class.tsd-is-private>.tsd-kind-icon:before{background-position:-34px -34px}.tsd-kind-class.tsd-has-type-parameter>.tsd-kind-icon:before{background-position:0px -51px}.tsd-kind-class.tsd-has-type-parameter.tsd-is-protected>.tsd-kind-icon:before{background-position:-17px -51px}.tsd-kind-class.tsd-has-type-parameter.tsd-is-private>.tsd-kind-icon:before{background-position:-34px -51px}.tsd-kind-interface>.tsd-kind-icon:before{background-position:0px -68px}.tsd-kind-interface.tsd-is-protected>.tsd-kind-icon:before{background-position:-17px -68px}.tsd-kind-interface.tsd-is-private>.tsd-kind-icon:before{background-position:-34px -68px}.tsd-kind-interface.tsd-has-type-parameter>.tsd-kind-icon:before{background-position:0px -85px}.tsd-kind-interface.tsd-has-type-parameter.tsd-is-protected>.tsd-kind-icon:before{background-position:-17px -85px}.tsd-kind-interface.tsd-has-type-parameter.tsd-is-private>.tsd-kind-icon:before{background-position:-34px -85px}.tsd-kind-namespace>.tsd-kind-icon:before{background-position:0px -102px}.tsd-kind-namespace.tsd-is-protected>.tsd-kind-icon:before{background-position:-17px -102px}.tsd-kind-namespace.tsd-is-private>.tsd-kind-icon:before{background-position:-34px -102px}.tsd-kind-module>.tsd-kind-icon:before{background-position:0px -102px}.tsd-kind-module.tsd-is-protected>.tsd-kind-icon:before{background-position:-17px -102px}.tsd-kind-module.tsd-is-private>.tsd-kind-icon:before{background-position:-34px -102px}.tsd-kind-enum>.tsd-kind-icon:before{background-position:0px -119px}.tsd-kind-enum.tsd-is-protected>.tsd-kind-icon:before{background-position:-17px -119px}.tsd-kind-enum.tsd-is-private>.tsd-kind-icon:before{background-position:-34px -119px}.tsd-kind-enum-member>.tsd-kind-icon:before{background-position:0px -136px}.tsd-kind-enum-member.tsd-is-protected>.tsd-kind-icon:before{background-position:-17px -136px}.tsd-kind-enum-member.tsd-is-private>.tsd-kind-icon:before{background-position:-34px -136px}.tsd-kind-signature>.tsd-kind-icon:before{background-position:0px -153px}.tsd-kind-signature.tsd-is-protected>.tsd-kind-icon:before{background-position:-17px -153px}.tsd-kind-signature.tsd-is-private>.tsd-kind-icon:before{background-position:-34px -153px}.tsd-kind-type-alias>.tsd-kind-icon:before{background-position:0px -170px}.tsd-kind-type-alias.tsd-is-protected>.tsd-kind-icon:before{background-position:-17px -170px}.tsd-kind-type-alias.tsd-is-private>.tsd-kind-icon:before{background-position:-34px -170px}.tsd-kind-type-alias.tsd-has-type-parameter>.tsd-kind-icon:before{background-position:0px -187px}.tsd-kind-type-alias.tsd-has-type-parameter.tsd-is-protected>.tsd-kind-icon:before{background-position:-17px -187px}.tsd-kind-type-alias.tsd-has-type-parameter.tsd-is-private>.tsd-kind-icon:before{background-position:-34px -187px}.tsd-kind-variable>.tsd-kind-icon:before{background-position:-136px -0px}.tsd-kind-variable.tsd-is-protected>.tsd-kind-icon:before{background-position:-153px -0px}.tsd-kind-variable.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -0px}.tsd-kind-variable.tsd-parent-kind-class>.tsd-kind-icon:before{background-position:-51px -0px}.tsd-kind-variable.tsd-parent-kind-class.tsd-is-inherited>.tsd-kind-icon:before{background-position:-68px -0px}.tsd-kind-variable.tsd-parent-kind-class.tsd-is-protected>.tsd-kind-icon:before{background-position:-85px -0px}.tsd-kind-variable.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited>.tsd-kind-icon:before{background-position:-102px -0px}.tsd-kind-variable.tsd-parent-kind-class.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -0px}.tsd-kind-variable.tsd-parent-kind-enum>.tsd-kind-icon:before{background-position:-170px -0px}.tsd-kind-variable.tsd-parent-kind-enum.tsd-is-protected>.tsd-kind-icon:before{background-position:-187px -0px}.tsd-kind-variable.tsd-parent-kind-enum.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -0px}.tsd-kind-variable.tsd-parent-kind-interface>.tsd-kind-icon:before{background-position:-204px -0px}.tsd-kind-variable.tsd-parent-kind-interface.tsd-is-inherited>.tsd-kind-icon:before{background-position:-221px -0px}.tsd-kind-property>.tsd-kind-icon:before{background-position:-136px -0px}.tsd-kind-property.tsd-is-protected>.tsd-kind-icon:before{background-position:-153px -0px}.tsd-kind-property.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -0px}.tsd-kind-property.tsd-parent-kind-class>.tsd-kind-icon:before{background-position:-51px -0px}.tsd-kind-property.tsd-parent-kind-class.tsd-is-inherited>.tsd-kind-icon:before{background-position:-68px -0px}.tsd-kind-property.tsd-parent-kind-class.tsd-is-protected>.tsd-kind-icon:before{background-position:-85px -0px}.tsd-kind-property.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited>.tsd-kind-icon:before{background-position:-102px -0px}.tsd-kind-property.tsd-parent-kind-class.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -0px}.tsd-kind-property.tsd-parent-kind-enum>.tsd-kind-icon:before{background-position:-170px -0px}.tsd-kind-property.tsd-parent-kind-enum.tsd-is-protected>.tsd-kind-icon:before{background-position:-187px -0px}.tsd-kind-property.tsd-parent-kind-enum.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -0px}.tsd-kind-property.tsd-parent-kind-interface>.tsd-kind-icon:before{background-position:-204px -0px}.tsd-kind-property.tsd-parent-kind-interface.tsd-is-inherited>.tsd-kind-icon:before{background-position:-221px -0px}.tsd-kind-get-signature>.tsd-kind-icon:before{background-position:-136px -17px}.tsd-kind-get-signature.tsd-is-protected>.tsd-kind-icon:before{background-position:-153px -17px}.tsd-kind-get-signature.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -17px}.tsd-kind-get-signature.tsd-parent-kind-class>.tsd-kind-icon:before{background-position:-51px -17px}.tsd-kind-get-signature.tsd-parent-kind-class.tsd-is-inherited>.tsd-kind-icon:before{background-position:-68px -17px}.tsd-kind-get-signature.tsd-parent-kind-class.tsd-is-protected>.tsd-kind-icon:before{background-position:-85px -17px}.tsd-kind-get-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited>.tsd-kind-icon:before{background-position:-102px -17px}.tsd-kind-get-signature.tsd-parent-kind-class.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -17px}.tsd-kind-get-signature.tsd-parent-kind-enum>.tsd-kind-icon:before{background-position:-170px -17px}.tsd-kind-get-signature.tsd-parent-kind-enum.tsd-is-protected>.tsd-kind-icon:before{background-position:-187px -17px}.tsd-kind-get-signature.tsd-parent-kind-enum.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -17px}.tsd-kind-get-signature.tsd-parent-kind-interface>.tsd-kind-icon:before{background-position:-204px -17px}.tsd-kind-get-signature.tsd-parent-kind-interface.tsd-is-inherited>.tsd-kind-icon:before{background-position:-221px -17px}.tsd-kind-set-signature>.tsd-kind-icon:before{background-position:-136px -34px}.tsd-kind-set-signature.tsd-is-protected>.tsd-kind-icon:before{background-position:-153px -34px}.tsd-kind-set-signature.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -34px}.tsd-kind-set-signature.tsd-parent-kind-class>.tsd-kind-icon:before{background-position:-51px -34px}.tsd-kind-set-signature.tsd-parent-kind-class.tsd-is-inherited>.tsd-kind-icon:before{background-position:-68px -34px}.tsd-kind-set-signature.tsd-parent-kind-class.tsd-is-protected>.tsd-kind-icon:before{background-position:-85px -34px}.tsd-kind-set-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited>.tsd-kind-icon:before{background-position:-102px -34px}.tsd-kind-set-signature.tsd-parent-kind-class.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -34px}.tsd-kind-set-signature.tsd-parent-kind-enum>.tsd-kind-icon:before{background-position:-170px -34px}.tsd-kind-set-signature.tsd-parent-kind-enum.tsd-is-protected>.tsd-kind-icon:before{background-position:-187px -34px}.tsd-kind-set-signature.tsd-parent-kind-enum.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -34px}.tsd-kind-set-signature.tsd-parent-kind-interface>.tsd-kind-icon:before{background-position:-204px -34px}.tsd-kind-set-signature.tsd-parent-kind-interface.tsd-is-inherited>.tsd-kind-icon:before{background-position:-221px -34px}.tsd-kind-accessor>.tsd-kind-icon:before{background-position:-136px -51px}.tsd-kind-accessor.tsd-is-protected>.tsd-kind-icon:before{background-position:-153px -51px}.tsd-kind-accessor.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -51px}.tsd-kind-accessor.tsd-parent-kind-class>.tsd-kind-icon:before{background-position:-51px -51px}.tsd-kind-accessor.tsd-parent-kind-class.tsd-is-inherited>.tsd-kind-icon:before{background-position:-68px -51px}.tsd-kind-accessor.tsd-parent-kind-class.tsd-is-protected>.tsd-kind-icon:before{background-position:-85px -51px}.tsd-kind-accessor.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited>.tsd-kind-icon:before{background-position:-102px -51px}.tsd-kind-accessor.tsd-parent-kind-class.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -51px}.tsd-kind-accessor.tsd-parent-kind-enum>.tsd-kind-icon:before{background-position:-170px -51px}.tsd-kind-accessor.tsd-parent-kind-enum.tsd-is-protected>.tsd-kind-icon:before{background-position:-187px -51px}.tsd-kind-accessor.tsd-parent-kind-enum.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -51px}.tsd-kind-accessor.tsd-parent-kind-interface>.tsd-kind-icon:before{background-position:-204px -51px}.tsd-kind-accessor.tsd-parent-kind-interface.tsd-is-inherited>.tsd-kind-icon:before{background-position:-221px -51px}.tsd-kind-function>.tsd-kind-icon:before{background-position:-136px -68px}.tsd-kind-function.tsd-is-protected>.tsd-kind-icon:before{background-position:-153px -68px}.tsd-kind-function.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -68px}.tsd-kind-function.tsd-parent-kind-class>.tsd-kind-icon:before{background-position:-51px -68px}.tsd-kind-function.tsd-parent-kind-class.tsd-is-inherited>.tsd-kind-icon:before{background-position:-68px -68px}.tsd-kind-function.tsd-parent-kind-class.tsd-is-protected>.tsd-kind-icon:before{background-position:-85px -68px}.tsd-kind-function.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited>.tsd-kind-icon:before{background-position:-102px -68px}.tsd-kind-function.tsd-parent-kind-class.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -68px}.tsd-kind-function.tsd-parent-kind-enum>.tsd-kind-icon:before{background-position:-170px -68px}.tsd-kind-function.tsd-parent-kind-enum.tsd-is-protected>.tsd-kind-icon:before{background-position:-187px -68px}.tsd-kind-function.tsd-parent-kind-enum.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -68px}.tsd-kind-function.tsd-parent-kind-interface>.tsd-kind-icon:before{background-position:-204px -68px}.tsd-kind-function.tsd-parent-kind-interface.tsd-is-inherited>.tsd-kind-icon:before{background-position:-221px -68px}.tsd-kind-method>.tsd-kind-icon:before{background-position:-136px -68px}.tsd-kind-method.tsd-is-protected>.tsd-kind-icon:before{background-position:-153px -68px}.tsd-kind-method.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -68px}.tsd-kind-method.tsd-parent-kind-class>.tsd-kind-icon:before{background-position:-51px -68px}.tsd-kind-method.tsd-parent-kind-class.tsd-is-inherited>.tsd-kind-icon:before{background-position:-68px -68px}.tsd-kind-method.tsd-parent-kind-class.tsd-is-protected>.tsd-kind-icon:before{background-position:-85px -68px}.tsd-kind-method.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited>.tsd-kind-icon:before{background-position:-102px -68px}.tsd-kind-method.tsd-parent-kind-class.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -68px}.tsd-kind-method.tsd-parent-kind-enum>.tsd-kind-icon:before{background-position:-170px -68px}.tsd-kind-method.tsd-parent-kind-enum.tsd-is-protected>.tsd-kind-icon:before{background-position:-187px -68px}.tsd-kind-method.tsd-parent-kind-enum.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -68px}.tsd-kind-method.tsd-parent-kind-interface>.tsd-kind-icon:before{background-position:-204px -68px}.tsd-kind-method.tsd-parent-kind-interface.tsd-is-inherited>.tsd-kind-icon:before{background-position:-221px -68px}.tsd-kind-call-signature>.tsd-kind-icon:before{background-position:-136px -68px}.tsd-kind-call-signature.tsd-is-protected>.tsd-kind-icon:before{background-position:-153px -68px}.tsd-kind-call-signature.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -68px}.tsd-kind-call-signature.tsd-parent-kind-class>.tsd-kind-icon:before{background-position:-51px -68px}.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-inherited>.tsd-kind-icon:before{background-position:-68px -68px}.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-protected>.tsd-kind-icon:before{background-position:-85px -68px}.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited>.tsd-kind-icon:before{background-position:-102px -68px}.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -68px}.tsd-kind-call-signature.tsd-parent-kind-enum>.tsd-kind-icon:before{background-position:-170px -68px}.tsd-kind-call-signature.tsd-parent-kind-enum.tsd-is-protected>.tsd-kind-icon:before{background-position:-187px -68px}.tsd-kind-call-signature.tsd-parent-kind-enum.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -68px}.tsd-kind-call-signature.tsd-parent-kind-interface>.tsd-kind-icon:before{background-position:-204px -68px}.tsd-kind-call-signature.tsd-parent-kind-interface.tsd-is-inherited>.tsd-kind-icon:before{background-position:-221px -68px}.tsd-kind-function.tsd-has-type-parameter>.tsd-kind-icon:before{background-position:-136px -85px}.tsd-kind-function.tsd-has-type-parameter.tsd-is-protected>.tsd-kind-icon:before{background-position:-153px -85px}.tsd-kind-function.tsd-has-type-parameter.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -85px}.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class>.tsd-kind-icon:before{background-position:-51px -85px}.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-inherited>.tsd-kind-icon:before{background-position:-68px -85px}.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-protected>.tsd-kind-icon:before{background-position:-85px -85px}.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited>.tsd-kind-icon:before{background-position:-102px -85px}.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -85px}.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-enum>.tsd-kind-icon:before{background-position:-170px -85px}.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-enum.tsd-is-protected>.tsd-kind-icon:before{background-position:-187px -85px}.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-enum.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -85px}.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-interface>.tsd-kind-icon:before{background-position:-204px -85px}.tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-interface.tsd-is-inherited>.tsd-kind-icon:before{background-position:-221px -85px}.tsd-kind-method.tsd-has-type-parameter>.tsd-kind-icon:before{background-position:-136px -85px}.tsd-kind-method.tsd-has-type-parameter.tsd-is-protected>.tsd-kind-icon:before{background-position:-153px -85px}.tsd-kind-method.tsd-has-type-parameter.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -85px}.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class>.tsd-kind-icon:before{background-position:-51px -85px}.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-inherited>.tsd-kind-icon:before{background-position:-68px -85px}.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-protected>.tsd-kind-icon:before{background-position:-85px -85px}.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited>.tsd-kind-icon:before{background-position:-102px -85px}.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -85px}.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-enum>.tsd-kind-icon:before{background-position:-170px -85px}.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-enum.tsd-is-protected>.tsd-kind-icon:before{background-position:-187px -85px}.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-enum.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -85px}.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-interface>.tsd-kind-icon:before{background-position:-204px -85px}.tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-interface.tsd-is-inherited>.tsd-kind-icon:before{background-position:-221px -85px}.tsd-kind-constructor>.tsd-kind-icon:before{background-position:-136px -102px}.tsd-kind-constructor.tsd-is-protected>.tsd-kind-icon:before{background-position:-153px -102px}.tsd-kind-constructor.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -102px}.tsd-kind-constructor.tsd-parent-kind-class>.tsd-kind-icon:before{background-position:-51px -102px}.tsd-kind-constructor.tsd-parent-kind-class.tsd-is-inherited>.tsd-kind-icon:before{background-position:-68px -102px}.tsd-kind-constructor.tsd-parent-kind-class.tsd-is-protected>.tsd-kind-icon:before{background-position:-85px -102px}.tsd-kind-constructor.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited>.tsd-kind-icon:before{background-position:-102px -102px}.tsd-kind-constructor.tsd-parent-kind-class.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -102px}.tsd-kind-constructor.tsd-parent-kind-enum>.tsd-kind-icon:before{background-position:-170px -102px}.tsd-kind-constructor.tsd-parent-kind-enum.tsd-is-protected>.tsd-kind-icon:before{background-position:-187px -102px}.tsd-kind-constructor.tsd-parent-kind-enum.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -102px}.tsd-kind-constructor.tsd-parent-kind-interface>.tsd-kind-icon:before{background-position:-204px -102px}.tsd-kind-constructor.tsd-parent-kind-interface.tsd-is-inherited>.tsd-kind-icon:before{background-position:-221px -102px}.tsd-kind-constructor-signature>.tsd-kind-icon:before{background-position:-136px -102px}.tsd-kind-constructor-signature.tsd-is-protected>.tsd-kind-icon:before{background-position:-153px -102px}.tsd-kind-constructor-signature.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -102px}.tsd-kind-constructor-signature.tsd-parent-kind-class>.tsd-kind-icon:before{background-position:-51px -102px}.tsd-kind-constructor-signature.tsd-parent-kind-class.tsd-is-inherited>.tsd-kind-icon:before{background-position:-68px -102px}.tsd-kind-constructor-signature.tsd-parent-kind-class.tsd-is-protected>.tsd-kind-icon:before{background-position:-85px -102px}.tsd-kind-constructor-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited>.tsd-kind-icon:before{background-position:-102px -102px}.tsd-kind-constructor-signature.tsd-parent-kind-class.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -102px}.tsd-kind-constructor-signature.tsd-parent-kind-enum>.tsd-kind-icon:before{background-position:-170px -102px}.tsd-kind-constructor-signature.tsd-parent-kind-enum.tsd-is-protected>.tsd-kind-icon:before{background-position:-187px -102px}.tsd-kind-constructor-signature.tsd-parent-kind-enum.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -102px}.tsd-kind-constructor-signature.tsd-parent-kind-interface>.tsd-kind-icon:before{background-position:-204px -102px}.tsd-kind-constructor-signature.tsd-parent-kind-interface.tsd-is-inherited>.tsd-kind-icon:before{background-position:-221px -102px}.tsd-kind-index-signature>.tsd-kind-icon:before{background-position:-136px -119px}.tsd-kind-index-signature.tsd-is-protected>.tsd-kind-icon:before{background-position:-153px -119px}.tsd-kind-index-signature.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -119px}.tsd-kind-index-signature.tsd-parent-kind-class>.tsd-kind-icon:before{background-position:-51px -119px}.tsd-kind-index-signature.tsd-parent-kind-class.tsd-is-inherited>.tsd-kind-icon:before{background-position:-68px -119px}.tsd-kind-index-signature.tsd-parent-kind-class.tsd-is-protected>.tsd-kind-icon:before{background-position:-85px -119px}.tsd-kind-index-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited>.tsd-kind-icon:before{background-position:-102px -119px}.tsd-kind-index-signature.tsd-parent-kind-class.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -119px}.tsd-kind-index-signature.tsd-parent-kind-enum>.tsd-kind-icon:before{background-position:-170px -119px}.tsd-kind-index-signature.tsd-parent-kind-enum.tsd-is-protected>.tsd-kind-icon:before{background-position:-187px -119px}.tsd-kind-index-signature.tsd-parent-kind-enum.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -119px}.tsd-kind-index-signature.tsd-parent-kind-interface>.tsd-kind-icon:before{background-position:-204px -119px}.tsd-kind-index-signature.tsd-parent-kind-interface.tsd-is-inherited>.tsd-kind-icon:before{background-position:-221px -119px}.tsd-kind-event>.tsd-kind-icon:before{background-position:-136px -136px}.tsd-kind-event.tsd-is-protected>.tsd-kind-icon:before{background-position:-153px -136px}.tsd-kind-event.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -136px}.tsd-kind-event.tsd-parent-kind-class>.tsd-kind-icon:before{background-position:-51px -136px}.tsd-kind-event.tsd-parent-kind-class.tsd-is-inherited>.tsd-kind-icon:before{background-position:-68px -136px}.tsd-kind-event.tsd-parent-kind-class.tsd-is-protected>.tsd-kind-icon:before{background-position:-85px -136px}.tsd-kind-event.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited>.tsd-kind-icon:before{background-position:-102px -136px}.tsd-kind-event.tsd-parent-kind-class.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -136px}.tsd-kind-event.tsd-parent-kind-enum>.tsd-kind-icon:before{background-position:-170px -136px}.tsd-kind-event.tsd-parent-kind-enum.tsd-is-protected>.tsd-kind-icon:before{background-position:-187px -136px}.tsd-kind-event.tsd-parent-kind-enum.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -136px}.tsd-kind-event.tsd-parent-kind-interface>.tsd-kind-icon:before{background-position:-204px -136px}.tsd-kind-event.tsd-parent-kind-interface.tsd-is-inherited>.tsd-kind-icon:before{background-position:-221px -136px}.tsd-is-static>.tsd-kind-icon:before{background-position:-136px -153px}.tsd-is-static.tsd-is-protected>.tsd-kind-icon:before{background-position:-153px -153px}.tsd-is-static.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -153px}.tsd-is-static.tsd-parent-kind-class>.tsd-kind-icon:before{background-position:-51px -153px}.tsd-is-static.tsd-parent-kind-class.tsd-is-inherited>.tsd-kind-icon:before{background-position:-68px -153px}.tsd-is-static.tsd-parent-kind-class.tsd-is-protected>.tsd-kind-icon:before{background-position:-85px -153px}.tsd-is-static.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited>.tsd-kind-icon:before{background-position:-102px -153px}.tsd-is-static.tsd-parent-kind-class.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -153px}.tsd-is-static.tsd-parent-kind-enum>.tsd-kind-icon:before{background-position:-170px -153px}.tsd-is-static.tsd-parent-kind-enum.tsd-is-protected>.tsd-kind-icon:before{background-position:-187px -153px}.tsd-is-static.tsd-parent-kind-enum.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -153px}.tsd-is-static.tsd-parent-kind-interface>.tsd-kind-icon:before{background-position:-204px -153px}.tsd-is-static.tsd-parent-kind-interface.tsd-is-inherited>.tsd-kind-icon:before{background-position:-221px -153px}.tsd-is-static.tsd-kind-function>.tsd-kind-icon:before{background-position:-136px -170px}.tsd-is-static.tsd-kind-function.tsd-is-protected>.tsd-kind-icon:before{background-position:-153px -170px}.tsd-is-static.tsd-kind-function.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -170px}.tsd-is-static.tsd-kind-function.tsd-parent-kind-class>.tsd-kind-icon:before{background-position:-51px -170px}.tsd-is-static.tsd-kind-function.tsd-parent-kind-class.tsd-is-inherited>.tsd-kind-icon:before{background-position:-68px -170px}.tsd-is-static.tsd-kind-function.tsd-parent-kind-class.tsd-is-protected>.tsd-kind-icon:before{background-position:-85px -170px}.tsd-is-static.tsd-kind-function.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited>.tsd-kind-icon:before{background-position:-102px -170px}.tsd-is-static.tsd-kind-function.tsd-parent-kind-class.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -170px}.tsd-is-static.tsd-kind-function.tsd-parent-kind-enum>.tsd-kind-icon:before{background-position:-170px -170px}.tsd-is-static.tsd-kind-function.tsd-parent-kind-enum.tsd-is-protected>.tsd-kind-icon:before{background-position:-187px -170px}.tsd-is-static.tsd-kind-function.tsd-parent-kind-enum.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -170px}.tsd-is-static.tsd-kind-function.tsd-parent-kind-interface>.tsd-kind-icon:before{background-position:-204px -170px}.tsd-is-static.tsd-kind-function.tsd-parent-kind-interface.tsd-is-inherited>.tsd-kind-icon:before{background-position:-221px -170px}.tsd-is-static.tsd-kind-method>.tsd-kind-icon:before{background-position:-136px -170px}.tsd-is-static.tsd-kind-method.tsd-is-protected>.tsd-kind-icon:before{background-position:-153px -170px}.tsd-is-static.tsd-kind-method.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -170px}.tsd-is-static.tsd-kind-method.tsd-parent-kind-class>.tsd-kind-icon:before{background-position:-51px -170px}.tsd-is-static.tsd-kind-method.tsd-parent-kind-class.tsd-is-inherited>.tsd-kind-icon:before{background-position:-68px -170px}.tsd-is-static.tsd-kind-method.tsd-parent-kind-class.tsd-is-protected>.tsd-kind-icon:before{background-position:-85px -170px}.tsd-is-static.tsd-kind-method.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited>.tsd-kind-icon:before{background-position:-102px -170px}.tsd-is-static.tsd-kind-method.tsd-parent-kind-class.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -170px}.tsd-is-static.tsd-kind-method.tsd-parent-kind-enum>.tsd-kind-icon:before{background-position:-170px -170px}.tsd-is-static.tsd-kind-method.tsd-parent-kind-enum.tsd-is-protected>.tsd-kind-icon:before{background-position:-187px -170px}.tsd-is-static.tsd-kind-method.tsd-parent-kind-enum.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -170px}.tsd-is-static.tsd-kind-method.tsd-parent-kind-interface>.tsd-kind-icon:before{background-position:-204px -170px}.tsd-is-static.tsd-kind-method.tsd-parent-kind-interface.tsd-is-inherited>.tsd-kind-icon:before{background-position:-221px -170px}.tsd-is-static.tsd-kind-call-signature>.tsd-kind-icon:before{background-position:-136px -170px}.tsd-is-static.tsd-kind-call-signature.tsd-is-protected>.tsd-kind-icon:before{background-position:-153px -170px}.tsd-is-static.tsd-kind-call-signature.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -170px}.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class>.tsd-kind-icon:before{background-position:-51px -170px}.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-inherited>.tsd-kind-icon:before{background-position:-68px -170px}.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-protected>.tsd-kind-icon:before{background-position:-85px -170px}.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited>.tsd-kind-icon:before{background-position:-102px -170px}.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -170px}.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-enum>.tsd-kind-icon:before{background-position:-170px -170px}.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-enum.tsd-is-protected>.tsd-kind-icon:before{background-position:-187px -170px}.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-enum.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -170px}.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-interface>.tsd-kind-icon:before{background-position:-204px -170px}.tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-interface.tsd-is-inherited>.tsd-kind-icon:before{background-position:-221px -170px}.tsd-is-static.tsd-kind-event>.tsd-kind-icon:before{background-position:-136px -187px}.tsd-is-static.tsd-kind-event.tsd-is-protected>.tsd-kind-icon:before{background-position:-153px -187px}.tsd-is-static.tsd-kind-event.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -187px}.tsd-is-static.tsd-kind-event.tsd-parent-kind-class>.tsd-kind-icon:before{background-position:-51px -187px}.tsd-is-static.tsd-kind-event.tsd-parent-kind-class.tsd-is-inherited>.tsd-kind-icon:before{background-position:-68px -187px}.tsd-is-static.tsd-kind-event.tsd-parent-kind-class.tsd-is-protected>.tsd-kind-icon:before{background-position:-85px -187px}.tsd-is-static.tsd-kind-event.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited>.tsd-kind-icon:before{background-position:-102px -187px}.tsd-is-static.tsd-kind-event.tsd-parent-kind-class.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -187px}.tsd-is-static.tsd-kind-event.tsd-parent-kind-enum>.tsd-kind-icon:before{background-position:-170px -187px}.tsd-is-static.tsd-kind-event.tsd-parent-kind-enum.tsd-is-protected>.tsd-kind-icon:before{background-position:-187px -187px}.tsd-is-static.tsd-kind-event.tsd-parent-kind-enum.tsd-is-private>.tsd-kind-icon:before{background-position:-119px -187px}.tsd-is-static.tsd-kind-event.tsd-parent-kind-interface>.tsd-kind-icon:before{background-position:-204px -187px}.tsd-is-static.tsd-kind-event.tsd-parent-kind-interface.tsd-is-inherited>.tsd-kind-icon:before{background-position:-221px -187px}@keyframes fade-in{from{opacity:0}to{opacity:1}}@keyframes fade-out{from{opacity:1;visibility:visible}to{opacity:0}}@keyframes fade-in-delayed{0%{opacity:0}33%{opacity:0}100%{opacity:1}}@keyframes fade-out-delayed{0%{opacity:1;visibility:visible}66%{opacity:0}100%{opacity:0}}@keyframes shift-to-left{from{transform:translate(0, 0)}to{transform:translate(-25%, 0)}}@keyframes unshift-to-left{from{transform:translate(-25%, 0)}to{transform:translate(0, 0)}}@keyframes pop-in-from-right{from{transform:translate(100%, 0)}to{transform:translate(0, 0)}}@keyframes pop-out-to-right{from{transform:translate(0, 0);visibility:visible}to{transform:translate(100%, 0)}}body{background:#fdfdfd;font-family:"Segoe UI",sans-serif;font-size:16px;color:#222}a{color:#4da6ff;text-decoration:none}a:hover{text-decoration:underline}code,pre{font-family:Menlo,Monaco,Consolas,"Courier New",monospace;padding:.2em;margin:0;font-size:14px;background-color:rgba(0,0,0,.04)}pre{padding:10px}pre code{padding:0;font-size:100%;background-color:transparent}.tsd-typography{line-height:1.333em}.tsd-typography ul{list-style:square;padding:0 0 0 20px;margin:0}.tsd-typography h4,.tsd-typography .tsd-index-panel h3,.tsd-index-panel .tsd-typography h3,.tsd-typography h5,.tsd-typography h6{font-size:1em;margin:0}.tsd-typography h5,.tsd-typography h6{font-weight:normal}.tsd-typography p,.tsd-typography ul,.tsd-typography ol{margin:1em 0}@media(min-width: 901px)and (max-width: 1024px){html.default .col-content{width:72%}html.default .col-menu{width:28%}html.default .tsd-navigation{padding-left:10px}}@media(max-width: 900px){html.default .col-content{float:none;width:100%}html.default .col-menu{position:fixed !important;overflow:auto;-webkit-overflow-scrolling:touch;z-index:1024;top:0 !important;bottom:0 !important;left:auto !important;right:0 !important;width:100%;padding:20px 20px 0 0;max-width:450px;visibility:hidden;background-color:#fff;transform:translate(100%, 0)}html.default .col-menu>*:last-child{padding-bottom:20px}html.default .overlay{content:"";display:block;position:fixed;z-index:1023;top:0;left:0;right:0;bottom:0;background-color:rgba(0,0,0,.75);visibility:hidden}html.default.to-has-menu .overlay{animation:fade-in .4s}html.default.to-has-menu header,html.default.to-has-menu footer,html.default.to-has-menu .col-content{animation:shift-to-left .4s}html.default.to-has-menu .col-menu{animation:pop-in-from-right .4s}html.default.from-has-menu .overlay{animation:fade-out .4s}html.default.from-has-menu header,html.default.from-has-menu footer,html.default.from-has-menu .col-content{animation:unshift-to-left .4s}html.default.from-has-menu .col-menu{animation:pop-out-to-right .4s}html.default.has-menu body{overflow:hidden}html.default.has-menu .overlay{visibility:visible}html.default.has-menu header,html.default.has-menu footer,html.default.has-menu .col-content{transform:translate(-25%, 0)}html.default.has-menu .col-menu{visibility:visible;transform:translate(0, 0)}}.tsd-page-title{padding:70px 0 20px 0;margin:0 0 40px 0;background:#fff;box-shadow:0 0 5px rgba(0,0,0,.35)}.tsd-page-title h1{margin:0}.tsd-breadcrumb{margin:0;padding:0;color:#707070}.tsd-breadcrumb a{color:#707070;text-decoration:none}.tsd-breadcrumb a:hover{text-decoration:underline}.tsd-breadcrumb li{display:inline}.tsd-breadcrumb li:after{content:" / "}html.minimal .container{margin:0}html.minimal .container-main{padding-top:50px;padding-bottom:0}html.minimal .content-wrap{padding-left:300px}html.minimal .tsd-navigation{position:fixed !important;overflow:auto;-webkit-overflow-scrolling:touch;box-sizing:border-box;z-index:1;left:0;top:40px;bottom:0;width:300px;padding:20px;margin:0}html.minimal .tsd-member .tsd-member{margin-left:0}html.minimal .tsd-page-toolbar{position:fixed;z-index:2}html.minimal #tsd-filter .tsd-filter-group{right:0;transform:none}html.minimal footer{background-color:transparent}html.minimal footer .container{padding:0}html.minimal .tsd-generator{padding:0}@media(max-width: 900px){html.minimal .tsd-navigation{display:none}html.minimal .content-wrap{padding-left:0}}dl.tsd-comment-tags{overflow:hidden}dl.tsd-comment-tags dt{float:left;padding:1px 5px;margin:0 10px 0 0;border-radius:4px;border:1px solid #707070;color:#707070;font-size:.8em;font-weight:normal}dl.tsd-comment-tags dd{margin:0 0 10px 0}dl.tsd-comment-tags dd:before,dl.tsd-comment-tags dd:after{display:table;content:" "}dl.tsd-comment-tags dd pre,dl.tsd-comment-tags dd:after{clear:both}dl.tsd-comment-tags p{margin:0}.tsd-panel.tsd-comment .lead{font-size:1.1em;line-height:1.333em;margin-bottom:2em}.tsd-panel.tsd-comment .lead:last-child{margin-bottom:0}.toggle-protected .tsd-is-private{display:none}.toggle-public .tsd-is-private,.toggle-public .tsd-is-protected,.toggle-public .tsd-is-private-protected{display:none}.toggle-inherited .tsd-is-inherited{display:none}.toggle-only-exported .tsd-is-not-exported{display:none}.toggle-externals .tsd-is-external{display:none}#tsd-filter{position:relative;display:inline-block;height:40px;vertical-align:bottom}.no-filter #tsd-filter{display:none}#tsd-filter .tsd-filter-group{display:inline-block;height:40px;vertical-align:bottom;white-space:nowrap}#tsd-filter input{display:none}@media(max-width: 900px){#tsd-filter .tsd-filter-group{display:block;position:absolute;top:40px;right:20px;height:auto;background-color:#fff;visibility:hidden;transform:translate(50%, 0);box-shadow:0 0 4px rgba(0,0,0,.25)}.has-options #tsd-filter .tsd-filter-group{visibility:visible}.to-has-options #tsd-filter .tsd-filter-group{animation:fade-in .2s}.from-has-options #tsd-filter .tsd-filter-group{animation:fade-out .2s}#tsd-filter label,#tsd-filter .tsd-select{display:block;padding-right:20px}}footer{border-top:1px solid #eee;background-color:#fff}footer.with-border-bottom{border-bottom:1px solid #eee}footer .tsd-legend-group{font-size:0}footer .tsd-legend{display:inline-block;width:25%;padding:0;font-size:16px;list-style:none;line-height:1.333em;vertical-align:top}@media(max-width: 900px){footer .tsd-legend{width:50%}}.tsd-hierarchy{list-style:square;padding:0 0 0 20px;margin:0}.tsd-hierarchy .target{font-weight:bold}.tsd-index-panel .tsd-index-content{margin-bottom:-30px !important}.tsd-index-panel .tsd-index-section{margin-bottom:30px !important}.tsd-index-panel h3{margin:0 -20px 10px -20px;padding:0 20px 10px 20px;border-bottom:1px solid #eee}.tsd-index-panel ul.tsd-index-list{-webkit-column-count:3;-moz-column-count:3;-ms-column-count:3;-o-column-count:3;column-count:3;-webkit-column-gap:20px;-moz-column-gap:20px;-ms-column-gap:20px;-o-column-gap:20px;column-gap:20px;padding:0;list-style:none;line-height:1.333em}@media(max-width: 900px){.tsd-index-panel ul.tsd-index-list{-webkit-column-count:1;-moz-column-count:1;-ms-column-count:1;-o-column-count:1;column-count:1}}@media(min-width: 901px)and (max-width: 1024px){.tsd-index-panel ul.tsd-index-list{-webkit-column-count:2;-moz-column-count:2;-ms-column-count:2;-o-column-count:2;column-count:2}}.tsd-index-panel ul.tsd-index-list li{-webkit-page-break-inside:avoid;-moz-page-break-inside:avoid;-ms-page-break-inside:avoid;-o-page-break-inside:avoid;page-break-inside:avoid}.tsd-index-panel a,.tsd-index-panel .tsd-parent-kind-module a{color:#9600ff}.tsd-index-panel .tsd-parent-kind-interface a{color:#647f1b}.tsd-index-panel .tsd-parent-kind-enum a{color:#937210}.tsd-index-panel .tsd-parent-kind-class a{color:#0672de}.tsd-index-panel .tsd-kind-module a{color:#9600ff}.tsd-index-panel .tsd-kind-interface a{color:#647f1b}.tsd-index-panel .tsd-kind-enum a{color:#937210}.tsd-index-panel .tsd-kind-class a{color:#0672de}.tsd-index-panel .tsd-is-private a{color:#707070}.tsd-flag{display:inline-block;padding:1px 5px;border-radius:4px;color:#fff;background-color:#707070;text-indent:0;font-size:14px;font-weight:normal}.tsd-anchor{position:absolute;top:-100px}.tsd-member{position:relative}.tsd-member .tsd-anchor+h3{margin-top:0;margin-bottom:0;border-bottom:none}.tsd-navigation{margin:0 0 0 40px}.tsd-navigation a{display:block;padding-top:2px;padding-bottom:2px;border-left:2px solid transparent;color:#222;text-decoration:none;transition:border-left-color .1s}.tsd-navigation a:hover{text-decoration:underline}.tsd-navigation ul{margin:0;padding:0;list-style:none}.tsd-navigation li{padding:0}.tsd-navigation.primary{padding-bottom:40px}.tsd-navigation.primary a{display:block;padding-top:6px;padding-bottom:6px}.tsd-navigation.primary ul li a{padding-left:5px}.tsd-navigation.primary ul li li a{padding-left:25px}.tsd-navigation.primary ul li li li a{padding-left:45px}.tsd-navigation.primary ul li li li li a{padding-left:65px}.tsd-navigation.primary ul li li li li li a{padding-left:85px}.tsd-navigation.primary ul li li li li li li a{padding-left:105px}.tsd-navigation.primary>ul{border-bottom:1px solid #eee}.tsd-navigation.primary li{border-top:1px solid #eee}.tsd-navigation.primary li.current>a{font-weight:bold}.tsd-navigation.primary li.label span{display:block;padding:20px 0 6px 5px;color:#707070}.tsd-navigation.primary li.globals+li>span,.tsd-navigation.primary li.globals+li>a{padding-top:20px}.tsd-navigation.secondary{max-height:calc(100vh - 1rem - 40px);overflow:auto;position:-webkit-sticky;position:sticky;top:calc(.5rem + 40px);transition:.3s}.tsd-navigation.secondary.tsd-navigation--toolbar-hide{max-height:calc(100vh - 1rem);top:.5rem}.tsd-navigation.secondary ul{transition:opacity .2s}.tsd-navigation.secondary ul li a{padding-left:25px}.tsd-navigation.secondary ul li li a{padding-left:45px}.tsd-navigation.secondary ul li li li a{padding-left:65px}.tsd-navigation.secondary ul li li li li a{padding-left:85px}.tsd-navigation.secondary ul li li li li li a{padding-left:105px}.tsd-navigation.secondary ul li li li li li li a{padding-left:125px}.tsd-navigation.secondary ul.current a{border-left-color:#eee}.tsd-navigation.secondary li.focus>a,.tsd-navigation.secondary ul.current li.focus>a{border-left-color:#000}.tsd-navigation.secondary li.current{margin-top:20px;margin-bottom:20px;border-left-color:#eee}.tsd-navigation.secondary li.current>a{font-weight:bold}@media(min-width: 901px){.menu-sticky-wrap{position:static}}.tsd-panel{margin:20px 0;padding:20px;background-color:#fff;box-shadow:0 0 4px rgba(0,0,0,.25)}.tsd-panel:empty{display:none}.tsd-panel>h1,.tsd-panel>h2,.tsd-panel>h3{margin:1.5em -20px 10px -20px;padding:0 20px 10px 20px;border-bottom:1px solid #eee}.tsd-panel>h1.tsd-before-signature,.tsd-panel>h2.tsd-before-signature,.tsd-panel>h3.tsd-before-signature{margin-bottom:0;border-bottom:0}.tsd-panel table{display:block;width:100%;overflow:auto;margin-top:10px;word-break:normal;word-break:keep-all}.tsd-panel table th{font-weight:bold}.tsd-panel table th,.tsd-panel table td{padding:6px 13px;border:1px solid #ddd}.tsd-panel table tr{background-color:#fff;border-top:1px solid #ccc}.tsd-panel table tr:nth-child(2n){background-color:#f8f8f8}.tsd-panel-group{margin:60px 0}.tsd-panel-group>h1,.tsd-panel-group>h2,.tsd-panel-group>h3{padding-left:20px;padding-right:20px}#tsd-search{transition:background-color .2s}#tsd-search .title{position:relative;z-index:2}#tsd-search .field{position:absolute;left:0;top:0;right:40px;height:40px}#tsd-search .field input{box-sizing:border-box;position:relative;top:-50px;z-index:1;width:100%;padding:0 10px;opacity:0;outline:0;border:0;background:transparent;color:#222}#tsd-search .field label{position:absolute;overflow:hidden;right:-40px}#tsd-search .field input,#tsd-search .title{transition:opacity .2s}#tsd-search .results{position:absolute;visibility:hidden;top:40px;width:100%;margin:0;padding:0;list-style:none;box-shadow:0 0 4px rgba(0,0,0,.25)}#tsd-search .results li{padding:0 10px;background-color:#fdfdfd}#tsd-search .results li:nth-child(even){background-color:#fff}#tsd-search .results li.state{display:none}#tsd-search .results li.current,#tsd-search .results li:hover{background-color:#eee}#tsd-search .results a{display:block}#tsd-search .results a:before{top:10px}#tsd-search .results span.parent{color:#707070;font-weight:normal}#tsd-search.has-focus{background-color:#eee}#tsd-search.has-focus .field input{top:0;opacity:1}#tsd-search.has-focus .title{z-index:0;opacity:0}#tsd-search.has-focus .results{visibility:visible}#tsd-search.loading .results li.state.loading{display:block}#tsd-search.failure .results li.state.failure{display:block}.tsd-signature{margin:0 0 1em 0;padding:10px;border:1px solid #eee;font-family:Menlo,Monaco,Consolas,"Courier New",monospace;font-size:14px;overflow-x:auto}.tsd-signature.tsd-kind-icon{padding-left:30px}.tsd-signature.tsd-kind-icon:before{top:10px;left:10px}.tsd-panel>.tsd-signature{margin-left:-20px;margin-right:-20px;border-width:1px 0}.tsd-panel>.tsd-signature.tsd-kind-icon{padding-left:40px}.tsd-panel>.tsd-signature.tsd-kind-icon:before{left:20px}.tsd-signature-symbol{color:#707070;font-weight:normal}.tsd-signature-type{font-style:italic;font-weight:normal}.tsd-signatures{padding:0;margin:0 0 1em 0;border:1px solid #eee}.tsd-signatures .tsd-signature{margin:0;border-width:1px 0 0 0;transition:background-color .1s}.tsd-signatures .tsd-signature:first-child{border-top-width:0}.tsd-signatures .tsd-signature.current{background-color:#eee}.tsd-signatures.active>.tsd-signature{cursor:pointer}.tsd-panel>.tsd-signatures{margin-left:-20px;margin-right:-20px;border-width:1px 0}.tsd-panel>.tsd-signatures .tsd-signature.tsd-kind-icon{padding-left:40px}.tsd-panel>.tsd-signatures .tsd-signature.tsd-kind-icon:before{left:20px}.tsd-panel>a.anchor+.tsd-signatures{border-top-width:0;margin-top:-20px}ul.tsd-descriptions{position:relative;overflow:hidden;padding:0;list-style:none}ul.tsd-descriptions.active>.tsd-description{display:none}ul.tsd-descriptions.active>.tsd-description.current{display:block}ul.tsd-descriptions.active>.tsd-description.fade-in{animation:fade-in-delayed .3s}ul.tsd-descriptions.active>.tsd-description.fade-out{animation:fade-out-delayed .3s;position:absolute;display:block;top:0;left:0;right:0;opacity:0;visibility:hidden}ul.tsd-descriptions h4,ul.tsd-descriptions .tsd-index-panel h3,.tsd-index-panel ul.tsd-descriptions h3{font-size:16px;margin:1em 0 .5em 0}ul.tsd-parameters,ul.tsd-type-parameters{list-style:square;margin:0;padding-left:20px}ul.tsd-parameters>li.tsd-parameter-signature,ul.tsd-type-parameters>li.tsd-parameter-signature{list-style:none;margin-left:-20px}ul.tsd-parameters h5,ul.tsd-type-parameters h5{font-size:16px;margin:1em 0 .5em 0}ul.tsd-parameters .tsd-comment,ul.tsd-type-parameters .tsd-comment{margin-top:-0.5em}.tsd-sources{font-size:14px;color:#707070;margin:0 0 1em 0}.tsd-sources a{color:#707070;text-decoration:underline}.tsd-sources ul,.tsd-sources p{margin:0 !important}.tsd-sources ul{list-style:none;padding:0}.tsd-page-toolbar{position:fixed;z-index:1;top:0;left:0;width:100%;height:40px;color:#333;background:#fff;border-bottom:1px solid #eee;transition:transform .3s linear}.tsd-page-toolbar a{color:#333;text-decoration:none}.tsd-page-toolbar a.title{font-weight:bold}.tsd-page-toolbar a.title:hover{text-decoration:underline}.tsd-page-toolbar .table-wrap{display:table;width:100%;height:40px}.tsd-page-toolbar .table-cell{display:table-cell;position:relative;white-space:nowrap;line-height:40px}.tsd-page-toolbar .table-cell:first-child{width:100%}.tsd-page-toolbar--hide{transform:translateY(-100%)}.tsd-select .tsd-select-list li:before,.tsd-select .tsd-select-label:before,.tsd-widget:before{content:"";display:inline-block;width:40px;height:40px;margin:0 -8px 0 0;background-image:url(../images/widgets.png);background-repeat:no-repeat;text-indent:-1024px;vertical-align:bottom}@media(-webkit-min-device-pixel-ratio: 1.5),(min-resolution: 144dpi){.tsd-select .tsd-select-list li:before,.tsd-select .tsd-select-label:before,.tsd-widget:before{background-image:url(../images/widgets@2x.png);background-size:320px 40px}}.tsd-widget{display:inline-block;overflow:hidden;opacity:.6;height:40px;transition:opacity .1s,background-color .2s;vertical-align:bottom;cursor:pointer}.tsd-widget:hover{opacity:.8}.tsd-widget.active{opacity:1;background-color:#eee}.tsd-widget.no-caption{width:40px}.tsd-widget.no-caption:before{margin:0}.tsd-widget.search:before{background-position:0 0}.tsd-widget.menu:before{background-position:-40px 0}.tsd-widget.options:before{background-position:-80px 0}.tsd-widget.options,.tsd-widget.menu{display:none}@media(max-width: 900px){.tsd-widget.options,.tsd-widget.menu{display:inline-block}}input[type=checkbox]+.tsd-widget:before{background-position:-120px 0}input[type=checkbox]:checked+.tsd-widget:before{background-position:-160px 0}.tsd-select{position:relative;display:inline-block;height:40px;transition:opacity .1s,background-color .2s;vertical-align:bottom;cursor:pointer}.tsd-select .tsd-select-label{opacity:.6;transition:opacity .2s}.tsd-select .tsd-select-label:before{background-position:-240px 0}.tsd-select.active .tsd-select-label{opacity:.8}.tsd-select.active .tsd-select-list{visibility:visible;opacity:1;transition-delay:0s}.tsd-select .tsd-select-list{position:absolute;visibility:hidden;top:40px;left:0;margin:0;padding:0;opacity:0;list-style:none;box-shadow:0 0 4px rgba(0,0,0,.25);transition:visibility 0s .2s,opacity .2s}.tsd-select .tsd-select-list li{padding:0 20px 0 0;background-color:#fdfdfd}.tsd-select .tsd-select-list li:before{background-position:40px 0}.tsd-select .tsd-select-list li:nth-child(even){background-color:#fff}.tsd-select .tsd-select-list li:hover{background-color:#eee}.tsd-select .tsd-select-list li.selected:before{background-position:-200px 0}@media(max-width: 900px){.tsd-select .tsd-select-list{top:0;left:auto;right:100%;margin-right:-5px}.tsd-select .tsd-select-label:before{background-position:-280px 0}}img{max-width:100%} diff --git a/docs/assets/images/icons.png b/docs/assets/images/icons.png new file mode 100644 index 0000000..3836d5f Binary files /dev/null and b/docs/assets/images/icons.png differ diff --git a/docs/assets/images/icons@2x.png b/docs/assets/images/icons@2x.png new file mode 100644 index 0000000..5a209e2 Binary files /dev/null and b/docs/assets/images/icons@2x.png differ diff --git a/docs/assets/images/widgets.png b/docs/assets/images/widgets.png new file mode 100644 index 0000000..c738053 Binary files /dev/null and b/docs/assets/images/widgets.png differ diff --git a/docs/assets/images/widgets@2x.png b/docs/assets/images/widgets@2x.png new file mode 100644 index 0000000..4bbbd57 Binary files /dev/null and b/docs/assets/images/widgets@2x.png differ diff --git a/docs/assets/js/main.js b/docs/assets/js/main.js new file mode 100644 index 0000000..c2190a9 --- /dev/null +++ b/docs/assets/js/main.js @@ -0,0 +1,51 @@ +!function(e){var t={};function r(n){if(t[n])return t[n].exports;var i=t[n]={i:n,l:!1,exports:{}};return e[n].call(i.exports,i,i.exports,r),i.l=!0,i.exports}r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)r.d(n,i,function(t){return e[t]}.bind(null,i));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=2)}([function(e,t,r){var n,i; +/** + * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 2.3.9 + * Copyright (C) 2020 Oliver Nightingale + * @license MIT + */!function(){var s,o,a,u,l,c,h,d,f,p,y,m,v,g,x,w,L,E,b,S,k,Q,O,P,T,_,C=function(e){var t=new C.Builder;return t.pipeline.add(C.trimmer,C.stopWordFilter,C.stemmer),t.searchPipeline.add(C.stemmer),e.call(t,t),t.build()};C.version="2.3.9" +/*! + * lunr.utils + * Copyright (C) 2020 Oliver Nightingale + */,C.utils={},C.utils.warn=(s=this,function(e){s.console&&console.warn&&console.warn(e)}),C.utils.asString=function(e){return null==e?"":e.toString()},C.utils.clone=function(e){if(null==e)return e;for(var t=Object.create(null),r=Object.keys(e),n=0;n0){var u=C.utils.clone(t)||{};u.position=[o,a],u.index=i.length,i.push(new C.Token(r.slice(o,s),u))}o=s+1}}return i},C.tokenizer.separator=/[\s\-]+/ +/*! + * lunr.Pipeline + * Copyright (C) 2020 Oliver Nightingale + */,C.Pipeline=function(){this._stack=[]},C.Pipeline.registeredFunctions=Object.create(null),C.Pipeline.registerFunction=function(e,t){t in this.registeredFunctions&&C.utils.warn("Overwriting existing registered function: "+t),e.label=t,C.Pipeline.registeredFunctions[e.label]=e},C.Pipeline.warnIfFunctionNotRegistered=function(e){e.label&&e.label in this.registeredFunctions||C.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},C.Pipeline.load=function(e){var t=new C.Pipeline;return e.forEach((function(e){var r=C.Pipeline.registeredFunctions[e];if(!r)throw new Error("Cannot load unregistered function: "+e);t.add(r)})),t},C.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach((function(e){C.Pipeline.warnIfFunctionNotRegistered(e),this._stack.push(e)}),this)},C.Pipeline.prototype.after=function(e,t){C.Pipeline.warnIfFunctionNotRegistered(t);var r=this._stack.indexOf(e);if(-1==r)throw new Error("Cannot find existingFn");r+=1,this._stack.splice(r,0,t)},C.Pipeline.prototype.before=function(e,t){C.Pipeline.warnIfFunctionNotRegistered(t);var r=this._stack.indexOf(e);if(-1==r)throw new Error("Cannot find existingFn");this._stack.splice(r,0,t)},C.Pipeline.prototype.remove=function(e){var t=this._stack.indexOf(e);-1!=t&&this._stack.splice(t,1)},C.Pipeline.prototype.run=function(e){for(var t=this._stack.length,r=0;r1&&(se&&(r=i),s!=e);)n=r-t,i=t+Math.floor(n/2),s=this.elements[2*i];return s==e||s>e?2*i:sa?l+=2:o==a&&(t+=r[u+1]*n[l+1],u+=2,l+=2);return t},C.Vector.prototype.similarity=function(e){return this.dot(e)/this.magnitude()||0},C.Vector.prototype.toArray=function(){for(var e=new Array(this.elements.length/2),t=1,r=0;t0){var s,o=i.str.charAt(0);o in i.node.edges?s=i.node.edges[o]:(s=new C.TokenSet,i.node.edges[o]=s),1==i.str.length&&(s.final=!0),n.push({node:s,editsRemaining:i.editsRemaining,str:i.str.slice(1)})}if(0!=i.editsRemaining){if("*"in i.node.edges)var a=i.node.edges["*"];else{a=new C.TokenSet;i.node.edges["*"]=a}if(0==i.str.length&&(a.final=!0),n.push({node:a,editsRemaining:i.editsRemaining-1,str:i.str}),i.str.length>1&&n.push({node:i.node,editsRemaining:i.editsRemaining-1,str:i.str.slice(1)}),1==i.str.length&&(i.node.final=!0),i.str.length>=1){if("*"in i.node.edges)var u=i.node.edges["*"];else{u=new C.TokenSet;i.node.edges["*"]=u}1==i.str.length&&(u.final=!0),n.push({node:u,editsRemaining:i.editsRemaining-1,str:i.str.slice(1)})}if(i.str.length>1){var l,c=i.str.charAt(0),h=i.str.charAt(1);h in i.node.edges?l=i.node.edges[h]:(l=new C.TokenSet,i.node.edges[h]=l),1==i.str.length&&(l.final=!0),n.push({node:l,editsRemaining:i.editsRemaining-1,str:c+i.str.slice(2)})}}}return r},C.TokenSet.fromString=function(e){for(var t=new C.TokenSet,r=t,n=0,i=e.length;n=e;t--){var r=this.uncheckedNodes[t],n=r.child.toString();n in this.minimizedNodes?r.parent.edges[r.char]=this.minimizedNodes[n]:(r.child._str=n,this.minimizedNodes[n]=r.child),this.uncheckedNodes.pop()}} +/*! + * lunr.Index + * Copyright (C) 2020 Oliver Nightingale + */,C.Index=function(e){this.invertedIndex=e.invertedIndex,this.fieldVectors=e.fieldVectors,this.tokenSet=e.tokenSet,this.fields=e.fields,this.pipeline=e.pipeline},C.Index.prototype.search=function(e){return this.query((function(t){new C.QueryParser(e,t).parse()}))},C.Index.prototype.query=function(e){for(var t=new C.Query(this.fields),r=Object.create(null),n=Object.create(null),i=Object.create(null),s=Object.create(null),o=Object.create(null),a=0;a1?1:e},C.Builder.prototype.k1=function(e){this._k1=e},C.Builder.prototype.add=function(e,t){var r=e[this._ref],n=Object.keys(this._fields);this._documents[r]=t||{},this.documentCount+=1;for(var i=0;i=this.length)return C.QueryLexer.EOS;var e=this.str.charAt(this.pos);return this.pos+=1,e},C.QueryLexer.prototype.width=function(){return this.pos-this.start},C.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},C.QueryLexer.prototype.backup=function(){this.pos-=1},C.QueryLexer.prototype.acceptDigitRun=function(){var e,t;do{t=(e=this.next()).charCodeAt(0)}while(t>47&&t<58);e!=C.QueryLexer.EOS&&this.backup()},C.QueryLexer.prototype.more=function(){return this.pos1&&(e.backup(),e.emit(C.QueryLexer.TERM)),e.ignore(),e.more())return C.QueryLexer.lexText},C.QueryLexer.lexEditDistance=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(C.QueryLexer.EDIT_DISTANCE),C.QueryLexer.lexText},C.QueryLexer.lexBoost=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(C.QueryLexer.BOOST),C.QueryLexer.lexText},C.QueryLexer.lexEOS=function(e){e.width()>0&&e.emit(C.QueryLexer.TERM)},C.QueryLexer.termSeparator=C.tokenizer.separator,C.QueryLexer.lexText=function(e){for(;;){var t=e.next();if(t==C.QueryLexer.EOS)return C.QueryLexer.lexEOS;if(92!=t.charCodeAt(0)){if(":"==t)return C.QueryLexer.lexField;if("~"==t)return e.backup(),e.width()>0&&e.emit(C.QueryLexer.TERM),C.QueryLexer.lexEditDistance;if("^"==t)return e.backup(),e.width()>0&&e.emit(C.QueryLexer.TERM),C.QueryLexer.lexBoost;if("+"==t&&1===e.width())return e.emit(C.QueryLexer.PRESENCE),C.QueryLexer.lexText;if("-"==t&&1===e.width())return e.emit(C.QueryLexer.PRESENCE),C.QueryLexer.lexText;if(t.match(C.QueryLexer.termSeparator))return C.QueryLexer.lexTerm}else e.escapeCharacter()}},C.QueryParser=function(e,t){this.lexer=new C.QueryLexer(e),this.query=t,this.currentClause={},this.lexemeIdx=0},C.QueryParser.prototype.parse=function(){this.lexer.run(),this.lexemes=this.lexer.lexemes;for(var e=C.QueryParser.parseClause;e;)e=e(this);return this.query},C.QueryParser.prototype.peekLexeme=function(){return this.lexemes[this.lexemeIdx]},C.QueryParser.prototype.consumeLexeme=function(){var e=this.peekLexeme();return this.lexemeIdx+=1,e},C.QueryParser.prototype.nextClause=function(){var e=this.currentClause;this.query.clause(e),this.currentClause={}},C.QueryParser.parseClause=function(e){var t=e.peekLexeme();if(null!=t)switch(t.type){case C.QueryLexer.PRESENCE:return C.QueryParser.parsePresence;case C.QueryLexer.FIELD:return C.QueryParser.parseField;case C.QueryLexer.TERM:return C.QueryParser.parseTerm;default:var r="expected either a field or a term, found "+t.type;throw t.str.length>=1&&(r+=" with value '"+t.str+"'"),new C.QueryParseError(r,t.start,t.end)}},C.QueryParser.parsePresence=function(e){var t=e.consumeLexeme();if(null!=t){switch(t.str){case"-":e.currentClause.presence=C.Query.presence.PROHIBITED;break;case"+":e.currentClause.presence=C.Query.presence.REQUIRED;break;default:var r="unrecognised presence operator'"+t.str+"'";throw new C.QueryParseError(r,t.start,t.end)}var n=e.peekLexeme();if(null==n){r="expecting term or field, found nothing";throw new C.QueryParseError(r,t.start,t.end)}switch(n.type){case C.QueryLexer.FIELD:return C.QueryParser.parseField;case C.QueryLexer.TERM:return C.QueryParser.parseTerm;default:r="expecting term or field, found '"+n.type+"'";throw new C.QueryParseError(r,n.start,n.end)}}},C.QueryParser.parseField=function(e){var t=e.consumeLexeme();if(null!=t){if(-1==e.query.allFields.indexOf(t.str)){var r=e.query.allFields.map((function(e){return"'"+e+"'"})).join(", "),n="unrecognised field '"+t.str+"', possible fields: "+r;throw new C.QueryParseError(n,t.start,t.end)}e.currentClause.fields=[t.str];var i=e.peekLexeme();if(null==i){n="expecting term, found nothing";throw new C.QueryParseError(n,t.start,t.end)}switch(i.type){case C.QueryLexer.TERM:return C.QueryParser.parseTerm;default:n="expecting term, found '"+i.type+"'";throw new C.QueryParseError(n,i.start,i.end)}}},C.QueryParser.parseTerm=function(e){var t=e.consumeLexeme();if(null!=t){e.currentClause.term=t.str.toLowerCase(),-1!=t.str.indexOf("*")&&(e.currentClause.usePipeline=!1);var r=e.peekLexeme();if(null!=r)switch(r.type){case C.QueryLexer.TERM:return e.nextClause(),C.QueryParser.parseTerm;case C.QueryLexer.FIELD:return e.nextClause(),C.QueryParser.parseField;case C.QueryLexer.EDIT_DISTANCE:return C.QueryParser.parseEditDistance;case C.QueryLexer.BOOST:return C.QueryParser.parseBoost;case C.QueryLexer.PRESENCE:return e.nextClause(),C.QueryParser.parsePresence;default:var n="Unexpected lexeme type '"+r.type+"'";throw new C.QueryParseError(n,r.start,r.end)}else e.nextClause()}},C.QueryParser.parseEditDistance=function(e){var t=e.consumeLexeme();if(null!=t){var r=parseInt(t.str,10);if(isNaN(r)){var n="edit distance must be numeric";throw new C.QueryParseError(n,t.start,t.end)}e.currentClause.editDistance=r;var i=e.peekLexeme();if(null!=i)switch(i.type){case C.QueryLexer.TERM:return e.nextClause(),C.QueryParser.parseTerm;case C.QueryLexer.FIELD:return e.nextClause(),C.QueryParser.parseField;case C.QueryLexer.EDIT_DISTANCE:return C.QueryParser.parseEditDistance;case C.QueryLexer.BOOST:return C.QueryParser.parseBoost;case C.QueryLexer.PRESENCE:return e.nextClause(),C.QueryParser.parsePresence;default:n="Unexpected lexeme type '"+i.type+"'";throw new C.QueryParseError(n,i.start,i.end)}else e.nextClause()}},C.QueryParser.parseBoost=function(e){var t=e.consumeLexeme();if(null!=t){var r=parseInt(t.str,10);if(isNaN(r)){var n="boost must be numeric";throw new C.QueryParseError(n,t.start,t.end)}e.currentClause.boost=r;var i=e.peekLexeme();if(null!=i)switch(i.type){case C.QueryLexer.TERM:return e.nextClause(),C.QueryParser.parseTerm;case C.QueryLexer.FIELD:return e.nextClause(),C.QueryParser.parseField;case C.QueryLexer.EDIT_DISTANCE:return C.QueryParser.parseEditDistance;case C.QueryLexer.BOOST:return C.QueryParser.parseBoost;case C.QueryLexer.PRESENCE:return e.nextClause(),C.QueryParser.parsePresence;default:n="Unexpected lexeme type '"+i.type+"'";throw new C.QueryParseError(n,i.start,i.end)}else e.nextClause()}},void 0===(i="function"==typeof(n=function(){return C})?n.call(t,r,t,e):n)||(e.exports=i)}()},function(e,t,r){},function(e,t,r){"use strict";r.r(t);var n=[];function i(e,t){n.push({selector:t,constructor:e})}var s,o,a=function(){function e(){this.createComponents(document.body)}return e.prototype.createComponents=function(e){n.forEach((function(t){e.querySelectorAll(t.selector).forEach((function(e){e.dataset.hasInstance||(new t.constructor({el:e}),e.dataset.hasInstance=String(!0))}))}))},e}(),u=function(e){this.el=e.el},l=r(0),c=(s=function(e,t){return(s=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r])})(e,t)},function(e,t){function r(){this.constructor=e}s(e,t),e.prototype=null===t?Object.create(t):(r.prototype=t.prototype,new r)});!function(e){e[e.Idle=0]="Idle",e[e.Loading=1]="Loading",e[e.Ready=2]="Ready",e[e.Failure=3]="Failure"}(o||(o={}));var h=function(e){function t(t){var r=e.call(this,t)||this;r.query="",r.loadingState=o.Idle,r.hasFocus=!1,r.preventPress=!1,r.data=null,r.index=null,r.resultClicked=!1;var n=document.querySelector("#tsd-search-field"),i=document.querySelector(".results");if(!n||!i)throw new Error("The input field or the result list wrapper are not found");return r.field=n,r.results=i,r.base=r.el.dataset.base+"/",r.bindEvents(),r}return c(t,e),t.prototype.loadIndex=function(){var e=this;if(this.loadingState==o.Idle&&!this.data){setTimeout((function(){e.loadingState==o.Idle&&e.setLoadingState(o.Loading)}),500);var t=this.el.dataset.index;t?fetch(t).then((function(e){if(!e.ok)throw new Error("The search index is missing");return e.json()})).then((function(t){e.data=t,e.index=l.Index.load(t.index),e.setLoadingState(o.Ready)})).catch((function(t){console.error(t),e.setLoadingState(o.Failure)})):this.setLoadingState(o.Failure)}},t.prototype.updateResults=function(){if(this.loadingState==o.Ready&&(this.results.textContent="",this.query&&this.index&&this.data)){var e=this.index.search("*"+this.query+"*");0===e.length&&(e=this.index.search("*"+this.query+"~1*"));for(var t=0,r=Math.min(10,e.length);t"+e+""})),s=n.parent||"";(s=s.replace(new RegExp(this.query,"i"),(function(e){return""+e+""})))&&(i=''+s+"."+i);var a=document.createElement("li");a.classList.value=n.classes,a.innerHTML='\n '+i+"\n ",this.results.appendChild(a)}}},t.prototype.setLoadingState=function(e){this.loadingState!=e&&(this.el.classList.remove(o[this.loadingState].toLowerCase()),this.loadingState=e,this.el.classList.add(o[this.loadingState].toLowerCase()),this.updateResults())},t.prototype.setHasFocus=function(e){this.hasFocus!=e&&(this.hasFocus=e,this.el.classList.toggle("has-focus"),e?(this.setQuery(""),this.field.value=""):this.field.value=this.query)},t.prototype.setQuery=function(e){this.query=e.trim(),this.updateResults()},t.prototype.setCurrentResult=function(e){var t=this.results.querySelector(".current");if(t){var r=1==e?t.nextElementSibling:t.previousElementSibling;r&&(t.classList.remove("current"),r.classList.add("current"))}else(t=this.results.querySelector(1==e?"li:first-child":"li:last-child"))&&t.classList.add("current")},t.prototype.gotoCurrentResult=function(){var e=this.results.querySelector(".current");if(e||(e=this.results.querySelector("li:first-child")),e){var t=e.querySelector("a");t&&(window.location.href=t.href),this.field.blur()}},t.prototype.bindEvents=function(){var e=this;this.results.addEventListener("mousedown",(function(){e.resultClicked=!0})),this.results.addEventListener("mouseup",(function(){e.resultClicked=!1,e.setHasFocus(!1)})),this.field.addEventListener("focusin",(function(){e.setHasFocus(!0),e.loadIndex()})),this.field.addEventListener("focusout",(function(){e.resultClicked?e.resultClicked=!1:setTimeout((function(){return e.setHasFocus(!1)}),100)})),this.field.addEventListener("input",(function(){e.setQuery(e.field.value)})),this.field.addEventListener("keydown",(function(t){13==t.keyCode||27==t.keyCode||38==t.keyCode||40==t.keyCode?(e.preventPress=!0,t.preventDefault(),13==t.keyCode?e.gotoCurrentResult():27==t.keyCode?e.field.blur():38==t.keyCode?e.setCurrentResult(-1):40==t.keyCode&&e.setCurrentResult(1)):e.preventPress=!1})),this.field.addEventListener("keypress",(function(t){e.preventPress&&t.preventDefault()})),document.body.addEventListener("keydown",(function(t){t.altKey||t.ctrlKey||t.metaKey||!e.hasFocus&&t.keyCode>47&&t.keyCode<112&&e.field.focus()}))},t}(u),d=function(){function e(){this.listeners={}}return e.prototype.addEventListener=function(e,t){e in this.listeners||(this.listeners[e]=[]),this.listeners[e].push(t)},e.prototype.removeEventListener=function(e,t){if(e in this.listeners)for(var r=this.listeners[e],n=0,i=r.length;n=this.scrollTop||0===this.scrollTop,e!==this.showToolbar&&(this.toolbar.classList.toggle("tsd-page-toolbar--hide"),this.secondaryNav.classList.toggle("tsd-navigation--toolbar-hide")),this.lastY=this.scrollTop},t.instance=new t,t}(d),m=function(){var e=function(t,r){return(e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r])})(t,r)};return function(t,r){function n(){this.constructor=t}e(t,r),t.prototype=null===r?Object.create(r):(n.prototype=r.prototype,new n)}}(),v=function(e){function t(t){var r=e.call(this,t)||this;return r.anchors=[],r.index=-1,y.instance.addEventListener("resize",(function(){return r.onResize()})),y.instance.addEventListener("scroll",(function(e){return r.onScroll(e)})),r.createAnchors(),r}return m(t,e),t.prototype.createAnchors=function(){var e=this,t=window.location.href;-1!=t.indexOf("#")&&(t=t.substr(0,t.indexOf("#"))),this.el.querySelectorAll("a").forEach((function(r){var n=r.href;if(-1!=n.indexOf("#")&&n.substr(0,t.length)==t){var i=n.substr(n.indexOf("#")+1),s=document.querySelector("a.tsd-anchor[name="+i+"]"),o=r.parentNode;s&&o&&e.anchors.push({link:o,anchor:s,position:0})}})),this.onResize()},t.prototype.onResize=function(){for(var e,t=0,r=this.anchors.length;t-1&&r[i].position>t;)i-=1;for(;i-1&&this.anchors[this.index].link.classList.remove("focus"),this.index=i,this.index>-1&&this.anchors[this.index].link.classList.add("focus"))},t}(u),g=function(){var e=function(t,r){return(e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r])})(t,r)};return function(t,r){function n(){this.constructor=t}e(t,r),t.prototype=null===r?Object.create(r):(n.prototype=r.prototype,new n)}}(),x=function(){function e(e,t){this.signature=e,this.description=t}return e.prototype.addClass=function(e){return this.signature.classList.add(e),this.description.classList.add(e),this},e.prototype.removeClass=function(e){return this.signature.classList.remove(e),this.description.classList.remove(e),this},e}(),w=function(e){function t(t){var r=e.call(this,t)||this;return r.groups=[],r.index=-1,r.createGroups(),r.container&&(r.el.classList.add("active"),Array.from(r.el.children).forEach((function(e){e.addEventListener("touchstart",(function(e){return r.onClick(e)})),e.addEventListener("click",(function(e){return r.onClick(e)}))})),r.container.classList.add("active"),r.setIndex(0)),r}return g(t,e),t.prototype.setIndex=function(e){if(e<0&&(e=0),e>this.groups.length-1&&(e=this.groups.length-1),this.index!=e){var t=this.groups[e];if(this.index>-1){var r=this.groups[this.index];r.removeClass("current").addClass("fade-out"),t.addClass("current"),t.addClass("fade-in"),y.instance.triggerResize(),setTimeout((function(){r.removeClass("fade-out"),t.removeClass("fade-in")}),300)}else t.addClass("current"),y.instance.triggerResize();this.index=e}},t.prototype.createGroups=function(){var e=this.el.children;if(!(e.length<2)){this.container=this.el.nextElementSibling;var t=this.container.children;this.groups=[];for(var r=0;r10}})),document.addEventListener(b,(function(){Q=!1})),document.addEventListener("click",(function(e){k&&(e.preventDefault(),e.stopImmediatePropagation(),k=!1)}));var T=function(){var e=function(t,r){return(e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r])})(t,r)};return function(t,r){function n(){this.constructor=t}e(t,r),t.prototype=null===r?Object.create(r):(n.prototype=r.prototype,new n)}}(),_=function(e){function t(t){var r=e.call(this,t)||this;return r.className=r.el.dataset.toggle||"",r.el.addEventListener(b,(function(e){return r.onPointerUp(e)})),r.el.addEventListener("click",(function(e){return e.preventDefault()})),document.addEventListener(L,(function(e){return r.onDocumentPointerDown(e)})),document.addEventListener(b,(function(e){return r.onDocumentPointerUp(e)})),r}return T(t,e),t.prototype.setActive=function(e){if(this.active!=e){this.active=e,document.documentElement.classList.toggle("has-"+this.className,e),this.el.classList.toggle("active",e);var t=(this.active?"to-has-":"from-has-")+this.className;document.documentElement.classList.add(t),setTimeout((function(){return document.documentElement.classList.remove(t)}),500)}},t.prototype.onPointerUp=function(e){O||(this.setActive(!0),e.preventDefault())},t.prototype.onDocumentPointerDown=function(e){if(this.active){if(e.target.closest(".col-menu, .tsd-filter-group"))return;this.setActive(!1)}},t.prototype.onDocumentPointerUp=function(e){var t=this;if(!O&&this.active&&e.target.closest(".col-menu")){var r=e.target.closest("a");if(r){var n=window.location.href;-1!=n.indexOf("#")&&(n=n.substr(0,n.indexOf("#"))),r.href.substr(0,n.length)==n&&setTimeout((function(){return t.setActive(!1)}),250)}}},t}(u),C=function(){var e=function(t,r){return(e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r])})(t,r)};return function(t,r){function n(){this.constructor=t}e(t,r),t.prototype=null===r?Object.create(r):(n.prototype=r.prototype,new n)}}(),R=function(){function e(e,t){this.key=e,this.value=t,this.defaultValue=t,this.initialize(),window.localStorage[this.key]&&this.setValue(this.fromLocalStorage(window.localStorage[this.key]))}return e.prototype.initialize=function(){},e.prototype.setValue=function(e){if(this.value!=e){var t=this.value;this.value=e,window.localStorage[this.key]=this.toLocalStorage(e),this.handleValueChange(t,e)}},e}(),I=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return C(t,e),t.prototype.initialize=function(){var e=this,t=document.querySelector("#tsd-filter-"+this.key);t&&(this.checkbox=t,this.checkbox.addEventListener("change",(function(){e.setValue(e.checkbox.checked)})))},t.prototype.handleValueChange=function(e,t){this.checkbox&&(this.checkbox.checked=this.value,document.documentElement.classList.toggle("toggle-"+this.key,this.value!=this.defaultValue))},t.prototype.fromLocalStorage=function(e){return"true"==e},t.prototype.toLocalStorage=function(e){return e?"true":"false"},t}(R),j=function(e){function t(){return null!==e&&e.apply(this,arguments)||this}return C(t,e),t.prototype.initialize=function(){var e=this;document.documentElement.classList.add("toggle-"+this.key+this.value);var t=document.querySelector("#tsd-filter-"+this.key);if(t){this.select=t;var r=function(){e.select.classList.add("active")};this.select.addEventListener(L,r),this.select.addEventListener("mouseover",r),this.select.addEventListener("mouseleave",(function(){e.select.classList.remove("active")})),this.select.querySelectorAll("li").forEach((function(r){r.addEventListener(b,(function(r){t.classList.remove("active"),e.setValue(r.target.dataset.value||"")}))})),document.addEventListener(L,(function(t){e.select.contains(t.target)||e.select.classList.remove("active")}))}},t.prototype.handleValueChange=function(e,t){this.select.querySelectorAll("li.selected").forEach((function(e){e.classList.remove("selected")}));var r=this.select.querySelector('li[data-value="'+t+'"]'),n=this.select.querySelector(".tsd-select-label");r&&n&&(r.classList.add("selected"),n.textContent=r.textContent),document.documentElement.classList.remove("toggle-"+e),document.documentElement.classList.add("toggle-"+t)},t.prototype.fromLocalStorage=function(e){return e},t.prototype.toLocalStorage=function(e){return e},t}(R),F=function(e){function t(t){var r=e.call(this,t)||this;return r.optionVisibility=new j("visibility","private"),r.optionInherited=new I("inherited",!0),r.optionExternals=new I("externals",!0),r.optionOnlyExported=new I("only-exported",!1),r}return C(t,e),t.isSupported=function(){try{return void 0!==window.localStorage}catch(e){return!1}},t}(u);r(1);i(h,"#tsd-search"),i(v,".menu-highlight"),i(w,".tsd-signatures"),i(_,"a[data-toggle]"),F.isSupported()?i(F,"#tsd-filter"):document.documentElement.classList.add("no-filter");var N=new a;Object.defineProperty(window,"app",{value:N})}]); \ No newline at end of file diff --git a/docs/assets/js/search.json b/docs/assets/js/search.json new file mode 100644 index 0000000..46d177c --- /dev/null +++ b/docs/assets/js/search.json @@ -0,0 +1 @@ +{"kinds":{"2":"Namespace","32":"Variable","64":"Function","128":"Class","256":"Interface","512":"Constructor","1024":"Property","2048":"Method"},"rows":[{"id":0,"kind":2,"name":"SVault","url":"modules/svault.html","classes":"tsd-kind-namespace"},{"id":1,"kind":256,"name":"SecureVaultItem","url":"interfaces/svault.securevaultitem.html","classes":"tsd-kind-interface tsd-parent-kind-namespace","parent":"SVault"},{"id":2,"kind":1024,"name":"u","url":"interfaces/svault.securevaultitem.html#u","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SVault.SecureVaultItem"},{"id":3,"kind":1024,"name":"d","url":"interfaces/svault.securevaultitem.html#d","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SVault.SecureVaultItem"},{"id":4,"kind":1024,"name":"k","url":"interfaces/svault.securevaultitem.html#k","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SVault.SecureVaultItem"},{"id":5,"kind":1024,"name":"iv","url":"interfaces/svault.securevaultitem.html#iv","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SVault.SecureVaultItem"},{"id":6,"kind":256,"name":"StorageItem","url":"interfaces/svault.storageitem.html","classes":"tsd-kind-interface tsd-parent-kind-namespace","parent":"SVault"},{"id":7,"kind":1024,"name":"u","url":"interfaces/svault.storageitem.html#u","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SVault.StorageItem"},{"id":8,"kind":1024,"name":"d","url":"interfaces/svault.storageitem.html#d","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SVault.StorageItem"},{"id":9,"kind":1024,"name":"t","url":"interfaces/svault.storageitem.html#t","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SVault.StorageItem"},{"id":10,"kind":256,"name":"secureVaultList","url":"interfaces/svault.securevaultlist.html","classes":"tsd-kind-interface tsd-parent-kind-namespace","parent":"SVault"},{"id":11,"kind":1024,"name":"items","url":"interfaces/svault.securevaultlist.html#items","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SVault.secureVaultList"},{"id":12,"kind":1024,"name":"publicKey","url":"interfaces/svault.securevaultlist.html#publickey","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SVault.secureVaultList"},{"id":13,"kind":1024,"name":"privateKey","url":"interfaces/svault.securevaultlist.html#privatekey","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"SVault.secureVaultList"},{"id":14,"kind":128,"name":"SecureVault","url":"classes/svault.securevault.html","classes":"tsd-kind-class tsd-parent-kind-namespace","parent":"SVault"},{"id":15,"kind":1024,"name":"safe","url":"classes/svault.securevault.html#safe","classes":"tsd-kind-property tsd-parent-kind-class","parent":"SVault.SecureVault"},{"id":16,"kind":1024,"name":"privPath","url":"classes/svault.securevault.html#privpath","classes":"tsd-kind-property tsd-parent-kind-class","parent":"SVault.SecureVault"},{"id":17,"kind":1024,"name":"pubPath","url":"classes/svault.securevault.html#pubpath","classes":"tsd-kind-property tsd-parent-kind-class","parent":"SVault.SecureVault"},{"id":18,"kind":1024,"name":"storage","url":"classes/svault.securevault.html#storage","classes":"tsd-kind-property tsd-parent-kind-class","parent":"SVault.SecureVault"},{"id":19,"kind":512,"name":"constructor","url":"classes/svault.securevault.html#constructor","classes":"tsd-kind-constructor tsd-parent-kind-class","parent":"SVault.SecureVault"},{"id":20,"kind":2048,"name":"pushData","url":"classes/svault.securevault.html#pushdata","classes":"tsd-kind-method tsd-parent-kind-class","parent":"SVault.SecureVault"},{"id":21,"kind":2048,"name":"writeTransaction","url":"classes/svault.securevault.html#writetransaction","classes":"tsd-kind-method tsd-parent-kind-class","parent":"SVault.SecureVault"},{"id":22,"kind":2048,"name":"saveData","url":"classes/svault.securevault.html#savedata","classes":"tsd-kind-method tsd-parent-kind-class","parent":"SVault.SecureVault"},{"id":23,"kind":2048,"name":"loadData","url":"classes/svault.securevault.html#loaddata","classes":"tsd-kind-method tsd-parent-kind-class","parent":"SVault.SecureVault"},{"id":24,"kind":2048,"name":"decryptData","url":"classes/svault.securevault.html#decryptdata","classes":"tsd-kind-method tsd-parent-kind-class","parent":"SVault.SecureVault"},{"id":25,"kind":2048,"name":"genKey","url":"classes/svault.securevault.html#genkey","classes":"tsd-kind-method tsd-parent-kind-class tsd-is-static","parent":"SVault.SecureVault"},{"id":26,"kind":2048,"name":"pushStorage","url":"classes/svault.securevault.html#pushstorage","classes":"tsd-kind-method tsd-parent-kind-class","parent":"SVault.SecureVault"},{"id":27,"kind":2048,"name":"setStorage","url":"classes/svault.securevault.html#setstorage","classes":"tsd-kind-method tsd-parent-kind-class","parent":"SVault.SecureVault"},{"id":28,"kind":2048,"name":"getStorage","url":"classes/svault.securevault.html#getstorage","classes":"tsd-kind-method tsd-parent-kind-class","parent":"SVault.SecureVault"},{"id":29,"kind":2048,"name":"findStorage","url":"classes/svault.securevault.html#findstorage","classes":"tsd-kind-method tsd-parent-kind-class","parent":"SVault.SecureVault"},{"id":30,"kind":2048,"name":"clearVault","url":"classes/svault.securevault.html#clearvault","classes":"tsd-kind-method tsd-parent-kind-class","parent":"SVault.SecureVault"},{"id":31,"kind":32,"name":"vaultVersion","url":"modules/svault.html#vaultversion","classes":"tsd-kind-variable tsd-parent-kind-namespace tsd-is-not-exported","parent":"SVault"},{"id":32,"kind":2,"name":"MLParser","url":"modules/mlparser.html","classes":"tsd-kind-namespace"},{"id":33,"kind":256,"name":"MLItem","url":"interfaces/mlparser.mlitem.html","classes":"tsd-kind-interface tsd-parent-kind-namespace","parent":"MLParser"},{"id":34,"kind":1024,"name":"mail","url":"interfaces/mlparser.mlitem.html#mail","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"MLParser.MLItem"},{"id":35,"kind":1024,"name":"name","url":"interfaces/mlparser.mlitem.html#name","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"MLParser.MLItem"},{"id":36,"kind":64,"name":"parseMails","url":"modules/mlparser.html#parsemails","classes":"tsd-kind-function tsd-parent-kind-namespace","parent":"MLParser"},{"id":37,"kind":256,"name":"OTGlobalConfig","url":"interfaces/otglobalconfig.html","classes":"tsd-kind-interface"},{"id":38,"kind":1024,"name":"mail","url":"interfaces/otglobalconfig.html#mail","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"OTGlobalConfig"},{"id":39,"kind":1024,"name":"mailFrom","url":"interfaces/otglobalconfig.html#mailfrom","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"OTGlobalConfig"},{"id":40,"kind":1024,"name":"outFileMatch","url":"interfaces/otglobalconfig.html#outfilematch","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"OTGlobalConfig"},{"id":41,"kind":1024,"name":"inFileMail","url":"interfaces/otglobalconfig.html#infilemail","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"OTGlobalConfig"},{"id":42,"kind":1024,"name":"htmlPath","url":"interfaces/otglobalconfig.html#htmlpath","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"OTGlobalConfig"},{"id":43,"kind":1024,"name":"usedTokens","url":"interfaces/otglobalconfig.html#usedtokens","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"OTGlobalConfig"},{"id":44,"kind":1024,"name":"usedMails","url":"interfaces/otglobalconfig.html#usedmails","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"OTGlobalConfig"},{"id":45,"kind":1024,"name":"dryrun","url":"interfaces/otglobalconfig.html#dryrun","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"OTGlobalConfig"},{"id":46,"kind":1024,"name":"force","url":"interfaces/otglobalconfig.html#force","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"OTGlobalConfig"},{"id":47,"kind":64,"name":"shuffleArray","url":"globals.html#shufflearray","classes":"tsd-kind-function"},{"id":48,"kind":64,"name":"mkstringCN","url":"globals.html#mkstringcn","classes":"tsd-kind-function"},{"id":49,"kind":64,"name":"delay","url":"globals.html#delay","classes":"tsd-kind-function"},{"id":50,"kind":2,"name":"MLGenerator","url":"modules/mlgenerator.html","classes":"tsd-kind-namespace"},{"id":51,"kind":256,"name":"MLGenReturn","url":"interfaces/mlgenerator.mlgenreturn.html","classes":"tsd-kind-interface tsd-parent-kind-namespace","parent":"MLGenerator"},{"id":52,"kind":1024,"name":"codes","url":"interfaces/mlgenerator.mlgenreturn.html#codes","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"MLGenerator.MLGenReturn"},{"id":53,"kind":1024,"name":"mails","url":"interfaces/mlgenerator.mlgenreturn.html#mails","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"MLGenerator.MLGenReturn"},{"id":54,"kind":64,"name":"generateToken","url":"modules/mlgenerator.html#generatetoken","classes":"tsd-kind-function tsd-parent-kind-namespace","parent":"MLGenerator"},{"id":55,"kind":64,"name":"generateCodes","url":"modules/mlgenerator.html#generatecodes","classes":"tsd-kind-function tsd-parent-kind-namespace tsd-is-not-exported","parent":"MLGenerator"},{"id":56,"kind":64,"name":"sendMails","url":"modules/mlgenerator.html#sendmails","classes":"tsd-kind-function tsd-parent-kind-namespace tsd-is-not-exported","parent":"MLGenerator"},{"id":57,"kind":64,"name":"send","url":"modules/mlgenerator.html#send","classes":"tsd-kind-function tsd-parent-kind-namespace tsd-is-not-exported","parent":"MLGenerator"},{"id":58,"kind":32,"name":"configPath","url":"globals.html#configpath","classes":"tsd-kind-variable"},{"id":59,"kind":32,"name":"action","url":"globals.html#action","classes":"tsd-kind-variable"},{"id":60,"kind":32,"name":"pubKey","url":"globals.html#pubkey","classes":"tsd-kind-variable"},{"id":61,"kind":32,"name":"privKey","url":"globals.html#privkey","classes":"tsd-kind-variable"},{"id":62,"kind":32,"name":"safeFile","url":"globals.html#safefile","classes":"tsd-kind-variable"},{"id":63,"kind":32,"name":"mails","url":"globals.html#mails","classes":"tsd-kind-variable"},{"id":64,"kind":32,"name":"html","url":"globals.html#html","classes":"tsd-kind-variable"},{"id":65,"kind":32,"name":"dryrun","url":"globals.html#dryrun","classes":"tsd-kind-variable"},{"id":66,"kind":32,"name":"force","url":"globals.html#force","classes":"tsd-kind-variable"}],"index":{"version":"2.3.9","fields":["name","parent"],"fieldVectors":[["name/0",[0,23.477]],["parent/0",[]],["name/1",[1,38.14]],["parent/1",[0,2.081]],["name/2",[2,33.032]],["parent/2",[3,2.407]],["name/3",[4,33.032]],["parent/3",[3,2.407]],["name/4",[5,38.14]],["parent/4",[3,2.407]],["name/5",[6,38.14]],["parent/5",[3,2.407]],["name/6",[7,38.14]],["parent/6",[0,2.081]],["name/7",[2,33.032]],["parent/7",[8,2.629]],["name/8",[4,33.032]],["parent/8",[8,2.629]],["name/9",[9,38.14]],["parent/9",[8,2.629]],["name/10",[10,38.14]],["parent/10",[0,2.081]],["name/11",[11,38.14]],["parent/11",[12,2.629]],["name/12",[13,38.14]],["parent/12",[12,2.629]],["name/13",[14,38.14]],["parent/13",[12,2.629]],["name/14",[15,38.14]],["parent/14",[0,2.081]],["name/15",[16,38.14]],["parent/15",[17,1.255]],["name/16",[18,38.14]],["parent/16",[17,1.255]],["name/17",[19,38.14]],["parent/17",[17,1.255]],["name/18",[20,38.14]],["parent/18",[17,1.255]],["name/19",[21,38.14]],["parent/19",[17,1.255]],["name/20",[22,38.14]],["parent/20",[17,1.255]],["name/21",[23,38.14]],["parent/21",[17,1.255]],["name/22",[24,38.14]],["parent/22",[17,1.255]],["name/23",[25,38.14]],["parent/23",[17,1.255]],["name/24",[26,38.14]],["parent/24",[17,1.255]],["name/25",[27,38.14]],["parent/25",[17,1.255]],["name/26",[28,38.14]],["parent/26",[17,1.255]],["name/27",[29,38.14]],["parent/27",[17,1.255]],["name/28",[30,38.14]],["parent/28",[17,1.255]],["name/29",[31,38.14]],["parent/29",[17,1.255]],["name/30",[32,38.14]],["parent/30",[17,1.255]],["name/31",[33,38.14]],["parent/31",[0,2.081]],["name/32",[34,29.667]],["parent/32",[]],["name/33",[35,38.14]],["parent/33",[34,2.629]],["name/34",[36,33.032]],["parent/34",[37,2.927]],["name/35",[38,38.14]],["parent/35",[37,2.927]],["name/36",[39,38.14]],["parent/36",[34,2.629]],["name/37",[40,18.681]],["parent/37",[]],["name/38",[36,33.032]],["parent/38",[40,1.656]],["name/39",[41,38.14]],["parent/39",[40,1.656]],["name/40",[42,38.14]],["parent/40",[40,1.656]],["name/41",[43,38.14]],["parent/41",[40,1.656]],["name/42",[44,38.14]],["parent/42",[40,1.656]],["name/43",[45,38.14]],["parent/43",[40,1.656]],["name/44",[46,38.14]],["parent/44",[40,1.656]],["name/45",[47,33.032]],["parent/45",[40,1.656]],["name/46",[48,33.032]],["parent/46",[40,1.656]],["name/47",[49,38.14]],["parent/47",[]],["name/48",[50,38.14]],["parent/48",[]],["name/49",[51,38.14]],["parent/49",[]],["name/50",[52,23.477]],["parent/50",[]],["name/51",[53,38.14]],["parent/51",[52,2.081]],["name/52",[54,38.14]],["parent/52",[55,2.927]],["name/53",[56,33.032]],["parent/53",[55,2.927]],["name/54",[57,38.14]],["parent/54",[52,2.081]],["name/55",[58,38.14]],["parent/55",[52,2.081]],["name/56",[59,38.14]],["parent/56",[52,2.081]],["name/57",[60,38.14]],["parent/57",[52,2.081]],["name/58",[61,38.14]],["parent/58",[]],["name/59",[62,38.14]],["parent/59",[]],["name/60",[63,38.14]],["parent/60",[]],["name/61",[64,38.14]],["parent/61",[]],["name/62",[65,38.14]],["parent/62",[]],["name/63",[56,33.032]],["parent/63",[]],["name/64",[66,38.14]],["parent/64",[]],["name/65",[47,33.032]],["parent/65",[]],["name/66",[48,33.032]],["parent/66",[]]],"invertedIndex":[["action",{"_index":62,"name":{"59":{}},"parent":{}}],["clearvault",{"_index":32,"name":{"30":{}},"parent":{}}],["codes",{"_index":54,"name":{"52":{}},"parent":{}}],["configpath",{"_index":61,"name":{"58":{}},"parent":{}}],["constructor",{"_index":21,"name":{"19":{}},"parent":{}}],["d",{"_index":4,"name":{"3":{},"8":{}},"parent":{}}],["decryptdata",{"_index":26,"name":{"24":{}},"parent":{}}],["delay",{"_index":51,"name":{"49":{}},"parent":{}}],["dryrun",{"_index":47,"name":{"45":{},"65":{}},"parent":{}}],["findstorage",{"_index":31,"name":{"29":{}},"parent":{}}],["force",{"_index":48,"name":{"46":{},"66":{}},"parent":{}}],["generatecodes",{"_index":58,"name":{"55":{}},"parent":{}}],["generatetoken",{"_index":57,"name":{"54":{}},"parent":{}}],["genkey",{"_index":27,"name":{"25":{}},"parent":{}}],["getstorage",{"_index":30,"name":{"28":{}},"parent":{}}],["html",{"_index":66,"name":{"64":{}},"parent":{}}],["htmlpath",{"_index":44,"name":{"42":{}},"parent":{}}],["infilemail",{"_index":43,"name":{"41":{}},"parent":{}}],["items",{"_index":11,"name":{"11":{}},"parent":{}}],["iv",{"_index":6,"name":{"5":{}},"parent":{}}],["k",{"_index":5,"name":{"4":{}},"parent":{}}],["loaddata",{"_index":25,"name":{"23":{}},"parent":{}}],["mail",{"_index":36,"name":{"34":{},"38":{}},"parent":{}}],["mailfrom",{"_index":41,"name":{"39":{}},"parent":{}}],["mails",{"_index":56,"name":{"53":{},"63":{}},"parent":{}}],["mkstringcn",{"_index":50,"name":{"48":{}},"parent":{}}],["mlgenerator",{"_index":52,"name":{"50":{}},"parent":{"51":{},"54":{},"55":{},"56":{},"57":{}}}],["mlgenerator.mlgenreturn",{"_index":55,"name":{},"parent":{"52":{},"53":{}}}],["mlgenreturn",{"_index":53,"name":{"51":{}},"parent":{}}],["mlitem",{"_index":35,"name":{"33":{}},"parent":{}}],["mlparser",{"_index":34,"name":{"32":{}},"parent":{"33":{},"36":{}}}],["mlparser.mlitem",{"_index":37,"name":{},"parent":{"34":{},"35":{}}}],["name",{"_index":38,"name":{"35":{}},"parent":{}}],["otglobalconfig",{"_index":40,"name":{"37":{}},"parent":{"38":{},"39":{},"40":{},"41":{},"42":{},"43":{},"44":{},"45":{},"46":{}}}],["outfilematch",{"_index":42,"name":{"40":{}},"parent":{}}],["parsemails",{"_index":39,"name":{"36":{}},"parent":{}}],["privatekey",{"_index":14,"name":{"13":{}},"parent":{}}],["privkey",{"_index":64,"name":{"61":{}},"parent":{}}],["privpath",{"_index":18,"name":{"16":{}},"parent":{}}],["pubkey",{"_index":63,"name":{"60":{}},"parent":{}}],["publickey",{"_index":13,"name":{"12":{}},"parent":{}}],["pubpath",{"_index":19,"name":{"17":{}},"parent":{}}],["pushdata",{"_index":22,"name":{"20":{}},"parent":{}}],["pushstorage",{"_index":28,"name":{"26":{}},"parent":{}}],["safe",{"_index":16,"name":{"15":{}},"parent":{}}],["safefile",{"_index":65,"name":{"62":{}},"parent":{}}],["savedata",{"_index":24,"name":{"22":{}},"parent":{}}],["securevault",{"_index":15,"name":{"14":{}},"parent":{}}],["securevaultitem",{"_index":1,"name":{"1":{}},"parent":{}}],["securevaultlist",{"_index":10,"name":{"10":{}},"parent":{}}],["send",{"_index":60,"name":{"57":{}},"parent":{}}],["sendmails",{"_index":59,"name":{"56":{}},"parent":{}}],["setstorage",{"_index":29,"name":{"27":{}},"parent":{}}],["shufflearray",{"_index":49,"name":{"47":{}},"parent":{}}],["storage",{"_index":20,"name":{"18":{}},"parent":{}}],["storageitem",{"_index":7,"name":{"6":{}},"parent":{}}],["svault",{"_index":0,"name":{"0":{}},"parent":{"1":{},"6":{},"10":{},"14":{},"31":{}}}],["svault.securevault",{"_index":17,"name":{},"parent":{"15":{},"16":{},"17":{},"18":{},"19":{},"20":{},"21":{},"22":{},"23":{},"24":{},"25":{},"26":{},"27":{},"28":{},"29":{},"30":{}}}],["svault.securevaultitem",{"_index":3,"name":{},"parent":{"2":{},"3":{},"4":{},"5":{}}}],["svault.securevaultlist",{"_index":12,"name":{},"parent":{"11":{},"12":{},"13":{}}}],["svault.storageitem",{"_index":8,"name":{},"parent":{"7":{},"8":{},"9":{}}}],["t",{"_index":9,"name":{"9":{}},"parent":{}}],["u",{"_index":2,"name":{"2":{},"7":{}},"parent":{}}],["usedmails",{"_index":46,"name":{"44":{}},"parent":{}}],["usedtokens",{"_index":45,"name":{"43":{}},"parent":{}}],["vaultversion",{"_index":33,"name":{"31":{}},"parent":{}}],["writetransaction",{"_index":23,"name":{"21":{}},"parent":{}}]],"pipeline":[]}} \ No newline at end of file diff --git a/docs/classes/svault.securevault.html b/docs/classes/svault.securevault.html new file mode 100644 index 0000000..282ac08 --- /dev/null +++ b/docs/classes/svault.securevault.html @@ -0,0 +1,697 @@ + + + + + + SecureVault | opentoken + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + + + +
+
+ Menu +
+
+
+
+
+
+ +

Class SecureVault

+
+
+
+
+
+
+
+
+
+

Class representing a SecureVault.

+
+
+
+
+

Hierarchy

+
    +
  • + SecureVault +
  • +
+
+
+

Index

+
+
+
+

Constructors

+ +
+
+

Properties

+ +
+
+

Methods

+ +
+
+
+
+
+

Constructors

+
+ +

constructor

+
    +
  • new SecureVault(publicKey?: undefined | string, privateKey?: undefined | string): SecureVault
  • +
+
    +
  • + +
    +
    +

    Create a SecureVault.

    +
    +
    +

    Parameters

    +
      +
    • +
      Optional publicKey: undefined | string
      +
      +
      +

      Path to public key.

      +
      +
      +
    • +
    • +
      Optional privateKey: undefined | string
      +
      +
      +

      Path to private key.

      +
      +
      +
    • +
    +

    Returns SecureVault

    +
  • +
+
+
+
+

Properties

+
+ +

Optional privPath

+
privPath: undefined | string
+ +
+
+

Path to private key

+
+
+
+
+ +

Optional pubPath

+
pubPath: undefined | string
+ +
+
+

Path to public key

+
+
+
+
+ +

safe

+ + +
+
+

Safe object

+
+
+
+
+ +

storage

+
storage: StorageItem[]
+ +
+
+

Array of unencrypted items

+
+
+
+
+
+

Methods

+
+ +

clearVault

+
    +
  • clearVault(): void
  • +
+
    +
  • + +
    +
    +

    Clears all encrypted items from safe.

    +
    +
    +

    Returns void

    +
  • +
+
+
+ +

decryptData

+
    +
  • decryptData(): Promise<void>
  • +
+
    +
  • + +
    +
    +

    Decrypts safe data. + Requires specified and loaded private key. + Prints data to console.

    +
    +
    +

    Returns Promise<void>

    +

    Resolves promise after decrypted

    +
  • +
+
+
+ +

findStorage

+ +
    +
  • + +
    +
    +

    Gets list of UUIDs matching the tag.

    +
    +
    +

    Parameters

    +
      +
    • +
      tag: string
      +
      +

      tag to search for

      +
      +
    • +
    +

    Returns StorageItem[]

    +

    UUID from item.

    +
  • +
+
+
+ +

getStorage

+
    +
  • getStorage(suuid: string): any
  • +
+
    +
  • + +
    +
    +

    Gets unencrypted data of item specified by suuid.

    +
    +
    +

    Parameters

    +
      +
    • +
      suuid: string
      +
      +

      UUID for item

      +
      +
    • +
    +

    Returns any

    +

    Data from item.

    +
  • +
+
+
+ +

loadData

+
    +
  • loadData(path: string): Promise<void>
  • +
+
    +
  • + +
    +
    +

    Loads safe from file and check compatibility

    +
    +
    +

    Parameters

    +
      +
    • +
      path: string
      +
      +

      Path to safefile.

      +
      +
    • +
    +

    Returns Promise<void>

    +

    Resolves promise after loaded

    +
  • +
+
+
+ +

pushData

+
    +
  • pushData(data: any): Promise<string>
  • +
+
    +
  • + +
    +
    +

    Encrypts and appends data to SecureVault. + Also writes data to transaction log using @function writeTransaction

    +
    +
    +

    Parameters

    +
      +
    • +
      data: any
      +
      +

      Path to public key.

      +
      +
    • +
    +

    Returns Promise<string>

    +

    Returns the uuid of the added object as promise

    +
  • +
+
+
+ +

pushStorage

+
    +
  • pushStorage(tag: string, data: any): void
  • +
+
    +
  • + +
    +
    +

    Appends unencrypted data to safe.

    +
    +
    +

    Parameters

    +
      +
    • +
      tag: string
      +
      +

      Tag for item

      +
      +
    • +
    • +
      data: any
      +
      +

      Data to store.

      +
      +
    • +
    +

    Returns void

    +
  • +
+
+
+ +

saveData

+
    +
  • saveData(path: string): Promise<void>
  • +
+
    +
  • + +
    +
    +

    Saves safe to file

    +
    +
    +

    Parameters

    +
      +
    • +
      path: string
      +
      +

      Path to safefile.

      +
      +
    • +
    +

    Returns Promise<void>

    +

    Resolves promise after loaded

    +
  • +
+
+
+ +

setStorage

+
    +
  • setStorage(suuid: string, data: any): void
  • +
+
    +
  • + +
    +
    +

    Sets unencrypted data for item specified by suuid.

    +
    +
    +

    Parameters

    +
      +
    • +
      suuid: string
      +
      +

      UUID for item

      +
      +
    • +
    • +
      data: any
      +
      +

      Data to store.

      +
      +
    • +
    +

    Returns void

    +
  • +
+
+
+ +

writeTransaction

+
    +
  • writeTransaction(payload: string): void
  • +
+
    +
  • + +
    +
    +

    Writes data to the vault log file located at ./vault.log

    +
    +
    +

    Parameters

    +
      +
    • +
      payload: string
      +
      +

      Text to append

      +
      +
    • +
    +

    Returns void

    +
  • +
+
+
+ +

Static genKey

+
    +
  • genKey(publicKeyDir: string, privateKeyDir: string): void
  • +
+
    +
  • + +
    +
    +

    Generates RSA keypair.

    +
    +
    +

    Parameters

    +
      +
    • +
      publicKeyDir: string
      +
    • +
    • +
      privateKeyDir: string
      +
    • +
    +

    Returns void

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

Legend

+
+
    +
  • Constructor
  • +
  • Property
  • +
  • Method
  • +
+
    +
  • Property
  • +
+
    +
  • Static method
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + \ No newline at end of file diff --git a/docs/globals.html b/docs/globals.html new file mode 100644 index 0000000..eb2d214 --- /dev/null +++ b/docs/globals.html @@ -0,0 +1,380 @@ + + + + + + opentoken + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + + + +
+
+ Menu +
+
+
+
+
+
+ +

opentoken

+
+
+
+
+
+
+
+

Index

+
+
+
+

Namespaces

+ +
+
+

Interfaces

+ +
+
+

Variables

+ +
+
+

Functions

+ +
+
+
+
+
+

Variables

+
+ +

Let action

+
action: number = -1
+ +
+
+ +

Let configPath

+
configPath: string = ""
+ +
+
+ +

Let dryrun

+
dryrun: boolean = false
+ +
+
+ +

Let force

+
force: boolean = false
+ +
+
+ +

Let html

+
html: string = ""
+ +
+
+ +

Let mails

+
mails: string = ""
+ +
+
+ +

Let privKey

+
privKey: string = ""
+ +
+
+ +

Let pubKey

+
pubKey: string = ""
+ +
+
+ +

Let safeFile

+
safeFile: string = ""
+ +
+
+
+

Functions

+
+ +

delay

+
    +
  • delay(t: number): Promise<unknown>
  • +
+
    +
  • + +
    +
    +

    Wraps setTimeout into Promise

    +
    +
    +

    Parameters

    +
      +
    • +
      t: number
      +
      +

      Millisceonds

      +
      +
    • +
    +

    Returns Promise<unknown>

    +
  • +
+
+
+ +

mkstringCN

+
    +
  • mkstringCN(length: number): string
  • +
+
    +
  • + +
    +
    +

    Generate random string with specified length. + Generates only numbers and capital letters.

    +
    +
    +

    Parameters

    +
      +
    • +
      length: number
      +
      +

      length of String

      +
      +
    • +
    +

    Returns string

    +

    generated string

    +
  • +
+
+
+ +

shuffleArray

+
    +
  • shuffleArray(array: any[]): void
  • +
+
    +
  • + +
    +
    +

    Randomize items in an array

    +
    +
    +

    Parameters

    +
      +
    • +
      array: any[]
      +
      +

      Array to be shuffeled

      +
      +
    • +
    +

    Returns void

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

Legend

+
+
    +
  • Property
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + \ No newline at end of file diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000..af3a006 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,316 @@ + + + + + + opentoken + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + + + +
+
+ Menu +
+
+
+
+
+
+ +

opentoken

+
+
+
+
+
+
+
+ +

one-time-code.js

+
+

Dies ist ein Programm zum erzeugen von anonymen Schlüsseln. Diese werden automatisch den Teilnehmern zugesendet. + Zudem wird ein asymetrisch verschlüsselter Safe erstellt.

+ +

Zweck

+
+

Für ananoyme Wahlen muss sichergestellt werden, dass:

+
    +
  1. Nur berechtigter Personen abstimmen können
  2. +
  3. Jeder Wähler nicht rückverfolgbar ist
  4. +
  5. Jeder Wähler nur einmal abstimmen kann
  6. +
+

Punkte 1. und 2. Lassen sich mit dieser Anwendug realisieren.

+ +

Funktionsprinzip

+
+

Diese Anwendung muss auf zwei Systemen installiert sein. Beide Systeme dürfen nicht aufeinander Zugreifen können und müssen von verschiedenen Personen bedient werden. + Die beiden Systeme sind:

+
    +
  • System A & Person A: Hier werden die Schlüssel erzeugt, benutzern zufällig zugewiesen und versendet.
  • +
  • System B & Person B: Hier wird das Schlüsselpaar erzeugt und hier kann der Safe entschlüsselt werden.
  • +
  • Person C: Erhält von Person A die gültigen Codes und verifiziert die eingehenden Wahlzettel.
  • +
+

Da Person A die SChlüssel-Nutzer Zuordnung zu keinem Zeitpunkt kennt, kann sie auch die selbe Person wie Person C sein.

+ +

Schritt 1

+
+

Auf System B wird ein Schlüsselpaar erzeugt. Dies besteht aus dem Öffentlichen und Privaten schlüssel.

+
    +
  • Der Öffentliche schlüssel dient zur Verschlüsselung der Daten und kann nicht zum entschlüsseln verwendet werden.
  • +
  • Der Private schlüssel dient zur entschlüsselung des Safes und darf System B NIEMALS verlassen.
  • +
+

Dazu wird z.B. folgender Befehl ausgeführt: + `ts-node .\index.ts --privkey private.key --pubkey public.key --genkey

+

Der erzeugte Öffentliche schlüssel muss an Person A übergeben werden. Diese nutzt den Schlüssel auf System A zum verschlüsseln des Passwortsafes.

+ +

Schritt 2

+
+

Auf System A werden jetzt die Codes erzeugt und an die Nutzer versendet. + Die Nutzer-Schlüssel zuweisung erfolgt temporär auf System A, ist jedoch nicht auslesbar und wird unmittelbar im Passwortsafe gespeichert.

+

Person A führt folgenden Befehl aus: + `ts-node .\index.ts --config config.json --pubkey public.key --send --safe .\out\credentials.json --mails mail.txt -html template.html

+

Dabei wird eine Liste mit den Mails und Namen sowie der schlüssel übergeben.

+

Der Ausfbau der mail.txt ist:

+
<mail>;<name>
+<mail>;<name>
+...
+

Es werden drei Ausgaben erzeugt:

+
    +
  • Eine RegEx vorlage für alle Codes
  • +
  • Safe-Datei
  • +
+

Die Speicherorte der Code-Files werden in der config.json angegeben. + Der Safe wird an Person B weitergegeben.

+

Das Programm versendet automatisch Mails an alle Personen. Die HTML Vorlage wird mit --html angegeben. + In der Vorlage werden folgende Zeichenketten ersetzt: + {{code}} => Genereirter Code {{name}} + => Name + `{{mail}} + => Mail

+

Der SMTP-Relay-Server wird in der config.json angegeben. + Geenaue Doku: https://nodemailer.com/smtp/

+ +

Schritt 3

+
+

Ggf. muss der Safe entschlüsselt werden. Beispielfälle wären:

+
    +
  • Teilnehmer hat keinen Zugriff auf das Mailkonto
  • +
  • Teilnehmer hat seinen Code vergessen
  • +
  • Mail wurd durch den Spamfilter entfernt
  • +
+

Person B muss dann mit dem Privaten Schlüssel den Safe auslesen und dem Teilnehmer seinen Code zukommen lassen. + Dazu muss golgender Befehl ausgeführt werden: + ts-node .\index.ts --privkey private.key --decrypt --safe .\out\credentials.json

+ +

Config-Datei

+
+
{
+    "mail":{
+        "host": "<mailserver>",
+        "port": <mailport>,
+        "secure": <use ssl>,
+        "auth": {
+            "user": "<mail-user>",
+            "pass": "<mail-password>"
+        },
+        "tls": {
+            "rejectUnauthorized": false,
+            "ciphers":"SSLv3"
+        }
+    },
+    "mailFrom": "<absender name>",
+    "outFileMatch": "<ausgabedatei regex>"
+}
+ +

Syntax

+
+

==> Schlüsselpaar Erzeugen + ts-node .\index.ts --privkey <path-to-private-key> --pubkey <path-to-public-key> --genkey

+

z.B. ts-node .\index.ts --privkey private.key --pubkey public.key --genkey

+

==> Codes Erzeugen und versenden + ts-node .\index.ts --config <path-to-config-key> --pubkey <path-to-public-key> --send --safe credentials.json --mails <path-to-mail-list> -html <path-to-html-template>

+

Achtung: Es wird im Safe geprüft, ob Mailadressen bereits "bedient" wurden. Sollte dies der Fall sein, werden keine Mails an diese Adresse gesendet. Dies lässt sich mit dem Schalter --force umgehen.

+

z.B. ts-node .\index.ts --config config.json --pubkey public.key --send --safe credentials.json --mails mail.txt -html template.html

+

==> Safe entschlüsseln + ts-node .\index.ts --privkey <path-to-private-key> --decrypt --safe credentials.json

+

z.B. ts-node .\index.ts --privkey private.key --decrypt --safe credentials.json

+ +

Erweiterte Schalter

+
+
    +
  • --dryrun : Mails werden nicht versendet und der Safe wird nicht verändert.
  • +
  • --force : Alle Codes werden neu generiert und alle mails werden gesendet. Ignoriere bereits gesendete mails.
  • +
+ +

Gepackte Binaries

+
+

Die gepackten Binaries sind für Linux, MacOS und Windoof verfügbar: Binaries

+

Die befehle ändern sich wie folgt:

+

==> Schlüsselpaar Erzeuge + ./opentoken --privkey <path-to-private-key> --pubkey <path-to-public-key> --genkey

+

z.B. ./opentoken --privkey private.key --pubkey public.key --genkey

+

==> Codes Erzeugen und versenden + ./opentoken --config <path-to-config-key> --pubkey <path-to-public-key> --send --safe .\out\credentials.json --mails <path-to-mail-list> -html <path-to-html-template>

+

z.B. ./opentoken --config config.json --pubkey public.key --send --safe .\out\credentials.json --mails mail.txt -html template.html

+

==> Safe entschlüsseln + ./opentoken --privkey <path-to-private-key> --decrypt --safe .\out\credentials.json

+

z.B. ./opentoken --privkey private.key --decrypt --safe .\out\credentials.json

+ +

Ausführen des Quellcodes

+
+

Der Sourcecode kann auch über ts-node ausgeführt werden. + Dazu ist Node.js Version 12 zu verwenden

+

nvm use 12

+

Zum Ausführen sind folgende npm Pakete notwendig:

+
    +
  • typescript
  • +
  • tslint
  • +
  • ts-node
  • +
+

Installerien sie diese mit: + npm install -g typescript tslint ts-node

+

Clonen sie dieses Repository auf ihren lokalen rechner und wechseln sie anschließend in dessen verzeichniss:

+

git clone https://gitlab.dennisgunia.de/dennisgunia/one-time-code-js.git

+

cd one-time-code-js

+

Installieren sie alle lokalen npm Pakete

+

npm install

+

Kopieren Sie die Config-Template und passen Sie die SMTP-Zugangsdaten an:

+

cp config.template.json config.json

+

vim config.json

+

Das Skript kann nun über npm run-script exec oder ts-node index.js ausgeführt werden.

+ +

Packen des Quellcodes

+
+

Zum Packen des Quellcodes ist das npm-Paket pkg zu installieren:

+

npm install -g pkg

+

Anschließend wird der Code in JS transpiliert und durch pkg gepackt:

+

npm run-script build

+

Die Binaries werden in ./bin gespeichert. Diese sind auch auf Systemen ohne node.js ausführbar.

+ +

Was landet im Safe?

+
+

Im safe landen die verschlüsselten Zuordnungen zwischen Codes und Mailadressen.

+

Zudem werden die verwendeten Codes und die bereits gesendeten Mailadressen seperat voneinander und zufällig gemischt in Klartext gespeichert.

+

Dies ermöglicht es, nachträglich benutzer hinzuzufügen, ohne allen anderen neue Mails oder gar neue Codes zukommen lassen zu müssen.

+

Es ist jedoch nocht empfohlen, nachträglich mails hinzuzufügen, da dies, abhängig von der Menge der gleichzeitig hinzugefügten Adressen eine grobe oder ggf. auch sehr genaue zuordnung zwischen Code und Mail der Nachzügler möglich ist.

+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Property
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + \ No newline at end of file diff --git a/docs/interfaces/mlgenerator.mlgenreturn.html b/docs/interfaces/mlgenerator.mlgenreturn.html new file mode 100644 index 0000000..fe63d83 --- /dev/null +++ b/docs/interfaces/mlgenerator.mlgenreturn.html @@ -0,0 +1,202 @@ + + + + + + MLGenReturn | opentoken + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + + + +
+
+ Menu +
+
+
+
+
+
+ +

Interface MLGenReturn

+
+
+
+
+
+
+
+
+
+

Interface used to Return codes and mails form the main Function generateToken

+
+
+
+
+

Hierarchy

+
    +
  • + MLGenReturn +
  • +
+
+
+

Index

+
+
+
+

Properties

+ +
+
+
+
+
+

Properties

+
+ +

codes

+
codes: string[]
+ +
+
+

List of generated codes

+
+
+
+
+ +

mails

+
mails: MLItem[]
+ +
+
+

List of processed mails

+
+
+
+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Property
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + \ No newline at end of file diff --git a/docs/interfaces/mlparser.mlitem.html b/docs/interfaces/mlparser.mlitem.html new file mode 100644 index 0000000..c505224 --- /dev/null +++ b/docs/interfaces/mlparser.mlitem.html @@ -0,0 +1,193 @@ + + + + + + MLItem | opentoken + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + + + +
+
+ Menu +
+
+
+
+
+
+ +

Interface MLItem

+
+
+
+
+
+
+
+
+
+

Interface containing properties of a single mail line

+
+
+
+
+

Hierarchy

+
    +
  • + MLItem +
  • +
+
+
+

Index

+
+
+
+

Properties

+ +
+
+
+
+
+

Properties

+
+ +

mail

+
mail: string
+ +
+
+

mail adress parsed form file

+
+
+
+
+ +

name

+
name: string
+ +
+
+

name parsed form file

+
+
+
+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Property
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + \ No newline at end of file diff --git a/docs/interfaces/otglobalconfig.html b/docs/interfaces/otglobalconfig.html new file mode 100644 index 0000000..1370c08 --- /dev/null +++ b/docs/interfaces/otglobalconfig.html @@ -0,0 +1,347 @@ + + + + + + OTGlobalConfig | opentoken + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + + + +
+
+ Menu +
+
+
+
+
+
+ +

Interface OTGlobalConfig

+
+
+
+
+
+
+
+
+
+

Interface containing all config properties for opentoken

+
+
+
+
+

Hierarchy

+
    +
  • + OTGlobalConfig +
  • +
+
+
+

Index

+
+
+
+

Properties

+ +
+
+
+
+
+

Properties

+
+ +

dryrun

+
dryrun: boolean
+ +
+
+

switch for dryrun

+
+
+
+
+ +

force

+
force: boolean
+ +
+
+

switch for force

+
+
+
+
+ +

Optional htmlPath

+
htmlPath: undefined | string
+ +
+
+

path to file containing mail template

+
+
+
+
+ +

Optional inFileMail

+
inFileMail: undefined | string
+ +
+
+

path to file containing mails

+
+
+
+
+ +

mail

+
mail: SMTPTransport
+ +
+
+

nodemailer SMTP configuration

+
+
+
+
+ +

mailFrom

+
mailFrom: string
+ +
+
+

sender alias

+
+
+
+
+ +

outFileMatch

+
outFileMatch: string
+ +
+
+

path to file containing matches

+
+
+
+
+ +

Optional usedMails

+
usedMails: MLItem[]
+ +
+
+

List of used mail adresses

+
+
+
+
+ +

Optional usedTokens

+
usedTokens: string[]
+ +
+
+

List of used tokens

+
+
+
+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Property
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + \ No newline at end of file diff --git a/docs/interfaces/svault.securevaultitem.html b/docs/interfaces/svault.securevaultitem.html new file mode 100644 index 0000000..6abbcd9 --- /dev/null +++ b/docs/interfaces/svault.securevaultitem.html @@ -0,0 +1,240 @@ + + + + + + SecureVaultItem | opentoken + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + + + +
+
+ Menu +
+
+
+
+
+
+ +

Interface SecureVaultItem

+
+
+
+
+
+
+
+
+
+

Interface for an vault item containing encrypted data

+
+
+
+
+

Hierarchy

+
    +
  • + SecureVaultItem +
  • +
+
+
+

Index

+
+
+
+

Properties

+ +
+
+
+
+
+

Properties

+
+ +

d

+
d: string
+ +
+
+

data

+
+
+
+
+ +

iv

+
iv: string
+ +
+
+

init vector

+
+
+
+
+ +

k

+
k: string
+ +
+
+

key

+
+
+
+
+ +

u

+
u: string
+ +
+
+

uuid

+
+
+
+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Property
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + \ No newline at end of file diff --git a/docs/interfaces/svault.securevaultlist.html b/docs/interfaces/svault.securevaultlist.html new file mode 100644 index 0000000..413a8b7 --- /dev/null +++ b/docs/interfaces/svault.securevaultlist.html @@ -0,0 +1,206 @@ + + + + + + secureVaultList | opentoken + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + + + +
+
+ Menu +
+
+
+
+
+
+ +

Interface secureVaultList

+
+
+
+
+
+
+
+
+
+

Interface for secureVault Array

+
+
+
+
+

Hierarchy

+
    +
  • + secureVaultList +
  • +
+
+
+

Index

+
+
+
+

Properties

+ +
+
+
+
+
+

Properties

+
+ +

items

+ + +
+
+ +

Optional privateKey

+
privateKey: Buffer
+ +
+
+ +

Optional publicKey

+
publicKey: Buffer
+ +
+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Property
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + \ No newline at end of file diff --git a/docs/interfaces/svault.storageitem.html b/docs/interfaces/svault.storageitem.html new file mode 100644 index 0000000..0259fbf --- /dev/null +++ b/docs/interfaces/svault.storageitem.html @@ -0,0 +1,221 @@ + + + + + + StorageItem | opentoken + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + + + +
+
+ Menu +
+
+
+
+
+
+ +

Interface StorageItem

+
+
+
+
+
+
+
+
+
+

Interface for an vault item containing unencrypted data

+
+
+
+
+

Hierarchy

+
    +
  • + StorageItem +
  • +
+
+
+

Index

+
+
+
+

Properties

+
    +
  • d
  • +
  • t
  • +
  • u
  • +
+
+
+
+
+
+

Properties

+
+ +

d

+
d: string
+ +
+
+

data

+
+
+
+
+ +

t

+
t: string
+ +
+
+

tag (can be used to find specific items)

+
+
+
+
+ +

u

+
u: string
+ +
+
+

uuid

+
+
+
+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Property
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + \ No newline at end of file diff --git a/docs/modules/mlgenerator.html b/docs/modules/mlgenerator.html new file mode 100644 index 0000000..a5400db --- /dev/null +++ b/docs/modules/mlgenerator.html @@ -0,0 +1,484 @@ + + + + + + MLGenerator | opentoken + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + + + +
+
+ Menu +
+
+
+
+
+
+ +

Namespace MLGenerator

+
+
+
+
+
+
+
+
+
+

Namespace containing the code for Generating the Code and delivering the mails

+
+
+
+
+

Index

+
+
+
+

Interfaces

+ +
+
+

Functions

+ +
+
+
+
+
+

Functions

+
+ +

generateCodes

+
    +
  • generateCodes(resolve: (value?: MLGenReturn) => void, error: (reason?: any) => void, mailArray: MLItem[], config: any, dataSafe: SecureVault): Promise<void>
  • +
+
    +
  • + +
    +
    +

    Generate the same amout of codes as distinct mail adresses and stores them to the list file + This function also includes previously used tokens to prevent duplicate tokens. + Rejects if matchfile cannot be saved.

    +
    +
    +
    internal
    +
    +
    +
    +

    Parameters

    +
      +
    • +
      resolve: (value?: MLGenReturn) => void
      +
      +

      Callback to resolve promise

      +
      +
        +
      • + +
          +
        • +

          Parameters

          + +

          Returns void

          +
        • +
        +
      • +
      +
    • +
    • +
      error: (reason?: any) => void
      +
      +

      Callback to reject promise

      +
      +
        +
      • +
          +
        • (reason?: any): void
        • +
        +
          +
        • +

          Parameters

          +
            +
          • +
            Optional reason: any
            +
          • +
          +

          Returns void

          +
        • +
        +
      • +
      +
    • +
    • +
      mailArray: MLItem[]
      +
      +

      list of mail adresses

      +
      +
    • +
    • +
      config: any
      +
      +

      Main configuration object + This Function uses the following variables: + usedTokens -> List of previosly used tokens + outFileMatch -> Path to match file

      +
      +
    • +
    • +
      dataSafe: SecureVault
      +
      +

      Main safe used for logging and storing data

      +
      +
    • +
    +

    Returns Promise<void>

    +
  • +
+
+
+ +

generateToken

+ +
    +
  • + +
    +
    +

    Main function used to generate and deliver codes

    +
    +
    +

    Parameters

    +
      +
    • +
      config: any
      +
      +

      Main configuration object

      +
      +
    • +
    • +
      dataSafe: SecureVault
      +
      +

      Main safe used for logging and storing data

      +
      +
    • +
    +

    Returns Promise<MLGenReturn>

    +

    used codes and processed mails

    +
  • +
+
+
+ +

send

+
    +
  • send(name: string, mail: string, code: string, template: HandlebarsTemplateDelegate<any>, mailserver: Mail, config: any, dataSafe: SecureVault): Promise<void>
  • +
+
    +
  • + +
    +
    +

    Reads template file and compiles template. + Iterate through mails and codes, randomly assign code to mail and send mail to recipient. + If dryrun is enabled, mails will not be sent and new mails won't be included in return. + Rejects if template cannot be read.

    +
    +
    +
    internal
    +
    +
    +
    +

    Parameters

    +
      +
    • +
      name: string
      +
      +

      Name of recpipient

      +
      +
    • +
    • +
      mail: string
      +
      +

      Mail of recpipient

      +
      +
    • +
    • +
      code: string
      +
      +

      Code of recpipient

      +
      +
    • +
    • +
      template: HandlebarsTemplateDelegate<any>
      +
      +

      compiled mail template

      +
      +
    • +
    • +
      mailserver: Mail
      +
      +

      Mailserver settings

      +
      +
    • +
    • +
      config: any
      +
      +

      Main configuration object + This Function uses the following variables: + mail.auth.user -> sender mail adress + mailFrom -> sender mail ailas + dryrun -> Boolean value. If true no mails will be sent.

      +
      +
    • +
    • +
      dataSafe: SecureVault
      +
      +

      Main safe used for logging and storing data

      +
      +
    • +
    +

    Returns Promise<void>

    +
  • +
+
+
+ +

sendMails

+
    +
  • sendMails(resolve: (value?: MLGenReturn) => void, error: (reason?: any) => void, mailArray: MLItem[], codeArray: string[], config: any, dataSafe: SecureVault): Promise<void>
  • +
+
    +
  • + +
    +
    +

    Reads template file and compiles template. + Iterate through mails and codes, randomly assign code to mail and send mail to recipient. + If dryrun is enabled, mails will not be sent and new mails won't be included in return. + Rejects if template cannot be read.

    +
    +
    +
    internal
    +
    +
    +
    +

    Parameters

    +
      +
    • +
      resolve: (value?: MLGenReturn) => void
      +
      +

      Callback to resolve promise

      +
      +
        +
      • + +
          +
        • +

          Parameters

          + +

          Returns void

          +
        • +
        +
      • +
      +
    • +
    • +
      error: (reason?: any) => void
      +
      +

      Callback to reject promise

      +
      +
        +
      • +
          +
        • (reason?: any): void
        • +
        +
          +
        • +

          Parameters

          +
            +
          • +
            Optional reason: any
            +
          • +
          +

          Returns void

          +
        • +
        +
      • +
      +
    • +
    • +
      mailArray: MLItem[]
      +
      +

      list of mail adresses

      +
      +
    • +
    • +
      codeArray: string[]
      +
      +

      list of generated codes

      +
      +
    • +
    • +
      config: any
      +
      +

      Main configuration object + This Function uses the following variables: + htmlPath -> Path to html template + dryrun -> Boolean value. If true no mails will be sent and list won't be updated. + force -> Boolean value. If true all mails are resent. + usedTokens -> Array of Strings. Specifies already used tokens adresses. + usedMails -> Array of Strings. Specifies already served mail adresses. + mail -> mailserver settings

      +
      +
    • +
    • +
      dataSafe: SecureVault
      +
      +

      Main safe used for logging and storing data

      +
      +
    • +
    +

    Returns Promise<void>

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

Legend

+
+
    +
  • Property
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + \ No newline at end of file diff --git a/docs/modules/mlparser.html b/docs/modules/mlparser.html new file mode 100644 index 0000000..ebf200f --- /dev/null +++ b/docs/modules/mlparser.html @@ -0,0 +1,188 @@ + + + + + + MLParser | opentoken + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + + + +
+
+ Menu +
+
+
+
+
+
+ +

Namespace MLParser

+
+
+
+
+
+
+
+
+
+

Namespace containing the code for Parsing the mail list.

+
+
+
+
+

Index

+
+
+
+

Interfaces

+ +
+
+

Functions

+ +
+
+
+
+
+

Functions

+
+ +

parseMails

+ +
    +
  • + +
    +
    +

    Encrypts and appends data to SecureVault. + Also writes data to transaction log using @function writeTransaction

    +
    +
    +

    Parameters

    +
      +
    • +
      config: any
      +
      +

      Reference to config object. + This Function uses the following variables: + inFileMail -> String reference to mail list + force -> Boolean value. If true all mails are resent. + usedMails -> Array of Strings. Specifies already served mail adresses.

      +
      +
    • +
    • +
      dataSafe: SecureVault
      +
      +

      Reference to safe object. This is needed for writing to the vault.log file

      +
      +
    • +
    +

    Returns Promise<MLItem[]>

    +

    Returns an array of all parsed mail adresses as promise

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

Legend

+
+
    +
  • Property
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + \ No newline at end of file diff --git a/docs/modules/svault.html b/docs/modules/svault.html new file mode 100644 index 0000000..ca33ab0 --- /dev/null +++ b/docs/modules/svault.html @@ -0,0 +1,177 @@ + + + + + + SVault | opentoken + + + + + +
+
+
+
+ +
+
+ Options +
+
+ All +
    +
  • Public
  • +
  • Public/Protected
  • +
  • All
  • +
+
+ + + + + + +
+
+ Menu +
+
+
+
+
+
+ +

Namespace SVault

+
+
+
+
+
+
+
+
+
+

Namespace containing the code for the SecureVault.

+
+
+
+
+

Index

+
+
+
+

Classes

+ +
+
+

Interfaces

+ +
+
+

Variables

+ +
+
+
+
+
+

Variables

+
+ +

Const vaultVersion

+
vaultVersion: "v1.2" = "v1.2"
+ +
+
+

vault version number. This variable will be added to the safe file and is used to chack compatibility.

+
+
+
+
+
+ +
+
+
+
+

Legend

+
+
    +
  • Property
  • +
+
+
+
+
+

Generated using TypeDoc

+
+
+ + + \ No newline at end of file diff --git a/index.ts b/index.ts index 9780ec7..8fa64f3 100644 --- a/index.ts +++ b/index.ts @@ -1,7 +1,28 @@ +/** + * Dennis Gunia (c) 2020 + * + * Entry point for opentoken. This file parses the cli parameters and runs the specified actions with the specified ßparameters. + * + * + * @summary Open-Token entry point + * @author Dennis Gunia + * @license Licensed under the Apache License, Version 2.0 (the "License"). + * + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file 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. + */ + import * as fs from 'fs' -import { generateToken } from './src/generate' -import { SecureVault } from './src/vault' -import { exit } from 'process'; +import { OTGlobalConfig } from './src/config.type'; +import { MLGenerator } from './src/generate'; +import { SVault } from './src/vault' let configPath = "", action = -1, pubKey = "", privKey = "", safeFile = "", mails = "", html = "", dryrun = false, force = false; // parse cli args @@ -53,13 +74,13 @@ if (!html && action == 1){ throw new Error("Mail-Template not specified") } if (action == 1){ - let dataSafe: SecureVault = new SecureVault(pubKey,privKey); + let dataSafe: SVault.SecureVault = new SVault.SecureVault(pubKey,privKey); dataSafe.writeTransaction(`Started ...`); // load config const confRaw = fs.readFileSync(configPath, 'utf8') - let config:any = {} + let config: OTGlobalConfig = JSON.parse(confRaw) let addition: boolean = false; // wenn nur weitere hinzugefügt werden - config = JSON.parse(confRaw) + // load safe if present if (fs.existsSync(safeFile)){ dataSafe.loadData(safeFile); @@ -80,7 +101,7 @@ if (action == 1){ console.error("Cannote read config file!") process.exit(100); } - generateToken(config,dataSafe).then(el => { + MLGenerator.generateToken(config,dataSafe).then(el => { if (addition){ dataSafe.setStorage(dataSafe.findStorage("usedTokens")[0].u,el.codes) dataSafe.setStorage(dataSafe.findStorage("usedMails")[0].u,el.mails) @@ -96,11 +117,11 @@ if (action == 1){ console.error("error", err) }) }else if(action == 2){ - let dataSafe: SecureVault = new SecureVault(pubKey,privKey); + let dataSafe: SVault.SecureVault = new SVault.SecureVault(pubKey,privKey); dataSafe.loadData(safeFile); dataSafe.decryptData(); }else if(action == 3){ - SecureVault.genKey(pubKey,privKey); + SVault.SecureVault.genKey(pubKey,privKey); } diff --git a/src/config.type.ts b/src/config.type.ts new file mode 100644 index 0000000..d2f67a8 --- /dev/null +++ b/src/config.type.ts @@ -0,0 +1,46 @@ +/** + * Dennis Gunia (c) 2020 + * + * Interface for global config object + * + * @summary Open-Token entry point + * @author Dennis Gunia + * @license Licensed under the Apache License, Version 2.0 (the "License"). + * + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file 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. + */ + +import SMTPTransport from 'nodemailer/lib/smtp-transport'; +import { MLParser } from './mailParser'; + +/** Interface containing all config properties for opentoken */ +export interface OTGlobalConfig { + /** nodemailer SMTP configuration */ + mail: SMTPTransport, + /** sender alias */ + mailFrom: string, + /** path to file containing matches */ + outFileMatch: string + /** path to file containing mails */ + inFileMail?: string + /** path to file containing mail template */ + htmlPath?: string + + /** List of used tokens */ + usedTokens? : string[] + /** List of used mail adresses */ + usedMails? : MLParser.MLItem[] + + /** switch for dryrun */ + dryrun: boolean + /** switch for force */ + force: boolean +} \ No newline at end of file diff --git a/src/generate.ts b/src/generate.ts index 14452d4..d26b495 100644 --- a/src/generate.ts +++ b/src/generate.ts @@ -1,151 +1,233 @@ +/** + * Dennis Gunia (c) 2020 + * + * Generator Implementation. + * This File provides the implementation of the code generator and mail sending functionality. + * + * + * @summary Generator Implementation. + * @author Dennis Gunia + * @license Licensed under the Apache License, Version 2.0 (the "License"). + * + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file 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. + */ + import * as fs from 'fs' import * as path from 'path' import * as nodemailer from 'nodemailer'; import * as cliProgress from 'cli-progress' -import { shuffleArray } from './util/shuffle'; -import { mkstring } from './util/token'; + import * as Handlebars from "handlebars"; import Mail from 'nodemailer/lib/mailer'; -import { SecureVault } from './vault'; -import { parseMails } from './mailParser'; +import { SVault } from './vault'; +import { MLParser } from './mailParser'; +import { shuffleArray } from './util/shuffle'; +import { delay, mkstringCN } from './util/misc'; -interface mail{ - mail: string; - name: string; -} - -export interface genReturn{ - codes: string[]; - mails: mail[]; -} - -export function generateToken(config: any,dataSafe: SecureVault): Promise{ - return new Promise((resolve,error) => { - parseMails(config, dataSafe).then(res => { - generateCodes(resolve,error,res,config,dataSafe); - }) - }); -} - -// generate codes -async function generateCodes(resolve: (value?: genReturn) => void,error: (reason?: any) => void,mailArray: mail[],config: any,dataSafe: SecureVault){ - console.log("\nGenerating codes") - const pbar = new cliProgress.SingleBar({}, cliProgress.Presets.shades_classic); - pbar.start(mailArray.length, 0,{ - speed: "N/A" - }); - let position = 0; - - let codeArray: string[] = []; - let checkString: string = ''; - - for(let i = 0; i < mailArray.length; i++){ // as many codes as adresses - // check that codes are unique - let code = ''; - do{ - code = mkstring(4); - }while ( (config.force ? codeArray : [...codeArray, ...config.usedTokens]).includes(code)) - codeArray.push(code); - checkString = `${checkString}|${code}` - position ++; - pbar.update(position); +/** + * Namespace containing the code for Generating the Code and delivering the mails + */ +export namespace MLGenerator { + + /** + * Interface used to Return codes and mails form the main Function {@link generateToken} + */ + export interface MLGenReturn{ + /** List of generated codes */ + codes: string[]; + /** List of processed mails */ + mails: MLParser.MLItem[]; } - checkString = checkString.substr(1); - pbar.stop(); - //write code lists - try { - if (!fs.existsSync(path.dirname(config.outFileMatch))){ - fs.mkdirSync(path.dirname(config.outFileMatch)); - } - fs.writeFileSync(config.outFileMatch, checkString); - } catch (err) { - - error(err); - } - sendMails(resolve,error,mailArray,codeArray,config,dataSafe); -} - - -// randomize mails and tokens -async function sendMails(resolve: (value?: genReturn) => void,error: (reason?: any) => void,mailArray: mail[],codeArray: string[],config: any,dataSafe: SecureVault){ - let mailserver = nodemailer.createTransport(config.mail); - // read mail template - let template!: HandlebarsTemplateDelegate; - try { - const htmlSrc=fs.readFileSync(config.htmlPath, "utf8") - template = Handlebars.compile(htmlSrc) - } catch (error) { - console.error("Cannote read template file!") - error(error); - } - - console.log("\nSending mails") - const pbar = new cliProgress.SingleBar({}, cliProgress.Presets.shades_classic); - pbar.start(mailArray.length, 0,{ - speed: "N/A" - }); - let position = 0; - - shuffleArray(mailArray); - shuffleArray(codeArray); - if (config.force){dataSafe.clearVault();} - for(let i = 0; i < mailArray.length; i++){ - // send mail - dataSafe.writeTransaction(`process: ${mailArray[i].mail}`); - if (!config.dryrun){ - dataSafe.pushData({ - name: mailArray[i].name, - mail: mailArray[i].mail, - code: codeArray[i] + + /** + * Main function used to generate and deliver codes + * @param config Main configuration object + * @param dataSafe Main safe used for logging and storing data + * @returns used codes and processed mails + */ + export function generateToken(config: any,dataSafe: SVault.SecureVault): Promise{ + return new Promise((resolve,error) => { + MLParser.parseMails(config, dataSafe).then(res => { + // next step + generateCodes(resolve,error,res,config,dataSafe); }) - } - await send(mailArray[i].name, mailArray[i].mail, codeArray[i],template,mailserver,config,dataSafe); - position ++; - pbar.update(position); + }); } - pbar.stop(); - shuffleArray(mailArray); - shuffleArray(codeArray); - shuffleArray(mailArray); - shuffleArray(codeArray); - resolve({ - codes: config.force ? codeArray : (config.dryrun ? config.usedTokens : [...codeArray, ...config.usedTokens]), - mails: config.force ? mailArray : (config.dryrun ? config.usedMails : [...mailArray, ...config.usedMails]) - }); - -} - -async function send(name: string, mail: string, code: string,template: HandlebarsTemplateDelegate,mailserver: Mail,config: any,dataSafe: SecureVault){ - if (config.dryrun){ - await delay(100); - console.log(`\n\x1b[36m -> dryrun: would send to ${mail}\x1b[0m`); - }else{ - // fill template - let html = template({ - "name": name, - "mail": mail, - "code": code - }) - let mailOptions = { - from: `${config.mailFrom} <${config.mail.auth.user}>`, // sender address - to: mail, // list of receivers - subject: `Dein Zugangscode zur BJR Wahl`, // Subject line - html: html - }; + + /** + * Generate the same amout of codes as distinct mail adresses and stores them to the list file + * This function also includes previously used tokens to prevent duplicate tokens. + * Rejects if matchfile cannot be saved. + * @internal + * @param resolve Callback to resolve promise + * @param error Callback to reject promise + * @param mailArray list of mail adresses + * @param config Main configuration object + * This Function uses the following variables: + * usedTokens -> List of previosly used tokens + * outFileMatch -> Path to match file + * @param dataSafe Main safe used for logging and storing data + */ + async function generateCodes(resolve: (value?: MLGenReturn) => void,error: (reason?: any) => void,mailArray: MLParser.MLItem[],config: any,dataSafe: SVault.SecureVault){ + console.log("\nGenerating codes") + const pbar = new cliProgress.SingleBar({}, cliProgress.Presets.shades_classic); + pbar.start(mailArray.length, 0,{ + speed: "N/A" + }); + let position = 0; + + let codeArray: string[] = []; + let checkString: string = ''; + + for(let i = 0; i < mailArray.length; i++){ // as many codes as adresses + // check that codes are unique + let code = ''; + do{ + code = mkstringCN(4); + }while ( (config.force ? codeArray : [...codeArray, ...config.usedTokens]).includes(code)) + codeArray.push(code); + checkString = `${checkString}|${code}` + position ++; + pbar.update(position); + } + checkString = checkString.substr(1); + pbar.stop(); + //write code lists try { - await mailserver.sendMail(mailOptions); - dataSafe.writeTransaction(` -> mail sent`); + if (!fs.existsSync(path.dirname(config.outFileMatch))){ + fs.mkdirSync(path.dirname(config.outFileMatch)); + } + fs.writeFileSync(config.outFileMatch, checkString); + } catch (err) { + + error(err); + } + // next + sendMails(resolve,error,mailArray,codeArray,config,dataSafe); + } + + + /** + * Reads template file and compiles template. + * Iterate through mails and codes, randomly assign code to mail and send mail to recipient. + * If dryrun is enabled, mails will not be sent and new mails won't be included in return. + * Rejects if template cannot be read. + * @internal + * @param resolve Callback to resolve promise + * @param error Callback to reject promise + * @param mailArray list of mail adresses + * @param codeArray list of generated codes + * @param config Main configuration object + * This Function uses the following variables: + * htmlPath -> Path to html template + * dryrun -> Boolean value. If true no mails will be sent and list won't be updated. + * force -> Boolean value. If true all mails are resent. + * usedTokens -> Array of Strings. Specifies already used tokens adresses. + * usedMails -> Array of Strings. Specifies already served mail adresses. + * mail -> mailserver settings + * @param dataSafe Main safe used for logging and storing data + */ + async function sendMails(resolve: (value?: MLGenReturn) => void,error: (reason?: any) => void,mailArray: MLParser.MLItem[],codeArray: string[],config: any,dataSafe: SVault.SecureVault){ + let mailserver = nodemailer.createTransport(config.mail); + // read mail template and compile + let template!: HandlebarsTemplateDelegate; + try { + const htmlSrc=fs.readFileSync(config.htmlPath, "utf8") + template = Handlebars.compile(htmlSrc) } catch (error) { - console.log(`Error sendign mail to ${mail} : ${error}`) - dataSafe.writeTransaction(` -> mail failed : ${error}`); + console.error("Cannote read template file!") + error(error); + } + + // send mails + console.log("\nSending mails") + const pbar = new cliProgress.SingleBar({}, cliProgress.Presets.shades_classic); + pbar.start(mailArray.length, 0,{ + speed: "N/A" + }); + let position = 0; + + // randomize arrays + shuffleArray(mailArray); + shuffleArray(codeArray); + if (config.force){dataSafe.clearVault();} + for(let i = 0; i < mailArray.length; i++){ + // send mail + dataSafe.writeTransaction(`process: ${mailArray[i].mail}`); + if (!config.dryrun){ + dataSafe.pushData({ + name: mailArray[i].name, + mail: mailArray[i].mail, + code: codeArray[i] + }) + } + await send(mailArray[i].name, mailArray[i].mail, codeArray[i],template,mailserver,config,dataSafe); + position ++; + pbar.update(position); + } + pbar.stop(); + shuffleArray(mailArray); + shuffleArray(codeArray); + shuffleArray(mailArray); + shuffleArray(codeArray); + resolve({ + codes: config.force ? codeArray : (config.dryrun ? config.usedTokens : [...codeArray, ...config.usedTokens]), + mails: config.force ? mailArray : (config.dryrun ? config.usedMails : [...mailArray, ...config.usedMails]) + }); + + } + + /** + * Reads template file and compiles template. + * Iterate through mails and codes, randomly assign code to mail and send mail to recipient. + * If dryrun is enabled, mails will not be sent and new mails won't be included in return. + * Rejects if template cannot be read. + * @internal + * @param name Name of recpipient + * @param mail Mail of recpipient + * @param code Code of recpipient + * @param template compiled mail template + * @param mailserver Mailserver settings + * @param config Main configuration object + * This Function uses the following variables: + * mail.auth.user -> sender mail adress + * mailFrom -> sender mail ailas + * dryrun -> Boolean value. If true no mails will be sent. + * @param dataSafe Main safe used for logging and storing data + */ + async function send(name: string, mail: string, code: string,template: HandlebarsTemplateDelegate,mailserver: Mail,config: any,dataSafe: SVault.SecureVault){ + if (config.dryrun){ + await delay(100); + console.log(`\n\x1b[36m -> dryrun: would send to ${mail}\x1b[0m`); + }else{ + // fill template + let html = template({ + "name": name, + "mail": mail, + "code": code + }) + let mailOptions = { + from: `${config.mailFrom} <${config.mail.auth.user}>`, // sender address + to: mail, // list of receivers + subject: `Dein Zugangscode zur BJR Wahl`, // Subject line + html: html + }; + try { + await mailserver.sendMail(mailOptions); + dataSafe.writeTransaction(` -> mail sent`); + } catch (error) { + console.log(`Error sendign mail to ${mail} : ${error}`) + dataSafe.writeTransaction(` -> mail failed : ${error}`); + } } } } -function delay(t: number, val?: number) { - return new Promise(function(resolve) { - setTimeout(function() { - resolve(val); - }, t); - }); - } \ No newline at end of file diff --git a/src/mailParser.ts b/src/mailParser.ts index c904995..c61d667 100644 --- a/src/mailParser.ts +++ b/src/mailParser.ts @@ -1,70 +1,118 @@ +/** + * Dennis Gunia (c) 2020 + * + * MailParser Implementation. + * This File provides a vault for storing encrypted and unencrypted data. Each encrypted element will be encrypted before storing it in an array. + * Each element (encrypted or unencrypted) ist stored in an array with an unique identifier. + * Safes can be stored and loaded. Unencrypted data can be stored, retrieved and modified. Encrypted data can be stored and retrieved. + * This class also implements an transaction function. + * + * @summary SecureVault Class Implementation + * @author Dennis Gunia + * @license Licensed under the Apache License, Version 2.0 (the "License"). + * + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file 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. + */ + import * as fs from 'fs' -import { SecureVault } from "./vault"; +import { SVault } from "./vault"; -export interface MLItem{ - mail: string; - name: string; -} - -export function parseMails(config: any, dataSafe: SecureVault) { - return new Promise((resolve,reject) => { - let mailArray: MLItem[] = []; - let currSection: string = "global"; - let lineCounter: number = 0; - let curCounter: number = 0; - - - console.log(`Reading mails for section ${currSection}`) - // read and process mail list - let readline = require('readline'), - instream = fs.createReadStream(config.inFileMail), - outstream = new (require('stream'))(), - rl = readline.createInterface(instream, outstream); - - rl.on('line', function (line:string) { - lineCounter ++; - if(line.startsWith('[')){ - if(line.endsWith(']')){ - console.log(`Read ${curCounter} adresses for section ${currSection}`) - curCounter = 0; - currSection=line.substring(1,line.length -1); - console.log(`Reading mails for section ${currSection}`) - }else{ - console.error(`Error parsing section on line ${lineCounter}: Syntax Error. Missing closing bracket ]`) - } - }else if (!line.startsWith('#')){ - const ix = line.indexOf(";") - if (ix !== -1){ - // check if already exist - dataSafe.writeTransaction(`reading mail ${line.substr(0,ix)} from category ${currSection}`); - if (config.force || config.usedMails.filter((el: MLItem) => el.mail == line.substr(0,ix)).length == 0){ - // check for duplicate - if ( mailArray.filter((el: MLItem) => el.mail == line.substr(0,ix)).length == 0){ - mailArray.push({ - mail: line.substr(0,ix), - name: line.substr(ix + 1) - }) - curCounter ++; +/** + * Namespace containing the code for Parsing the mail list. + */ +export namespace MLParser{ + /** + * Interface containing properties of a single mail line + */ + export interface MLItem{ + /** mail adress parsed form file */ + mail: string; + /** name parsed form file */ + name: string; + } + + /** + * Encrypts and appends data to SecureVault. + * Also writes data to transaction log using @function writeTransaction + * @param config - Reference to config object. + * This Function uses the following variables: + * inFileMail -> String reference to mail list + * force -> Boolean value. If true all mails are resent. + * usedMails -> Array of Strings. Specifies already served mail adresses. + * + * @param dataSafe - Reference to safe object. This is needed for writing to the vault.log file + * @return Returns an array of all parsed mail adresses as promise + */ + export function parseMails(config: any, dataSafe: SVault.SecureVault) { + return new Promise((resolve,reject) => { + let mailArray: MLItem[] = []; + let currSection: string = "global"; + let lineCounter: number = 0; + let curCounter: number = 0; + + + console.log(`Reading mails for section ${currSection}`) + // read and process mail list + let readline = require('readline'), + instream = fs.createReadStream(config.inFileMail), + outstream = new (require('stream'))(), + rl = readline.createInterface(instream, outstream); + + rl.on('line', function (line:string) { + lineCounter ++; + if(line.startsWith('[')){ + if(line.endsWith(']')){ + console.log(`Read ${curCounter} adresses for section ${currSection}`) + curCounter = 0; + currSection=line.substring(1,line.length -1); + console.log(`Reading mails for section ${currSection}`) + }else{ + console.error(`Error parsing section on line ${lineCounter}: Syntax Error. Missing closing bracket ]`) + } + }else if (!line.startsWith('#')){ + const ix = line.indexOf(";") + if (ix !== -1){ + // check if already exist + dataSafe.writeTransaction(`reading mail ${line.substr(0,ix)} from category ${currSection}`); + if (config.force || config.usedMails.filter((el: MLItem) => el.mail == line.substr(0,ix)).length == 0){ + // check for duplicate + if ( mailArray.filter((el: MLItem) => el.mail == line.substr(0,ix)).length == 0){ + mailArray.push({ + mail: line.substr(0,ix), + name: line.substr(ix + 1) + }) + curCounter ++; + }else{ + dataSafe.writeTransaction(` -> duplicate mail. Skipping`); + console.error(`Skipping ${line.substr(0,ix)}: Duplicate`) + } }else{ - dataSafe.writeTransaction(` -> duplicate mail. Skipping`); - console.error(`Skipping ${line.substr(0,ix)}: Duplicate`) + dataSafe.writeTransaction(` -> already exists. Skipping`); + console.error(`Skipping ${line.substr(0,ix)}: Already sent`) } }else{ - dataSafe.writeTransaction(` -> already exists. Skipping`); - console.error(`Skipping ${line.substr(0,ix)}: Already sent`) + console.error(`Error parsing mail on line ${lineCounter}: Syntax Error. Missing ;`) } - }else{ - console.error(`Error parsing mail on line ${lineCounter}: Syntax Error. Missing ;`) - } - - } - }); - rl.on('close', function (line:string) { - // next step - console.log(`Read ${curCounter} adresses for section ${currSection}\n${mailArray.length} mails read!`) - resolve(mailArray); - }); - - }) + + } + }); + rl.on('close', function (line:string) { + // next step + console.log(`Read ${curCounter} adresses for section ${currSection}\n${mailArray.length} mails read!`) + resolve(mailArray); + }); + + }) + } + } + diff --git a/src/util/misc.ts b/src/util/misc.ts new file mode 100644 index 0000000..71a4270 --- /dev/null +++ b/src/util/misc.ts @@ -0,0 +1,50 @@ +/** + * Dennis Gunia (c) 2020 + * + * Reusable functions for different projects. + * + * @summary Open-Token entry point + * @author Dennis Gunia + * @license Licensed under the Apache License, Version 2.0 (the "License"). + * + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file 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. + */ + + + + +/** + * Generate random string with specified length. + * Generates only numbers and capital letters. + * @param length length of String + * @return generated string + */ +export function mkstringCN (length:number ) { + var result = ''; + var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; + var charactersLength = characters.length; + for ( var i = 0; i < length; i++ ) { + result += characters.charAt(Math.floor(Math.random() * charactersLength)); + } + return result; +} + +/** + * Wraps setTimeout into Promise + * @param t Millisceonds + */ +export function delay(t: number) { + return new Promise(function(resolve) { + setTimeout(function() { + resolve(); + }, t); + }); +} \ No newline at end of file diff --git a/src/util/shuffle.ts b/src/util/shuffle.ts index 144802c..25c594f 100644 --- a/src/util/shuffle.ts +++ b/src/util/shuffle.ts @@ -1,3 +1,7 @@ +/** + * Randomize items in an array + * @param array Array to be shuffeled + */ export function shuffleArray(array: any[]) { for (var i = array.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); @@ -5,4 +9,4 @@ export function shuffleArray(array: any[]) { array[i] = array[j]; array[j] = temp; } -} \ No newline at end of file +} diff --git a/src/util/token.ts b/src/util/token.ts deleted file mode 100644 index e8bcd23..0000000 --- a/src/util/token.ts +++ /dev/null @@ -1,9 +0,0 @@ -export function mkstring (length:number ) { - var result = ''; - var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; - var charactersLength = characters.length; - for ( var i = 0; i < length; i++ ) { - result += characters.charAt(Math.floor(Math.random() * charactersLength)); - } - return result; -} diff --git a/src/vault.ts b/src/vault.ts index 1c329db..66413b6 100644 --- a/src/vault.ts +++ b/src/vault.ts @@ -1,184 +1,285 @@ +/** + * Dennis Gunia (c) 2020 + * + * SecureVault Class Implementation. + * This Class provides a vault for storing encrypted and unencrypted data. Each encrypted element will be encrypted before storing it in an array. + * Each element (encrypted or unencrypted) ist stored in an array with an unique identifier. + * Safes can be stored and loaded. Unencrypted data can be stored, retrieved and modified. Encrypted data can be stored and retrieved. + * This class also implements an transaction function. + * + * @summary SecureVault Class Implementation + * @author Dennis Gunia + * @license Licensed under the Apache License, Version 2.0 (the "License"). + * + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file 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. + */ + import * as crypto from 'crypto' import * as uuid from 'uuid' import path from 'path'; import * as fs from 'fs' import { generateKeyPair } from 'crypto'; -import { Console } from 'console'; -const vaultVersion = 'v1.2' +/** + * Namespace containing the code for the SecureVault. + */ +export namespace SVault { + /** vault version number. This variable will be added to the safe file and is used to chack compatibility. */ + const vaultVersion = 'v1.2' -export interface SecureVaultItem { - u: string; // uuid - d: string; // data - k: string; // key - iv: string; // init vector -} - -export interface StorageItem { - u: string; // uuid - d: string; // data - t: string; // tag -} - -export interface secureVaultList { - items: SecureVaultItem[]; - publicKey?: Buffer; - privateKey?: Buffer; -} - -export class SecureVault { - - safe: secureVaultList; - privPath?: string; - pubPath?: string; - storage: StorageItem[]; - - constructor (publicKey: string, privateKey?: string) { - this.storage = []; - this.safe = { - items: [], - publicKey: publicKey ?fs.readFileSync(path.resolve(publicKey)): undefined, - privateKey: privateKey ? fs.readFileSync(path.resolve(privateKey)): undefined - }; - this.privPath = publicKey ? path.resolve(publicKey): undefined, - this.pubPath = privateKey ? path.resolve(privateKey): undefined + /** Interface for an vault item containing encrypted data */ + export interface SecureVaultItem { + /** uuid */ + u: string; + /** data */ + d: string; + /** key */ + k: string; + /** init vector */ + iv: string; } - async pushData(data: any): Promise{ - // encrypt payload - const txtData = JSON.stringify(data); - const key = crypto.randomBytes(32); - const iv = crypto.randomBytes(16); - let cipher = crypto.createCipheriv('aes-256-cbc', Buffer.from(key), iv); - let encrypted = cipher.update(txtData); - encrypted = Buffer.concat([encrypted, cipher.final()]); - // encrypt key - var buffer = new Buffer(key); - if (!this.safe.publicKey){ - throw new Error("Public Key not found"); + /** Interface for an vault item containing unencrypted data */ + export interface StorageItem { + /** uuid */ + u: string; + /** data */ + d: string; + /** tag (can be used to find specific items) */ + t: string; + } + + /** Interface for secureVault Array */ + export interface secureVaultList { + items: SecureVaultItem[]; /** Array of encrypted items */ + publicKey?: Buffer; /** Binary of public key */ + privateKey?: Buffer; /** Binary of private key */ + } + + /** Class representing a SecureVault. */ + export class SecureVault { + /** Safe object */ + safe: secureVaultList; + /** Path to private key */ + privPath?: string; + /** Path to public key */ + pubPath?: string; + /** Array of unencrypted items */ + storage: StorageItem[]; + + /** + * Create a SecureVault. + * @param publicKey - Path to public key. + * @param privateKey - Path to private key. + */ + constructor (publicKey?: string, privateKey?: string) { + this.storage = []; + this.safe = { + items: [], + publicKey: publicKey ?fs.readFileSync(path.resolve(publicKey)): undefined, + privateKey: privateKey ? fs.readFileSync(path.resolve(privateKey)): undefined + }; + this.privPath = publicKey ? path.resolve(publicKey): undefined, + this.pubPath = privateKey ? path.resolve(privateKey): undefined } - var asym_encrypted = crypto.publicEncrypt(this.safe.publicKey, buffer); - const u = uuid.v4() - const item = { - u, - d: encrypted.toString('hex'), - k: asym_encrypted.toString("base64"), - iv: iv.toString('hex') - } - this.writeTransaction("push: " + JSON.stringify(item)) - this.safe.items.push(item) - return u; - } - - writeTransaction(payload: string){ - fs.appendFileSync('vault.log', `${payload}\n`); - } - - async saveData(path: string): Promise{ - fs.writeFileSync(path, JSON.stringify({ - version: vaultVersion, - vault: this.safe.items, - storage: this.storage - })); - } - - async loadData(path: string): Promise{ - const loaded = JSON.parse(fs.readFileSync(path, 'utf8')); - switch (loaded.version){ - case 'v1.1': - this.safe.items = loaded.vault; - break; - case 'v1.2': - this.safe.items = loaded.vault; - this.storage = loaded.storage; - break; - default: - console.error(`Unknown or unsupported vault file version: ${loaded.version}`) - } - - } - - async decryptData(): Promise{ - - this.safe.items.forEach(el => { - // decrpyt key - let buffer = new Buffer(el.k, "base64"); - if (!this.safe.privateKey){ - throw new Error("Private Key not found"); + /** + * Encrypts and appends data to SecureVault. + * Also writes data to transaction log using @function writeTransaction + * @param data - Path to public key. + * @return Returns the uuid of the added object as promise + */ + async pushData(data: any): Promise{ + // encrypt payload + const txtData = JSON.stringify(data); + const key = crypto.randomBytes(32); + const iv = crypto.randomBytes(16); + let cipher = crypto.createCipheriv('aes-256-cbc', Buffer.from(key), iv); + let encrypted = cipher.update(txtData); + encrypted = Buffer.concat([encrypted, cipher.final()]); + // encrypt key + var buffer = new Buffer(key); + if (!this.safe.publicKey){ + throw new Error("Public Key not found"); } - var key = crypto.privateDecrypt(this.safe.privateKey, buffer); - // decrpyt payload - let iv = Buffer.from(el.iv, 'hex'); - let encryptedText = Buffer.from(el.d, 'hex'); - let decipher = crypto.createDecipheriv('aes-256-cbc', key, iv); - let decrypted = decipher.update(encryptedText); - decrypted = Buffer.concat([decrypted, decipher.final()]); - const obj = JSON.parse(decrypted.toString()); - console.log(obj); - }) - } + var asym_encrypted = crypto.publicEncrypt(this.safe.publicKey, buffer); + const u = uuid.v4() - static genKey(publicKeyDir: string, privateKeyDir: string){ - generateKeyPair('rsa', { - modulusLength: 4096, - publicKeyEncoding: { - type: 'pkcs1', - format: 'pem' - }, - privateKeyEncoding: { - type: 'pkcs1', - format: 'pem', + const item = { + u, + d: encrypted.toString('hex'), + k: asym_encrypted.toString("base64"), + iv: iv.toString('hex') } - }, (err, publicKey, privateKey) => { - fs.writeFileSync(privateKeyDir, privateKey); - fs.writeFileSync(publicKeyDir, publicKey); - }); - } + this.writeTransaction("push: " + JSON.stringify(item)) + this.safe.items.push(item) + return u; + } - pushStorage(tag:string, data: any){ - if (vaultVersion !== 'v1.2'){ - throw new Error(`Storage not supported in ${vaultVersion}`); - }else{ - let objJsonStr = JSON.stringify(data); - let objJsonB64 = Buffer.from(objJsonStr).toString("base64"); - this.storage.push({ - u: uuid.v4(), - d: objJsonB64, - t: tag + /** + * Writes data to the vault log file located at ./vault.log + * @param payload - Text to append + */ + writeTransaction(payload: string){ + fs.appendFileSync('vault.log', `${payload}\n`); + } + + /** + * Saves safe to file + * @param path - Path to safefile. + * @return Resolves promise after loaded + */ + async saveData(path: string): Promise{ + fs.writeFileSync(path, JSON.stringify({ + version: vaultVersion, + vault: this.safe.items, + storage: this.storage + })); + } + + /** + * Loads safe from file and check compatibility + * @param path - Path to safefile. + * @return Resolves promise after loaded + */ + async loadData(path: string): Promise{ + const loaded = JSON.parse(fs.readFileSync(path, 'utf8')); + switch (loaded.version){ + case 'v1.1': + this.safe.items = loaded.vault; + break; + case 'v1.2': + this.safe.items = loaded.vault; + this.storage = loaded.storage; + break; + default: + console.error(`Unknown or unsupported vault file version: ${loaded.version}`) + } + + } + + /** + * Decrypts safe data. + * Requires specified and loaded private key. + * Prints data to console. + * @return Resolves promise after decrypted + */ + async decryptData(): Promise{ + + this.safe.items.forEach(el => { + // decrpyt key + let buffer = new Buffer(el.k, "base64"); + if (!this.safe.privateKey){ + throw new Error("Private Key not found"); + } + var key = crypto.privateDecrypt(this.safe.privateKey, buffer); + // decrpyt payload + let iv = Buffer.from(el.iv, 'hex'); + let encryptedText = Buffer.from(el.d, 'hex'); + let decipher = crypto.createDecipheriv('aes-256-cbc', key, iv); + let decrypted = decipher.update(encryptedText); + decrypted = Buffer.concat([decrypted, decipher.final()]); + const obj = JSON.parse(decrypted.toString()); + console.log(obj); + }) + } + /** + * Generates RSA keypair. + * @param publicKey - Path to public key. + * @param privateKey - Path to private key. + */ + static genKey(publicKeyDir: string, privateKeyDir: string){ + generateKeyPair('rsa', { + modulusLength: 4096, + publicKeyEncoding: { + type: 'pkcs1', + format: 'pem' + }, + privateKeyEncoding: { + type: 'pkcs1', + format: 'pem', + } + }, (err, publicKey, privateKey) => { + fs.writeFileSync(privateKeyDir, privateKey); + fs.writeFileSync(publicKeyDir, publicKey); }); } - } - setStorage(suuid:string, data: any){ - if (vaultVersion !== 'v1.2'){ - throw new Error(`Storage not supported in ${vaultVersion}`); - }else{ - let objJsonStr = JSON.stringify(data); - let objJsonB64 = Buffer.from(objJsonStr,"utf8").toString("base64"); - this.storage.filter(el => el.u == suuid)[0].d = objJsonB64; + /** + * Appends unencrypted data to safe. + * @param tag - Tag for item + * @param data - Data to store. + */ + pushStorage(tag:string, data: any){ + if (vaultVersion !== 'v1.2'){ + throw new Error(`Storage not supported in ${vaultVersion}`); + }else{ + let objJsonStr = JSON.stringify(data); + let objJsonB64 = Buffer.from(objJsonStr).toString("base64"); + this.storage.push({ + u: uuid.v4(), + d: objJsonB64, + t: tag + }); + } + } + + /** + * Sets unencrypted data for item specified by suuid. + * @param suuid - UUID for item + * @param data - Data to store. + */ + setStorage(suuid:string, data: any){ + if (vaultVersion !== 'v1.2'){ + throw new Error(`Storage not supported in ${vaultVersion}`); + }else{ + let objJsonStr = JSON.stringify(data); + let objJsonB64 = Buffer.from(objJsonStr,"utf8").toString("base64"); + this.storage.filter(el => el.u == suuid)[0].d = objJsonB64; + } + } + + /** + * Gets unencrypted data of item specified by suuid. + * @param suuid - UUID for item + * @return Data from item. + */ + getStorage(suuid:string){ + if (vaultVersion !== 'v1.2'){ + throw new Error(`Storage not supported in ${vaultVersion}`); + }else{ + const data = this.storage.filter(el => el.u == suuid)[0]; + let objJsonB64 = new Buffer(data.d, 'base64'); + return JSON.parse(objJsonB64.toString('utf8')); + } + } + + /** + * Gets list of UUIDs matching the tag. + * @param tag - tag to search for + * @return UUID from item. + */ + findStorage(tag:string){ + if (vaultVersion !== 'v1.2'){ + throw new Error(`Storage not supported in ${vaultVersion}`); + }else{ + return this.storage.filter(el => el.t == tag); + } + } + + /** + * Clears all encrypted items from safe. + */ + clearVault(){ + this.safe.items = []; } } - - getStorage(suuid:string){ - if (vaultVersion !== 'v1.2'){ - throw new Error(`Storage not supported in ${vaultVersion}`); - }else{ - const data = this.storage.filter(el => el.u == suuid)[0]; - let objJsonB64 = new Buffer(data.d, 'base64'); - return JSON.parse(objJsonB64.toString('utf8')); - } - } - - findStorage(tag:string){ - if (vaultVersion !== 'v1.2'){ - throw new Error(`Storage not supported in ${vaultVersion}`); - }else{ - return this.storage.filter(el => el.t == tag); - } - } - - clearVault(){ - this.safe.items = []; - } -} \ No newline at end of file +} diff --git a/typedoc.json b/typedoc.json new file mode 100644 index 0000000..d95ccc6 --- /dev/null +++ b/typedoc.json @@ -0,0 +1,4 @@ +{ + "mode": "file", + "out": "docs" +} \ No newline at end of file