diff --git a/TwitToMast.js b/TwitToMast.js index dbc1b83..f3debfa 100644 --- a/TwitToMast.js +++ b/TwitToMast.js @@ -1,210 +1,41 @@ //REQUIREMENTS - const webdriver = require('selenium-webdriver'); const chrome = require('selenium-webdriver/chrome'); -const By = webdriver.By; -const until = webdriver.until; const fs = require('fs'); -const csvWriter = require('csv-write-stream'); -const Masto = require('mastodon'); -const client = require('https'); -const request = require("request"); -const Q = require("q"); -//VALIDATE INPUT +//LOCAL REQUIREMENTS +const support = require('./ref/functions/support.js'); +const debuglog = support.debuglog; +const elements = require('./ref/functions/elements.js'); +const csv = require('./ref/functions/csv.js'); +const mastodon = require('./ref/functions/mastodon.js'); -const args = process.argv; -if (args[2] == "-h"){ - console.log("usage: $node ./TwitToMast.js [username] [tweet count] [debug level] [disable posts] [print header]"); - console.log(" username: (string) -username of account to scrape - required"); - console.log(" tweet count: (integer) -number of tweets to scrape - required"); - console.log(" debug level: (0-2) -amount of information to print to console - 0 by default"); - console.log(" disable posts: ('write','noWrite') -enable/disable posting to Mastodon - disabled by default"); - console.log(" print header: ('printHeader') -enable attaching a header with the user's name, twitter"); - console.log(" handle, and link to tweet - disabled by default"); - console.log(" config.txt:"); - console.log(" API_KEY"); - console.log(" API_URL"); - console.log(" ENABLE_QUOTE_TWEETS"); - console.log(" ENABLE_THREAD_TWEETS"); - console.log(" "); - process.exit(0); -} -if (typeof args[2] == 'undefined') { - console.log("Expected String with length greater than 1, got '" + args[2] + "' instead"); - console.log("for help: $TwitToMast.js -h"); - process.exit(1); -} else if (args[2].length < 1) { - console.log("Expected String with length greater than 1, got '" + args[2] + "' instead"); - console.log("for help: $TwitToMast.js -h"); - process.exit(1); -} -if (isNaN(parseInt(args[3]))){ - console.log("Expected Integer, got '" + args[3] + "' instead"); - console.log("for help: $TwitToMast.js -h"); - process.exit(1); -} -if (!((parseInt(args[4]) >= 0) && (parseInt(args[4]) <= 2)) && (typeof args[4] != 'undefined')){ - console.log("Expected [0-2], got '" + args[4] + "' instead"); - console.log("for help: $TwitToMast.js -h"); - process.exit(1); -} -if ((args[5] != 'noWrite' && args[5] != 'write') && typeof args[5] != 'undefined') { - console.log("Expected 'noWrite', 'write', or undefined, got '" + args[5] + "' instead"); - console.log("for help: $TwitToMast.js -h"); - process.exit(1); -} +const Args = require('./ref/classes/arguments.js'); +const args = new Args(); +const Formats = require('./ref/classes/formats.js'); +const format = new Formats(); +const Tweets = require('./ref/classes/tweets.js'); -//PROCESS CONFIG +//LOG ARGUMENTS -const config = fs.readFileSync("./config.txt").toString().split(/[\r\n]+/); -var M = new Masto({ - access_token: config[0], - api_url: config[1] -}) -var modulesToEnable = [false, false]; -for(var c = 2; c < 4; c++){ - if (config[c] = "true"){ - modulesToEnable[c-2] = true; - } else if (config[c] = "false"){ - modulesToEnable[c-2] = false; - } else { - console.log("config.txt line " + (c+1) + ": Expected [true/false], got '" + config[c] + "' instead"); - console.log("for help: $TwitToMast.js -h"); - process.exit(1); - } -} +support.validateArgs(); +support.logArguments(); +//SETUP SAVE DIRECTORY VARIABLES -//PROCESS ARGUMENTS - -const userName = args[2]; -const maxTweetScan = parseInt(args[3]); -const debug = args[4]; -if (typeof args[4] == 'undefined') {debug = 0;} -var disablePosts = false; -if (typeof args[5] == 'undefined') { - disablePosts = false; -} else if (args[5] == 'noWrite') { - disablePosts = true; -} -var printHeader = false; -if (args[6] == 'printHeader'){ - printHeader = true; -} else { - printHeader = false; -} -debuglog(args,2); -debuglog("userName: " + userName,2); -debuglog("maxTweetScan: " + maxTweetScan,2); -debuglog("debug: " + debug,2); -debuglog("disable posts: " + disablePosts,2); - -//FUNCTIONS - -function downloadImage(url, filepath) { - return new Promise((resolve, reject) => { - client.get(url, (res) => { - if (res.statusCode === 200) { - res.pipe(fs.createWriteStream(filepath)) - .on('error', reject) - .once('close', () => resolve(filepath)); - } else { - res.resume(); - reject(new Error(`Request Failed With a Status Code: ${res.statusCode}`)); - - } - }); - }); -} - -function debuglog(debugString,logLevel) { - prefix = ""; - switch (logLevel) { - case 0: - prefix = ""; - break; - case 1: - prefix = "-"; - break; - case 2: - prefix = "!"; - break; - } - if (logLevel <= debug) {console.log(prefix + " " + debugString);} -} - -function expandUrl(shortUrl) { - var deferred = Q.defer(); - request( { method: "HEAD", url: shortUrl, followAllRedirects: true }, - function (error, response) { - if (error) { - deferred.reject(new Error(error)); - } else { - deferred.resolve(response.request.href); - } - }); - return deferred.promise; -} - -debuglog("Setting up...",1); -debuglog("userName: " + userName,1); -debuglog("maxTweetScan: " + maxTweetScan,1); -debuglog("debug: " + debug,1); -debuglog("API_URL: " + config[1],1); -debuglog("Enable Quote Tweets: " + modulesToEnable[0],1); -debuglog("Enable Thread Tweets: " + modulesToEnable[1],1); -debuglog("Disable posting to Mastodon: " + disablePosts,1); -debuglog("running from loop: " + printHeader,1); - -//SETUP REMAINDER OF VARIABLES - -const csvFilename = "./URLList.csv"; const localDir = './'; -const imgSavePath = (localDir + userName + '/'); +const imgSavePath = (`${localDir}imgs/${args.userName}/`); if (!fs.existsSync(imgSavePath)){ fs.mkdirSync(imgSavePath); } - -//XPATH CONSTANTS - -const timeLineXPath = `//*[@id="react-root"]/div/div/div[2]/main/div/div/div/div/div/div[3]/div/div/section/div/div`; //the immediate parent div of all tweets - -const tweetXPath = (timeLineXPath + `/div`); //the div containing individual tweet content: (tweetXpath + '[1]') - -//the following xpaths follow an individual tweet xpath: (tweetXpath + '[1]' + variableXPath) - -const urlCardXPath = `/div/div/div/article/div/div/div/div[*]/div[*]/div[*]/div[*]/div/div[2]/a` - -const tweeterHandle = `/div/div/div/article/div/div/div/div[2]/div[2]/div[1]/div/div/div[1]/div/div/div[2]/div/div[1]/a/div/span[contains(text(),"@")]` //text label containing tweeter's handle - -const tweeterName = `/div/div/div/article/div/div/div/div[2]/div[2]/div[1]/div/div/div[1]/div/div/div[1]/div/a/div/div[1]/span/span` //text label containing tweeter's name - -const quoteTweetHandleXPath = `/div/div/div/article/div/div/div/div[2]/div[2]/div[2]/div[2]/div[*]/div[2]/div/div[1]/div/div/div/div/div/div[2]/div[1]/div/div/div/span`; //xpath to text label that reveals if a tweet is a quote tweet (leads to the quote tweeted user's handle) - -const quoteTweetContentXPath= `/div/div/div/article/div/div/div/div[2]/div[2]/div[2]/div[2]/div[*]/div[2][div/div[1]/div/div/div/div/div/div[2]/div[1]/div/div/div/span]` //xpath to locate entirety of Quote Tweeted Content - -const retweetIndicatorXPath = `/div/div/div/article/div/div/div/div[1]/div/div/div/div/div[2]/div/div/div/a/span`; //xpath to text label that reveals if a tweet is a retweet - -const threadIndicatorXPath = `/div/div/div/article/div/a/div/div[2]/div/span`; //xpath to text label that reveals if a tweet is a part of a thread - -const tweetTextXPath = `//div[@data-testid="tweetText"]`; //xpath that leads to div containing all tweet text - -const tweetURLXPath = `//div[3]/a[contains(@href, 'status')]`; //xpath to tweet url - -const singleImageXPath = `//div[2]/div/img[@alt="Image"]`; //xpath to image that reveals if a tweet has one image - -const multiImageXPath = `//div[2]/div[2]/div[2]/div[2]/div/div/div/div/div[2]/div/div[1]/div[1]//a/div/div/img[@alt="Image"]`; //xpath to image that reveals if a tweet has more than one image - -//the following xpaths follow and individual tweet xpath and are used to find all images in a tweet with multiple images: (tweetXpath + '[1]' + multiImage1XPath + x + multiImage2XPath + y + multiImage3XPath) -// the following combinations of x,y variables point to the corresponding image -// 1,1 = first image -// 2,1 = second image -// 2,2 = third image -// 1,2 = fourth image -const multiImage1XPath = `//div[2]/div[2]/div[2]/div[2]/div/div/div/div/div[2]/div/div[`; -const multiImage2XPath = `]/div[`; -const multiImage3XPath = `]//a/div/div/img[@alt="Image"]`; +const csvSaveDir = (`${localDir}csv/`); +const csvFileName = (`${csvSaveDir + args.userName}.csv`); +if (!fs.existsSync(csvSaveDir)){ + fs.mkdirSync(csvSaveDir); +} +var csvOutput = "_"; +debuglog(`csv file name: ${csvFileName}`,2); +debuglog(`user image save path${imgSavePath}`,2); //SETUP HEADLESS WEBDRIVER @@ -212,314 +43,187 @@ const screen = { width: 1920, height: 1080 }; +let chromeOptions = new chrome.Options().addArguments(['user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36']); +if (!args.displayBrowser) {chromeOptions.headless().windowSize(screen);} var driver = new webdriver.Builder() .forBrowser('chrome') - .setChromeOptions(new chrome.Options().headless().windowSize(screen).addArguments(['user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.50 Safari/537.36'])) + .setChromeOptions(chromeOptions) .build(); //START WEBDRIVER AND ZOOM OUT -driver.get('https://mobile.twitter.com/' + userName + '/'); +debuglog("starting webdriver...",2); +driver.get(`https://mobile.twitter.com/${args.userName}/`); +debuglog("started webdriver!",2); driver.executeScript("document.body.style.zoom='35%'"); (async function(){ - //WAIT UNTIL TIMELINE RENDERS - await driver.wait(until.elementLocated(By.xpath(timeLineXPath + `[count(div) > 1]`)), 30000); - //OPEN CSV FILE, CREATE IF NEEDED - - var csvOutput = " "; - await fs.readFile(csvFilename, "utf-8", (err, data) => { - if (err) { - debuglog("Could not get CSV Data!",2) - debuglog(err,1); - writer = csvWriter({sendHeaders: false}); - writer.pipe(fs.createWriteStream(csvFilename)); - writer.write({ - header1: 'URLs' - }); - writer.end(); - } else { - csvOutput = data; - } + debuglog("opening csv",2); + fs.readFile(csvFileName, "utf-8", (err, data) => { + if (err) { + debuglog("Could not get CSV Data!", 2); + debuglog(err, 2); + csv.initCSV(csvFileName); + } else { + debuglog(`CSV OUTPUT IS:\n${data}`, 2); + csvOutput = data; + } }); - - for (var i = 1; i < (maxTweetScan+1); i++) { - //RUN THIS CODE FOR EVERY TWEET SCANNED - debuglog("Processing tweet " + i + " of " + maxTweetScan + "...",1); - //PER-TWEET VARIABLES - var thisTweetXPath = tweetXPath + `[1]`; - var keepTweet = false; - var quotedContent = ""; - + debuglog("opened csv",2); + var processedTweets = [];//DEFINE ARRAY THAT WILL BE POPULATED WITH TWEETS PROCESSED DURING THIS SESSION + for (var t = 1; t < (parseInt(args.tweetCount) + 1); t++) {//LOOP THE NUMBER OF TIMES SPECIFIED IN ARGS + + debuglog(format.notice(`Processing tweet #${t} of ${args.tweetCount}...`),1); + var homeTweet = new Tweets("home",t); //RESET HOME TWEET FOR PROCESSING + var threadTweet = new Tweets("thread",1); //RESET HOME TWEET FOR PROCESSING + var threadTweetArray = []; //ARRAY OF THREAD TWEET OBJECTS + + await elements.waitFor(driver,homeTweet.x.containsDivs,args.timeOut); //WAIT FOR TIMELINE TO POPULATE ITSELF WITH TWEETS //REMOVE NON-PRIMARY TWEETS debuglog("Filtering out disabled tweets...",2) - while (!keepTweet) { - await driver.wait(until.elementLocated(By.xpath(thisTweetXPath)), 30000); - - if (!modulesToEnable[0]) { - //CHECK FOR QUOTE TWEETS - isQT = await driver.findElement(webdriver.By.xpath(thisTweetXPath + quoteTweetContentXPath)).then(function() { - return true; // It existed - }, function(err) { - if (err instanceof webdriver.error.NoSuchElementError) { - return false; // It was not found - } else { - //webdriver.promise.rejected(err); - } - }); - } - if (!modulesToEnable[1]) { - //CHECK FOR THREAD TWEET - isThread = await driver.findElement(webdriver.By.xpath(thisTweetXPath + threadIndicatorXPath)).then(function() { - return true; // It existed - }, function(err) { - if (err instanceof webdriver.error.NoSuchElementError) { - return false; // It was not found - } else { - //webdriver.promise.rejected(err); - } - }); - } - - //CHECK FOR RETWEETS - isRT = await driver.findElement(webdriver.By.xpath(thisTweetXPath + retweetIndicatorXPath)).then(function() { - return true; // It existed - }, function(err) { - if (err instanceof webdriver.error.NoSuchElementError) { - return false; // It was not found - } else { - //webdriver.promise.rejected(err); - } - }); + while (!homeTweet.keep) { + debuglog(`xpath: ${homeTweet.x.path}`,2) //PRINT XPATH OF CURRENT TWEET + await elements.waitFor(driver, homeTweet.x.path,args.timeOut); //WAIT UNTIL CURRENT TWEET IS LOADED - //IF TWEET IS DISABLED, MARK FOR REMOVAL - if (isRT || ((!modulesToEnable[0] && isQT) || (!modulesToEnable[1] && isThread)) ) { - //TWEET IS QT, RT, OR THREAD - keepTweet = false; - driver.executeScript('var element = document.evaluate(`' + thisTweetXPath + '`,document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null ).singleNodeValue.remove();'); + await homeTweet.identifyElements(driver); //IDENTIFY WHAT ELEMENTS EXIST WITHIN TWEET + + if ((((homeTweet.isRT || homeTweet.isAR) || homeTweet.isPin) || (!args.enableQuotes && homeTweet.isQT)) || (!args.enableThreads && homeTweet.isThread) ) {//IF TWEET IS DISABLED, MARK FOR REMOVAL + debuglog("removing tweet",2); + homeTweet.keep = false; //INDICATE THAT WE ARE NOT READY TO EXIT, CURRENT TWEET IS NOT ELIGIBLE FOR REPOST + await driver.executeScript(`var element = document.evaluate(\`${homeTweet.x.path}\`,document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null ).singleNodeValue.remove();`); //REMOVE TWEET FROM DOM TO PROCESS NEXT + homeTweet = new Tweets("home",1); //RESET HOME TWEET OBJECT TO MAKE NEW TWEET READY FOR CHECKING } else { - keepTweet = true; + debuglog("keeping tweet! It is eligible for processing"); + homeTweet.keep = true; //INDICATE THAT WE ARE READY TO EXIT, CURRENT TWEET IS ELIGIBLE FOR REPOST } } - //GET TWEET URL - await driver.wait(until.elementLocated(By.xpath(thisTweetXPath + tweetURLXPath)), 1000); - mobileTweetURL = await driver.findElement(By.xpath(thisTweetXPath + tweetURLXPath)).getAttribute('href'); - tweetURL = await mobileTweetURL.replace('mobile.',''); - debuglog(tweetURL,2); + processedTweets.forEach(function(u, uindex) { //CHECK IF TWEET HAS BEEN PROCESSED IN THIS SESSION + debuglog(`${u.url} exists at index ${uindex} ${(u.url == homeTweet.url)}`); + if (u.url == homeTweet.url) {homeTweet.processed = true;} + }) + debuglog(`tweet has been proccessed: ${homeTweet.processed}`); - if (!csvOutput.includes(tweetURL)) { + if (!homeTweet.processed && !csvOutput.includes(homeTweet.url)) { //IF CSV DOES NOT CONTAIN THE TWEET URL + debuglog(`Tweet #${homeTweet.no} has not been processed.`, 1); - //SETUP TEXT FOR TWEET STATUS - var tweetHasText = false; - await driver.wait(until.elementLocated(By.xpath(timeLineXPath + tweetTextXPath)), 1000); - tweetText = "" + if (homeTweet.isThread){ //IF TWEET IS A THREAD, RUN TWEET THREAD STUFF + var threadTweet = new Tweets("thread",1); //CREATE NEW THREAD TWEET OBJECT + var threadTweetArray = []; //ARRAY OF THREAD TWEET OBJECTS + debuglog(`THREAD TIMELINE: ${threadTweet.x.timeLine}`,2); //XPATH OF THREAD TIMELINE - //IS TWEET PART OF MULTISCRAPER, IF SO ADD HEADER - if (printHeader) { - tweeterHandleText = await driver.findElement(By.xpath(thisTweetXPath + tweeterHandle)).getText(); - tweeterNameText = await driver.findElement(By.xpath(thisTweetXPath + tweeterName)).getText(); - tweetText = (tweeterNameText + " (" + tweeterHandleText + ")\r\n" + tweetURL + "\r\n\r\n") - } - - //DOES TWEET HAVE TEXT - tweetHasText = await driver.findElement(webdriver.By.xpath(thisTweetXPath + tweetTextXPath)).then(function() { - return true; // It existed - }, function(err) { - if (err instanceof webdriver.error.NoSuchElementError) { - return false; // It was not found - } else { - webdriver.promise.rejected(err); - } - }); - //IF SO, ADD BODY TEXT TO TWEET TEXT - if (tweetHasText){ - tweetText = tweetText + await driver.findElement(By.xpath(thisTweetXPath + tweetTextXPath)).getText(); - } - - //DOES TWEET HAVE A URL CARD - tweetHasURL = await driver.findElement(webdriver.By.xpath(thisTweetXPath + urlCardXPath)).then(function() { - return true; // It existed - }, function(err) { - if (err instanceof webdriver.error.NoSuchElementError) { - return false; // It was not found - } else { - webdriver.promise.rejected(err); - } - }); - //IF SO, ADD URL TO TWEET TEXT - if (tweetHasURL){ - tweetCardURL = await driver.findElement(By.xpath(thisTweetXPath + urlCardXPath)).getAttribute('href'); - await expandUrl(tweetCardURL) - .then(function (longUrl) { - debuglog("Long URL:" + longUrl,2); - tweetText = tweetText + "\r\n\r\n" + longUrl; - }); - } - - //IS TWEET A QUOTE TWEET - isQT = await driver.findElement(webdriver.By.xpath(thisTweetXPath + quoteTweetContentXPath)).then(function() { - return true; // It existed - }, function(err) { - if (err instanceof webdriver.error.NoSuchElementError) { - return false; // It was not found - } else { - //webdriver.promise.rejected(err); - } - }); - //IF SO, ADD QUOTE TWEET LINK TO TWEET TEXT - if (isQT){ - await driver.sleep(1 * 1000) - quotedContent = await driver.findElement(webdriver.By.xpath(thisTweetXPath + quoteTweetContentXPath)); - await driver.findElement(webdriver.By.xpath(thisTweetXPath + quoteTweetContentXPath)).sendKeys(webdriver.Key.CONTROL, webdriver.Key.ENTER); - var parent = await driver.getWindowHandle(); - var windows = await driver.getAllWindowHandles(); - await driver.switchTo().window(windows[1]).then(() => { - driver.getCurrentUrl().then(url => { - debuglog('current url: "' + url + '"',2); - tweetText = tweetText + "\r\n\r\n" + "Quote tweeting: " + url; - }); - driver.switchTo().window(parent); - }); - await driver.switchTo().window(windows[1]); - await driver.close(); - await driver.switchTo().window(parent); - } - - debuglog(tweetText,1) - - //CODE TO RUN IF TWEET IS NOT IN CSV - debuglog("Tweet #" + i + " has not been processed.", 1); - - //HANDLE SAVING SINGLE IMAGES - var singleImageExisted = await driver.findElement(webdriver.By.xpath(thisTweetXPath + singleImageXPath)).then(function() { - return true; // It existed - }, function(err) { - if (err instanceof webdriver.error.NoSuchElementError) { - return false; // It was not found - } else { - webdriver.promise.rejected(err); - } - }); - if (singleImageExisted) { - debuglog("Tweet #" + i + " contains a single image.", 2) - imageCount = 1; - imageURL = await driver.findElement(webdriver.By.xpath(thisTweetXPath + singleImageXPath)).getAttribute("src"); - await downloadImage(imageURL, imgSavePath + i + "." + 1 +'.jpg') - .then(/*console.log*/) - .catch(console.error); - debuglog("Downloaded " + imageCount + "image from tweet #" + i + ".", 2) - } - - //HANDLE SAVING MULTTIPLE IMAGES - var multiImageExisted = await driver.findElement(webdriver.By.xpath(thisTweetXPath + multiImageXPath)).then(function() { - return true; // It existed - }, function(err) { - if (err instanceof webdriver.error.NoSuchElementError) { - return false; // It was not found - } else { - webdriver.promise.rejected(err); - } - }); - if (multiImageExisted) { - debuglog("Tweet #" + i + " contains multiple images.", 2) - imageCount = 0; - for (var x = 1; x < 3; x++) { - for (var y = 1; y < 3; y++) { - thisIteratExists = await driver.findElement(webdriver.By.xpath(thisTweetXPath + multiImage1XPath + x + multiImage2XPath + y + multiImage3XPath)).then(function() { - return true; // It existed - }, function(err) { - if (err instanceof webdriver.error.NoSuchElementError) { - return false; // It was not found - } else { - debuglog('I hope this doesnt break'); - //webdriver.promise.rejected(err); - } - }); - if (thisIteratExists) { - debuglog(x + "," + y + " Exists!") - iteratImgURL = await driver.findElement(webdriver.By.xpath(thisTweetXPath + multiImage1XPath + x + multiImage2XPath + y + multiImage3XPath)).getAttribute("src"); - imageCount++; - await downloadImage(iteratImgURL, imgSavePath + i + "." + imageCount +'.jpg') - .then(/*console.log*/) - .catch(console.error); - } - } - } - debuglog("Downloaded " + imageCount + "images from tweet #" + i + ".", 2) - } - - //HANDLE POSTING TWEETS TO MASTODON - if (!disablePosts){ - if (singleImageExisted || multiImageExisted) {var imageExisted = true} else {var imageExisted = false} - if (imageExisted) { + driver.executeScript(`window.open("${homeTweet.url}");`); //OPEN THREAD IN NEW TAB + var parent = await driver.getWindowHandle(); + var windows = await driver.getAllWindowHandles(); + await driver.switchTo().window(windows[1]); //SWITCH TO NEW TAB WITH THREAD - //MAKE MASTODON POST WITH IMAGES - debuglog("Uploading images to Mastodon...",1); - var imageArray = []; - for (var f = 1; f < (imageCount+1); f++) { - await M.post('media', { file: fs.createReadStream(imgSavePath + i + '.' + f + '.jpg') }).then(resp => { - imageArray.push(resp.data.id); - }, function(err) { - if (err) { - debuglog(err,1); - } - }) + await elements.waitFor(driver,threadTweet.x.containsDivs,args.timeOut); + await driver.executeScript("document.body.style.zoom='20%'"); + await driver.executeScript("window.scrollTo(0, 0)"); + //await driver.executeScript("window.scrollTo(0, -document.body.scrollHeight)"); + await driver.sleep(1*5000) //WAIT 5 SECONDS TO GIVE BROWSER TIME TO SET ITSELF UP + + await elements.waitFor(driver,threadTweet.x.containsDivs,args.timeOut); //WAIT UNTIL THREAD IS POPULATED WITH DIVS + + for (var r = 1; !threadTweet.entryIsOpen; r++) {//LOOP UNTIL INDICATED THAT WE'VE REACHED THE ENTRY TWEET + threadTweet = new Tweets("thread", r); //RESETS ALL THREAD TWEET VARIABLES TO START FRESH + + debuglog(threadTweet.x.path,2); //PRINTS XPATH TO CURRENT ITERATE DIV + threadTweet.entryIsOpen = await elements.doesExist(driver,threadTweet.x.entryTweet) // CHECKS IF THE CURRENT ITERATE DIV IS THE ONE USED TO OPEN THE THREAD + if (!threadTweet.entryIsOpen){ //CURRENT ITERATE DIV DOES NOT CONTAIN THE TWEET USED TO OPEN THE THREAD + + await threadTweet.identifyElements(driver); //IDENTIFIES WHAT THE TWEET CONTAINS + + debuglog(`current tweet #${threadTweet.no} is not entry to thread`,2); + + debuglog(csvOutput); + + if (processedTweets.some(e => e.url == processedTweets.url)) { + debuglog("TWEET EXISTS IN PROCESSED ARRAY!!",2); + } + + if (!csvOutput.includes(threadTweet.url)) {//CODE TO RUN IF TWEET IS NOT IN CSV + debuglog(`Thread tweet #${threadTweet.no} has not been processed.`, 1); + + await threadTweet.getElementProperties(driver); //COMPILE HEADER, BODY, AND FOOTER + + threadTweet.compileText();//COMPILE TEXT FOR CROSS-POST + + threadTweet.printPreview()//PRINT TWEET PREVIEW + + await threadTweet.downloadImages(driver,imgSavePath); + + await threadTweet.uploadImages(imgSavePath); + } + threadTweetArray.push(threadTweet); + processedTweets.push(threadTweet); + } + } - imageArray.length = 4 - debuglog("Publishing post to Mastodon...",1); - await M.post('statuses', { status: tweetText, media_ids: imageArray }, (err, data) => { - if (err) { - debuglog("Post to Mastodon failed with error: " + err, 1); - } else { - //ADD TWEET TO CSV TO PREVENT FUTURE INDEXING - debuglog("Posting tweet #" + i + " to Mastodon succeeded!", 1); - writer = csvWriter({sendHeaders: false}); - writer.pipe(fs.createWriteStream(csvFilename, {flags: 'a'})); - writer.write({ - header1: tweetURL - }); - writer.end(); - } + + var csvArray = csvOutput.split(/[\r\n]+/); + for (var a = 0;a < threadTweetArray.length; a++) {//SET TWEET OBJECT ID TO SAVED ID IF IT EXISTS IN CSV + debuglog(`CSV ARRAY: ${csvArray}`,2); + csvArray.forEach(function(row, csvIndex) { + debuglog(`csv row: ${row}`); + rowArr = row.split(","); + debuglog(`searching for '${threadTweetArray[a].url}' in '${row}'`,2) + if (row.includes(threadTweetArray[a].url)){ + debuglog(`URL Exists at index ${csvIndex} of csv`,2); + threadTweetArray[a].id = rowArr[1]; + threadTweetArray[a].posted = true; + } + }) + } + + threadTweetArray.forEach(twt =>{//LIST IDs THAT WERE DERIVED FROM CSV + debuglog(`${twt.no} id: ${twt.id}`,2) }) - } else { - //MAKE MASTODON POST WITHOUT IMAGES - debuglog("Publishing post to Mastodon...",1); - - await M.post('statuses', { status: tweetText}, (err, data) => { - if (err) { - debuglog("Post to Mastodon failed with error: " + err, 1); - } else { - //ADD TWEET TO CSV TO PREVENT FUTURE PROCESSING - debuglog("Posting tweet #" + i + " to Mastodon succeeded!", 1); - writer = csvWriter({sendHeaders: false}); - writer.pipe(fs.createWriteStream(csvFilename, {flags: 'a'})); - writer.write({ - header1: tweetURL - }); - writer.end(); + + for (var a = 0;a < threadTweetArray.length; a++) {//POST TO MASTODON REFERENCING ID OF PRIOR OBJECT AS PROMPT + if (a != 0) {threadTweetArray[a].prompt = threadTweetArray[a - 1].id} + if (!threadTweetArray[a].posted){ + debuglog(`posting tweet: ${threadTweetArray[a].no} to mastodon in reply to id: ${threadTweetArray[a].prompt}`, 2); + threadTweetArray[a].id = await mastodon.postStatus(threadTweetArray[a],csvFileName,csvOutput) + debuglog(`POSTED TO MASTODON AND GOT BACK AN ID OF: ${threadTweetArray[a].id}`,2) } - }) + } + + await driver.close(); + await driver.switchTo().window(parent); } - } - } else { - //CODE TO RUN IF TWEET IS IN CSV - debuglog("Tweet #" + i + " has already been processed.",1); - } + await homeTweet.getElementProperties(driver); - if (i < maxTweetScan) {driver.executeScript('var element = document.evaluate(`' + thisTweetXPath + '`,document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null ).singleNodeValue.remove();');} + homeTweet.compileText();//COMPILE TEXT FOR CROSS-POST + + homeTweet.printPreview();//PRINT TWEET PREVIEW + + await homeTweet.downloadImages(driver,imgSavePath);//DOWNLOAD IMAGES FROM TWITTER + + await homeTweet.uploadImages(imgSavePath);//UPLOAD IMAGES TO MASTODON + + if (threadTweetArray.length>0) {homeTweet.prompt = threadTweetArray[threadTweetArray.length-1].id;} + debuglog(`Publishing post ${homeTweet.no} to Mastodon...`,2); + homeTweet.id = await mastodon.postStatus(homeTweet,csvFileName,csvOutput); + + processedTweets.push(homeTweet); + } else { //HOME TWEET EXISTS IN CSV + debuglog(`Tweet #${homeTweet.no} has already been processed.`,1); //HOME TWEET EXISTS IN CSV + } + + if (homeTweet.no < args.tweetCount) {driver.executeScript(`var element = document.evaluate(\`${homeTweet.x.path}\`,document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null ).singleNodeValue.remove();`);}//REMOVE TWEET FROM DOM TO PROCESS NEXT TWEET } - //REMOVE SAVED IMAGE FILES - debuglog("Cleaning up...",1); - fs.rm(imgSavePath, { recursive: true, force: true }, (error) => { - //you can handle the error here - }); - debuglog("Finished scraping " + userName + "'s tweets",1) - //EXIT WEBDRIVER - driver.quit(); + debuglog("Cleaning up...",1); //REMOVE SAVED IMAGES + fs.rm(imgSavePath, { recursive: true, force: true }, (error) => { + debuglog(error,2); + }); + debuglog(format.bold(`Finished scraping @${args.userName}'s tweets`),1) //CLOSE WEBDRIVER + setTimeout(() => { + driver.quit(); + }, 100); }()); \ No newline at end of file diff --git a/URLList.csv b/URLList.csv deleted file mode 100644 index 0539374..0000000 --- a/URLList.csv +++ /dev/null @@ -1 +0,0 @@ -URLs diff --git a/multi.js b/multi.js index 4e5903a..28d526b 100644 --- a/multi.js +++ b/multi.js @@ -1,29 +1,39 @@ +//REQUIREMENTS const childProcess = require('child_process') const path = require('path'); +const support = require('./ref/functions/support.js'); + +//FUNCTIONS + async function fork(scriptPath, args = []) { return new Promise((resolve, reject) => { let process = childProcess.fork(scriptPath, args, { cwd: path.dirname(scriptPath) }); - process.on('exit', code => resolve(code)); process.on('error', err => reject(err)); }); } + +//RUNTIME + (async function(){ - const args = process.argv; + const args = [...process.argv]; const defArgs = ["node","path","name","tweetCount","0","write","fromLoop"] - for (var i = 0; i < 2; i++) {args.shift();} - const config = require('fs').readFileSync("./usernameslist.txt").toString().split(/[\r\n]+/); + for (var i = 0; i < 2; i++) {args.shift();} //REMOVES `node ./TwitToMaster` from args + const config = require('fs').readFileSync("./usernameslist.txt").toString().split(/[\r\n]+/);//GET USERNAME LIST AS ARRAY + + const customIndex = args.indexOf("-u"); + console.log(args); + console.log(customIndex); + args.splice(customIndex,2); + console.log(args) + for (let name of config) { - var pArgs = [...args]; - pArgs.splice(0, 0, name); - for (var i = 3; i < 7; i++) { - if (typeof pArgs[i-2] == 'undefined') { - pArgs.push(defArgs[i]); - } - } - console.log("pArgs: " + pArgs); - await fork('./TwitToMast.js', pArgs); + var fArgs = [...args]; + fArgs.push("-u"); + fArgs.push(name); + console.log("args: " + fArgs); + await fork('./TwitToMast.js', fArgs); } }()); diff --git a/null b/null deleted file mode 100644 index caa185b..0000000 Binary files a/null and /dev/null differ diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 3a0cae8..0000000 --- a/package-lock.json +++ /dev/null @@ -1,3140 +0,0 @@ -{ - "name": "TwitToMast", - "version": "1.0.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "TwitToMast", - "version": "1.0.0", - "license": "ISC", - "dependencies": { - "csv-write-stream": "^2.0.0", - "filesystem": "^1.0.1", - "https": "^1.0.0", - "image-convert": "^0.1.33", - "jimp": "^0.22.4", - "mastodon": "^1.2.2", - "selenium-webdriver": "^4.8.0", - "until": "^0.1.1" - } - }, - "node_modules/@jimp/bmp": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/bmp/-/bmp-0.22.4.tgz", - "integrity": "sha512-ZDwQ/tLihpZuTCFGGa0zcyZIWHfhvHkrdbsoHUY0GG/JpH/y2xzlm2I48/TicCpoujN8oGKLHIJje0HmVX3xaA==", - "dependencies": { - "@jimp/utils": "^0.22.4", - "bmp-js": "^0.1.0" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/core": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/core/-/core-0.22.4.tgz", - "integrity": "sha512-K7guEYpXV44SCLR35QdPyKqF+mFZaEUAqiSL8qQ/F4N4Ws9JkPzFI/qYTjOkDoKxSWkXlKnlsk1sfMzy0yqA5g==", - "dependencies": { - "@jimp/utils": "^0.22.4", - "any-base": "^1.1.0", - "buffer": "^5.2.0", - "exif-parser": "^0.1.12", - "file-type": "^16.5.4", - "isomorphic-fetch": "^3.0.0", - "mkdirp": "^2.1.3", - "pixelmatch": "^4.0.2", - "tinycolor2": "^1.6.0" - } - }, - "node_modules/@jimp/custom": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/custom/-/custom-0.22.4.tgz", - "integrity": "sha512-k9m/RfxjPjklUsgZ2nszlyNkodUG/4xlxlif70UELhxW8bdqZqqlQGzwA9p+PUiSnlSJYZjL6q+P8cd7yj1ggA==", - "dependencies": { - "@jimp/core": "^0.22.4" - } - }, - "node_modules/@jimp/gif": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/gif/-/gif-0.22.4.tgz", - "integrity": "sha512-KmN7GoaQTzLAX4JXLBRkIiZAXthgQdKe+Y7BOw4n6CMe6LAS/XCQqrYCG3Av/GqIO7UAKems6D7kIGAUuhpNlQ==", - "dependencies": { - "@jimp/utils": "^0.22.4", - "gifwrap": "^0.9.2", - "omggif": "^1.0.9" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/jpeg": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/jpeg/-/jpeg-0.22.4.tgz", - "integrity": "sha512-mMJNhEtJpne65mxpIXEvT0VIzmsKiZWmaFT/c2eQ2tBLEtWAFpkvoP+F7jEaU+F3Ur4fXKFkJ/xOSXtRr/gGNw==", - "dependencies": { - "@jimp/utils": "^0.22.4", - "jpeg-js": "^0.4.4" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-blit": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/plugin-blit/-/plugin-blit-0.22.4.tgz", - "integrity": "sha512-QQHe+rFarsxJQxWKlyHEMfLyXmUG9AiQky+8WfwjZVBYilIFyiBywOc3sThonOsru+7LOSUDmbN6mvbFk4R+gw==", - "dependencies": { - "@jimp/utils": "^0.22.4" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-blur": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/plugin-blur/-/plugin-blur-0.22.4.tgz", - "integrity": "sha512-p57Ac5LEQckIogiwf7qyOojGvLOD08eMaQd5ylOhet/fbdwAzD/8flWFhSIKsdAVzvnfGcszuLtrsV07jDutTw==", - "dependencies": { - "@jimp/utils": "^0.22.4" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-circle": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/plugin-circle/-/plugin-circle-0.22.4.tgz", - "integrity": "sha512-T+TpG+s+wM9kKHlpIEfCAfOM+QrYVqcMoWjkULddc0KtaDEhqgGYFhN+/SlzJfDbZKw0xUgIuAw89sXuzMIUjw==", - "dependencies": { - "@jimp/utils": "^0.22.4" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-color": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/plugin-color/-/plugin-color-0.22.4.tgz", - "integrity": "sha512-TZqcqepoCcIlF7VodPPfS3WET+LL5Y/XnXOBk4tWnG5i+lhNrs7/U0HOJY6Iw9o4g267DddnlfKWmunvzBcvOQ==", - "dependencies": { - "@jimp/utils": "^0.22.4", - "tinycolor2": "^1.6.0" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-contain": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/plugin-contain/-/plugin-contain-0.22.4.tgz", - "integrity": "sha512-Hl+TO4v+EpRfEl3R6k/bEgOGOpm6JqNfEIyCFWLi6yqJQjMGzBQ0vt+VHe2u3WIFaFrDWsGxeuFZBDzgtjTwxw==", - "dependencies": { - "@jimp/utils": "^0.22.4" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5", - "@jimp/plugin-blit": ">=0.3.5", - "@jimp/plugin-resize": ">=0.3.5", - "@jimp/plugin-scale": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-cover": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/plugin-cover/-/plugin-cover-0.22.4.tgz", - "integrity": "sha512-KMTQjN/B7r/RNzoLFwnhqhLrgT0kMqTkBMEZQSopj5vPLPNjIX0ElEYC8AIVFKeZAV+1mYkyss+IDdxq4fyRng==", - "dependencies": { - "@jimp/utils": "^0.22.4" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5", - "@jimp/plugin-crop": ">=0.3.5", - "@jimp/plugin-resize": ">=0.3.5", - "@jimp/plugin-scale": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-crop": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/plugin-crop/-/plugin-crop-0.22.4.tgz", - "integrity": "sha512-8krDt7xzBa1fbtlYCzEMZIgNjTkhgywho0FJpgIMkIUMjaZITS1Ea/Veb3UrWt8EsgQS6hxjGVE/Q1FvP5iPLA==", - "dependencies": { - "@jimp/utils": "^0.22.4" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-displace": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/plugin-displace/-/plugin-displace-0.22.4.tgz", - "integrity": "sha512-3gBfwYVFrOjp8SUpb7H0UMgqvsG/sxY1PVBIfRW9MUCosiH1eE/Mo5cbxhQ6/w5f3sh23lBmG8W0WuSrnXLorg==", - "dependencies": { - "@jimp/utils": "^0.22.4" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-dither": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/plugin-dither/-/plugin-dither-0.22.4.tgz", - "integrity": "sha512-oOhdZBDJpSGIoTUhPOIvLIVUwILRWgrWdA4Vbzcyz2RHvaPHS8gdBH0EdIPbJ5agNyFnY8sJWFM7YKx/rLNKsw==", - "dependencies": { - "@jimp/utils": "^0.22.4" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-fisheye": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/plugin-fisheye/-/plugin-fisheye-0.22.4.tgz", - "integrity": "sha512-2myNZyDrwUOV8MKd4NeULnEOojYF7XRbnRHiUPsNptpmK6g/gI4xt+5k7BallAYZD8ZLfZVjstUogsObprHd/Q==", - "dependencies": { - "@jimp/utils": "^0.22.4" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-flip": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/plugin-flip/-/plugin-flip-0.22.4.tgz", - "integrity": "sha512-9FZ0k5N5leLDefeDjizXXTl17dzo23PYtCD/T4xeSVr96d1pQDwbeIk7pEhhHr1rl98tJe0U/OV2dFXFYauKPw==", - "dependencies": { - "@jimp/utils": "^0.22.4" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5", - "@jimp/plugin-rotate": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-gaussian": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/plugin-gaussian/-/plugin-gaussian-0.22.4.tgz", - "integrity": "sha512-irOSwLdZ9kTq5Wd5dpkMgIMJVwemYcqgnzd04+P6TJGYmem2HR6JUCDpjbET3Fpbo/snFLm4mZ+2A+SmeCGjKA==", - "dependencies": { - "@jimp/utils": "^0.22.4" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-invert": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/plugin-invert/-/plugin-invert-0.22.4.tgz", - "integrity": "sha512-/WtZeLrF+H+mzbjqudeGvvSxudlHy1kyiP1gVWDxhYNQOuZJI57Vn20kSTYvHBNjvy31LV4/uestyX8j8tE2Qg==", - "dependencies": { - "@jimp/utils": "^0.22.4" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-mask": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/plugin-mask/-/plugin-mask-0.22.4.tgz", - "integrity": "sha512-U0SrOwBNKkMYTNPTz5CXeJdZ4c5easFlq2B9Txy0kPsav2OraTv8cZjpMxrWUejo/AQGVUDbaGtXMm9pE13/6w==", - "dependencies": { - "@jimp/utils": "^0.22.4" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-normalize": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/plugin-normalize/-/plugin-normalize-0.22.4.tgz", - "integrity": "sha512-XJiPBJGCHWmIzUdmL4mWP1Ev5LMp77oMmPXdgQGDty1cxfyo3CbkTjZSsnwF/XLlrQ1yfLW+8JB+ihGKcVEOxA==", - "dependencies": { - "@jimp/utils": "^0.22.4" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-print": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/plugin-print/-/plugin-print-0.22.4.tgz", - "integrity": "sha512-mayiPhg6c7KYjvq3fYOW9ohhXD1eWdEiseV9dAWqTOEbDbohT8S6eTGhVIiVa2sVySLcpNEKZSk07c5EhJAMcw==", - "dependencies": { - "@jimp/utils": "^0.22.4", - "load-bmfont": "^1.4.1" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5", - "@jimp/plugin-blit": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-resize": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/plugin-resize/-/plugin-resize-0.22.4.tgz", - "integrity": "sha512-2wMdpPNGf6Zo2lfJg1QHHQ+ds5baQH75IcFpdjw717dcEISpn1jPG//iClXOGh16OJsRQlwHESaZTgEo/5Dw/g==", - "dependencies": { - "@jimp/utils": "^0.22.4" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-rotate": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/plugin-rotate/-/plugin-rotate-0.22.4.tgz", - "integrity": "sha512-g08LBsPENbeA6NVoeq0iuDgAL89+N+aZrvYVKYkiJZIM7vUvueJyAIq4+bjDl4r54OR8XBFX0GsrKsqrULh1eA==", - "dependencies": { - "@jimp/utils": "^0.22.4" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5", - "@jimp/plugin-blit": ">=0.3.5", - "@jimp/plugin-crop": ">=0.3.5", - "@jimp/plugin-resize": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-scale": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/plugin-scale/-/plugin-scale-0.22.4.tgz", - "integrity": "sha512-cJiLQtTcNk6/+j05R23TFGXy+smDV0BdlmzJVDb+7Ye9qcmWpkdjVSioQQqZr0QScIYKhhRCY/lFTepBx67yzw==", - "dependencies": { - "@jimp/utils": "^0.22.4" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5", - "@jimp/plugin-resize": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-shadow": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/plugin-shadow/-/plugin-shadow-0.22.4.tgz", - "integrity": "sha512-a5hdpzGBzBo91DNiKaGvs8iJbs2bYQmDRm/BrCh4NET+h5l5AwXNu/Ak0bWRhN16YQ55XYNGHer2jOwBPrf2WQ==", - "dependencies": { - "@jimp/utils": "^0.22.4" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5", - "@jimp/plugin-blur": ">=0.3.5", - "@jimp/plugin-resize": ">=0.3.5" - } - }, - "node_modules/@jimp/plugin-threshold": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/plugin-threshold/-/plugin-threshold-0.22.4.tgz", - "integrity": "sha512-jTT/+p2zb2NESzd7O0bVRowiQszoaHeBf2OgP7lFde10fHd+fn78m5brUmSmlGAdlMRwm8S8ZcxTj5ZjdQns5w==", - "dependencies": { - "@jimp/utils": "^0.22.4" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5", - "@jimp/plugin-color": ">=0.8.0", - "@jimp/plugin-resize": ">=0.8.0" - } - }, - "node_modules/@jimp/plugins": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/plugins/-/plugins-0.22.4.tgz", - "integrity": "sha512-yAxcA4UR3Bs7j73I7wt4ty52vm5MzPmr+8DYk8jrS/ng2Z2iuXzbcTe4mf9eEqXYVah3rTIggo4dPjW75DRZtA==", - "dependencies": { - "@jimp/plugin-blit": "^0.22.4", - "@jimp/plugin-blur": "^0.22.4", - "@jimp/plugin-circle": "^0.22.4", - "@jimp/plugin-color": "^0.22.4", - "@jimp/plugin-contain": "^0.22.4", - "@jimp/plugin-cover": "^0.22.4", - "@jimp/plugin-crop": "^0.22.4", - "@jimp/plugin-displace": "^0.22.4", - "@jimp/plugin-dither": "^0.22.4", - "@jimp/plugin-fisheye": "^0.22.4", - "@jimp/plugin-flip": "^0.22.4", - "@jimp/plugin-gaussian": "^0.22.4", - "@jimp/plugin-invert": "^0.22.4", - "@jimp/plugin-mask": "^0.22.4", - "@jimp/plugin-normalize": "^0.22.4", - "@jimp/plugin-print": "^0.22.4", - "@jimp/plugin-resize": "^0.22.4", - "@jimp/plugin-rotate": "^0.22.4", - "@jimp/plugin-scale": "^0.22.4", - "@jimp/plugin-shadow": "^0.22.4", - "@jimp/plugin-threshold": "^0.22.4", - "timm": "^1.6.1" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/png": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/png/-/png-0.22.4.tgz", - "integrity": "sha512-kDovx9dTyV/TSR40HQHdRyVgNNb7Cny4/0PPEa+xeR7snuDC3dV5hu9s/QJwY0RMGiAkiuKDpiaBuSZuz8dwRQ==", - "dependencies": { - "@jimp/utils": "^0.22.4", - "pngjs": "^6.0.0" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/tiff": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/tiff/-/tiff-0.22.4.tgz", - "integrity": "sha512-RStUATRnb+unYzzuGxU+SPZALqh5NxYdcS6UGTBvhCMlijopGiY/iL01wstIOst0ypKIjwbcSVj7mAHn6B7Qbw==", - "dependencies": { - "utif2": "^4.0.1" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/types": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/types/-/types-0.22.4.tgz", - "integrity": "sha512-v3hm8LGc3we6P6ML0ticiLX7wtdvywrKthYxqVrJVIu3vRL0Z4q3ngFjwzqDmaIF8wC0neq98s/t7ODWfeIiRQ==", - "dependencies": { - "@jimp/bmp": "^0.22.4", - "@jimp/gif": "^0.22.4", - "@jimp/jpeg": "^0.22.4", - "@jimp/png": "^0.22.4", - "@jimp/tiff": "^0.22.4", - "timm": "^1.6.1" - }, - "peerDependencies": { - "@jimp/custom": ">=0.3.5" - } - }, - "node_modules/@jimp/utils": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/utils/-/utils-0.22.4.tgz", - "integrity": "sha512-EPaBMNg4NvVXnMpSFJEsdCQqdSVU2ACreAL+Ipkq19C/FkDEj9Q10t6Mjx8zOe/AAjBQj1vTALS/DykcHOn4bQ==", - "dependencies": { - "regenerator-runtime": "^0.13.3" - } - }, - "node_modules/@tokenizer/token": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", - "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==" - }, - "node_modules/@types/node": { - "version": "16.9.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.9.1.tgz", - "integrity": "sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g==" - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/any-base": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/any-base/-/any-base-1.1.0.tgz", - "integrity": "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg==" - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", - "engines": { - "node": "*" - } - }, - "node_modules/aws4": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", - "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==" - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", - "dependencies": { - "tweetnacl": "^0.14.3" - } - }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" - }, - "node_modules/bmp-js": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/bmp-js/-/bmp-js-0.1.0.tgz", - "integrity": "sha512-vHdS19CnY3hwiNdkaqk93DvjVLfbEcI8mys4UjuWrlX1haDmroo8o4xCzh4wD6DGV6HxRCyauwhHRqMTfERtjw==" - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/buffer-equal": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz", - "integrity": "sha512-RgSV6InVQ9ODPdLWJ5UAqBqJBOg370Nz6ZQtRzpt6nUjc8v0St97uJ4PYC6NztqIScrAXafKM3mZPMygSe1ggA==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/bufferjs": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/bufferjs/-/bufferjs-3.0.1.tgz", - "integrity": "sha512-qrCIGPcd9ODawCNyqR2o55zgaC/r7XHZ7oUh2s99uk+NVBS3SjIHigxS1S2KXpt8wsoQxAN55iPi8GIH8TGMRg==", - "engines": { - "node": ">=0.2.0" - } - }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" - }, - "node_modules/configuration-processor": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/configuration-processor/-/configuration-processor-1.1.1.tgz", - "integrity": "sha512-nQYMSZfAxUyBWpCQQh2tk/kJ8Eg6c50klw2edEY1R6xoUJ0Vy6IYQclNYubXR6B0bThDahn/TNQfDD+vzxpTFQ==", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" - }, - "node_modules/csv-write-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/csv-write-stream/-/csv-write-stream-2.0.0.tgz", - "integrity": "sha512-QTraH6FOYfM5f+YGwx71hW1nR9ZjlWri67/D4CWtiBkdce0UAa91Vc0yyHg0CjC0NeEGnvO/tBSJkA1XF9D9GQ==", - "dependencies": { - "argparse": "^1.0.7", - "generate-object-property": "^1.0.0", - "ndjson": "^1.3.0" - }, - "bin": { - "csv-write": "cli.js" - } - }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", - "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/data-container": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/data-container/-/data-container-1.1.0.tgz", - "integrity": "sha512-WnmEstSHZMOYJsy+BHKVxtZ1M0scmN74pLfm8CwMtQr/AxJjUVXFt3M04T/B2iahhtMxGIiLKFi3nr/tdBmX5Q==", - "dependencies": { - "configuration-processor": "~1" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/dom-walk": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", - "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==" - }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "node_modules/event-dispatcher": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/event-dispatcher/-/event-dispatcher-2.4.0.tgz", - "integrity": "sha512-08u6SPGt/atk1W5o1Fa2IeH0cme8Fsp42qI1XsdKqZbl+rgcwY/AYtlqV04nylyhKAQ33Zql0rkYH0Z4/TVy8Q==", - "dependencies": { - "configuration-processor": "~1", - "data-container": "~1" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/exif-parser": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/exif-parser/-/exif-parser-0.1.12.tgz", - "integrity": "sha512-c2bQfLNbMzLPmzQuOr8fy0csy84WmwnER81W88DzTp9CYNPJ6yzOj2EZAh9pywYpqHnshVLHQJ8WzldAyfY+Iw==" - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", - "engines": [ - "node >=0.6.0" - ] - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "node_modules/File": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/File/-/File-0.10.2.tgz", - "integrity": "sha512-gomQVTq/10wIR399uhGTWtYcYneTXbfe3p2RO/NR0MPrLkIyOaE9DCEPXihAm+72epLtXaplitwfJ/wkmj88dg==", - "dependencies": { - "mime": ">= 0.0.0" - } - }, - "node_modules/file-api": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/file-api/-/file-api-0.10.4.tgz", - "integrity": "sha512-RVBXJGmsnQxokdpy264pmsdBjbUuxE6QT2xxhOrO2pzwTetbTNoWVFgkONFWmopm5mellsXrQIQhMY9fjufi9g==", - "dependencies": { - "bufferjs": "> 0.2.0", - "File": ">= 0.10.0", - "file-error": ">= 0.10.0", - "FileList": ">= 0.10.0", - "filereader": ">= 0.10.3", - "formdata": ">= 0.10.0", - "mime": ">= 1.2.11", - "remedial": ">= 1.0.7" - } - }, - "node_modules/file-error": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/file-error/-/file-error-0.10.2.tgz", - "integrity": "sha512-hJsQ7sEz6dM4vuRS7cipKiixV6EymEXHe+TCf2XVWsGTOehzrmcqqKMgeYTmV24XhjWSj+pQj1e5yjPJ7DtQvw==" - }, - "node_modules/file-type": { - "version": "16.5.4", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-16.5.4.tgz", - "integrity": "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==", - "dependencies": { - "readable-web-to-node-stream": "^3.0.0", - "strtok3": "^6.2.4", - "token-types": "^4.1.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/file-type?sponsor=1" - } - }, - "node_modules/FileList": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/FileList/-/FileList-0.10.2.tgz", - "integrity": "sha512-HCe9WvojxLiMEfa3l6jFkQJLzhzDXgQmfnKFoRvhEnsyVoIc5piAQNLyhOwsZsmf8IwDBfr5H71nB8Wi5w0XwA==" - }, - "node_modules/filereader": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/filereader/-/filereader-0.10.3.tgz", - "integrity": "sha512-7F8w6GSXuHLN80ukaVOcHgBaiTRHUZr8GeEhNdqfAECcnBoROg4i8hTl+KqtF4yUPffOJVHEFg4iDJb7xIYFng==" - }, - "node_modules/filesystem": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/filesystem/-/filesystem-1.0.1.tgz", - "integrity": "sha512-IlnKZqVmv+UNR8kVknA47RY1rSfdJxNNmiX0osELJxhNj010cjlXH7nj7Vq1bPBPTrHtVrRYIWymXjVPlxffdw==", - "dependencies": { - "configuration-processor": "~1", - "event-dispatcher": "~2" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/foreachasync": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/foreachasync/-/foreachasync-3.0.0.tgz", - "integrity": "sha512-J+ler7Ta54FwwNcx6wQRDhTIbNeyDcARMkOcguEqnEdtm0jKvN3Li3PDAb2Du3ubJYEWfYL83XMROXdsXAXycw==" - }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", - "engines": { - "node": "*" - } - }, - "node_modules/form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/formdata": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/formdata/-/formdata-0.10.4.tgz", - "integrity": "sha512-IsHa+GYLLXHx0RmpUmzQTdwxDjNinxD+1zKOYPLaRwiqTfex5caQhOzgPIjFgJkL0O884Ers76BSHzXJxHvPLw==", - "dependencies": { - "bufferjs": "^2.0.0", - "File": "^0.10.2", - "FileList": "^0.10.2", - "filereader": "^0.10.3", - "foreachasync": "^3.0.0", - "remedial": "^1.0.7" - } - }, - "node_modules/formdata/node_modules/bufferjs": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/bufferjs/-/bufferjs-2.0.0.tgz", - "integrity": "sha512-VnTCQKC+AJ61OFGe/hn3jRXoIt/B95NUcuxzAwiVT0PFB0KRZImkoDPYdFqDIs7xAs1eJ3yiKcHnuUiiYe7ucQ==", - "engines": { - "node": ">=0.2.0" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" - }, - "node_modules/generate-object-property": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", - "integrity": "sha512-TuOwZWgJ2VAMEGJvAyPWvpqxSANF0LDpmyHauMjFYzaACvn+QTT/AZomvPCzVBV7yDN3OmwHQ5OvHaeLKre3JQ==", - "dependencies": { - "is-property": "^1.0.0" - } - }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", - "dependencies": { - "assert-plus": "^1.0.0" - } - }, - "node_modules/gifwrap": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/gifwrap/-/gifwrap-0.9.4.tgz", - "integrity": "sha512-MDMwbhASQuVeD4JKd1fKgNgCRL3fGqMM4WaqpNhWO0JiMOAjbQdumbs4BbBZEy9/M00EHEjKN3HieVhCUlwjeQ==", - "dependencies": { - "image-q": "^4.0.0", - "omggif": "^1.0.10" - } - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/global": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", - "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", - "dependencies": { - "min-document": "^2.19.0", - "process": "^0.11.10" - } - }, - "node_modules/har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", - "engines": { - "node": ">=4" - } - }, - "node_modules/har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "deprecated": "this library is no longer supported", - "dependencies": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - }, - "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" - } - }, - "node_modules/https": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https/-/https-1.0.0.tgz", - "integrity": "sha512-4EC57ddXrkaF0x83Oj8sM6SLQHAWXw90Skqu2M4AEWENZ3F02dFJE/GARA8igO79tcgYqGrD7ae4f5L3um2lgg==" - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/image-convert": { - "version": "0.1.33", - "resolved": "https://registry.npmjs.org/image-convert/-/image-convert-0.1.33.tgz", - "integrity": "sha512-nUK+LJooUoDXYb6g7OtbRHbwNdyjfhrWMGTDblhJi3LJm0uybs9u9pP5LItOYqc3fFvFoGt08Onv27oes60w4w==", - "dependencies": { - "file-api": "^0.10.4", - "images": "^3.0.0", - "request": "^2.79.0" - } - }, - "node_modules/image-q": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/image-q/-/image-q-4.0.0.tgz", - "integrity": "sha512-PfJGVgIfKQJuq3s0tTDOKtztksibuUEbJQIYT3by6wctQo+Rdlh7ef4evJ5NCdxY4CfMbvFkocEwbl4BF8RlJw==", - "dependencies": { - "@types/node": "16.9.1" - } - }, - "node_modules/images": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/images/-/images-3.2.4.tgz", - "integrity": "sha512-Uq61/Q8XixCRyKvws7tPwboK0O70Dbr4kMQZHw2dqdEhnU6TpaGwyMg0vzQ4aaGtrO9N3etq46XwF7hxbqp8ug==", - "hasInstallScript": true - }, - "node_modules/immediate": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", - "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==" - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/is-function": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", - "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==" - }, - "node_modules/is-property": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", - "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==" - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" - }, - "node_modules/isomorphic-fetch": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", - "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==", - "dependencies": { - "node-fetch": "^2.6.1", - "whatwg-fetch": "^3.4.1" - } - }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" - }, - "node_modules/jimp": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/jimp/-/jimp-0.22.4.tgz", - "integrity": "sha512-reGESbcYp38VlGtdAe8qrmbjLLEYXMrQWc2XXb7+czulKfCCidUHEpNfrS3hx5XXMWrAmoYKkxPTqCvll6Q6ug==", - "dependencies": { - "@jimp/custom": "^0.22.4", - "@jimp/plugins": "^0.22.4", - "@jimp/types": "^0.22.4", - "regenerator-runtime": "^0.13.3" - } - }, - "node_modules/jpeg-js": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.4.tgz", - "integrity": "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==" - }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==" - }, - "node_modules/json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" - }, - "node_modules/jsprim": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", - "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/jszip": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", - "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", - "dependencies": { - "lie": "~3.3.0", - "pako": "~1.0.2", - "readable-stream": "~2.3.6", - "setimmediate": "^1.0.5" - } - }, - "node_modules/lie": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", - "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", - "dependencies": { - "immediate": "~3.0.5" - } - }, - "node_modules/load-bmfont": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/load-bmfont/-/load-bmfont-1.4.1.tgz", - "integrity": "sha512-8UyQoYmdRDy81Brz6aLAUhfZLwr5zV0L3taTQ4hju7m6biuwiWiJXjPhBJxbUQJA8PrkvJ/7Enqmwk2sM14soA==", - "dependencies": { - "buffer-equal": "0.0.1", - "mime": "^1.3.4", - "parse-bmfont-ascii": "^1.0.3", - "parse-bmfont-binary": "^1.0.5", - "parse-bmfont-xml": "^1.1.4", - "phin": "^2.9.1", - "xhr": "^2.0.1", - "xtend": "^4.0.0" - } - }, - "node_modules/mastodon": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/mastodon/-/mastodon-1.2.2.tgz", - "integrity": "sha512-ixcYkzn6SorH8U2jNc1vwiX89EiVMjzd2aDYFtr191YY9rdoVo+owI6cQo2EjUnzg2RN9WxyBJ9KDuw+R4lt+w==", - "dependencies": { - "bluebird": "^3.1.5", - "mime": "^1.3.4", - "request": "^2.68.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/min-document": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", - "integrity": "sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==", - "dependencies": { - "dom-walk": "^0.1.0" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", - "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/mkdirp": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-2.1.3.tgz", - "integrity": "sha512-sjAkg21peAG9HS+Dkx7hlG9Ztx7HLeKnvB3NQRcu/mltCVmvkF0pisbiTSfDVYTT86XEfZrTUosLdZLStquZUw==", - "bin": { - "mkdirp": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/ndjson": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/ndjson/-/ndjson-1.5.0.tgz", - "integrity": "sha512-hUPLuaziboGjNF7wHngkgVc0FOclR8dDk/HfEvTtDr/iUrqBWiRcRSTK3/nLOqKH33th714BrMmTPtObI9gZxQ==", - "dependencies": { - "json-stringify-safe": "^5.0.1", - "minimist": "^1.2.0", - "split2": "^2.1.0", - "through2": "^2.0.3" - }, - "bin": { - "ndjson": "cli.js" - } - }, - "node_modules/node-fetch": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz", - "integrity": "sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "engines": { - "node": "*" - } - }, - "node_modules/omggif": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/omggif/-/omggif-1.0.10.tgz", - "integrity": "sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==" - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" - }, - "node_modules/parse-bmfont-ascii": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/parse-bmfont-ascii/-/parse-bmfont-ascii-1.0.6.tgz", - "integrity": "sha512-U4RrVsUFCleIOBsIGYOMKjn9PavsGOXxbvYGtMOEfnId0SVNsgehXh1DxUdVPLoxd5mvcEtvmKs2Mmf0Mpa1ZA==" - }, - "node_modules/parse-bmfont-binary": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/parse-bmfont-binary/-/parse-bmfont-binary-1.0.6.tgz", - "integrity": "sha512-GxmsRea0wdGdYthjuUeWTMWPqm2+FAd4GI8vCvhgJsFnoGhTrLhXDDupwTo7rXVAgaLIGoVHDZS9p/5XbSqeWA==" - }, - "node_modules/parse-bmfont-xml": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/parse-bmfont-xml/-/parse-bmfont-xml-1.1.4.tgz", - "integrity": "sha512-bjnliEOmGv3y1aMEfREMBJ9tfL3WR0i0CKPj61DnSLaoxWR3nLrsQrEbCId/8rF4NyRF0cCqisSVXyQYWM+mCQ==", - "dependencies": { - "xml-parse-from-string": "^1.0.0", - "xml2js": "^0.4.5" - } - }, - "node_modules/parse-headers": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.5.tgz", - "integrity": "sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA==" - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/peek-readable": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.1.0.tgz", - "integrity": "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==", - "engines": { - "node": ">=8" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" - } - }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" - }, - "node_modules/phin": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/phin/-/phin-2.9.3.tgz", - "integrity": "sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA==" - }, - "node_modules/pixelmatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-4.0.2.tgz", - "integrity": "sha512-J8B6xqiO37sU/gkcMglv6h5Jbd9xNER7aHzpfRdNmV4IbQBzBpe4l9XmbG+xPF/znacgu2jfEw+wHffaq/YkXA==", - "dependencies": { - "pngjs": "^3.0.0" - }, - "bin": { - "pixelmatch": "bin/pixelmatch" - } - }, - "node_modules/pixelmatch/node_modules/pngjs": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", - "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/pngjs": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-6.0.0.tgz", - "integrity": "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg==", - "engines": { - "node": ">=12.13.0" - } - }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "node_modules/psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" - }, - "node_modules/punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/qs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/readable-web-to-node-stream": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz", - "integrity": "sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==", - "dependencies": { - "readable-stream": "^3.6.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" - } - }, - "node_modules/readable-web-to-node-stream/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" - }, - "node_modules/remedial": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/remedial/-/remedial-1.0.8.tgz", - "integrity": "sha512-/62tYiOe6DzS5BqVsNpH/nkGlX45C/Sp6V+NtiN6JQNS1Viay7cWkazmRkrQrdFj2eshDe96SIQNIoMxqhzBOg==", - "engines": { - "node": "*" - } - }, - "node_modules/request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" - }, - "node_modules/selenium-webdriver": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-4.8.0.tgz", - "integrity": "sha512-s/HL8WNwy1ggHR244+tAhjhyKMJnZLt1HKJ6Gn7nQgVjB/ybDF+46Uui0qI2J7AjPNJzlUmTncdC/jg/kKkn0A==", - "dependencies": { - "jszip": "^3.10.0", - "tmp": "^0.2.1", - "ws": ">=8.11.0" - }, - "engines": { - "node": ">= 14.20.0" - } - }, - "node_modules/setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" - }, - "node_modules/split2": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-2.2.0.tgz", - "integrity": "sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw==", - "dependencies": { - "through2": "^2.0.2" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" - }, - "node_modules/sshpk": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", - "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/strtok3": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.3.0.tgz", - "integrity": "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==", - "dependencies": { - "@tokenizer/token": "^0.3.0", - "peek-readable": "^4.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" - } - }, - "node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/timm": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/timm/-/timm-1.7.1.tgz", - "integrity": "sha512-IjZc9KIotudix8bMaBW6QvMuq64BrJWFs1+4V0lXwWGQZwH+LnX87doAYhem4caOEusRP9/g6jVDQmZ8XOk1nw==" - }, - "node_modules/tinycolor2": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.6.0.tgz", - "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==" - }, - "node_modules/tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "dependencies": { - "rimraf": "^3.0.0" - }, - "engines": { - "node": ">=8.17.0" - } - }, - "node_modules/token-types": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/token-types/-/token-types-4.2.1.tgz", - "integrity": "sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ==", - "dependencies": { - "@tokenizer/token": "^0.3.0", - "ieee754": "^1.2.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" - } - }, - "node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" - }, - "node_modules/until": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/until/-/until-0.1.1.tgz", - "integrity": "sha512-WoXRtltRMS87Iwilt72d4Er3CMaQmzPCTx3B16LCXty/3Xl5VJhccyn0nSyotfh1TyH4IzoTgfZ747wXVpLhvQ==" - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/utif2": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/utif2/-/utif2-4.0.1.tgz", - "integrity": "sha512-KMaD76dbzK1VjbwsckHJiqDjhP3pbpwyV+FdqkY6XFQenc2o/HS6pjPSYdu4+NQMHf2NLTW+nVP/eFP1CvOYQQ==", - "dependencies": { - "pako": "^1.0.11" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "bin": { - "uuid": "bin/uuid" - } - }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "node_modules/verror/node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" - }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "node_modules/whatwg-fetch": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz", - "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==" - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" - }, - "node_modules/ws": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.12.0.tgz", - "integrity": "sha512-kU62emKIdKVeEIOIKVegvqpXMSTAMLJozpHZaJNDYqBjzlSYXQGviYwN1osDLJ9av68qHd4a2oSjd7yD4pacig==", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xhr": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz", - "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==", - "dependencies": { - "global": "~4.4.0", - "is-function": "^1.0.1", - "parse-headers": "^2.0.0", - "xtend": "^4.0.0" - } - }, - "node_modules/xml-parse-from-string": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz", - "integrity": "sha512-ErcKwJTF54uRzzNMXq2X5sMIy88zJvfN2DmdoQvy7PAFJ+tPRU6ydWuOKNMyfmOjdyBQTFREi60s0Y0SyI0G0g==" - }, - "node_modules/xml2js": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", - "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", - "dependencies": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "engines": { - "node": ">=0.4" - } - } - }, - "dependencies": { - "@jimp/bmp": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/bmp/-/bmp-0.22.4.tgz", - "integrity": "sha512-ZDwQ/tLihpZuTCFGGa0zcyZIWHfhvHkrdbsoHUY0GG/JpH/y2xzlm2I48/TicCpoujN8oGKLHIJje0HmVX3xaA==", - "requires": { - "@jimp/utils": "^0.22.4", - "bmp-js": "^0.1.0" - } - }, - "@jimp/core": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/core/-/core-0.22.4.tgz", - "integrity": "sha512-K7guEYpXV44SCLR35QdPyKqF+mFZaEUAqiSL8qQ/F4N4Ws9JkPzFI/qYTjOkDoKxSWkXlKnlsk1sfMzy0yqA5g==", - "requires": { - "@jimp/utils": "^0.22.4", - "any-base": "^1.1.0", - "buffer": "^5.2.0", - "exif-parser": "^0.1.12", - "file-type": "^16.5.4", - "isomorphic-fetch": "^3.0.0", - "mkdirp": "^2.1.3", - "pixelmatch": "^4.0.2", - "tinycolor2": "^1.6.0" - } - }, - "@jimp/custom": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/custom/-/custom-0.22.4.tgz", - "integrity": "sha512-k9m/RfxjPjklUsgZ2nszlyNkodUG/4xlxlif70UELhxW8bdqZqqlQGzwA9p+PUiSnlSJYZjL6q+P8cd7yj1ggA==", - "requires": { - "@jimp/core": "^0.22.4" - } - }, - "@jimp/gif": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/gif/-/gif-0.22.4.tgz", - "integrity": "sha512-KmN7GoaQTzLAX4JXLBRkIiZAXthgQdKe+Y7BOw4n6CMe6LAS/XCQqrYCG3Av/GqIO7UAKems6D7kIGAUuhpNlQ==", - "requires": { - "@jimp/utils": "^0.22.4", - "gifwrap": "^0.9.2", - "omggif": "^1.0.9" - } - }, - "@jimp/jpeg": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/jpeg/-/jpeg-0.22.4.tgz", - "integrity": "sha512-mMJNhEtJpne65mxpIXEvT0VIzmsKiZWmaFT/c2eQ2tBLEtWAFpkvoP+F7jEaU+F3Ur4fXKFkJ/xOSXtRr/gGNw==", - "requires": { - "@jimp/utils": "^0.22.4", - "jpeg-js": "^0.4.4" - } - }, - "@jimp/plugin-blit": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/plugin-blit/-/plugin-blit-0.22.4.tgz", - "integrity": "sha512-QQHe+rFarsxJQxWKlyHEMfLyXmUG9AiQky+8WfwjZVBYilIFyiBywOc3sThonOsru+7LOSUDmbN6mvbFk4R+gw==", - "requires": { - "@jimp/utils": "^0.22.4" - } - }, - "@jimp/plugin-blur": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/plugin-blur/-/plugin-blur-0.22.4.tgz", - "integrity": "sha512-p57Ac5LEQckIogiwf7qyOojGvLOD08eMaQd5ylOhet/fbdwAzD/8flWFhSIKsdAVzvnfGcszuLtrsV07jDutTw==", - "requires": { - "@jimp/utils": "^0.22.4" - } - }, - "@jimp/plugin-circle": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/plugin-circle/-/plugin-circle-0.22.4.tgz", - "integrity": "sha512-T+TpG+s+wM9kKHlpIEfCAfOM+QrYVqcMoWjkULddc0KtaDEhqgGYFhN+/SlzJfDbZKw0xUgIuAw89sXuzMIUjw==", - "requires": { - "@jimp/utils": "^0.22.4" - } - }, - "@jimp/plugin-color": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/plugin-color/-/plugin-color-0.22.4.tgz", - "integrity": "sha512-TZqcqepoCcIlF7VodPPfS3WET+LL5Y/XnXOBk4tWnG5i+lhNrs7/U0HOJY6Iw9o4g267DddnlfKWmunvzBcvOQ==", - "requires": { - "@jimp/utils": "^0.22.4", - "tinycolor2": "^1.6.0" - } - }, - "@jimp/plugin-contain": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/plugin-contain/-/plugin-contain-0.22.4.tgz", - "integrity": "sha512-Hl+TO4v+EpRfEl3R6k/bEgOGOpm6JqNfEIyCFWLi6yqJQjMGzBQ0vt+VHe2u3WIFaFrDWsGxeuFZBDzgtjTwxw==", - "requires": { - "@jimp/utils": "^0.22.4" - } - }, - "@jimp/plugin-cover": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/plugin-cover/-/plugin-cover-0.22.4.tgz", - "integrity": "sha512-KMTQjN/B7r/RNzoLFwnhqhLrgT0kMqTkBMEZQSopj5vPLPNjIX0ElEYC8AIVFKeZAV+1mYkyss+IDdxq4fyRng==", - "requires": { - "@jimp/utils": "^0.22.4" - } - }, - "@jimp/plugin-crop": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/plugin-crop/-/plugin-crop-0.22.4.tgz", - "integrity": "sha512-8krDt7xzBa1fbtlYCzEMZIgNjTkhgywho0FJpgIMkIUMjaZITS1Ea/Veb3UrWt8EsgQS6hxjGVE/Q1FvP5iPLA==", - "requires": { - "@jimp/utils": "^0.22.4" - } - }, - "@jimp/plugin-displace": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/plugin-displace/-/plugin-displace-0.22.4.tgz", - "integrity": "sha512-3gBfwYVFrOjp8SUpb7H0UMgqvsG/sxY1PVBIfRW9MUCosiH1eE/Mo5cbxhQ6/w5f3sh23lBmG8W0WuSrnXLorg==", - "requires": { - "@jimp/utils": "^0.22.4" - } - }, - "@jimp/plugin-dither": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/plugin-dither/-/plugin-dither-0.22.4.tgz", - "integrity": "sha512-oOhdZBDJpSGIoTUhPOIvLIVUwILRWgrWdA4Vbzcyz2RHvaPHS8gdBH0EdIPbJ5agNyFnY8sJWFM7YKx/rLNKsw==", - "requires": { - "@jimp/utils": "^0.22.4" - } - }, - "@jimp/plugin-fisheye": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/plugin-fisheye/-/plugin-fisheye-0.22.4.tgz", - "integrity": "sha512-2myNZyDrwUOV8MKd4NeULnEOojYF7XRbnRHiUPsNptpmK6g/gI4xt+5k7BallAYZD8ZLfZVjstUogsObprHd/Q==", - "requires": { - "@jimp/utils": "^0.22.4" - } - }, - "@jimp/plugin-flip": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/plugin-flip/-/plugin-flip-0.22.4.tgz", - "integrity": "sha512-9FZ0k5N5leLDefeDjizXXTl17dzo23PYtCD/T4xeSVr96d1pQDwbeIk7pEhhHr1rl98tJe0U/OV2dFXFYauKPw==", - "requires": { - "@jimp/utils": "^0.22.4" - } - }, - "@jimp/plugin-gaussian": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/plugin-gaussian/-/plugin-gaussian-0.22.4.tgz", - "integrity": "sha512-irOSwLdZ9kTq5Wd5dpkMgIMJVwemYcqgnzd04+P6TJGYmem2HR6JUCDpjbET3Fpbo/snFLm4mZ+2A+SmeCGjKA==", - "requires": { - "@jimp/utils": "^0.22.4" - } - }, - "@jimp/plugin-invert": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/plugin-invert/-/plugin-invert-0.22.4.tgz", - "integrity": "sha512-/WtZeLrF+H+mzbjqudeGvvSxudlHy1kyiP1gVWDxhYNQOuZJI57Vn20kSTYvHBNjvy31LV4/uestyX8j8tE2Qg==", - "requires": { - "@jimp/utils": "^0.22.4" - } - }, - "@jimp/plugin-mask": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/plugin-mask/-/plugin-mask-0.22.4.tgz", - "integrity": "sha512-U0SrOwBNKkMYTNPTz5CXeJdZ4c5easFlq2B9Txy0kPsav2OraTv8cZjpMxrWUejo/AQGVUDbaGtXMm9pE13/6w==", - "requires": { - "@jimp/utils": "^0.22.4" - } - }, - "@jimp/plugin-normalize": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/plugin-normalize/-/plugin-normalize-0.22.4.tgz", - "integrity": "sha512-XJiPBJGCHWmIzUdmL4mWP1Ev5LMp77oMmPXdgQGDty1cxfyo3CbkTjZSsnwF/XLlrQ1yfLW+8JB+ihGKcVEOxA==", - "requires": { - "@jimp/utils": "^0.22.4" - } - }, - "@jimp/plugin-print": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/plugin-print/-/plugin-print-0.22.4.tgz", - "integrity": "sha512-mayiPhg6c7KYjvq3fYOW9ohhXD1eWdEiseV9dAWqTOEbDbohT8S6eTGhVIiVa2sVySLcpNEKZSk07c5EhJAMcw==", - "requires": { - "@jimp/utils": "^0.22.4", - "load-bmfont": "^1.4.1" - } - }, - "@jimp/plugin-resize": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/plugin-resize/-/plugin-resize-0.22.4.tgz", - "integrity": "sha512-2wMdpPNGf6Zo2lfJg1QHHQ+ds5baQH75IcFpdjw717dcEISpn1jPG//iClXOGh16OJsRQlwHESaZTgEo/5Dw/g==", - "requires": { - "@jimp/utils": "^0.22.4" - } - }, - "@jimp/plugin-rotate": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/plugin-rotate/-/plugin-rotate-0.22.4.tgz", - "integrity": "sha512-g08LBsPENbeA6NVoeq0iuDgAL89+N+aZrvYVKYkiJZIM7vUvueJyAIq4+bjDl4r54OR8XBFX0GsrKsqrULh1eA==", - "requires": { - "@jimp/utils": "^0.22.4" - } - }, - "@jimp/plugin-scale": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/plugin-scale/-/plugin-scale-0.22.4.tgz", - "integrity": "sha512-cJiLQtTcNk6/+j05R23TFGXy+smDV0BdlmzJVDb+7Ye9qcmWpkdjVSioQQqZr0QScIYKhhRCY/lFTepBx67yzw==", - "requires": { - "@jimp/utils": "^0.22.4" - } - }, - "@jimp/plugin-shadow": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/plugin-shadow/-/plugin-shadow-0.22.4.tgz", - "integrity": "sha512-a5hdpzGBzBo91DNiKaGvs8iJbs2bYQmDRm/BrCh4NET+h5l5AwXNu/Ak0bWRhN16YQ55XYNGHer2jOwBPrf2WQ==", - "requires": { - "@jimp/utils": "^0.22.4" - } - }, - "@jimp/plugin-threshold": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/plugin-threshold/-/plugin-threshold-0.22.4.tgz", - "integrity": "sha512-jTT/+p2zb2NESzd7O0bVRowiQszoaHeBf2OgP7lFde10fHd+fn78m5brUmSmlGAdlMRwm8S8ZcxTj5ZjdQns5w==", - "requires": { - "@jimp/utils": "^0.22.4" - } - }, - "@jimp/plugins": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/plugins/-/plugins-0.22.4.tgz", - "integrity": "sha512-yAxcA4UR3Bs7j73I7wt4ty52vm5MzPmr+8DYk8jrS/ng2Z2iuXzbcTe4mf9eEqXYVah3rTIggo4dPjW75DRZtA==", - "requires": { - "@jimp/plugin-blit": "^0.22.4", - "@jimp/plugin-blur": "^0.22.4", - "@jimp/plugin-circle": "^0.22.4", - "@jimp/plugin-color": "^0.22.4", - "@jimp/plugin-contain": "^0.22.4", - "@jimp/plugin-cover": "^0.22.4", - "@jimp/plugin-crop": "^0.22.4", - "@jimp/plugin-displace": "^0.22.4", - "@jimp/plugin-dither": "^0.22.4", - "@jimp/plugin-fisheye": "^0.22.4", - "@jimp/plugin-flip": "^0.22.4", - "@jimp/plugin-gaussian": "^0.22.4", - "@jimp/plugin-invert": "^0.22.4", - "@jimp/plugin-mask": "^0.22.4", - "@jimp/plugin-normalize": "^0.22.4", - "@jimp/plugin-print": "^0.22.4", - "@jimp/plugin-resize": "^0.22.4", - "@jimp/plugin-rotate": "^0.22.4", - "@jimp/plugin-scale": "^0.22.4", - "@jimp/plugin-shadow": "^0.22.4", - "@jimp/plugin-threshold": "^0.22.4", - "timm": "^1.6.1" - } - }, - "@jimp/png": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/png/-/png-0.22.4.tgz", - "integrity": "sha512-kDovx9dTyV/TSR40HQHdRyVgNNb7Cny4/0PPEa+xeR7snuDC3dV5hu9s/QJwY0RMGiAkiuKDpiaBuSZuz8dwRQ==", - "requires": { - "@jimp/utils": "^0.22.4", - "pngjs": "^6.0.0" - } - }, - "@jimp/tiff": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/tiff/-/tiff-0.22.4.tgz", - "integrity": "sha512-RStUATRnb+unYzzuGxU+SPZALqh5NxYdcS6UGTBvhCMlijopGiY/iL01wstIOst0ypKIjwbcSVj7mAHn6B7Qbw==", - "requires": { - "utif2": "^4.0.1" - } - }, - "@jimp/types": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/types/-/types-0.22.4.tgz", - "integrity": "sha512-v3hm8LGc3we6P6ML0ticiLX7wtdvywrKthYxqVrJVIu3vRL0Z4q3ngFjwzqDmaIF8wC0neq98s/t7ODWfeIiRQ==", - "requires": { - "@jimp/bmp": "^0.22.4", - "@jimp/gif": "^0.22.4", - "@jimp/jpeg": "^0.22.4", - "@jimp/png": "^0.22.4", - "@jimp/tiff": "^0.22.4", - "timm": "^1.6.1" - } - }, - "@jimp/utils": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@jimp/utils/-/utils-0.22.4.tgz", - "integrity": "sha512-EPaBMNg4NvVXnMpSFJEsdCQqdSVU2ACreAL+Ipkq19C/FkDEj9Q10t6Mjx8zOe/AAjBQj1vTALS/DykcHOn4bQ==", - "requires": { - "regenerator-runtime": "^0.13.3" - } - }, - "@tokenizer/token": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", - "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==" - }, - "@types/node": { - "version": "16.9.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.9.1.tgz", - "integrity": "sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g==" - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "any-base": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/any-base/-/any-base-1.1.0.tgz", - "integrity": "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg==" - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==" - }, - "aws4": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", - "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==" - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" - }, - "bmp-js": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/bmp-js/-/bmp-js-0.1.0.tgz", - "integrity": "sha512-vHdS19CnY3hwiNdkaqk93DvjVLfbEcI8mys4UjuWrlX1haDmroo8o4xCzh4wD6DGV6HxRCyauwhHRqMTfERtjw==" - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "buffer-equal": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz", - "integrity": "sha512-RgSV6InVQ9ODPdLWJ5UAqBqJBOg370Nz6ZQtRzpt6nUjc8v0St97uJ4PYC6NztqIScrAXafKM3mZPMygSe1ggA==" - }, - "bufferjs": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/bufferjs/-/bufferjs-3.0.1.tgz", - "integrity": "sha512-qrCIGPcd9ODawCNyqR2o55zgaC/r7XHZ7oUh2s99uk+NVBS3SjIHigxS1S2KXpt8wsoQxAN55iPi8GIH8TGMRg==" - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" - }, - "configuration-processor": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/configuration-processor/-/configuration-processor-1.1.1.tgz", - "integrity": "sha512-nQYMSZfAxUyBWpCQQh2tk/kJ8Eg6c50klw2edEY1R6xoUJ0Vy6IYQclNYubXR6B0bThDahn/TNQfDD+vzxpTFQ==" - }, - "core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" - }, - "csv-write-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/csv-write-stream/-/csv-write-stream-2.0.0.tgz", - "integrity": "sha512-QTraH6FOYfM5f+YGwx71hW1nR9ZjlWri67/D4CWtiBkdce0UAa91Vc0yyHg0CjC0NeEGnvO/tBSJkA1XF9D9GQ==", - "requires": { - "argparse": "^1.0.7", - "generate-object-property": "^1.0.0", - "ndjson": "^1.3.0" - } - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "data-container": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/data-container/-/data-container-1.1.0.tgz", - "integrity": "sha512-WnmEstSHZMOYJsy+BHKVxtZ1M0scmN74pLfm8CwMtQr/AxJjUVXFt3M04T/B2iahhtMxGIiLKFi3nr/tdBmX5Q==", - "requires": { - "configuration-processor": "~1" - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" - }, - "dom-walk": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", - "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==" - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "event-dispatcher": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/event-dispatcher/-/event-dispatcher-2.4.0.tgz", - "integrity": "sha512-08u6SPGt/atk1W5o1Fa2IeH0cme8Fsp42qI1XsdKqZbl+rgcwY/AYtlqV04nylyhKAQ33Zql0rkYH0Z4/TVy8Q==", - "requires": { - "configuration-processor": "~1", - "data-container": "~1" - } - }, - "exif-parser": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/exif-parser/-/exif-parser-0.1.12.tgz", - "integrity": "sha512-c2bQfLNbMzLPmzQuOr8fy0csy84WmwnER81W88DzTp9CYNPJ6yzOj2EZAh9pywYpqHnshVLHQJ8WzldAyfY+Iw==" - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==" - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "File": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/File/-/File-0.10.2.tgz", - "integrity": "sha512-gomQVTq/10wIR399uhGTWtYcYneTXbfe3p2RO/NR0MPrLkIyOaE9DCEPXihAm+72epLtXaplitwfJ/wkmj88dg==", - "requires": { - "mime": ">= 0.0.0" - } - }, - "file-api": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/file-api/-/file-api-0.10.4.tgz", - "integrity": "sha512-RVBXJGmsnQxokdpy264pmsdBjbUuxE6QT2xxhOrO2pzwTetbTNoWVFgkONFWmopm5mellsXrQIQhMY9fjufi9g==", - "requires": { - "bufferjs": "> 0.2.0", - "File": ">= 0.10.0", - "file-error": ">= 0.10.0", - "FileList": ">= 0.10.0", - "filereader": ">= 0.10.3", - "formdata": ">= 0.10.0", - "mime": ">= 1.2.11", - "remedial": ">= 1.0.7" - } - }, - "file-error": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/file-error/-/file-error-0.10.2.tgz", - "integrity": "sha512-hJsQ7sEz6dM4vuRS7cipKiixV6EymEXHe+TCf2XVWsGTOehzrmcqqKMgeYTmV24XhjWSj+pQj1e5yjPJ7DtQvw==" - }, - "file-type": { - "version": "16.5.4", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-16.5.4.tgz", - "integrity": "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==", - "requires": { - "readable-web-to-node-stream": "^3.0.0", - "strtok3": "^6.2.4", - "token-types": "^4.1.1" - } - }, - "FileList": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/FileList/-/FileList-0.10.2.tgz", - "integrity": "sha512-HCe9WvojxLiMEfa3l6jFkQJLzhzDXgQmfnKFoRvhEnsyVoIc5piAQNLyhOwsZsmf8IwDBfr5H71nB8Wi5w0XwA==" - }, - "filereader": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/filereader/-/filereader-0.10.3.tgz", - "integrity": "sha512-7F8w6GSXuHLN80ukaVOcHgBaiTRHUZr8GeEhNdqfAECcnBoROg4i8hTl+KqtF4yUPffOJVHEFg4iDJb7xIYFng==" - }, - "filesystem": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/filesystem/-/filesystem-1.0.1.tgz", - "integrity": "sha512-IlnKZqVmv+UNR8kVknA47RY1rSfdJxNNmiX0osELJxhNj010cjlXH7nj7Vq1bPBPTrHtVrRYIWymXjVPlxffdw==", - "requires": { - "configuration-processor": "~1", - "event-dispatcher": "~2" - } - }, - "foreachasync": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/foreachasync/-/foreachasync-3.0.0.tgz", - "integrity": "sha512-J+ler7Ta54FwwNcx6wQRDhTIbNeyDcARMkOcguEqnEdtm0jKvN3Li3PDAb2Du3ubJYEWfYL83XMROXdsXAXycw==" - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "formdata": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/formdata/-/formdata-0.10.4.tgz", - "integrity": "sha512-IsHa+GYLLXHx0RmpUmzQTdwxDjNinxD+1zKOYPLaRwiqTfex5caQhOzgPIjFgJkL0O884Ers76BSHzXJxHvPLw==", - "requires": { - "bufferjs": "^2.0.0", - "File": "^0.10.2", - "FileList": "^0.10.2", - "filereader": "^0.10.3", - "foreachasync": "^3.0.0", - "remedial": "^1.0.7" - }, - "dependencies": { - "bufferjs": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/bufferjs/-/bufferjs-2.0.0.tgz", - "integrity": "sha512-VnTCQKC+AJ61OFGe/hn3jRXoIt/B95NUcuxzAwiVT0PFB0KRZImkoDPYdFqDIs7xAs1eJ3yiKcHnuUiiYe7ucQ==" - } - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" - }, - "generate-object-property": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", - "integrity": "sha512-TuOwZWgJ2VAMEGJvAyPWvpqxSANF0LDpmyHauMjFYzaACvn+QTT/AZomvPCzVBV7yDN3OmwHQ5OvHaeLKre3JQ==", - "requires": { - "is-property": "^1.0.0" - } - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "gifwrap": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/gifwrap/-/gifwrap-0.9.4.tgz", - "integrity": "sha512-MDMwbhASQuVeD4JKd1fKgNgCRL3fGqMM4WaqpNhWO0JiMOAjbQdumbs4BbBZEy9/M00EHEjKN3HieVhCUlwjeQ==", - "requires": { - "image-q": "^4.0.0", - "omggif": "^1.0.10" - } - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "global": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", - "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", - "requires": { - "min-document": "^2.19.0", - "process": "^0.11.10" - } - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==" - }, - "har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "requires": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https/-/https-1.0.0.tgz", - "integrity": "sha512-4EC57ddXrkaF0x83Oj8sM6SLQHAWXw90Skqu2M4AEWENZ3F02dFJE/GARA8igO79tcgYqGrD7ae4f5L3um2lgg==" - }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" - }, - "image-convert": { - "version": "0.1.33", - "resolved": "https://registry.npmjs.org/image-convert/-/image-convert-0.1.33.tgz", - "integrity": "sha512-nUK+LJooUoDXYb6g7OtbRHbwNdyjfhrWMGTDblhJi3LJm0uybs9u9pP5LItOYqc3fFvFoGt08Onv27oes60w4w==", - "requires": { - "file-api": "^0.10.4", - "images": "^3.0.0", - "request": "^2.79.0" - } - }, - "image-q": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/image-q/-/image-q-4.0.0.tgz", - "integrity": "sha512-PfJGVgIfKQJuq3s0tTDOKtztksibuUEbJQIYT3by6wctQo+Rdlh7ef4evJ5NCdxY4CfMbvFkocEwbl4BF8RlJw==", - "requires": { - "@types/node": "16.9.1" - } - }, - "images": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/images/-/images-3.2.4.tgz", - "integrity": "sha512-Uq61/Q8XixCRyKvws7tPwboK0O70Dbr4kMQZHw2dqdEhnU6TpaGwyMg0vzQ4aaGtrO9N3etq46XwF7hxbqp8ug==" - }, - "immediate": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", - "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==" - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "is-function": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", - "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==" - }, - "is-property": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", - "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==" - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" - }, - "isomorphic-fetch": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz", - "integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==", - "requires": { - "node-fetch": "^2.6.1", - "whatwg-fetch": "^3.4.1" - } - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" - }, - "jimp": { - "version": "0.22.4", - "resolved": "https://registry.npmjs.org/jimp/-/jimp-0.22.4.tgz", - "integrity": "sha512-reGESbcYp38VlGtdAe8qrmbjLLEYXMrQWc2XXb7+czulKfCCidUHEpNfrS3hx5XXMWrAmoYKkxPTqCvll6Q6ug==", - "requires": { - "@jimp/custom": "^0.22.4", - "@jimp/plugins": "^0.22.4", - "@jimp/types": "^0.22.4", - "regenerator-runtime": "^0.13.3" - } - }, - "jpeg-js": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.4.tgz", - "integrity": "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==" - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==" - }, - "json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" - }, - "jsprim": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", - "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - } - }, - "jszip": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", - "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", - "requires": { - "lie": "~3.3.0", - "pako": "~1.0.2", - "readable-stream": "~2.3.6", - "setimmediate": "^1.0.5" - } - }, - "lie": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", - "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", - "requires": { - "immediate": "~3.0.5" - } - }, - "load-bmfont": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/load-bmfont/-/load-bmfont-1.4.1.tgz", - "integrity": "sha512-8UyQoYmdRDy81Brz6aLAUhfZLwr5zV0L3taTQ4hju7m6biuwiWiJXjPhBJxbUQJA8PrkvJ/7Enqmwk2sM14soA==", - "requires": { - "buffer-equal": "0.0.1", - "mime": "^1.3.4", - "parse-bmfont-ascii": "^1.0.3", - "parse-bmfont-binary": "^1.0.5", - "parse-bmfont-xml": "^1.1.4", - "phin": "^2.9.1", - "xhr": "^2.0.1", - "xtend": "^4.0.0" - } - }, - "mastodon": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/mastodon/-/mastodon-1.2.2.tgz", - "integrity": "sha512-ixcYkzn6SorH8U2jNc1vwiX89EiVMjzd2aDYFtr191YY9rdoVo+owI6cQo2EjUnzg2RN9WxyBJ9KDuw+R4lt+w==", - "requires": { - "bluebird": "^3.1.5", - "mime": "^1.3.4", - "request": "^2.68.0" - } - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" - }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" - }, - "mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "requires": { - "mime-db": "1.52.0" - } - }, - "min-document": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", - "integrity": "sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==", - "requires": { - "dom-walk": "^0.1.0" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", - "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==" - }, - "mkdirp": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-2.1.3.tgz", - "integrity": "sha512-sjAkg21peAG9HS+Dkx7hlG9Ztx7HLeKnvB3NQRcu/mltCVmvkF0pisbiTSfDVYTT86XEfZrTUosLdZLStquZUw==" - }, - "ndjson": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/ndjson/-/ndjson-1.5.0.tgz", - "integrity": "sha512-hUPLuaziboGjNF7wHngkgVc0FOclR8dDk/HfEvTtDr/iUrqBWiRcRSTK3/nLOqKH33th714BrMmTPtObI9gZxQ==", - "requires": { - "json-stringify-safe": "^5.0.1", - "minimist": "^1.2.0", - "split2": "^2.1.0", - "through2": "^2.0.3" - } - }, - "node-fetch": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz", - "integrity": "sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==", - "requires": { - "whatwg-url": "^5.0.0" - } - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "omggif": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/omggif/-/omggif-1.0.10.tgz", - "integrity": "sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==" - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "requires": { - "wrappy": "1" - } - }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" - }, - "parse-bmfont-ascii": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/parse-bmfont-ascii/-/parse-bmfont-ascii-1.0.6.tgz", - "integrity": "sha512-U4RrVsUFCleIOBsIGYOMKjn9PavsGOXxbvYGtMOEfnId0SVNsgehXh1DxUdVPLoxd5mvcEtvmKs2Mmf0Mpa1ZA==" - }, - "parse-bmfont-binary": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/parse-bmfont-binary/-/parse-bmfont-binary-1.0.6.tgz", - "integrity": "sha512-GxmsRea0wdGdYthjuUeWTMWPqm2+FAd4GI8vCvhgJsFnoGhTrLhXDDupwTo7rXVAgaLIGoVHDZS9p/5XbSqeWA==" - }, - "parse-bmfont-xml": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/parse-bmfont-xml/-/parse-bmfont-xml-1.1.4.tgz", - "integrity": "sha512-bjnliEOmGv3y1aMEfREMBJ9tfL3WR0i0CKPj61DnSLaoxWR3nLrsQrEbCId/8rF4NyRF0cCqisSVXyQYWM+mCQ==", - "requires": { - "xml-parse-from-string": "^1.0.0", - "xml2js": "^0.4.5" - } - }, - "parse-headers": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.5.tgz", - "integrity": "sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA==" - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" - }, - "peek-readable": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.1.0.tgz", - "integrity": "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==" - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" - }, - "phin": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/phin/-/phin-2.9.3.tgz", - "integrity": "sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA==" - }, - "pixelmatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-4.0.2.tgz", - "integrity": "sha512-J8B6xqiO37sU/gkcMglv6h5Jbd9xNER7aHzpfRdNmV4IbQBzBpe4l9XmbG+xPF/znacgu2jfEw+wHffaq/YkXA==", - "requires": { - "pngjs": "^3.0.0" - }, - "dependencies": { - "pngjs": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", - "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==" - } - } - }, - "pngjs": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-6.0.0.tgz", - "integrity": "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg==" - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==" - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" - }, - "punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==" - }, - "qs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==" - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "readable-web-to-node-stream": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz", - "integrity": "sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==", - "requires": { - "readable-stream": "^3.6.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" - }, - "remedial": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/remedial/-/remedial-1.0.8.tgz", - "integrity": "sha512-/62tYiOe6DzS5BqVsNpH/nkGlX45C/Sp6V+NtiN6JQNS1Viay7cWkazmRkrQrdFj2eshDe96SIQNIoMxqhzBOg==" - }, - "request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" - }, - "selenium-webdriver": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-4.8.0.tgz", - "integrity": "sha512-s/HL8WNwy1ggHR244+tAhjhyKMJnZLt1HKJ6Gn7nQgVjB/ybDF+46Uui0qI2J7AjPNJzlUmTncdC/jg/kKkn0A==", - "requires": { - "jszip": "^3.10.0", - "tmp": "^0.2.1", - "ws": ">=8.11.0" - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" - }, - "split2": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-2.2.0.tgz", - "integrity": "sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw==", - "requires": { - "through2": "^2.0.2" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" - }, - "sshpk": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", - "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strtok3": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.3.0.tgz", - "integrity": "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==", - "requires": { - "@tokenizer/token": "^0.3.0", - "peek-readable": "^4.1.0" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "timm": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/timm/-/timm-1.7.1.tgz", - "integrity": "sha512-IjZc9KIotudix8bMaBW6QvMuq64BrJWFs1+4V0lXwWGQZwH+LnX87doAYhem4caOEusRP9/g6jVDQmZ8XOk1nw==" - }, - "tinycolor2": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.6.0.tgz", - "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==" - }, - "tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "requires": { - "rimraf": "^3.0.0" - } - }, - "token-types": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/token-types/-/token-types-4.2.1.tgz", - "integrity": "sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ==", - "requires": { - "@tokenizer/token": "^0.3.0", - "ieee754": "^1.2.1" - } - }, - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" - }, - "until": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/until/-/until-0.1.1.tgz", - "integrity": "sha512-WoXRtltRMS87Iwilt72d4Er3CMaQmzPCTx3B16LCXty/3Xl5VJhccyn0nSyotfh1TyH4IzoTgfZ747wXVpLhvQ==" - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "requires": { - "punycode": "^2.1.0" - } - }, - "utif2": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/utif2/-/utif2-4.0.1.tgz", - "integrity": "sha512-KMaD76dbzK1VjbwsckHJiqDjhP3pbpwyV+FdqkY6XFQenc2o/HS6pjPSYdu4+NQMHf2NLTW+nVP/eFP1CvOYQQ==", - "requires": { - "pako": "^1.0.11" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - }, - "dependencies": { - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" - } - } - }, - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "whatwg-fetch": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz", - "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==" - }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" - }, - "ws": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.12.0.tgz", - "integrity": "sha512-kU62emKIdKVeEIOIKVegvqpXMSTAMLJozpHZaJNDYqBjzlSYXQGviYwN1osDLJ9av68qHd4a2oSjd7yD4pacig==", - "requires": {} - }, - "xhr": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz", - "integrity": "sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==", - "requires": { - "global": "~4.4.0", - "is-function": "^1.0.1", - "parse-headers": "^2.0.0", - "xtend": "^4.0.0" - } - }, - "xml-parse-from-string": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz", - "integrity": "sha512-ErcKwJTF54uRzzNMXq2X5sMIy88zJvfN2DmdoQvy7PAFJ+tPRU6ydWuOKNMyfmOjdyBQTFREi60s0Y0SyI0G0g==" - }, - "xml2js": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", - "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", - "requires": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - } - }, - "xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==" - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" - } - } -} diff --git a/ref/classes/arguments.js b/ref/classes/arguments.js new file mode 100644 index 0000000..b958e29 --- /dev/null +++ b/ref/classes/arguments.js @@ -0,0 +1,48 @@ +Array.prototype.findReg = function(match) { + var reg = match; + return this.filter(function(item){ + return typeof item == 'string' && item.match(reg); + }); +} + +class Args { + constructor() { + this.help = this.getFlag("h",); //show help screen + this.displayBrowser = this.getFlag("b"); //show browser running (disable headless) + this.enablePosts = this.getFlag("p"); //enable posting images or statuses to Mastodon + this.forceCSV = this.getFlag("c"); //force logging tweets to CSV, even if not posted to Mastodon (by request or failure) + this.printMeta = this.getFlag("m"); //include Display Name, handle, and URL in Mastodon post + this.enableQuotes = this.getFlag("q"); //enable cross-posting quote tweets + this.enableThreads = this.getFlag("t"); //enable cross-posting thread tweets + this.reQuotes = this.getFlag("r"); //put links to quote tweets at top of mastodon posts + + var userNamePreFormat = this.getArgument("-u","Twitter",false); + this.userName = userNamePreFormat.replace('@','') + this.tweetCount = this.getArgument("-n",5); + this.debug = this.getArgument("-d",1); + this.timeOut = this.getArgument("-w",30000); + } + + getFlag(char){ + let args = [...process.argv]; + var regex = new RegExp(`-\\S*[${char}]\\S*`, "g"); + return args.indexOf(args.findReg(regex)[0]) > -1 ? true : false; + } + + getArgument(flag, def, isInt = true) { + const args = [...process.argv]; + const customIndex = args.indexOf(flag); + const customValue = (customIndex > -1) ? args[customIndex + 1] : undefined; + let flagValue = customValue || def; + flagValue = isInt ? parseInt(flagValue) || def : flagValue; + return flagValue; + } +} + + + + + + + +module.exports = Args \ No newline at end of file diff --git a/ref/classes/formats.js b/ref/classes/formats.js new file mode 100644 index 0000000..ef8d7fa --- /dev/null +++ b/ref/classes/formats.js @@ -0,0 +1,15 @@ +const colors = require('cli-color'); + +class Formats { + constructor() { + this.success = colors.green.bold; + this.error = colors.red.bold; + this.warn = colors.yellow; + this.notice = colors.blue.bold; + this.bold = colors.bold; + this.underline = colors.underline; + this.italic = colors.italic; + } +} + +module.exports = Formats \ No newline at end of file diff --git a/ref/classes/tweets.js b/ref/classes/tweets.js new file mode 100644 index 0000000..09277cc --- /dev/null +++ b/ref/classes/tweets.js @@ -0,0 +1,245 @@ +const webdriver = require('selenium-webdriver'); +const By = webdriver.By; +//const { format } = require('fast-csv'); + +const elements = require('../functions/elements.js'); //link support.js +const XPathObjects = require('../classes/xpaths.js'); //link xpaths.js +const Args = require('../classes/arguments.js'); +const args = new Args(); +const support = require('../functions/support.js'); +const debuglog = support.debuglog; +const funcs = require('../functions/functions.js'); //link functions.js +const mastodon = require('../functions/mastodon.js'); //link mastodon.js +const Formats = require('../classes/formats.js'); +const format = new Formats(); + +//const homeX = new XPathObjects.TweetPaths("home"); //import xpath class object for home timeline +//const threadX = new XPathObjects.TweetPaths("thread"); //import xpath class object for thread timeline + +class Tweets { + constructor(orig,i) { + //parameters + this.orig = orig; + this.index = i-1; + this.no = i; + this.processed = false; + + //detect to filter out + this.isRT = false; + this.isAR = false; + this.isPin = false; + this.keep = false; + + //detect to move into thread + this.isThread = false; + + //processed text for posting + this.text = ""; + + //header + this.name = ""; + this.handle = ""; + this.url = ""; + this.header = ""; + + //body + this.hasBody = false; + this.body = ""; + this.hasLinks = false; + this.links = ""; + + //footer + this.hasVideo = false; + this.isQT = false; + this.quoteLink = ""; + this.footer = ""; + + //media + this.hasSingleImage = false; + this.hasMultiImage = false; + this.hasImages = false; + this.imgArray = []; + this.imgCount = 0; + this.imgUrl = ""; + this.iterateExists = false; + this.iteratePath = ""; + + //mastodon + this.id = 0; + this.prompt = 0; + this.posted = false; + + if (orig == "thread") { + this.threadLength = 0; + this.entryIsOpen = false; + } + //xpaths of tweet & elements + this.x = new XPathObjects.TweetPaths(orig,i); + } + + compileText(){ + const sectionArray = [this.header, this.body, this.footer]; + const nonEmptySections = sectionArray.filter(section => section !== ''); + this.text = nonEmptySections.join('\r\n\r\n'); + } + + appendSection(txt, section) { + switch (section) { + case 'header': + this.header += this.header ? `\r\n${txt}` : txt; + break; + case 'body': + this.body += this.body ? `\r\n${txt}` : txt; + break; + case 'footer': + this.footer += this.footer ? `\r\n${txt}` : txt; + break; + default: + throw new Error(`Invalid section: ${section}`); + } + } + + async identifyElements(driver){ + await elements.waitFor(driver,this.x.tweet,args.timeOut); //WAIT FOR TWEET URL OF CURRENT ITERATE TWEET + + this.isAR = await elements.doesExist(driver,this.x.ageRestricted);//IS TWEET AGE-RESTRICTED? + if (this.isAR){ + return; + } + + var mTweetURL = await elements.getAttribute(driver,this.x.tweetURL,'href') //GET URL OF TWEET + this.url = await mTweetURL.replace('://mobile.','://'); //SAVE TWEET URL TO TWEET OBJECT WITHOUT MOBILE + + this.hasBody = await elements.doesExist(driver,this.x.tweetText);//DOES TWEET HAVE BODY TEST? + this.hasLinks = await elements.doesExist(driver,this.x.urlCard);//DOES TWEET HAVE URL CARDS + this.hasVideo = await elements.doesExist(driver,this.x.video);//DOES TWEET HAVE VIDEO MEDIA? + + this.isQT = await elements.doesExist(driver, this.x.quoteTweetContent);//IS TWEET A QUOTE TWEET + this.isThread = await elements.doesExist(driver,this.x.detectThread);//IS TWEET A PART OF THREAD + + this.isRT = await elements.doesExist(driver,this.x.detectRT);//CHECK FOR RETWEETS + this.isPin = await elements.doesExist(driver,this.x.pinnedTweet);//IS TWEET PINNED + + this.hasSingleImage = await elements.doesExist(driver, this.x.singleImage);//DOES TWEET HAVE SINGLE IMAGE? + this.hasMultiImage = await elements.doesExist(driver,this.x.multiImage);//DOES TWEET HAVE MULTIPLE IMAGES? + this.hasImages = this.hasSingleImage || this.hasMultiImage;//DOES TWEET HAVE ANY MEDIA? + + } + + async getElementProperties(driver){ + if (args.printMeta) { //IF TWEET HEADER IS ENABLED + debuglog("running header stuff",2); + this.handle = await elements.getText(driver,this.x.tweeterHandle);//GET TEXT OF TWEETER HANDLE (@) + this.name = await elements.getText(driver,this.x.tweeterName);//GET TEXT OF TWEETER NAME (DISPLAY NAME) + this.appendSection(`${this.name} (${this.handle})\r\n${this.url}`,'header');//COMBINE HEADER COMPONENTS WITH URL + debuglog(`Tweet Header:\r\n${this.header}`); + } + + if (this.hasBody){//IF TWEET HAS BODY TEXT + debuglog("running body text stuff",2); + /*use this later to make emojis work? https://stackoverflow.com/questions/65328118/convert-img-with-alt-attribute-to-text-with-selenium-webdriver + await driver.findElement(webdriver.By.xpath(this.x.timeLine)) // GETS NUMBER OF ELEMENTS IN THREAD, SHOULD NOT ITERATE MORE THAN THIS MANY TIMES. NOT USED ANYMORE + .findElements(webdriver.By.xpath(this.x.emoji)) + .then(function(elements){ + debuglog("Found emoji!",2); + //this.threadLength = elements.length; + });*/ + const bodyText = await elements.getText(driver,this.x.tweetText);//SET TWEET BODY TO TEXT OF TWEET + this.appendSection(bodyText,'body'); + debuglog(`Tweet Body:\r\n${this.body}`); + } + + if (this.hasLinks){//IF TWEET HAS URL CARD + debuglog("running url card stuff",2); + var tweetCardURL = await elements.getAttribute(driver,this.x.urlCard,"href");//GET URL OF URL CARD + this.links = await funcs.expandUrl(tweetCardURL); + this.appendSection(this.links,'body'); + debuglog(`Tweet link: ${this.links}`); + } + + if (this.isQT){ //IF THREAD IS A QUOTE TWEET, GET URL AND ADD TO EITHER HEADER OR FOOTER + debuglog("running quote tweet stuff",2); + await driver.findElement(By.xpath(this.x.quoteTweetContent)).sendKeys(webdriver.Key.CONTROL, webdriver.Key.ENTER);//OPEN QUOTE TWEET IN NEW TAB + this.parent = await driver.getWindowHandle(); + var windows = await driver.getAllWindowHandles(); + await driver.switchTo().window(windows[windows.length-1]).then(() => { //SWITCH TO NEW TAB WITH QUOTED TWEET + driver.getCurrentUrl().then(url => { + this.quoteLink = url.replace('://mobile.','://'); //MAKE MOBILE TWEET NON-MOBILE + const text = args.reQuotes //DETERMINE HOW TO FORMAT QUOTE LINK DEPENDING ON RELAVANT ARGUMENT + ? `Re: ${this.quoteLink}` + : `« Quoting ${this.quoteLink} »`; + args.reQuotes ? this.appendSection(text,'header') : this.appendSection(text,'footer'); //PLACE QUOTE LINK AT HEADER OR FOOTER OF TWEET + }); + driver.switchTo().window(this.parent);//SWITCH BACK TO ORIGINAL TAB + }); + await driver.switchTo().window(windows[windows.length-1]);//SWITCH TO NEW TAB AGAIN BECAUSE THAT'S THE ONLY WAY I COULD MAKE THIS PART WORK + await driver.close();//CLOSE NEW TAB + await driver.switchTo().window(this.parent);//SWITCH BACK TO ORIGINAL TAB... AGAIN + debuglog(`Tweet Header: ${this.header}`) + debuglog(`Tweet Footer: ${this.footer}`); + } + + if (this.hasVideo) {//IF TWEET HAS NON-POSTABLE MEDIA, APPEND FOOTER DETAILING SO + debuglog("running video stuff",2); + this.appendSection(`⚠ Original tweet had attachment(s) that couldn't be cross-posted. View it at ${homeTweet.url}`,'footer'); + debuglog(`Tweet Footer: ${this.footer}`); + } + } + + async downloadImages(driver,imgSavePath) { + if (this.hasSingleImage) { + debuglog(`${this.orig} Tweet #${this.no} contains a single image.`, 2) + this.imgCount = 1; + this.imgUrl = await elements.getAttribute(driver,this.x.singleImage,"src") + const jpgPath = `${imgSavePath}${this.orig == 'home' ? '' : 'r'}${this.no}.${this.imgCount}.jpg` + await funcs.downloadImage(this.imgUrl, jpgPath) + .then(debuglog) + .catch(console.error); + debuglog(`Downloaded ${this.imgCount} image from tweet #${this.no}.`, 2) + } else if (this.hasMultiImage) { + debuglog(`${this.orig} Tweet #${this.no} contains multiple images.`, 2) + this.imgCount = 0; + for (var x = 1; x < 3; x++) { + for (var y = 1; y < 3; y++) { + this.iterateExists = await elements.doesExist(driver,this.x.multiImages(x,y)); + if (this.iterateExists) { + debuglog(`${x},${y} Exists!`); + this.imgUrl = await elements.getAttribute(driver,this.x.multiImages(x,y),'src') + debuglog(this.imgUrl,2); + this.imgCount++ + const jpgPath = `${imgSavePath}${this.orig == 'home' ? '' : 'r'}${this.no}.${this.imgCount}.jpg` + await funcs.downloadImage(this.imgUrl, jpgPath) + .then(debuglog) + .catch(console.error); + } + } + } + debuglog(`Downloaded ${this.imgCount} images from tweet #${this.no}.`,1) + } + } + + async uploadImages(imgSavePath) { + if (this.hasImages) {debuglog("Uploading images to Mastodon...",1);} + for (var f = 1; f < (this.imgCount+1); f++) { + var jpgPath = `${imgSavePath}${this.orig == 'home' ? '' : 'r'}${this.no}.${f}.jpg` + debuglog(`uploading image to mastodon: ${jpgPath}`); + var imgid = await mastodon.postMedia(jpgPath) + debuglog(`mastodon image id: ${imgid}`); + this.imgArray.push(imgid); + } + } + + async printPreview(){ + const postPreviewMessage = `${format.success('Mastodon Post Preview:')} +╔${'═'.repeat(process.stdout.columns-2)}╗ +${this.text} +╚${'═'.repeat(process.stdout.columns-2)}╝`; + debuglog(postPreviewMessage, 1); + } +} + +module.exports = Tweets + + + + diff --git a/ref/classes/xpaths.js b/ref/classes/xpaths.js new file mode 100644 index 0000000..21d9070 --- /dev/null +++ b/ref/classes/xpaths.js @@ -0,0 +1,60 @@ +class TweetPaths { + constructor(orig,i) { + if (orig == 'home') { + this.timeLine = "//*[@id='react-root']/div/div/div[2]/main/div/div/div/div/div/div[3]/div/div/section/div/div"; //the immediate parent div of all tweets + } else if (orig == 'thread') { + this.timeLine = "/html/body/div[1]/div/div/div[2]/main/div/div/div/div[1]/div/section/div/div" //thread tweet xpath + } + this.tweet = (`${this.timeLine}/div`); //the div containing individual tweet content: (tweetXpath + '[1]') + this.containsDivs = (`${this.timeLine}[count(div) > 1]`) //timeline conntaining divs + this.path = `${this.tweet}[${orig == 'home' ? 1 : i}]`; + + //the following xpaths follow an individual tweet xpath: (tweetXpath + '[1]' + variableXPath) + this.urlCard = `${this.path}/div/div/div/article/div/div/div/div[*]/div[*]/div[*]/div[*]/div/div[2]/a` + this.tweeterHandle = `${this.path}/div/div/div/article/div/div/div/div[2]/div[2]/div[1]/div/div/div[1]/div/div/div[2]/div/div[1]/a/div/span[contains(text(),'@')]` /*text label containing tweeter's handle*/ + this.tweeterName = `${this.path}/div/div/div/article/div/div/div/div[2]/div[2]/div[1]/div/div/div[1]/div/div/div[1]/div/a/div/div[1]/span` /*text label containing tweeter's name*/ + this.quoteTweetHandle = `${this.path}/div/div/div/article/div/div/div/div[2]/div[2]/div[2]/div[2]/div[*]/div[2]/div/div[1]/div/div/div/div/div/div[2]/div[1]/div/div/div/span`; //xpath to text label that reveals if a tweet is a quote tweet (leads to the quote tweeted user's handle) + this.quoteTweetContent = `${this.path}/div/div/div/article/div/div/div/div[2]/div[2]/div[2]/div[2]/div[*]/div[2][div/div[1]/div/div/div/div/div/div[2]/div[1]/div/div/div/span]` /*xpath to locate entirety of Quote Tweeted Content*/ + + this.ageRestricted = `${this.path}/div/div/div/article//span/span[1]/span[contains(text(),'Age-restricted')]`; //xpath that reveals if tweet is age-restricted (& therefore not visible) + this.pinnedTweet = `${this.path}/div/div/div/article/div/div/div/div[1]/div/div/div/div/div[2]/div/div/div/span[contains(text(),'Pinned')]` /*//xpath that reveals if tweet is pinned*/ + + this.tweetText = `${this.path}//div[@data-testid='tweetText']`; //xpath that leads to div containing all tweet text + //this.emoji = this.path + "//img"; //xpath that leads to div containing all tweet text + this.tweetURL = `${this.path}//div[3]/a[contains(@href, 'status')]`; //xpath to tweet url + this.video = `${this.path}//div[1]//video`; //xpath that leads to video + this.singleImage = `${this.path}//div[1]/div/div/div/div/a/div/div[2]/div/img[@alt='Image']`; //xpath to image that reveals if a tweet has one image + this.multiImage = `${this.path}//div[2]/div[2]/div[2]/div[2]/div/div/div/div/div[2]/div/div[1]/div[1]//a/div/div/img[@alt='Image']`; //xpath to image that reveals if a tweet has more than one image + + if (orig == 'home') { //home timeline only + this.detectThread = `${this.path}/div/div/div/article/div/a/div/div[2]/div/span`; //xpath to text label that reveals if a tweet is a part of a thread from home timeline + this.detectRT = `${this.path}/div/div/div/article/div/div/div/div[1]/div/div/div/div/div[2]/div/div/div/a/span`; //xpath to text label that reveals if a tweet is a retweet + } else if (orig == 'thread'){ //thread timeline only + this.entryTweet = `${this.path}/div/div/div/article/div/div/div/div[3]/div[5]/div/div[1]/div/a` /*xpath that reveals if tweet is open in thread //openThreadTweetTSXPath*/ + } + + //the following xpaths follow an individual tweet xpath and are used to find all images in a tweet with multiple images: (tweetXpath + '[1]' + multiImage1XPath + x + multiImage2XPath + y + multiImage3XPath) + // the following combinations of x,y variables point to the corresponding image + // 1,1 = first image + // 2,1 = second image + // 2,2 = third image + // 1,2 = fourth image + this.multiImage1 = "//div[2]/div[2]/div[2]/div[2]/div/div/div/div/div[2]/div/div["; + this.multiImage2 = "]/div["; + this.multiImage3 = "]//a/div/div/img[@alt='Image']"; + } + tweetElement(i, pathFromTweet) { + let xPath = (this.path + pathFromTweet); + return xPath; + } + multiImages(x,y) { + let xPath = (this.path + this.multiImage1 + x + this.multiImage2 + y + this.multiImage3); + return xPath; + } +} + +module.exports = { TweetPaths } + + + + diff --git a/ref/functions/csv.js b/ref/functions/csv.js new file mode 100644 index 0000000..ac9b269 --- /dev/null +++ b/ref/functions/csv.js @@ -0,0 +1,45 @@ +const csvWriter = require('csv-write-stream'); +const fs = require('fs'); +const support = require('../functions/support.js'); +const debuglog = support.debuglog; + +async function initCSV(csvFN){ + writer = csvWriter({sendHeaders: false}); + writer.pipe(fs.createWriteStream(csvFN)); + writer.write({ + header1: 'URLs', + header2: 'IDs', + header3: 'Origin' + }); + writer.end(); +} + +async function openCSV(csvFN){ + await fs.readFile(csvFN, "utf-8", (err, data) => { + if (!err) { + return data; + } + }); + return output; +} +async function appendToCSV(url,id,orig,csvFN,fc){ + debuglog(`writing '${url}' to CSV!!`,2) + writer = csvWriter({sendHeaders: false}); + writer.pipe(fs.createWriteStream(csvFN, {flags: 'a'})); + debuglog(`file contents: ${fc}`); + if (!fc.includes(url)){ + writer.write({ + header1: url, + header2: id, + header3: orig + }); + } + writer.end(); +} + +module.exports = { initCSV,appendToCSV,openCSV }; + + + + + diff --git a/ref/functions/elements.js b/ref/functions/elements.js new file mode 100644 index 0000000..bf8f45e --- /dev/null +++ b/ref/functions/elements.js @@ -0,0 +1,37 @@ +const webdriver = require('selenium-webdriver'); +const By = webdriver.By; +const until = webdriver.until; + +async function doesExist(drvr,path){ + exists = drvr.findElement(By.xpath(path)).then(function() { + return true; // It existed + }, function(err) { + if (err instanceof webdriver.error.NoSuchElementError) { + return false; // It was not found + } + }); + return exists; +} + +async function waitFor(drvr,xpath,ms){ + await drvr.wait(until.elementLocated(By.xpath(xpath)), ms); +} + +async function getAttribute(drvr,xpath,attribute){ + return drvr.findElement(By.xpath(xpath)).getAttribute(attribute); +} + +async function getText(drvr,xpath){ + return drvr.findElement(By.xpath(xpath)).getText(); +} + +async function getElement(drvr,xpath){ + return drvr.findElement(By.xpath(xpath)); +} + +module.exports = { doesExist,waitFor,getAttribute,getText,getElement }; + + + + + diff --git a/ref/functions/functions.js b/ref/functions/functions.js new file mode 100644 index 0000000..507f28a --- /dev/null +++ b/ref/functions/functions.js @@ -0,0 +1,41 @@ +const fs = require('fs'); +const client = require('https'); +var { tall } = require('tall') + +function downloadImage(url, filepath) { + return new Promise((resolve, reject) => { + client.get(url, (res) => { + if (res.statusCode === 200) { + res.pipe(fs.createWriteStream(filepath)) + .on('error', reject) + .once('close', () => resolve(filepath)); + } else { + res.resume(); + reject(new Error(`Request Failed With a Status Code: ${res.statusCode}`)); + } + }); + }); +} + +async function expandUrl(shortUrl) { + try { + const unshortenedUrl = await tall(shortUrl); + return unshortenedUrl; + } catch (err) { + console.error('Error unshortening url: ', err) + return ""; + } + } + +function rand(min, max) { + return Math.floor( + Math.random() * (max - min + 1) + min + ) +} + +module.exports = { downloadImage,expandUrl,rand }; + + + + + diff --git a/ref/functions/mastodon.js b/ref/functions/mastodon.js new file mode 100644 index 0000000..807d6b2 --- /dev/null +++ b/ref/functions/mastodon.js @@ -0,0 +1,80 @@ +const fs = require('fs'); +const Masto = require('mastodon'); + +const support = require('../functions/support.js'); +const csv = require('../functions/csv.js'); +const debuglog = support.debuglog; +const funcs = require('../functions/functions.js'); +const Args = require('../classes/arguments.js'); +const args = new Args(); +const Formats = require('../classes/formats.js'); +const format = new Formats(); + +function setupMastodon(){ + const config = fs.readFileSync("./config.txt").toString().split(/[\r\n]+/); + var M = new Masto({ + access_token: config[0], + api_url: config[1] + }) + return M; +} + +async function postMedia(path){ + id = 0; + if (args.enablePosts){ + var M = setupMastodon(); + await M.post('media', { file: fs.createReadStream(path) }).then(resp => { + id = resp.data.id; + }, function(err) { + if (err) { + debuglog(err,0); + return "err"; + } + }) + } else if (args.forceCSV) { + return funcs.rand(1,100); + } + return id; +} + +async function postStatus(tweet,file,csvc){ + var id = 0; + if (args.enablePosts){ + var M = setupMastodon(); + params = { status: tweet.text } + debuglog(`${tweet.no} is a reply to ${tweet.prompt}`); + if (tweet.hasImages) {//POST HAS IMAGES + debuglog("post has images!!",2) + debuglog(`images array: ${tweet.imgArray}`,2) + Object.assign(params, { media_ids: tweet.imgArray }); + } + if (tweet.prompt != 0) {//POST IS A REPLY + debuglog("reply to: " + tweet.prompt,2) + Object.assign(params, { in_reply_to_id: tweet.prompt }); + } + await M.post('statuses', params, (err, data) => { + if (err) { + debuglog(format.error(`Post to Mastodon failed with error: ${err}`), 1); + return "err"; + } else { + //ADD TWEET TO CSV TO PREVENT FUTURE PROCESSING + csv.appendToCSV(tweet.url,data.id,tweet.orig,file,csvc); + debuglog(`posted to mastodon and got back id: ${data.id}`); + debuglog(format.bold(`Successfully posted ${tweet.url} to Mastodon!`),1); + id = data.id; + } + }) + } else if (args.forceCSV) { + var fakeID = funcs.rand(1,100); + csv.appendToCSV(tweet.url,fakeID,(`forced ${tweet.orig}`),file,csvc); + id = fakeID; + } + return id; +} + +module.exports = { postMedia,postStatus }; + + + + + diff --git a/ref/functions/support.js b/ref/functions/support.js new file mode 100644 index 0000000..5d6e264 --- /dev/null +++ b/ref/functions/support.js @@ -0,0 +1,87 @@ +const fs = require('fs'); +const Args = require('../classes/arguments.js'); +const args = new Args(); + +const Formats = require('../classes/formats.js'); +const format = new Formats(); + +function printHelp() { //PRINT USAGE TO CONSOLE + const usageText = fs.readFileSync('./usage.txt', 'utf-8'); + const formattedUsage = usageText.replace(/{([^{}]+)}/g, format.bold('$1')) + .replace(/~([^~]+)~/g, format.underline('$1')) + .replace(/<([^<>]+)>/g, format.italic('$1')) + .replace(/(\r\n|\r|\n)/g, '\n░ '); + debuglog(formattedUsage,1); +} + +function logArguments() {//PRINT ARGUMENTS TO CONSOLE + debuglog("Settings: ", 2); + debuglog(`-h help: ${args.help}`, 2); + debuglog(`-q quotes: ${args.enableQuotes}`, 2); + debuglog(`-t threads: ${args.enableThreads}`, 2); + debuglog(`-b displayBrowser: ${args.displayBrowser}`, 2); + debuglog(`-p enablePosts: ${args.enablePosts}`, 2); + debuglog(`-c forceCSV: ${args.forceCSV}`, 2); + debuglog(`-m printMeta: ${args.printMeta}`, 2); + debuglog(`-u userName: ${args.userName}`, 2); + debuglog(`-n tweetCount: ${args.tweetCount}`, 2); + debuglog(`-d debug: ${args.debug}`, 2); + debuglog(`-w timeout: ${args.timeOut}`, 2); + + debuglog(`Scraping ${format.bold(args.tweetCount)} tweet(s) from ${format.bold(`@${args.userName}`)}...`, 1); + debuglog(`Browser is${args.displayBrowser ? "" : " not"} visible`, 1); + debuglog(`Tweets${args.enableQuotes ? ", Quote" : ""}${args.enableThreads ? ", Thread" : ""} Tweets will${args.enablePosts ? "" : " not"} be posted to Mastodon`, 1); + debuglog(`Tweet URLs will${args.forceCSV ? "" : " not"} be forcibly added to CSV file`, 1); + debuglog(`Name, handle, and URL will${args.printMeta ? "" : " not"} be added to the body text`, 1); +} + + +function debuglog(debugString,logLevel = 2) {//CUSTOM CONSOLE LOG THAT ALLOWS USER-SET DEBUG OUTPUT LEVELS + const prefixes = { + 0: " ", + 1: "░", + 2: "█", + }; + const prefix = prefixes[logLevel]; + if (logLevel <= args.debug) { + console.log(`${prefix} ${debugString}`); + } +} + +function validateArgs() { + if (args.help) { + printHelp(); + process.exit(0); + } + + const userNameRegex = /^@?(\w){1,15}$/g; + const usernameError = format.error("Uh-oh! It seems like the username doesn't work! Make sure you're entering the user's handle as it appears on-screen."); + const helpText = format.notice("For help: $node ./TwitToMast.js -h"); + const tweetCountError = format.error(`Expected Integer greater than 0, got '${args.tweetCount}' instead`); + const debugError = format.error(`Expected 0-2, got '${args.debug}' instead`); + + if (!userNameRegex.test(args.userName)) { + debuglog(usernameError, 0); + debuglog(helpText, 0); + process.exit(1); + } + + if (args.tweetCount < 1) { + debuglog(tweetCountError, 0); + debuglog(helpText, 0); + process.exit(1); + } + + if (args.debug < 0 || args.debug > 2) { + debuglog(debugError, 0); + debuglog(helpText, 0); + process.exit(1); + } + } + +module.exports = { printHelp,logArguments,debuglog,validateArgs }; + + + + + diff --git a/usage.txt b/usage.txt new file mode 100644 index 0000000..281343d --- /dev/null +++ b/usage.txt @@ -0,0 +1,42 @@ + +{Usage} + {node ./TwitToMast.js} [{-htqrpmbc}] [{-u} ~username~] [{-n} ~tweetcount~] [{-d} ~debuglevel~] [{-w} ~timeout~] + {node ./multi.js} [{-htqrpmbc}] [{-n} ~tweetcount~] [{-d} ~debuglevel~] [{-w} ~timeout~] + +{Arguments} + {-h:} - show help screen (you made it here!) + {-u:} ~username~ + - the twitter handle of the user whose account will be scraped + <- defaults to 'Twitter' (@twitter)> + {-n:} ~tweetcount~ + - the number of enabled tweets that will be scraped from the targeted account + <- defaults to 5> + {-t:} - tweets that are part of threads will be included in the scan + {-q:} - quote tweets will be included in the scan + {-r:} - Link to quoted tweet will appear in the header, preceded by "re: " + - default behavior posts link at bottom of Mastodon post preceded by "Quoting " + {-p:} - enable/disable posting to Mastodon + {-m:} - include user's name, handle, and link to tweet + {-b:} - display browser (disable headless mode) + {-c:} - force URL to be logged to file if posts are disabled + {-d:} ~debuglevel~ + - amount of information to print to console + <0: only errors> + <1: current task + tweet Text (default)> + <2: pretty much everything> + {-w:} ~timeout~ + - length of time (in ms) to wait for page elements to load + <- defaults to 30000 (30 seconds)> + +{config.txt} + {Line 1: API_KEY} + - Your Access Token obtained from Mastodon > Preferences > Development > Application + {Line 2: API_URL} + - https://~your mastodon server url~/api/v1/ + +{Examples} + {Scrape 10 most recent tweets, quote tweets, and thread tweets from @twitter account, and post to Mastodon} + $node ./TwitToMast.js -qtp -u twitter -n 10 + {Scrape 10 most recent tweets, quote tweets, and thread tweets from accounts listed in usernameslist.txt, and post to Mastodon} + $node ./multi.js -qtp -n 10 + diff --git a/usernameslist.txt b/usernameslist.txt index b330850..1c412b9 100644 --- a/usernameslist.txt +++ b/usernameslist.txt @@ -9,4 +9,4 @@ TwitterBlue TwitterDesign TwitterEng Policy -TwitterDev +TwitterDev \ No newline at end of file