├── .gitignore ├── .travis.yml ├── README.md ├── lib ├── endpoints.js └── opensubtitles.js ├── package-lock.json ├── package.json ├── sample.py └── test ├── avi-8e245d9679d31e12 ├── breakdance.avi ├── leakdetector.js └── test.js /.gitignore: -------------------------------------------------------------------------------- 1 | lib-cov 2 | *.seed 3 | *.log 4 | *.csv 5 | *.dat 6 | *.out 7 | *.pid 8 | *.gz 9 | 10 | pids 11 | logs 12 | results 13 | 14 | node_modules 15 | npm-debug.log -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "0.10" 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | node-opensubtitles-api 2 | ====================== 3 | 4 | Node.js API library to query opensubtitles.org 5 | 6 | ![build status](https://travis-ci.org/ka2er/node-opensubtitles-api.svg?branch=master) 7 | 8 | Usage 9 | ----- 10 | 11 | The lib get hashing function : 12 | 13 | var OS = require("opensubtitles"); 14 | var os = new OS(); 15 | os.computeHash('./test/breakdance.avi', function(err, size){ 16 | if (err) return; 17 | 18 | os.checkMovieHash([size], function(err, res) { 19 | if(err) return; 20 | 21 | console.log(res); 22 | }) 23 | }); 24 | 25 | And it also bind all XML-RPC methods : 26 | 27 | os.api.LogIn(function(err, res){ 28 | console.log(res); 29 | },user, pass, lang, ua); 30 | 31 | Tests 32 | ----- 33 | 34 | simply run : 35 | 36 | $ mocha 37 | 38 | About 39 | ----- 40 | 41 | The MIT License - Copyright (c) 2015 ka2er 42 | 43 | >Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 44 | > 45 | >The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 46 | > 47 | >THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 48 | 49 | Subtitles service powered by www.OpenSubtitles.org 50 | -------------------------------------------------------------------------------- /lib/endpoints.js: -------------------------------------------------------------------------------- 1 | /** 2 | * User: seb 3 | * Date: 10/5/12 4 | * Time: 5:15 PM 5 | * To change this template use File | Settings | File Templates. 6 | */ 7 | var xmlrpc = require('xmlrpc'); 8 | 9 | var ep = module.exports = function() { 10 | 11 | this.clientOptions = 'http://api.opensubtitles.org/xml-rpc'; 12 | this.client = xmlrpc.createClient(this.clientOptions); 13 | 14 | /* 15 | var def = "array LogIn( $username, $password, $language, $useragent )"+ 16 | "string LogOut( $token )"+ 17 | "array SearchSubtitles( $token, array(array('sublanguageid' => $sublanguageid, 'moviehash' => $moviehash, 'moviebytesize' => $moviesize, imdbid => $imdbid, query => 'movie name', 'season' => 'season number', 'episode' => 'episode number', 'tag' => tag ),array(...)))"+ 18 | "array SearchToMail( $token, array( $sublanguageid, $sublanguageid, ...), array( array( 'moviehash' => $moviehash, 'moviesize' => $moviesize), array( 'moviehash' => $moviehash, 'moviesize' => $moviesize), ...) )"+ 19 | "array CheckSubHash( $token, array($subhash, $subhash, ...) )"+ 20 | "array CheckMovieHash( $token, array($moviehash, $moviehash, ...) )"+ 21 | "array CheckMovieHash2( $token, array($moviehash, $moviehash, ...) )"+ 22 | "array InsertMovieHash( $token, array( array('moviehash' => $moviehash, 'moviebytesize' => $moviebytesize, 'imdbid' => $imdbid, 'movietimems' => $movietimems, 'moviefps' => $moviefps, 'moviefilename' => $moviefilename), array(...) ) )"+ 23 | "array TryUploadSubtitles( $token, array('cd1' => array('subhash' => $submd5hash, 'subfilename' => $subfilename, 'moviehash' => $moviehash, 'moviebytesize' => $moviesize, 'movietimems' => $movietimems, 'movieframes' => $movieframes, 'moviefps' => $moviefps, 'moviefilename' => $moviefilename), 'cd2' => array(...) ) )"+ 24 | "array UploadSubtitles( $token,array( 'baseinfo' => array ( 'idmovieimdb' => $idmovieimdb, 'moviereleasename' => $scene_releasename, 'movieaka' => $aka_in_subtitle_language, 'sublanguageid' => $sublanguageid, 'subauthorcomment' => $author_comment, 'hearingimpaired' => $hearing_impaired, 'highdefinition' => $high_definition, 'automatictranslation' => $automatic_translation), 'cd1' => array( 'subhash' => $md5subhash, 'subfilename' => $subfilename, 'moviehash' => $moviehash, 'moviebytesize' => $moviebytesize, 'movietimems' => $movietimems, 'moviefps' => $moviefps, 'movieframes' => $movieframes, 'moviefilename' => $moviefilename, 'subcontent' => $subtitlecontent ), 'cd2' => array (...) ) )"+ 25 | "array DetectLanguage( $token, array($text, $text, ...) )"+ 26 | "array DownloadSubtitles( $token, array($IDSubtitleFile, $IDSubtitleFile,...) )"+ 27 | "array ReportWrongMovieHash( $token, $IDSubMovieFile )"+ 28 | "array ReportWrongImdbMovie( $token, array('moviehash' => $moviehash, 'moviebytesize' => $moviebytesize, 'imdbid' => $imdbid )"+ 29 | "array GetSubLanguages( $language = 'en' )"+ 30 | "array GetAvailableTranslations( $token, $program )"+ 31 | "array GetTranslation( $token, $iso639, $format, $program )"+ 32 | "array SearchMoviesOnIMDB( $token, $query )"+ 33 | "array GetIMDBMovieDetails( $token, $imdbid )"+ 34 | "array InsertMovie( $token, array('moviename' => $moviename, 'movieyear' => $movieyear) )"+ 35 | "array SubtitlesVote( $token, array('idsubtitle' => $idsubtitle, 'score' => $score) )"+ 36 | "array GetComments( $token, array($idsubtitle, $idsubtitle, ...))"+ 37 | "array AddComment( $token, array('idsubtitle' => $idsubtitle, 'comment' => $comment, 'badsubtitle' => $int) )"+ 38 | "array AddRequest( $token, array('sublanguageid' => $sublanguageid, 'idmovieimdb' => $idmovieimdb, 'comment' => $comment ) )"+ 39 | "array AutoUpdate ( $program_name )"+ 40 | "array NoOperation( $token )"; 41 | 42 | def = def.split('strong>').join('').split('<').join('').split('/'); 43 | for (var i in def) { 44 | var t_meth = def[i].split(' '); 45 | var t_args = def[i].split('('); 46 | t_args.shift(); 47 | var args = t_args.join(''); 48 | 49 | 50 | console.log(t_meth[1].split('(')[0]+' = function(cb, '+args.replace(/\$/g, '')+'{'); 51 | console.log(' this.call(\''+t_meth[1].replace('(', '')+'\', arguments);'); 52 | console.log('};'); 53 | } 54 | console.log(def.join('***')); 55 | */ 56 | }; 57 | 58 | ep.prototype.call = function(method, args) { 59 | var cb = args[0]; 60 | var t = []; 61 | delete(args[0]); 62 | for(var i in args) { 63 | t.push(args[i]); 64 | } 65 | this.client.methodCall(method, t, cb); 66 | }; 67 | 68 | 69 | /** protocol methods */ 70 | ep.prototype.LogIn = function(cb, username, password, language, useragent ){ 71 | this.call('LogIn', arguments); 72 | }; 73 | ep.prototype.LogOut = function(cb, token ){ 74 | this.call('LogOut', arguments); 75 | }; 76 | ep.prototype.SearchSubtitles = function(cb, token, t_queries){ 77 | this.call('SearchSubtitles', arguments); 78 | }; 79 | 80 | ep.prototype.SearchToMail = function(cb, token, t_langs, t_movies){ 81 | this.call('SearchToMail', arguments); 82 | }; 83 | ep.prototype.CheckSubHash = function(cb, token, t_subs_hash){ 84 | this.call('CheckSubHash', arguments); 85 | }; 86 | ep.prototype.CheckMovieHash = function(cb, token, t_movies_hash){ 87 | this.call('CheckMovieHash', arguments); 88 | }; 89 | ep.prototype.CheckMovieHash2 = function(cb, token, t_movies_hash){ 90 | this.call('CheckMovieHash2', arguments); 91 | }; 92 | ep.prototype.InsertMovieHash = function(cb, token, t_movies_info){ 93 | this.call('InsertMovieHash', arguments); 94 | }; 95 | ep.prototype.TryUploadSubtitles = function(cb, token, t_sub){ 96 | this.call('TryUploadSubtitles', arguments); 97 | }; 98 | ep.prototype.UploadSubtitles = function(cb, token, t_sub){ 99 | this.call('UploadSubtitles', arguments); 100 | }; 101 | ep.prototype.DetectLanguage = function(cb, token, t_texts){ 102 | this.call('DetectLanguage', arguments); 103 | }; 104 | ep.prototype.DownloadSubtitles = function(cb, token, t_subid){ 105 | this.call('DownloadSubtitles', arguments); 106 | }; 107 | ep.prototype.ReportWrongMovieHash = function(cb, token, IDSubMovieFile ){ 108 | this.call('ReportWrongMovieHash', arguments); 109 | }; 110 | ep.prototype.ReportWrongImdbMovie = function(cb, token, t_movie){ 111 | this.call('ReportWrongImdbMovie', arguments); 112 | }; 113 | ep.prototype.GetSubLanguages = function(cb, language){ 114 | this.call('GetSubLanguages', arguments); 115 | }; 116 | ep.prototype.GetAvailableTranslations = function(cb, token, program ){ 117 | this.call('GetAvailableTranslations', arguments); 118 | }; 119 | ep.prototype.GetTranslation = function(cb, token, iso639, format, program ){ 120 | this.call('GetTranslation', arguments); 121 | }; 122 | ep.prototype.SearchMoviesOnIMDB = function(cb, token, query ){ 123 | this.call('SearchMoviesOnIMDB', arguments); 124 | }; 125 | ep.prototype.GetIMDBMovieDetails = function(cb, token, imdbid ){ 126 | this.call('GetIMDBMovieDetails', arguments); 127 | }; 128 | ep.prototype.InsertMovie = function(cb, token, t_movie){ 129 | this.call('InsertMovie', arguments); 130 | }; 131 | ep.prototype.SubtitlesVote = function(cb, token, t_vote){ 132 | this.call('SubtitlesVote', arguments); 133 | }; 134 | ep.prototype.GetComments = function(cb, token, t_subids){ 135 | this.call('GetComments', arguments); 136 | }; 137 | ep.prototype.AddComment = function(cb, token, t_comments){ 138 | this.call('AddComment', arguments); 139 | }; 140 | ep.prototype.AddRequest = function(cb, token, t_request){ 141 | this.call('AddRequest', arguments); 142 | }; 143 | ep.prototype.AutoUpdate = function(cb, program_name ){ 144 | this.call('AutoUpdate', arguments); 145 | }; 146 | ep.prototype.NoOperation = function(cb, token ){ 147 | this.call('NoOperation', arguments); 148 | }; 149 | -------------------------------------------------------------------------------- /lib/opensubtitles.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'), 2 | ee = require('events').EventEmitter, 3 | Api = require('./endpoints.js'); 4 | 5 | 6 | var os = module.exports = function(user, password, lang, ua) { 7 | 8 | this.api = new Api(); 9 | this.user = user; 10 | this.password = password; 11 | this.lang = lang ? lang : 'en'; 12 | this.ua = ua ? ua : 'NodeOpensubtitles v0.0.1'; 13 | }; 14 | 15 | os.prototype.__proto__ = ee.prototype; 16 | 17 | 18 | // http://api.opensubtitles.org/xml-rpc 19 | 20 | 21 | os.prototype.checkMovieHash = function(t_hash, cb) { 22 | var self = this; 23 | this.api.LogIn(function(err, res) { 24 | if(err) return cb(err); 25 | 26 | var token = res.token; 27 | self.api.CheckMovieHash(function(err, res){ 28 | 29 | if(err) return cb(err); 30 | 31 | cb(null, res); 32 | },token, t_hash); 33 | }, this.user, this.password, this.lang, this.ua); 34 | }; 35 | 36 | os.prototype.computeHash = function(path, cb) { 37 | // get file size 38 | // get first 64kb 39 | // get last 64kb 40 | // summup everything 41 | 42 | var chunk_size = 65536; 43 | var buf_start = new Buffer(chunk_size*2); 44 | var buf_end = new Buffer(chunk_size*2); 45 | var file_size = 0; 46 | var self = this; 47 | var t_chksum = []; 48 | 49 | function checksumReady(chksum_part, name) { 50 | self.emit('checksum-ready', chksum_part, name); 51 | 52 | t_chksum.push(chksum_part); 53 | if(t_chksum.length == 3) { 54 | var chksum = self.sumHex64bits(t_chksum[0], t_chksum[1]); 55 | chksum = self.sumHex64bits(chksum, t_chksum[2]); 56 | chksum = chksum.substr(-16); 57 | cb(null, self.padLeft(chksum, '0', 16)); 58 | } 59 | } 60 | 61 | 62 | fs.stat(path, function(err, stat) { 63 | if(err) return cb(err); 64 | 65 | file_size = stat.size; 66 | 67 | checksumReady(file_size.toString(16), "filesize"); 68 | 69 | fs.open(path, 'r', function(err, fd) { 70 | if(err) { 71 | return cb(err); 72 | } 73 | 74 | var t_buffers = [{buf:buf_start, offset:0}, {buf:buf_end, offset:file_size-chunk_size}]; 75 | for(var i in t_buffers) { 76 | fs.read(fd, t_buffers[i].buf, 0, chunk_size*2, t_buffers[i].offset, function(err, bytesRead, buffer) { 77 | if(err) return cb(err); 78 | checksumReady(self.checksumBuffer(buffer, 16), "buf?"); 79 | }); 80 | } 81 | fs.close(fd); 82 | }); 83 | }); 84 | }; 85 | 86 | 87 | /** 88 | * read 64 bits from buffer starting at offset as LITTLE ENDIAN hex 89 | * 90 | * @param buffer 91 | * @param offset 92 | * @return {String} 93 | */ 94 | os.prototype.read64LE = function(buffer, offset) { 95 | var ret_64_be = buffer.toString('hex', offset*8, ((offset+1)*8)); 96 | var t = []; 97 | for(var i=0; i<8; i++) { 98 | t.push(ret_64_be.substr(i*2, 2)); 99 | } 100 | t.reverse(); 101 | return t.join(''); 102 | }; 103 | 104 | 105 | /** 106 | * compute checksum of the buffer splitting by chunk of lengths bits 107 | * 108 | * @param buf 109 | * @param length 110 | */ 111 | os.prototype.checksumBuffer = function(buf, length) { 112 | var checksum = 0, checksum_hex = 0; 113 | for(var i=0; i<(buf.length/length); i++) { 114 | checksum_hex = this.read64LE(buf, i); 115 | checksum = this.sumHex64bits(checksum.toString(), checksum_hex).substr(-16); 116 | //console.log("hash#"+i+" "+checksum_hex+" => "+checksum); 117 | } 118 | //console.log("chck sum : "+checksum); 119 | return checksum; 120 | }; 121 | 122 | /** 123 | * calculate hex sum between 2 64bits hex numbers 124 | * 125 | * @param n1 126 | * @param n2 127 | * @return {String} 128 | */ 129 | os.prototype.sumHex64bits = function(n1, n2) { 130 | 131 | if(n1.length < 16) n1 = this.padLeft(n1, '0', 16); 132 | if(n2.length < 16) n2 = this.padLeft(n2, '0', 16); 133 | 134 | //console.log("n1 "+n1); 135 | //console.log("n2 "+n2); 136 | 137 | // 1st 32 bits 138 | var n1_0 = n1.substr(0, 8); 139 | var n2_0 = n2.substr(0, 8); 140 | var i_0 = parseInt(n1_0, 16) + parseInt(n2_0, 16); 141 | 142 | // 2nd 32 bits 143 | var n1_1 = n1.substr(8, 8); 144 | var n2_1 = n2.substr(8, 8); 145 | var i_1 = parseInt(n1_1, 16) + parseInt(n2_1, 16); 146 | 147 | // back to hex 148 | var h_1 = i_1.toString(16); 149 | //console.log('i'+i_1); 150 | //console.log('x'+h_1); 151 | //console.log(h_1.length); 152 | var i_1_over = 0; 153 | if(h_1.length > 8) { 154 | //console.log('retenue'); 155 | i_1_over = parseInt(h_1.substr(0, h_1.length - 8), 16); 156 | } else { 157 | h_1 = this.padLeft(h_1, '0', 8); 158 | } 159 | 160 | var h_0 = (i_1_over + i_0).toString(16); 161 | 162 | //console.log(h_0+' | '+h_1); 163 | return h_0 + h_1.substr(-8); 164 | }; 165 | 166 | /** 167 | * pad left with c up to length characters 168 | * 169 | * @param str 170 | * @param c 171 | * @param length 172 | * @return {*} 173 | */ 174 | os.prototype.padLeft = function(str, c, length) { 175 | while(str.length < length) { 176 | str = c.toString() + str; 177 | } 178 | return str; 179 | }; -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "opensubtitles", 3 | "version": "0.1.1", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "opensubtitles", 9 | "version": "0.1.1", 10 | "license": "MIT", 11 | "dependencies": { 12 | "xmlrpc": "1.0.2" 13 | }, 14 | "devDependencies": { 15 | "heapdump": "^0.3.5", 16 | "mocha": "^10.0.0" 17 | }, 18 | "engines": { 19 | "node": "*" 20 | } 21 | }, 22 | "node_modules/@ungap/promise-all-settled": { 23 | "version": "1.1.2", 24 | "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", 25 | "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", 26 | "dev": true 27 | }, 28 | "node_modules/ansi-colors": { 29 | "version": "4.1.1", 30 | "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", 31 | "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", 32 | "dev": true, 33 | "engines": { 34 | "node": ">=6" 35 | } 36 | }, 37 | "node_modules/ansi-regex": { 38 | "version": "5.0.1", 39 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 40 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 41 | "dev": true, 42 | "engines": { 43 | "node": ">=8" 44 | } 45 | }, 46 | "node_modules/ansi-styles": { 47 | "version": "4.3.0", 48 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 49 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 50 | "dev": true, 51 | "dependencies": { 52 | "color-convert": "^2.0.1" 53 | }, 54 | "engines": { 55 | "node": ">=8" 56 | }, 57 | "funding": { 58 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 59 | } 60 | }, 61 | "node_modules/anymatch": { 62 | "version": "3.1.2", 63 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", 64 | "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", 65 | "dev": true, 66 | "dependencies": { 67 | "normalize-path": "^3.0.0", 68 | "picomatch": "^2.0.4" 69 | }, 70 | "engines": { 71 | "node": ">= 8" 72 | } 73 | }, 74 | "node_modules/argparse": { 75 | "version": "2.0.1", 76 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", 77 | "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", 78 | "dev": true 79 | }, 80 | "node_modules/balanced-match": { 81 | "version": "1.0.2", 82 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 83 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 84 | "dev": true 85 | }, 86 | "node_modules/binary-extensions": { 87 | "version": "2.2.0", 88 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", 89 | "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", 90 | "dev": true, 91 | "engines": { 92 | "node": ">=8" 93 | } 94 | }, 95 | "node_modules/brace-expansion": { 96 | "version": "2.0.1", 97 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", 98 | "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", 99 | "dev": true, 100 | "dependencies": { 101 | "balanced-match": "^1.0.0" 102 | } 103 | }, 104 | "node_modules/braces": { 105 | "version": "3.0.2", 106 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", 107 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", 108 | "dev": true, 109 | "dependencies": { 110 | "fill-range": "^7.0.1" 111 | }, 112 | "engines": { 113 | "node": ">=8" 114 | } 115 | }, 116 | "node_modules/browser-stdout": { 117 | "version": "1.3.1", 118 | "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", 119 | "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", 120 | "dev": true 121 | }, 122 | "node_modules/camelcase": { 123 | "version": "6.3.0", 124 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", 125 | "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", 126 | "dev": true, 127 | "engines": { 128 | "node": ">=10" 129 | }, 130 | "funding": { 131 | "url": "https://github.com/sponsors/sindresorhus" 132 | } 133 | }, 134 | "node_modules/chalk": { 135 | "version": "4.1.2", 136 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", 137 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", 138 | "dev": true, 139 | "dependencies": { 140 | "ansi-styles": "^4.1.0", 141 | "supports-color": "^7.1.0" 142 | }, 143 | "engines": { 144 | "node": ">=10" 145 | }, 146 | "funding": { 147 | "url": "https://github.com/chalk/chalk?sponsor=1" 148 | } 149 | }, 150 | "node_modules/chalk/node_modules/supports-color": { 151 | "version": "7.2.0", 152 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 153 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 154 | "dev": true, 155 | "dependencies": { 156 | "has-flag": "^4.0.0" 157 | }, 158 | "engines": { 159 | "node": ">=8" 160 | } 161 | }, 162 | "node_modules/chokidar": { 163 | "version": "3.5.3", 164 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", 165 | "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", 166 | "dev": true, 167 | "funding": [ 168 | { 169 | "type": "individual", 170 | "url": "https://paulmillr.com/funding/" 171 | } 172 | ], 173 | "dependencies": { 174 | "anymatch": "~3.1.2", 175 | "braces": "~3.0.2", 176 | "glob-parent": "~5.1.2", 177 | "is-binary-path": "~2.1.0", 178 | "is-glob": "~4.0.1", 179 | "normalize-path": "~3.0.0", 180 | "readdirp": "~3.6.0" 181 | }, 182 | "engines": { 183 | "node": ">= 8.10.0" 184 | }, 185 | "optionalDependencies": { 186 | "fsevents": "~2.3.2" 187 | } 188 | }, 189 | "node_modules/cliui": { 190 | "version": "7.0.4", 191 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", 192 | "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", 193 | "dev": true, 194 | "dependencies": { 195 | "string-width": "^4.2.0", 196 | "strip-ansi": "^6.0.0", 197 | "wrap-ansi": "^7.0.0" 198 | } 199 | }, 200 | "node_modules/color-convert": { 201 | "version": "2.0.1", 202 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 203 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 204 | "dev": true, 205 | "dependencies": { 206 | "color-name": "~1.1.4" 207 | }, 208 | "engines": { 209 | "node": ">=7.0.0" 210 | } 211 | }, 212 | "node_modules/color-name": { 213 | "version": "1.1.4", 214 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 215 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 216 | "dev": true 217 | }, 218 | "node_modules/concat-map": { 219 | "version": "0.0.1", 220 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 221 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 222 | "dev": true 223 | }, 224 | "node_modules/debug": { 225 | "version": "4.3.4", 226 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", 227 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", 228 | "dev": true, 229 | "dependencies": { 230 | "ms": "2.1.2" 231 | }, 232 | "engines": { 233 | "node": ">=6.0" 234 | }, 235 | "peerDependenciesMeta": { 236 | "supports-color": { 237 | "optional": true 238 | } 239 | } 240 | }, 241 | "node_modules/debug/node_modules/ms": { 242 | "version": "2.1.2", 243 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 244 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 245 | "dev": true 246 | }, 247 | "node_modules/decamelize": { 248 | "version": "4.0.0", 249 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", 250 | "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", 251 | "dev": true, 252 | "engines": { 253 | "node": ">=10" 254 | }, 255 | "funding": { 256 | "url": "https://github.com/sponsors/sindresorhus" 257 | } 258 | }, 259 | "node_modules/diff": { 260 | "version": "5.0.0", 261 | "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", 262 | "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", 263 | "dev": true, 264 | "engines": { 265 | "node": ">=0.3.1" 266 | } 267 | }, 268 | "node_modules/emoji-regex": { 269 | "version": "8.0.0", 270 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 271 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 272 | "dev": true 273 | }, 274 | "node_modules/escalade": { 275 | "version": "3.1.1", 276 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", 277 | "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", 278 | "dev": true, 279 | "engines": { 280 | "node": ">=6" 281 | } 282 | }, 283 | "node_modules/escape-string-regexp": { 284 | "version": "4.0.0", 285 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", 286 | "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", 287 | "dev": true, 288 | "engines": { 289 | "node": ">=10" 290 | }, 291 | "funding": { 292 | "url": "https://github.com/sponsors/sindresorhus" 293 | } 294 | }, 295 | "node_modules/fill-range": { 296 | "version": "7.0.1", 297 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", 298 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", 299 | "dev": true, 300 | "dependencies": { 301 | "to-regex-range": "^5.0.1" 302 | }, 303 | "engines": { 304 | "node": ">=8" 305 | } 306 | }, 307 | "node_modules/find-up": { 308 | "version": "5.0.0", 309 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", 310 | "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", 311 | "dev": true, 312 | "dependencies": { 313 | "locate-path": "^6.0.0", 314 | "path-exists": "^4.0.0" 315 | }, 316 | "engines": { 317 | "node": ">=10" 318 | }, 319 | "funding": { 320 | "url": "https://github.com/sponsors/sindresorhus" 321 | } 322 | }, 323 | "node_modules/flat": { 324 | "version": "5.0.2", 325 | "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", 326 | "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", 327 | "dev": true, 328 | "bin": { 329 | "flat": "cli.js" 330 | } 331 | }, 332 | "node_modules/fs.realpath": { 333 | "version": "1.0.0", 334 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 335 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 336 | "dev": true 337 | }, 338 | "node_modules/fsevents": { 339 | "version": "2.3.2", 340 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 341 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 342 | "dev": true, 343 | "hasInstallScript": true, 344 | "optional": true, 345 | "os": [ 346 | "darwin" 347 | ], 348 | "engines": { 349 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 350 | } 351 | }, 352 | "node_modules/get-caller-file": { 353 | "version": "2.0.5", 354 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", 355 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", 356 | "dev": true, 357 | "engines": { 358 | "node": "6.* || 8.* || >= 10.*" 359 | } 360 | }, 361 | "node_modules/glob": { 362 | "version": "7.2.0", 363 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", 364 | "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", 365 | "dev": true, 366 | "dependencies": { 367 | "fs.realpath": "^1.0.0", 368 | "inflight": "^1.0.4", 369 | "inherits": "2", 370 | "minimatch": "^3.0.4", 371 | "once": "^1.3.0", 372 | "path-is-absolute": "^1.0.0" 373 | }, 374 | "engines": { 375 | "node": "*" 376 | }, 377 | "funding": { 378 | "url": "https://github.com/sponsors/isaacs" 379 | } 380 | }, 381 | "node_modules/glob-parent": { 382 | "version": "5.1.2", 383 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 384 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 385 | "dev": true, 386 | "dependencies": { 387 | "is-glob": "^4.0.1" 388 | }, 389 | "engines": { 390 | "node": ">= 6" 391 | } 392 | }, 393 | "node_modules/glob/node_modules/brace-expansion": { 394 | "version": "1.1.11", 395 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 396 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 397 | "dev": true, 398 | "dependencies": { 399 | "balanced-match": "^1.0.0", 400 | "concat-map": "0.0.1" 401 | } 402 | }, 403 | "node_modules/glob/node_modules/minimatch": { 404 | "version": "3.1.2", 405 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 406 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 407 | "dev": true, 408 | "dependencies": { 409 | "brace-expansion": "^1.1.7" 410 | }, 411 | "engines": { 412 | "node": "*" 413 | } 414 | }, 415 | "node_modules/has-flag": { 416 | "version": "4.0.0", 417 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 418 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 419 | "dev": true, 420 | "engines": { 421 | "node": ">=8" 422 | } 423 | }, 424 | "node_modules/he": { 425 | "version": "1.2.0", 426 | "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", 427 | "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", 428 | "dev": true, 429 | "bin": { 430 | "he": "bin/he" 431 | } 432 | }, 433 | "node_modules/heapdump": { 434 | "version": "0.3.15", 435 | "resolved": "https://registry.npmjs.org/heapdump/-/heapdump-0.3.15.tgz", 436 | "integrity": "sha512-n8aSFscI9r3gfhOcAECAtXFaQ1uy4QSke6bnaL+iymYZ/dWs9cqDqHM+rALfsHUwukUbxsdlECZ0pKmJdQ/4OA==", 437 | "dev": true, 438 | "hasInstallScript": true, 439 | "dependencies": { 440 | "nan": "^2.13.2" 441 | }, 442 | "engines": { 443 | "node": ">=0.10.0" 444 | } 445 | }, 446 | "node_modules/inflight": { 447 | "version": "1.0.6", 448 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 449 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 450 | "dev": true, 451 | "dependencies": { 452 | "once": "^1.3.0", 453 | "wrappy": "1" 454 | } 455 | }, 456 | "node_modules/inherits": { 457 | "version": "2.0.4", 458 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 459 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 460 | "dev": true 461 | }, 462 | "node_modules/is-binary-path": { 463 | "version": "2.1.0", 464 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", 465 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", 466 | "dev": true, 467 | "dependencies": { 468 | "binary-extensions": "^2.0.0" 469 | }, 470 | "engines": { 471 | "node": ">=8" 472 | } 473 | }, 474 | "node_modules/is-extglob": { 475 | "version": "2.1.1", 476 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 477 | "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", 478 | "dev": true, 479 | "engines": { 480 | "node": ">=0.10.0" 481 | } 482 | }, 483 | "node_modules/is-fullwidth-code-point": { 484 | "version": "3.0.0", 485 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 486 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 487 | "dev": true, 488 | "engines": { 489 | "node": ">=8" 490 | } 491 | }, 492 | "node_modules/is-glob": { 493 | "version": "4.0.3", 494 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 495 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 496 | "dev": true, 497 | "dependencies": { 498 | "is-extglob": "^2.1.1" 499 | }, 500 | "engines": { 501 | "node": ">=0.10.0" 502 | } 503 | }, 504 | "node_modules/is-number": { 505 | "version": "7.0.0", 506 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 507 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 508 | "dev": true, 509 | "engines": { 510 | "node": ">=0.12.0" 511 | } 512 | }, 513 | "node_modules/is-plain-obj": { 514 | "version": "2.1.0", 515 | "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", 516 | "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", 517 | "dev": true, 518 | "engines": { 519 | "node": ">=8" 520 | } 521 | }, 522 | "node_modules/is-unicode-supported": { 523 | "version": "0.1.0", 524 | "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", 525 | "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", 526 | "dev": true, 527 | "engines": { 528 | "node": ">=10" 529 | }, 530 | "funding": { 531 | "url": "https://github.com/sponsors/sindresorhus" 532 | } 533 | }, 534 | "node_modules/js-yaml": { 535 | "version": "4.1.0", 536 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", 537 | "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", 538 | "dev": true, 539 | "dependencies": { 540 | "argparse": "^2.0.1" 541 | }, 542 | "bin": { 543 | "js-yaml": "bin/js-yaml.js" 544 | } 545 | }, 546 | "node_modules/locate-path": { 547 | "version": "6.0.0", 548 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", 549 | "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", 550 | "dev": true, 551 | "dependencies": { 552 | "p-locate": "^5.0.0" 553 | }, 554 | "engines": { 555 | "node": ">=10" 556 | }, 557 | "funding": { 558 | "url": "https://github.com/sponsors/sindresorhus" 559 | } 560 | }, 561 | "node_modules/log-symbols": { 562 | "version": "4.1.0", 563 | "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", 564 | "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", 565 | "dev": true, 566 | "dependencies": { 567 | "chalk": "^4.1.0", 568 | "is-unicode-supported": "^0.1.0" 569 | }, 570 | "engines": { 571 | "node": ">=10" 572 | }, 573 | "funding": { 574 | "url": "https://github.com/sponsors/sindresorhus" 575 | } 576 | }, 577 | "node_modules/minimatch": { 578 | "version": "5.0.1", 579 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", 580 | "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", 581 | "dev": true, 582 | "dependencies": { 583 | "brace-expansion": "^2.0.1" 584 | }, 585 | "engines": { 586 | "node": ">=10" 587 | } 588 | }, 589 | "node_modules/mocha": { 590 | "version": "10.0.0", 591 | "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.0.0.tgz", 592 | "integrity": "sha512-0Wl+elVUD43Y0BqPZBzZt8Tnkw9CMUdNYnUsTfOM1vuhJVZL+kiesFYsqwBkEEuEixaiPe5ZQdqDgX2jddhmoA==", 593 | "dev": true, 594 | "dependencies": { 595 | "@ungap/promise-all-settled": "1.1.2", 596 | "ansi-colors": "4.1.1", 597 | "browser-stdout": "1.3.1", 598 | "chokidar": "3.5.3", 599 | "debug": "4.3.4", 600 | "diff": "5.0.0", 601 | "escape-string-regexp": "4.0.0", 602 | "find-up": "5.0.0", 603 | "glob": "7.2.0", 604 | "he": "1.2.0", 605 | "js-yaml": "4.1.0", 606 | "log-symbols": "4.1.0", 607 | "minimatch": "5.0.1", 608 | "ms": "2.1.3", 609 | "nanoid": "3.3.3", 610 | "serialize-javascript": "6.0.0", 611 | "strip-json-comments": "3.1.1", 612 | "supports-color": "8.1.1", 613 | "workerpool": "6.2.1", 614 | "yargs": "16.2.0", 615 | "yargs-parser": "20.2.4", 616 | "yargs-unparser": "2.0.0" 617 | }, 618 | "bin": { 619 | "_mocha": "bin/_mocha", 620 | "mocha": "bin/mocha.js" 621 | }, 622 | "engines": { 623 | "node": ">= 14.0.0" 624 | }, 625 | "funding": { 626 | "type": "opencollective", 627 | "url": "https://opencollective.com/mochajs" 628 | } 629 | }, 630 | "node_modules/ms": { 631 | "version": "2.1.3", 632 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 633 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 634 | "dev": true 635 | }, 636 | "node_modules/nan": { 637 | "version": "2.15.0", 638 | "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", 639 | "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==", 640 | "dev": true 641 | }, 642 | "node_modules/nanoid": { 643 | "version": "3.3.3", 644 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", 645 | "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", 646 | "dev": true, 647 | "bin": { 648 | "nanoid": "bin/nanoid.cjs" 649 | }, 650 | "engines": { 651 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" 652 | } 653 | }, 654 | "node_modules/normalize-path": { 655 | "version": "3.0.0", 656 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", 657 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", 658 | "dev": true, 659 | "engines": { 660 | "node": ">=0.10.0" 661 | } 662 | }, 663 | "node_modules/once": { 664 | "version": "1.4.0", 665 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 666 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 667 | "dev": true, 668 | "dependencies": { 669 | "wrappy": "1" 670 | } 671 | }, 672 | "node_modules/p-limit": { 673 | "version": "3.1.0", 674 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", 675 | "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", 676 | "dev": true, 677 | "dependencies": { 678 | "yocto-queue": "^0.1.0" 679 | }, 680 | "engines": { 681 | "node": ">=10" 682 | }, 683 | "funding": { 684 | "url": "https://github.com/sponsors/sindresorhus" 685 | } 686 | }, 687 | "node_modules/p-locate": { 688 | "version": "5.0.0", 689 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", 690 | "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", 691 | "dev": true, 692 | "dependencies": { 693 | "p-limit": "^3.0.2" 694 | }, 695 | "engines": { 696 | "node": ">=10" 697 | }, 698 | "funding": { 699 | "url": "https://github.com/sponsors/sindresorhus" 700 | } 701 | }, 702 | "node_modules/path-exists": { 703 | "version": "4.0.0", 704 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", 705 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", 706 | "dev": true, 707 | "engines": { 708 | "node": ">=8" 709 | } 710 | }, 711 | "node_modules/path-is-absolute": { 712 | "version": "1.0.1", 713 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 714 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 715 | "dev": true, 716 | "engines": { 717 | "node": ">=0.10.0" 718 | } 719 | }, 720 | "node_modules/picomatch": { 721 | "version": "2.3.1", 722 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 723 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 724 | "dev": true, 725 | "engines": { 726 | "node": ">=8.6" 727 | }, 728 | "funding": { 729 | "url": "https://github.com/sponsors/jonschlinkert" 730 | } 731 | }, 732 | "node_modules/randombytes": { 733 | "version": "2.1.0", 734 | "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", 735 | "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", 736 | "dev": true, 737 | "dependencies": { 738 | "safe-buffer": "^5.1.0" 739 | } 740 | }, 741 | "node_modules/readdirp": { 742 | "version": "3.6.0", 743 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", 744 | "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", 745 | "dev": true, 746 | "dependencies": { 747 | "picomatch": "^2.2.1" 748 | }, 749 | "engines": { 750 | "node": ">=8.10.0" 751 | } 752 | }, 753 | "node_modules/require-directory": { 754 | "version": "2.1.1", 755 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", 756 | "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", 757 | "dev": true, 758 | "engines": { 759 | "node": ">=0.10.0" 760 | } 761 | }, 762 | "node_modules/safe-buffer": { 763 | "version": "5.2.1", 764 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 765 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 766 | "dev": true, 767 | "funding": [ 768 | { 769 | "type": "github", 770 | "url": "https://github.com/sponsors/feross" 771 | }, 772 | { 773 | "type": "patreon", 774 | "url": "https://www.patreon.com/feross" 775 | }, 776 | { 777 | "type": "consulting", 778 | "url": "https://feross.org/support" 779 | } 780 | ] 781 | }, 782 | "node_modules/sax": { 783 | "version": "0.4.3", 784 | "resolved": "https://registry.npmjs.org/sax/-/sax-0.4.3.tgz", 785 | "integrity": "sha1-cA46NOsueSzjgHkccSgPNzGWXdw=" 786 | }, 787 | "node_modules/serialize-javascript": { 788 | "version": "6.0.0", 789 | "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", 790 | "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", 791 | "dev": true, 792 | "dependencies": { 793 | "randombytes": "^2.1.0" 794 | } 795 | }, 796 | "node_modules/string-width": { 797 | "version": "4.2.3", 798 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 799 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 800 | "dev": true, 801 | "dependencies": { 802 | "emoji-regex": "^8.0.0", 803 | "is-fullwidth-code-point": "^3.0.0", 804 | "strip-ansi": "^6.0.1" 805 | }, 806 | "engines": { 807 | "node": ">=8" 808 | } 809 | }, 810 | "node_modules/strip-ansi": { 811 | "version": "6.0.1", 812 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 813 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 814 | "dev": true, 815 | "dependencies": { 816 | "ansi-regex": "^5.0.1" 817 | }, 818 | "engines": { 819 | "node": ">=8" 820 | } 821 | }, 822 | "node_modules/strip-json-comments": { 823 | "version": "3.1.1", 824 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", 825 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 826 | "dev": true, 827 | "engines": { 828 | "node": ">=8" 829 | }, 830 | "funding": { 831 | "url": "https://github.com/sponsors/sindresorhus" 832 | } 833 | }, 834 | "node_modules/supports-color": { 835 | "version": "8.1.1", 836 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", 837 | "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", 838 | "dev": true, 839 | "dependencies": { 840 | "has-flag": "^4.0.0" 841 | }, 842 | "engines": { 843 | "node": ">=10" 844 | }, 845 | "funding": { 846 | "url": "https://github.com/chalk/supports-color?sponsor=1" 847 | } 848 | }, 849 | "node_modules/to-regex-range": { 850 | "version": "5.0.1", 851 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 852 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 853 | "dev": true, 854 | "dependencies": { 855 | "is-number": "^7.0.0" 856 | }, 857 | "engines": { 858 | "node": ">=8.0" 859 | } 860 | }, 861 | "node_modules/workerpool": { 862 | "version": "6.2.1", 863 | "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", 864 | "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", 865 | "dev": true 866 | }, 867 | "node_modules/wrap-ansi": { 868 | "version": "7.0.0", 869 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", 870 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", 871 | "dev": true, 872 | "dependencies": { 873 | "ansi-styles": "^4.0.0", 874 | "string-width": "^4.1.0", 875 | "strip-ansi": "^6.0.0" 876 | }, 877 | "engines": { 878 | "node": ">=10" 879 | }, 880 | "funding": { 881 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1" 882 | } 883 | }, 884 | "node_modules/wrappy": { 885 | "version": "1.0.2", 886 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 887 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 888 | "dev": true 889 | }, 890 | "node_modules/xmlbuilder": { 891 | "version": "0.3.1", 892 | "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-0.3.1.tgz", 893 | "integrity": "sha1-XtTCK0YiwkN/r4Pk8jbyPWu/JkE=", 894 | "engines": { 895 | "node": ">=0.2.0" 896 | } 897 | }, 898 | "node_modules/xmlrpc": { 899 | "version": "1.0.2", 900 | "resolved": "https://registry.npmjs.org/xmlrpc/-/xmlrpc-1.0.2.tgz", 901 | "integrity": "sha1-2qe/Zy6RpZBkUXf/KXZ23ofb4qE=", 902 | "dependencies": { 903 | "sax": "0.4.x", 904 | "xmlbuilder": "0.3.1" 905 | }, 906 | "engines": { 907 | "node": ">=0.4", 908 | "npm": ">=1.0.0" 909 | } 910 | }, 911 | "node_modules/y18n": { 912 | "version": "5.0.8", 913 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", 914 | "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", 915 | "dev": true, 916 | "engines": { 917 | "node": ">=10" 918 | } 919 | }, 920 | "node_modules/yargs": { 921 | "version": "16.2.0", 922 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", 923 | "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", 924 | "dev": true, 925 | "dependencies": { 926 | "cliui": "^7.0.2", 927 | "escalade": "^3.1.1", 928 | "get-caller-file": "^2.0.5", 929 | "require-directory": "^2.1.1", 930 | "string-width": "^4.2.0", 931 | "y18n": "^5.0.5", 932 | "yargs-parser": "^20.2.2" 933 | }, 934 | "engines": { 935 | "node": ">=10" 936 | } 937 | }, 938 | "node_modules/yargs-parser": { 939 | "version": "20.2.4", 940 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", 941 | "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", 942 | "dev": true, 943 | "engines": { 944 | "node": ">=10" 945 | } 946 | }, 947 | "node_modules/yargs-unparser": { 948 | "version": "2.0.0", 949 | "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", 950 | "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", 951 | "dev": true, 952 | "dependencies": { 953 | "camelcase": "^6.0.0", 954 | "decamelize": "^4.0.0", 955 | "flat": "^5.0.2", 956 | "is-plain-obj": "^2.1.0" 957 | }, 958 | "engines": { 959 | "node": ">=10" 960 | } 961 | }, 962 | "node_modules/yocto-queue": { 963 | "version": "0.1.0", 964 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", 965 | "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", 966 | "dev": true, 967 | "engines": { 968 | "node": ">=10" 969 | }, 970 | "funding": { 971 | "url": "https://github.com/sponsors/sindresorhus" 972 | } 973 | } 974 | }, 975 | "dependencies": { 976 | "@ungap/promise-all-settled": { 977 | "version": "1.1.2", 978 | "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", 979 | "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", 980 | "dev": true 981 | }, 982 | "ansi-colors": { 983 | "version": "4.1.1", 984 | "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", 985 | "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", 986 | "dev": true 987 | }, 988 | "ansi-regex": { 989 | "version": "5.0.1", 990 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 991 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 992 | "dev": true 993 | }, 994 | "ansi-styles": { 995 | "version": "4.3.0", 996 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 997 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 998 | "dev": true, 999 | "requires": { 1000 | "color-convert": "^2.0.1" 1001 | } 1002 | }, 1003 | "anymatch": { 1004 | "version": "3.1.2", 1005 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", 1006 | "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", 1007 | "dev": true, 1008 | "requires": { 1009 | "normalize-path": "^3.0.0", 1010 | "picomatch": "^2.0.4" 1011 | } 1012 | }, 1013 | "argparse": { 1014 | "version": "2.0.1", 1015 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", 1016 | "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", 1017 | "dev": true 1018 | }, 1019 | "balanced-match": { 1020 | "version": "1.0.2", 1021 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 1022 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 1023 | "dev": true 1024 | }, 1025 | "binary-extensions": { 1026 | "version": "2.2.0", 1027 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", 1028 | "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", 1029 | "dev": true 1030 | }, 1031 | "brace-expansion": { 1032 | "version": "2.0.1", 1033 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", 1034 | "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", 1035 | "dev": true, 1036 | "requires": { 1037 | "balanced-match": "^1.0.0" 1038 | } 1039 | }, 1040 | "braces": { 1041 | "version": "3.0.2", 1042 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", 1043 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", 1044 | "dev": true, 1045 | "requires": { 1046 | "fill-range": "^7.0.1" 1047 | } 1048 | }, 1049 | "browser-stdout": { 1050 | "version": "1.3.1", 1051 | "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", 1052 | "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", 1053 | "dev": true 1054 | }, 1055 | "camelcase": { 1056 | "version": "6.3.0", 1057 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", 1058 | "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", 1059 | "dev": true 1060 | }, 1061 | "chalk": { 1062 | "version": "4.1.2", 1063 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", 1064 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", 1065 | "dev": true, 1066 | "requires": { 1067 | "ansi-styles": "^4.1.0", 1068 | "supports-color": "^7.1.0" 1069 | }, 1070 | "dependencies": { 1071 | "supports-color": { 1072 | "version": "7.2.0", 1073 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 1074 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 1075 | "dev": true, 1076 | "requires": { 1077 | "has-flag": "^4.0.0" 1078 | } 1079 | } 1080 | } 1081 | }, 1082 | "chokidar": { 1083 | "version": "3.5.3", 1084 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", 1085 | "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", 1086 | "dev": true, 1087 | "requires": { 1088 | "anymatch": "~3.1.2", 1089 | "braces": "~3.0.2", 1090 | "fsevents": "~2.3.2", 1091 | "glob-parent": "~5.1.2", 1092 | "is-binary-path": "~2.1.0", 1093 | "is-glob": "~4.0.1", 1094 | "normalize-path": "~3.0.0", 1095 | "readdirp": "~3.6.0" 1096 | } 1097 | }, 1098 | "cliui": { 1099 | "version": "7.0.4", 1100 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", 1101 | "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", 1102 | "dev": true, 1103 | "requires": { 1104 | "string-width": "^4.2.0", 1105 | "strip-ansi": "^6.0.0", 1106 | "wrap-ansi": "^7.0.0" 1107 | } 1108 | }, 1109 | "color-convert": { 1110 | "version": "2.0.1", 1111 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 1112 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 1113 | "dev": true, 1114 | "requires": { 1115 | "color-name": "~1.1.4" 1116 | } 1117 | }, 1118 | "color-name": { 1119 | "version": "1.1.4", 1120 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 1121 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 1122 | "dev": true 1123 | }, 1124 | "concat-map": { 1125 | "version": "0.0.1", 1126 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 1127 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 1128 | "dev": true 1129 | }, 1130 | "debug": { 1131 | "version": "4.3.4", 1132 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", 1133 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", 1134 | "dev": true, 1135 | "requires": { 1136 | "ms": "2.1.2" 1137 | }, 1138 | "dependencies": { 1139 | "ms": { 1140 | "version": "2.1.2", 1141 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 1142 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 1143 | "dev": true 1144 | } 1145 | } 1146 | }, 1147 | "decamelize": { 1148 | "version": "4.0.0", 1149 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", 1150 | "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", 1151 | "dev": true 1152 | }, 1153 | "diff": { 1154 | "version": "5.0.0", 1155 | "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", 1156 | "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", 1157 | "dev": true 1158 | }, 1159 | "emoji-regex": { 1160 | "version": "8.0.0", 1161 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 1162 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 1163 | "dev": true 1164 | }, 1165 | "escalade": { 1166 | "version": "3.1.1", 1167 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", 1168 | "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", 1169 | "dev": true 1170 | }, 1171 | "escape-string-regexp": { 1172 | "version": "4.0.0", 1173 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", 1174 | "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", 1175 | "dev": true 1176 | }, 1177 | "fill-range": { 1178 | "version": "7.0.1", 1179 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", 1180 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", 1181 | "dev": true, 1182 | "requires": { 1183 | "to-regex-range": "^5.0.1" 1184 | } 1185 | }, 1186 | "find-up": { 1187 | "version": "5.0.0", 1188 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", 1189 | "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", 1190 | "dev": true, 1191 | "requires": { 1192 | "locate-path": "^6.0.0", 1193 | "path-exists": "^4.0.0" 1194 | } 1195 | }, 1196 | "flat": { 1197 | "version": "5.0.2", 1198 | "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", 1199 | "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", 1200 | "dev": true 1201 | }, 1202 | "fs.realpath": { 1203 | "version": "1.0.0", 1204 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 1205 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 1206 | "dev": true 1207 | }, 1208 | "fsevents": { 1209 | "version": "2.3.2", 1210 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 1211 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 1212 | "dev": true, 1213 | "optional": true 1214 | }, 1215 | "get-caller-file": { 1216 | "version": "2.0.5", 1217 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", 1218 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", 1219 | "dev": true 1220 | }, 1221 | "glob": { 1222 | "version": "7.2.0", 1223 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", 1224 | "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", 1225 | "dev": true, 1226 | "requires": { 1227 | "fs.realpath": "^1.0.0", 1228 | "inflight": "^1.0.4", 1229 | "inherits": "2", 1230 | "minimatch": "^3.0.4", 1231 | "once": "^1.3.0", 1232 | "path-is-absolute": "^1.0.0" 1233 | }, 1234 | "dependencies": { 1235 | "brace-expansion": { 1236 | "version": "1.1.11", 1237 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 1238 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 1239 | "dev": true, 1240 | "requires": { 1241 | "balanced-match": "^1.0.0", 1242 | "concat-map": "0.0.1" 1243 | } 1244 | }, 1245 | "minimatch": { 1246 | "version": "3.1.2", 1247 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 1248 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 1249 | "dev": true, 1250 | "requires": { 1251 | "brace-expansion": "^1.1.7" 1252 | } 1253 | } 1254 | } 1255 | }, 1256 | "glob-parent": { 1257 | "version": "5.1.2", 1258 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 1259 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 1260 | "dev": true, 1261 | "requires": { 1262 | "is-glob": "^4.0.1" 1263 | } 1264 | }, 1265 | "has-flag": { 1266 | "version": "4.0.0", 1267 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 1268 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 1269 | "dev": true 1270 | }, 1271 | "he": { 1272 | "version": "1.2.0", 1273 | "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", 1274 | "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", 1275 | "dev": true 1276 | }, 1277 | "heapdump": { 1278 | "version": "0.3.15", 1279 | "resolved": "https://registry.npmjs.org/heapdump/-/heapdump-0.3.15.tgz", 1280 | "integrity": "sha512-n8aSFscI9r3gfhOcAECAtXFaQ1uy4QSke6bnaL+iymYZ/dWs9cqDqHM+rALfsHUwukUbxsdlECZ0pKmJdQ/4OA==", 1281 | "dev": true, 1282 | "requires": { 1283 | "nan": "^2.13.2" 1284 | } 1285 | }, 1286 | "inflight": { 1287 | "version": "1.0.6", 1288 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 1289 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 1290 | "dev": true, 1291 | "requires": { 1292 | "once": "^1.3.0", 1293 | "wrappy": "1" 1294 | } 1295 | }, 1296 | "inherits": { 1297 | "version": "2.0.4", 1298 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 1299 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 1300 | "dev": true 1301 | }, 1302 | "is-binary-path": { 1303 | "version": "2.1.0", 1304 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", 1305 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", 1306 | "dev": true, 1307 | "requires": { 1308 | "binary-extensions": "^2.0.0" 1309 | } 1310 | }, 1311 | "is-extglob": { 1312 | "version": "2.1.1", 1313 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 1314 | "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", 1315 | "dev": true 1316 | }, 1317 | "is-fullwidth-code-point": { 1318 | "version": "3.0.0", 1319 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 1320 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 1321 | "dev": true 1322 | }, 1323 | "is-glob": { 1324 | "version": "4.0.3", 1325 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 1326 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 1327 | "dev": true, 1328 | "requires": { 1329 | "is-extglob": "^2.1.1" 1330 | } 1331 | }, 1332 | "is-number": { 1333 | "version": "7.0.0", 1334 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 1335 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 1336 | "dev": true 1337 | }, 1338 | "is-plain-obj": { 1339 | "version": "2.1.0", 1340 | "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", 1341 | "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", 1342 | "dev": true 1343 | }, 1344 | "is-unicode-supported": { 1345 | "version": "0.1.0", 1346 | "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", 1347 | "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", 1348 | "dev": true 1349 | }, 1350 | "js-yaml": { 1351 | "version": "4.1.0", 1352 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", 1353 | "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", 1354 | "dev": true, 1355 | "requires": { 1356 | "argparse": "^2.0.1" 1357 | } 1358 | }, 1359 | "locate-path": { 1360 | "version": "6.0.0", 1361 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", 1362 | "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", 1363 | "dev": true, 1364 | "requires": { 1365 | "p-locate": "^5.0.0" 1366 | } 1367 | }, 1368 | "log-symbols": { 1369 | "version": "4.1.0", 1370 | "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", 1371 | "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", 1372 | "dev": true, 1373 | "requires": { 1374 | "chalk": "^4.1.0", 1375 | "is-unicode-supported": "^0.1.0" 1376 | } 1377 | }, 1378 | "minimatch": { 1379 | "version": "5.0.1", 1380 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", 1381 | "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", 1382 | "dev": true, 1383 | "requires": { 1384 | "brace-expansion": "^2.0.1" 1385 | } 1386 | }, 1387 | "mocha": { 1388 | "version": "10.0.0", 1389 | "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.0.0.tgz", 1390 | "integrity": "sha512-0Wl+elVUD43Y0BqPZBzZt8Tnkw9CMUdNYnUsTfOM1vuhJVZL+kiesFYsqwBkEEuEixaiPe5ZQdqDgX2jddhmoA==", 1391 | "dev": true, 1392 | "requires": { 1393 | "@ungap/promise-all-settled": "1.1.2", 1394 | "ansi-colors": "4.1.1", 1395 | "browser-stdout": "1.3.1", 1396 | "chokidar": "3.5.3", 1397 | "debug": "4.3.4", 1398 | "diff": "5.0.0", 1399 | "escape-string-regexp": "4.0.0", 1400 | "find-up": "5.0.0", 1401 | "glob": "7.2.0", 1402 | "he": "1.2.0", 1403 | "js-yaml": "4.1.0", 1404 | "log-symbols": "4.1.0", 1405 | "minimatch": "5.0.1", 1406 | "ms": "2.1.3", 1407 | "nanoid": "3.3.3", 1408 | "serialize-javascript": "6.0.0", 1409 | "strip-json-comments": "3.1.1", 1410 | "supports-color": "8.1.1", 1411 | "workerpool": "6.2.1", 1412 | "yargs": "16.2.0", 1413 | "yargs-parser": "20.2.4", 1414 | "yargs-unparser": "2.0.0" 1415 | } 1416 | }, 1417 | "ms": { 1418 | "version": "2.1.3", 1419 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 1420 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 1421 | "dev": true 1422 | }, 1423 | "nan": { 1424 | "version": "2.15.0", 1425 | "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", 1426 | "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==", 1427 | "dev": true 1428 | }, 1429 | "nanoid": { 1430 | "version": "3.3.3", 1431 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", 1432 | "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", 1433 | "dev": true 1434 | }, 1435 | "normalize-path": { 1436 | "version": "3.0.0", 1437 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", 1438 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", 1439 | "dev": true 1440 | }, 1441 | "once": { 1442 | "version": "1.4.0", 1443 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1444 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 1445 | "dev": true, 1446 | "requires": { 1447 | "wrappy": "1" 1448 | } 1449 | }, 1450 | "p-limit": { 1451 | "version": "3.1.0", 1452 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", 1453 | "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", 1454 | "dev": true, 1455 | "requires": { 1456 | "yocto-queue": "^0.1.0" 1457 | } 1458 | }, 1459 | "p-locate": { 1460 | "version": "5.0.0", 1461 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", 1462 | "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", 1463 | "dev": true, 1464 | "requires": { 1465 | "p-limit": "^3.0.2" 1466 | } 1467 | }, 1468 | "path-exists": { 1469 | "version": "4.0.0", 1470 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", 1471 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", 1472 | "dev": true 1473 | }, 1474 | "path-is-absolute": { 1475 | "version": "1.0.1", 1476 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 1477 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 1478 | "dev": true 1479 | }, 1480 | "picomatch": { 1481 | "version": "2.3.1", 1482 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 1483 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 1484 | "dev": true 1485 | }, 1486 | "randombytes": { 1487 | "version": "2.1.0", 1488 | "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", 1489 | "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", 1490 | "dev": true, 1491 | "requires": { 1492 | "safe-buffer": "^5.1.0" 1493 | } 1494 | }, 1495 | "readdirp": { 1496 | "version": "3.6.0", 1497 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", 1498 | "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", 1499 | "dev": true, 1500 | "requires": { 1501 | "picomatch": "^2.2.1" 1502 | } 1503 | }, 1504 | "require-directory": { 1505 | "version": "2.1.1", 1506 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", 1507 | "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", 1508 | "dev": true 1509 | }, 1510 | "safe-buffer": { 1511 | "version": "5.2.1", 1512 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 1513 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 1514 | "dev": true 1515 | }, 1516 | "sax": { 1517 | "version": "0.4.3", 1518 | "resolved": "https://registry.npmjs.org/sax/-/sax-0.4.3.tgz", 1519 | "integrity": "sha1-cA46NOsueSzjgHkccSgPNzGWXdw=" 1520 | }, 1521 | "serialize-javascript": { 1522 | "version": "6.0.0", 1523 | "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", 1524 | "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", 1525 | "dev": true, 1526 | "requires": { 1527 | "randombytes": "^2.1.0" 1528 | } 1529 | }, 1530 | "string-width": { 1531 | "version": "4.2.3", 1532 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 1533 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 1534 | "dev": true, 1535 | "requires": { 1536 | "emoji-regex": "^8.0.0", 1537 | "is-fullwidth-code-point": "^3.0.0", 1538 | "strip-ansi": "^6.0.1" 1539 | } 1540 | }, 1541 | "strip-ansi": { 1542 | "version": "6.0.1", 1543 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 1544 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 1545 | "dev": true, 1546 | "requires": { 1547 | "ansi-regex": "^5.0.1" 1548 | } 1549 | }, 1550 | "strip-json-comments": { 1551 | "version": "3.1.1", 1552 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", 1553 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 1554 | "dev": true 1555 | }, 1556 | "supports-color": { 1557 | "version": "8.1.1", 1558 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", 1559 | "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", 1560 | "dev": true, 1561 | "requires": { 1562 | "has-flag": "^4.0.0" 1563 | } 1564 | }, 1565 | "to-regex-range": { 1566 | "version": "5.0.1", 1567 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 1568 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 1569 | "dev": true, 1570 | "requires": { 1571 | "is-number": "^7.0.0" 1572 | } 1573 | }, 1574 | "workerpool": { 1575 | "version": "6.2.1", 1576 | "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", 1577 | "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", 1578 | "dev": true 1579 | }, 1580 | "wrap-ansi": { 1581 | "version": "7.0.0", 1582 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", 1583 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", 1584 | "dev": true, 1585 | "requires": { 1586 | "ansi-styles": "^4.0.0", 1587 | "string-width": "^4.1.0", 1588 | "strip-ansi": "^6.0.0" 1589 | } 1590 | }, 1591 | "wrappy": { 1592 | "version": "1.0.2", 1593 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1594 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 1595 | "dev": true 1596 | }, 1597 | "xmlbuilder": { 1598 | "version": "0.3.1", 1599 | "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-0.3.1.tgz", 1600 | "integrity": "sha1-XtTCK0YiwkN/r4Pk8jbyPWu/JkE=" 1601 | }, 1602 | "xmlrpc": { 1603 | "version": "1.0.2", 1604 | "resolved": "https://registry.npmjs.org/xmlrpc/-/xmlrpc-1.0.2.tgz", 1605 | "integrity": "sha1-2qe/Zy6RpZBkUXf/KXZ23ofb4qE=", 1606 | "requires": { 1607 | "sax": "0.4.x", 1608 | "xmlbuilder": "0.3.1" 1609 | } 1610 | }, 1611 | "y18n": { 1612 | "version": "5.0.8", 1613 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", 1614 | "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", 1615 | "dev": true 1616 | }, 1617 | "yargs": { 1618 | "version": "16.2.0", 1619 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", 1620 | "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", 1621 | "dev": true, 1622 | "requires": { 1623 | "cliui": "^7.0.2", 1624 | "escalade": "^3.1.1", 1625 | "get-caller-file": "^2.0.5", 1626 | "require-directory": "^2.1.1", 1627 | "string-width": "^4.2.0", 1628 | "y18n": "^5.0.5", 1629 | "yargs-parser": "^20.2.2" 1630 | } 1631 | }, 1632 | "yargs-parser": { 1633 | "version": "20.2.4", 1634 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", 1635 | "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", 1636 | "dev": true 1637 | }, 1638 | "yargs-unparser": { 1639 | "version": "2.0.0", 1640 | "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", 1641 | "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", 1642 | "dev": true, 1643 | "requires": { 1644 | "camelcase": "^6.0.0", 1645 | "decamelize": "^4.0.0", 1646 | "flat": "^5.0.2", 1647 | "is-plain-obj": "^2.1.0" 1648 | } 1649 | }, 1650 | "yocto-queue": { 1651 | "version": "0.1.0", 1652 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", 1653 | "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", 1654 | "dev": true 1655 | } 1656 | } 1657 | } 1658 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": "ka2er ", 3 | "name": "opensubtitles", 4 | "description": "API to interact with opensubtitles services", 5 | "version": "0.1.1", 6 | "repository": { 7 | "type": "git", 8 | "url": "git://github.com/ka2er/node-opensubtitles-api.git" 9 | }, 10 | "scripts": { 11 | "test": "mocha test/test.js" 12 | }, 13 | "main": "lib/opensubtitles.js", 14 | "dependencies": { 15 | "xmlrpc": "1.0.2" 16 | }, 17 | "devDependencies": { 18 | "heapdump": "^0.3.5", 19 | "mocha": "^10.0.0" 20 | }, 21 | "engines": { 22 | "node": "*" 23 | }, 24 | "keywords": [ 25 | "opensubtitles" 26 | ], 27 | "license": "MIT", 28 | "bugs": { 29 | "url": "https://github.com/ka2er/node-opensubtitles-api/issues" 30 | }, 31 | "directories": { 32 | "test": "test" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /sample.py: -------------------------------------------------------------------------------- 1 | import struct, os 2 | 3 | def hashFile(name, size): 4 | try: 5 | debug = 0 6 | longlongformat = 'q' # long long 7 | bytesize = struct.calcsize(longlongformat) 8 | 9 | f = open(name, "rb") 10 | 11 | filesize = os.path.getsize(name) 12 | print "filesize : %d" % filesize 13 | hash = 0 14 | 15 | if filesize < size * 2: 16 | return "SizeError" 17 | 18 | for x in range(size/bytesize): 19 | buffer = f.read(bytesize) 20 | (l_value,)= struct.unpack(longlongformat, buffer) 21 | #print hash 22 | hash += l_value 23 | if debug: 24 | print "hash#1 %d %016x => %016x" % (x, l_value, hash) 25 | hash = hash & 0xFFFFFFFFFFFFFFFF #to remain as 64bit number 26 | 27 | print "start buffer chcksum : %016x" % hash 28 | 29 | 30 | hash2 = 0 31 | f.seek(max(0,filesize-size),0) 32 | for x in range(size/bytesize): 33 | buffer = f.read(bytesize) 34 | (l_value,)= struct.unpack(longlongformat, buffer) 35 | hash2 += l_value 36 | hash2 = hash2 & 0xFFFFFFFFFFFFFFFF 37 | if debug: 38 | print "hash#2 %d %016x => %016x" % (x, l_value, hash2) 39 | 40 | f.close() 41 | 42 | print "end buffer chcksum : %016x" % hash2 43 | 44 | # hash+size a la fin 45 | hash += filesize 46 | hash = hash & 0xFFFFFFFFFFFFFFFF 47 | print "hash+filsesize %016x " % (hash) 48 | 49 | 50 | hash += hash2 51 | hash = hash & 0xFFFFFFFFFFFFFFFF 52 | print "^+hash2 %016x " % (hash) 53 | 54 | returnedhash = "%016x" % hash 55 | return returnedhash 56 | 57 | except(IOError): 58 | return "IOError" 59 | 60 | 61 | print "CHKSUM : 0x%s" % hashFile('/home/seb/dev/node-opensubtitles-api/test/breakdance.avi', 512); -------------------------------------------------------------------------------- /test/avi-8e245d9679d31e12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ka2er/node-opensubtitles-api/1ec080bfe3123d16e04d353a80ab93ea9c85acdc/test/avi-8e245d9679d31e12 -------------------------------------------------------------------------------- /test/breakdance.avi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ka2er/node-opensubtitles-api/1ec080bfe3123d16e04d353a80ab93ea9c85acdc/test/breakdance.avi -------------------------------------------------------------------------------- /test/leakdetector.js: -------------------------------------------------------------------------------- 1 | var heapdump = require("heapdump"); 2 | 3 | var OS = require("../lib/opensubtitles.js"); 4 | var os = new OS(); 5 | 6 | var current = 0; 7 | var limit = 500; 8 | 9 | function computeHashUntilLimit() { 10 | console.log("compute hash current %d/%d", current, limit); 11 | 12 | if (current === 0) { 13 | writeSnapshot(); 14 | } 15 | 16 | if (current === limit) { 17 | writeSnapshot(); 18 | return; 19 | } 20 | 21 | os.computeHash(__dirname + '/breakdance.avi', function (err, size) { 22 | current++; 23 | computeHashUntilLimit(); 24 | }); 25 | 26 | } 27 | 28 | function writeSnapshot() { 29 | heapdump.writeSnapshot(__dirname + '/' + Date.now() + '.heapsnapshot'); 30 | } 31 | 32 | 33 | computeHashUntilLimit(); -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * User: seb 3 | * Date: 03/10/12 4 | * Time: 10:07 5 | * To change this template use File | Settings | File Templates. 6 | */ 7 | 8 | var assert = require("assert"); 9 | OS = require("../lib/opensubtitles.js"); 10 | 11 | describe('Opensubtitles', function() { 12 | 13 | describe('#computeHash()', function(){ 14 | 15 | it('should return a opensubtitles hash of the movie file ', function(done){ 16 | var os = new OS(); 17 | os.computeHash(process.cwd()+'/test/breakdance.avi', function(err, size){ 18 | if (err) return done(err); 19 | assert.equal(size, '8e245d9679d31e12'); 20 | done(); 21 | }); 22 | }); 23 | 24 | 25 | it('should return a 64bits length opensubtitles hash of the movie file ', function(done){ 26 | var os = new OS(); 27 | os.computeHash(process.cwd()+'/test/breakdance.avi', function(err, size){ 28 | if (err) return done(err); 29 | assert.equal(size.length, '8e245d9679d31e12'.length); 30 | done(); 31 | }); 32 | }); 33 | 34 | }); 35 | 36 | describe('#padLeft', function() { 37 | it('should left pad a string as occurence of max char', function() { 38 | 39 | var os = new OS(); 40 | assert.equal(os.padLeft("123456", 0, 10), "0000123456"); 41 | assert.equal(os.padLeft("123456", "0", 10), "0000123456"); 42 | }); 43 | }); 44 | 45 | describe('#read64LE', function() { 46 | it('should read 64 bits Little indian order from buffer ', function() { 47 | 48 | var os = new OS(); 49 | var buf = new Buffer([ 50 | 0x00, 0x11, 0x22, 0x33, 0X44, 0x55, 0x66, 0x77 51 | ]); 52 | 53 | assert.equal(os.read64LE(buf, 0), "7766554433221100"); 54 | }); 55 | }); 56 | 57 | describe('#sumHex64Bits', function() { 58 | it('should add 64 bits hex string', function() { 59 | var os = new OS(); 60 | assert.equal( 61 | os.sumHex64bits( 62 | "3a3e2a2340", 63 | "4d6b464332" 64 | ), 65 | "87a9706672" 66 | ); 67 | //assert.equal(os.padLeft("123456", "0", 10), "0000123456"); 68 | }); 69 | }); 70 | 71 | describe('#sumHex64Bits', function() { 72 | it('should add 64 bits hex string', function() { 73 | var os = new OS(); 74 | assert.equal( 75 | os.sumHex64bits( 76 | "22ac84f761e", 77 | "0000000062773130" 78 | ), 79 | "22b2ac6a74e" 80 | ); 81 | }); 82 | }); 83 | 84 | describe('#checkMovieHash', function() { 85 | it('should identify Iron Man', function(done) { 86 | var os = new OS(); 87 | os.checkMovieHash(['d7aa0275cace4410'], function(err, res) { 88 | if(err) return done(err); 89 | assert.equal(res.data['d7aa0275cace4410'].MovieName, "Iron Man"); 90 | done(); 91 | }) 92 | }); 93 | }); 94 | }); 95 | 96 | --------------------------------------------------------------------------------