diff --git a/avatars_reccommendations_1707315582744.jpg b/avatars_reccommendations_1707315582744.jpg new file mode 100644 index 0000000..58b704a Binary files /dev/null and b/avatars_reccommendations_1707315582744.jpg differ diff --git a/helpers/libs/utils.mjs b/helpers/libs/utils.mjs index b153cdb..d411594 100644 --- a/helpers/libs/utils.mjs +++ b/helpers/libs/utils.mjs @@ -1,51 +1,48 @@ -import Masto from "mastodon"; -import dotenv from "dotenv"; -import sharp from 'sharp'; -import fs from 'fs'; -import https from 'https'; -import moment from "moment"; - -import Parser from 'rss-parser'; +import Masto from 'mastodon' +import dotenv from 'dotenv' +import sharp from 'sharp' +import fs from 'fs' +import https from 'https' +import moment from 'moment' +import Parser from 'rss-parser' +import { load } from 'cheerio' let local_node_env_conf = dotenv.config() -const myArgs = process.argv.slice(2); -export const reallySendPost = hasCliArgument('--force'); +const myArgs = process.argv.slice(2) +export const reallySendPost = hasCliArgument('--force') export const folderBlogPostsPreview = process.cwd() + '/assets/blog_posts_medias/' - -export function randomIntFromInterval(min, max) { // min and max included - return Math.floor(Math.random() * (max - min + 1) + min) | 1 +export function randomIntFromInterval (min, max) { // min and max included + return Math.floor(Math.random() * (max - min + 1) + min) | 1 } -export function getRandomElementOfArray(listItems) { - return listItems[Math.floor(Math.random() * listItems.length)] +export function getRandomElementOfArray (listItems) { + return listItems[Math.floor(Math.random() * listItems.length)] } - let nowDate = new Date() export let defaultConfigMasto = { - author: 'curator', - visibility: 'public', - language: 'fr', - sensitive: false, - disable_slugify: false, - reallySendPost, - image: '', - folder_image: process.cwd() + '/assets/blog_posts_medias/', - message: "Hey coucou! on est le" + nowDate, - scheduled_at: "", - scheduled_at_bool: false, - content_type: "text/markdown", - website: 'qzine', - slug: 'default_post_title', - postObject: {}, + author: 'curator', + visibility: 'public', + language: 'fr', + sensitive: false, + disable_slugify: false, + reallySendPost, + image: '', + folder_image: process.cwd() + '/assets/blog_posts_medias/', + message: 'Hey coucou! on est le' + nowDate, + scheduled_at: '', + scheduled_at_bool: false, + content_type: 'text/markdown', + website: 'qzine', + slug: 'default_post_title', + postObject: {}, } - -export function tokenForAuthorIsPresentInDotEnv(author) { - return process.env['TOKEN_' + author.toUpperCase()]; +export function tokenForAuthorIsPresentInDotEnv (author) { + return process.env['TOKEN_' + author.toUpperCase()] } /** @@ -53,13 +50,13 @@ export function tokenForAuthorIsPresentInDotEnv(author) { * @param userNickName * @returns {Mastodon} */ -export function createMastoFetcherWithAuthorLogin(userNickName) { - let accessToken = process.env['TOKEN_' + userNickName.toUpperCase()] - const masto = new Masto({ - access_token: accessToken, - api_url: process.env.INSTANCE_MASTODON + '/api/v1/', - }); - return masto; +export function createMastoFetcherWithAuthorLogin (userNickName) { + let accessToken = process.env['TOKEN_' + userNickName.toUpperCase()] + const masto = new Masto({ + access_token: accessToken, + api_url: process.env.INSTANCE_MASTODON + '/api/v1/', + }) + return masto } /** @@ -67,140 +64,139 @@ export function createMastoFetcherWithAuthorLogin(userNickName) { * @param config * @returns {*} */ -export default function sendPostMastodon(config) { +export default function sendPostMastodon (config) { - // console.log('send post', config.postObject.post_guid , config.postObject.guid ) - // override defaults with input argument - config = { - ...defaultConfigMasto, - ...config, - } + // console.log('send post', config.postObject.post_guid , config.postObject.guid ) + // override defaults with input argument + config = { + ...defaultConfigMasto, + ...config, + } - // console.log("sendPostMastodon config", config) + // console.log("sendPostMastodon config", config) - if (!config.reallySendPost) { + if (!config.reallySendPost) { - console.log("\n\n =========== le message ne sera PAS réellement posté sur le compte @" + config.author + "@" + process.env.INSTANCE_MASTODON + " =========== \n") - // console.log('configPost.folder_image', config.folder_image) - console.log('config', config.message) - } else { + console.log('\n\n =========== le message ne sera PAS réellement posté sur le compte @' + config.author + '@' + process.env.INSTANCE_MASTODON + ' =========== \n') + // console.log('configPost.folder_image', config.folder_image) + console.log('config', config.message) + } else { - console.log(" ") - if (process.env.INSTANCE_MASTODON && tokenForAuthorIsPresentInDotEnv(config.author)) { + console.log(' ') + if (process.env.INSTANCE_MASTODON && tokenForAuthorIsPresentInDotEnv(config.author)) { - let visibility = 'public'; - let language = 'fr'; - let sensitive = false; + let visibility = 'public' + let language = 'fr' + let sensitive = false - let accessToken = process.env['TOKEN_' + config.author.toUpperCase()] - const masto = new Masto({ - access_token: accessToken, - api_url: process.env.INSTANCE_MASTODON + '/api/v1/', - }); + let accessToken = process.env['TOKEN_' + config.author.toUpperCase()] + const masto = new Masto({ + access_token: accessToken, + api_url: process.env.INSTANCE_MASTODON + '/api/v1/', + }) - let params = { - status: config.message, - visibility, - language, - sensitive - } - if (config.cw) { - params['spoiler_text'] = config.cw - } - if (config.scheduled_at && config.scheduled_at_bool) { - let dateschedule = new Date(config.scheduled_at) - params['scheduled_at'] = dateschedule.toISOString() - } + let params = { + status: config.message, + visibility, + language, + sensitive + } + if (config.cw) { + params['spoiler_text'] = config.cw + } + if (config.scheduled_at && config.scheduled_at_bool) { + let dateschedule = new Date(config.scheduled_at) + params['scheduled_at'] = dateschedule.toISOString() + } - /** - * envoi sans fichier joint - */ - if (!config.image) { - console.log('pas d image dans la config') + /** + * envoi sans fichier joint + */ + if (!config.image) { + console.log('pas d image dans la config') - if (config.reallySendPost) { + if (config.reallySendPost) { - masto.post('statuses', params).then(rep => { + masto.post('statuses', params).then(rep => { - console.log("posté, yay!") - }, err => { - console.error(err) - }) - } - } + console.log('posté, yay!') + }, err => { + console.error(err) + }) + } + } - /** - * envoi avec fichier, - * on doit d'abord faire un upload du fichier, - * puis relier son id de média au nouveau post. - */ - else if (config.image) { + /** + * envoi avec fichier, + * on doit d'abord faire un upload du fichier, + * puis relier son id de média au nouveau post. + */ + else if (config.image) { - var id; - console.log("envoi du média", config.image) - // upload new media - return masto.post('media', {file: fs.createReadStream(config.image)}) - .then(resp => { - id = resp.data.id; - params.media_ids = [id] - console.log("\n ✅ image, id", id) - masto.post('statuses', params).then(rep => { - // console.log('rep', rep) - console.log("\n ✅ posté avec une nouvelle image, WOOT") - }, err => { - console.error(err) + var id + console.log('envoi du média', config.image) + // upload new media + return masto.post('media', { file: fs.createReadStream(config.image) }) + .then(resp => { + id = resp.data.id + params.media_ids = [id] + console.log('\n ✅ image, id', id) + masto.post('statuses', params).then(rep => { + // console.log('rep', rep) + console.log('\n ✅ posté avec une nouvelle image, WOOT') + }, err => { + console.error(err) - console.log("erreur T_T") - }) - }) - } + console.log('erreur T_T') + }) + }) + } - // } + // } - } else { - console.error(`pas de token pour l'auteur "${config.author}" ou pas d'instance mastodon définie`) - } + } else { + console.error(`pas de token pour l'auteur "${config.author}" ou pas d'instance mastodon définie`) + } - } + } } // Slugify a string -export function slugify(str) { - str = str.replace(/^\s+|\s+$/g, ''); +export function slugify (str) { + str = str.replace(/^\s+|\s+$/g, '') - // Make the string lowercase - str = str.toLowerCase(); + // Make the string lowercase + str = str.toLowerCase() - // Remove accents, swap ñ for n, etc - var from = "ÁÄÂÀÃÅČÇĆĎÉĚËÈÊẼĔȆÍÌÎÏŇÑÓÖÒÔÕØŘŔŠŤÚŮÜÙÛÝŸŽáäâàãåčçćďéěëèêẽĕȇíìîïňñóöòôõøðřŕšťúůüùûýÿžþÞĐđßÆa·/_,:;"; - var to = "AAAAAACCCDEEEEEEEEIIIINNOOOOOORRSTUUUUUYYZaaaaaacccdeeeeeeeeiiiinnooooooorrstuuuuuyyzbBDdBAa------"; - for (var i = 0, l = from.length; i < l; i++) { - str = str.replace(new RegExp(from.charAt(i), 'g'), to.charAt(i)); - } + // Remove accents, swap ñ for n, etc + var from = 'ÁÄÂÀÃÅČÇĆĎÉĚËÈÊẼĔȆÍÌÎÏŇÑÓÖÒÔÕØŘŔŠŤÚŮÜÙÛÝŸŽáäâàãåčçćďéěëèêẽĕȇíìîïňñóöòôõøðřŕšťúůüùûýÿžþÞĐđßÆa·/_,:;' + var to = 'AAAAAACCCDEEEEEEEEIIIINNOOOOOORRSTUUUUUYYZaaaaaacccdeeeeeeeeiiiinnooooooorrstuuuuuyyzbBDdBAa------' + for (var i = 0, l = from.length; i < l; i++) { + str = str.replace(new RegExp(from.charAt(i), 'g'), to.charAt(i)) + } - // Remove invalid chars - str = str.replace(/[^a-z0-9 -]/g, '') - // Collapse whitespace and replace by - - .replace(/\s+/g, '-') - // Collapse dashes - .replace(/-+/g, '-'); + // Remove invalid chars + str = str.replace(/[^a-z0-9 -]/g, '') + // Collapse whitespace and replace by - + .replace(/\s+/g, '-') + // Collapse dashes + .replace(/-+/g, '-') - return str; + return str } - /** * @name listFilesOfFolder * lister les noms de fichier que l'on peut publier dans un dossier. * retourne un tableau */ -export function listFilesOfFolder(folderPath) { - let filesNames = [] - fs.readdirSync(folderPath).map(fileName => { - return filesNames.push(fileName); - }); +export function listFilesOfFolder (folderPath) { + let filesNames = [] + fs.readdirSync(folderPath).map(fileName => { + return filesNames.push(fileName) + }) - return filesNames; + return filesNames } /** @@ -208,14 +204,14 @@ export function listFilesOfFolder(folderPath) { * crée un dossier d'assets, avec ses sous dossiers not_published et published si ils manquent. * une fois que l'on prendra une image dans le dossier non publié, on la déplacera dans le dossier des images publées. */ -export function initializeFolderForPictures(folderName) { - try { - if (!fs.existsSync(folderName)) { - fs.mkdirSync(folderName); - } - } catch (err) { - console.error(err); - } +export function initializeFolderForPictures (folderName) { + try { + if (!fs.existsSync(folderName)) { + fs.mkdirSync(folderName) + } + } catch (err) { + console.error(err) + } } /** @@ -223,36 +219,36 @@ export function initializeFolderForPictures(folderName) { * @param htmlContent * @returns {string} */ -export function findFirstImageInContent(htmlContent = '') { - let result = '' - let foundPictures = htmlContent.match(/]*?src\s*=\s*['\"]([^'\"]*?)['\"][^>]*?>/); - let first = ''; - if (foundPictures && foundPictures[0]) { +export function findFirstImageInContent (htmlContent = '') { + let result = '' + let foundPictures = htmlContent.match(/]*?src\s*=\s*['\"]([^'\"]*?)['\"][^>]*?>/) + let first = '' + if (foundPictures && foundPictures[0]) { - first = foundPictures[0] + first = foundPictures[0] - } else { - console.log('pas d image trouvée dans le contenu ', htmlContent) - } - if (first) { - result = first.match(/src\=\"(.*)\"/i) - if (result.length && result[0]) { - result = result[0].split('"') - result = result[1] - } - } - result = clearLink(result) - console.log('clearLink', result) - return result; + } else { + console.log('pas d image trouvée dans le contenu ', htmlContent) + } + if (first) { + result = first.match(/src\=\"(.*)\"/i) + if (result.length && result[0]) { + result = result[0].split('"') + result = result[1] + } + } + result = clearLink(result) + console.log('clearLink', result) + return result } -function clearLink(linkString) { - linkString = linkString.replace('http:', 'https:') - linkString = linkString.replace('https://www.ailesse.info/~tykayn/bazar/kotlife', 'https://www.tykayn.fr/wp-content/uploads/i/kotlife') - linkString = linkString.replace('https://blog.artlemoine.com/public/i', 'https://www.tykayn.fr/wp-content/uploads/i') - linkString = linkString.replace('https://www.ailesse.com/%7Etykayn/bazar', 'https://www.tykayn.fr/wp-content/uploads/i/bazar') +function clearLink (linkString) { + linkString = linkString.replace('http:', 'https:') + linkString = linkString.replace('https://www.ailesse.info/~tykayn/bazar/kotlife', 'https://www.tykayn.fr/wp-content/uploads/i/kotlife') + linkString = linkString.replace('https://blog.artlemoine.com/public/i', 'https://www.tykayn.fr/wp-content/uploads/i') + linkString = linkString.replace('https://www.ailesse.com/%7Etykayn/bazar', 'https://www.tykayn.fr/wp-content/uploads/i/bazar') - return linkString + return linkString } /** @@ -264,25 +260,25 @@ function clearLink(linkString) { * @param filepath * @returns {Promise} */ -export function downloadImage(url, filepath) { - return new Promise((resolve, reject) => { - const options = { - headers: {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 Edg/107.0.1418.52"} - }; +export function downloadImage (url, filepath) { + return new Promise((resolve, reject) => { + const options = { + headers: { 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 Edg/107.0.1418.52' } + } - https.get(url, options, (res) => { - if (res.statusCode === 200) { - res.pipe(fs.createWriteStream(filepath)) - .on('error', reject) - .once('close', () => resolve(filepath)); - } else { - // Consume response data to free up memory - res.resume(); - reject(new Error(`Request Failed With a Status Code: ${res.statusCode}; \n ${res.statusMessage} `)); + https.get(url, options, (res) => { + if (res.statusCode === 200) { + res.pipe(fs.createWriteStream(filepath)) + .on('error', reject) + .once('close', () => resolve(filepath)) + } else { + // Consume response data to free up memory + res.resume() + reject(new Error(`Request Failed With a Status Code: ${res.statusCode}; \n ${res.statusMessage} `)) - } - }); - }); + } + }) + }) } /** @@ -293,124 +289,238 @@ export function downloadImage(url, filepath) { * @returns {Promise} * @constructor */ -export function CropPicture(pictureName, width = 500, height = 300) { +export function CropPicture (pictureName, width = 500, height = 300) { - return sharp(pictureName) + return sharp(pictureName) - .extract({left: 0, top: 0, width, height}) - .toFile('thumb_' + pictureName, function (err) { - if (err) console.log(err); - }); + .extract({ left: 0, top: 0, width, height }) + .toFile('thumb_' + pictureName, function (err) { + if (err) console.log(err) + }) } /** * prendre un post parmi tous ceux du blog, dans ceux qui ont été publiés * @returns {*} */ -export function getRandomLinkGeneral(tkpostsjson) { - let filteredLinks = [] - if (tkpostsjson[0].post_status) { +export function getRandomLinkGeneral (tkpostsjson) { + let filteredLinks = [] + if (tkpostsjson[0].post_status) { - filteredLinks = tkpostsjson.filter(elem => elem.post_status === 'publish') - } else if (tkpostsjson[0].status) { - filteredLinks = tkpostsjson.filter(elem => elem.status === 'publish') - } - return getRandomElementOfArray(filteredLinks) + filteredLinks = tkpostsjson.filter(elem => elem.post_status === 'publish') + } else if (tkpostsjson[0].status) { + filteredLinks = tkpostsjson.filter(elem => elem.status === 'publish') + } + return getRandomElementOfArray(filteredLinks) } - /** * trouver l'image du contenu si il y en a * @param postContent * @param configPost */ -export function findPictureAndSendPost(postContent, configPost) { +export function findPictureAndSendPost (postContent, configPost) { - let firstPictureSource = findFirstImageInContent(postContent); + let firstPictureSource = findFirstImageInContent(postContent) + let filePathForDownloadedImage = `${configPost.folder_image}_${configPost.website}_media_post_${slugify(configPost.slug)}.jpg` - let filePathForDownloadedImage = `${configPost.folder_image}_${configPost.website}_media_post_${slugify(configPost.slug)}.jpg` + if (firstPictureSource) { + console.log('firstPictureSource found', firstPictureSource) - if (firstPictureSource) { - console.log("firstPictureSource found", firstPictureSource) + // check if picture already exist + console.log('on envoie le média et l image : ', filePathForDownloadedImage) + downloadImage(firstPictureSource, filePathForDownloadedImage) + .then((res) => { + // suite du poste avec upload d'image - // check if picture already exist - console.log('on envoie le média et l image : ', filePathForDownloadedImage) - downloadImage(firstPictureSource, filePathForDownloadedImage) - .then((res) => { - // suite du poste avec upload d'image + console.log('média téléchargé, on envoie le post') + configPost.image = filePathForDownloadedImage - console.log('média téléchargé, on envoie le post') - configPost.image = filePathForDownloadedImage; + sendPostMastodon(configPost) - sendPostMastodon(configPost) + }, + (err) => { + console.log('pas dimage trouvée pour l URL ', firstPictureSource, err) + sendPostMastodon(configPost) + } + ) + .catch((err) => { + console.log('erreur avec cette URL ', firstPictureSource, err) + sendPostMastodon(configPost) + }) + } else { - }, - (err) => { - console.log('pas dimage trouvée pour l URL ', firstPictureSource, err) - sendPostMastodon(configPost) - } - ) - .catch((err) => { - console.log('erreur avec cette URL ', firstPictureSource, err) - sendPostMastodon(configPost) - }) - } else { + // no image provided - // no image provided - - console.log("pas d'image dans le corps du texte", configPost.image) - // on envoie avec l'image par défaut - sendPostMastodon(configPost) - } + console.log('pas d\'image dans le corps du texte', configPost.image) + // on envoie avec l'image par défaut + sendPostMastodon(configPost) + } } - /** * find cli argument * @param argument * @returns {boolean} */ -export function hasCliArgument(argument) { - return myArgs.indexOf(argument) !== -1 +export function hasCliArgument (argument) { + return myArgs.indexOf(argument) !== -1 } +let parser = new Parser() -let parser = new Parser(); +export function diffDaysBetweenTwoDates (date1, date2) { - -export function diffDaysBetweenTwoDates(date1, date2) { - - const a = moment(date1); - const b = moment(date2); - return a.diff(b, 'days'); + const a = moment(date1) + const b = moment(date2) + return a.diff(b, 'days') } - -export function filterRegionAgendaDuLibreEvents(events_list, filter_critera) { - let selection = [] - events_list.forEach(item => { - if (item.region_id == filter_critera) { - selection.push(item) - } - }) - return selection; +export function filterRegionAgendaDuLibreEvents (events_list, filter_critera) { + let selection = [] + events_list.forEach(item => { + if (item.region_id == filter_critera) { + selection.push(item) + } + }) + return selection } -moment.locale('fr'); +moment.locale('fr') -export function groupEventsByDay(events_list) { - let selection = {} - events_list.forEach(item => { +export function groupEventsByDay (events_list) { + let selection = {} + events_list.forEach(item => { - let formattedDay = moment(item.start_time).format('dddd DD') + let formattedDay = moment(item.start_time).format('dddd DD') + + if (!selection[formattedDay]) { + selection[formattedDay] = [] + } + selection[formattedDay].push(item) + }) + return selection +} + +export function convertHTMLtoMD (htmlContent) { + const $ = load(htmlContent) + + translateNode($) + + return $.html() +} + +export function translateNode ($) { + const elementsToTranslate = [ + { tag: 'h1', mdTag: '##' }, + { tag: 'h2', mdTag: '###' }, + { tag: 'h3', mdTag: '####' }, + { tag: 'h4', mdTag: '#####' }, + { tag: 'h5', mdTag: '######' }, + { tag: 'p', mdTag: '\n\n' }, + { tag: 'ul', preserveChildren: true, transformChild: ($child) => '\n- ' + $.text($child) }, + { tag: 'ol', preserveChildren: true, transformChild: ($child, idx) => `\n${idx + 1}. ${$.text($child)}` }, + { tag: 'a', parseAttr: ('href', link => `[${link}](${link})`) }, + { tag: 'strong', mdFormat: '$&' }, + { tag: 'em', mdFormat: '_$&_' }, + { tag: 'code', mdFormat: '`$&`' }, + ] + + elementsToTranslate.forEach(element => { + $(element.tag).each((_, el) => { + const $el = $(el) + if (element.parseAttr) { + const attrVal = $el.attr(element.parseAttr[0]) + if (attrVal) { + $el.replaceWith(element.parseAttr[1](attrVal)) + } else { + $el.remove() + } + } else if (element.transformChild) { + $el.contents().filter(() => !!this.parent()).each((_, childEl) => { + const transformedText = element.transformChild($(childEl), $el.index()) + $el.before('\n' + transformedText) + }) + $el.remove() + } else { + $el.replaceWith(element.mdTag + $el.text() + element.mdFormat) + } + }) + }) +} + +export function getRequestOptions (host, port, path) { + const options = { + host: host, + port: port, + path: path, + method: 'GET', + headers: { + Accept: 'application/activity+json', + 'User-Agent': 'MyApp/1.0.0 (contact@myemail.org)', + }, + } + + return options +} + +export async function sendGetRequest (options) { + return new Promise((resolve, reject) => { + const req = http.request(options, (res) => { + let body = Buffer.alloc(0) + + res.on('data', (chunk) => { + body = Buffer.concat([body, chunk]) + }) + + res.on('end', () => { + resolve(JSON.parse(body.toString())) + }) + }) + + req.on('error', (err) => { + reject(err) + }) + + req.end() + }) +} + +const splitTextIntoChunks = (text, limit) => { + const words = text.trim().split(/\s+/g) + const chunks = [] + let currentChunk = [] + let wordCount = 0 + + for (const word of words) { + if (wordCount + word.length > limit) { + chunks.push(currentChunk.join(' ')) + currentChunk = [word] + wordCount = word.length + } else { + currentChunk.push(word) + wordCount += word.length + 1 + } + } + + if (currentChunk.length > 0) { + const joinedWords = currentChunk.join(' ') + chunks.push(joinedWords.length <= limit ? joinedWords : joinedWords.substr(0, limit) + '...') + } + + return chunks +} + +export function splitLongDescription (text, limit) { + let chunks = splitTextIntoChunks(text, limit) + if (chunks) { + if (chunks[0]) { + return chunks[0] + } + return '' + } +} - if (!selection[formattedDay]) { - selection[formattedDay] = [] - } - selection[formattedDay].push(item) - }) - return selection; -} \ No newline at end of file diff --git a/helpers/wip/recommandations_curator.mjs b/helpers/wip/recommandations_curator.mjs deleted file mode 100644 index 8a509c1..0000000 --- a/helpers/wip/recommandations_curator.mjs +++ /dev/null @@ -1,83 +0,0 @@ - -import sendPostMastodon, { - getArticlesFromDaysInRssFeed, - makeTitleContentFromRss, - parseRssFeed, -} from "./libs/utils.mjs"; - -// const afis_rss_feed_url = 'https://afis.org/rss.xml'; -// const days_back_in_rss_feed = 7; - -async function postLink() { - - - // selectionner un compte parmi les gens suivis dans une liste - - // export des abonnements utilisateur https://mastodon.cipherbliss.com/settings/exports/follows.csv/home/cipherbliss/Nextcloud/inbox/following_accounts.csv - // ; rel="next", ; rel="prev" - // https://mastodon.cipherbliss.com/api/v1/accounts/relationships?id[]=109484382634211819&id[]=109280269336881811&id[]=109280889310776283&id[]=109248504398682634&id[]=109310268216721885&id[]=109916178850231009&id[]=109541053771316772&id[]=151980&id[]=80685&id[]=106835252230809041&id[]=109167546376395742&id[]=109791782092094822&id[]=109770197347890560&id[]=109768052505508503&id[]=108202891614303950&id[]=109749045115736569&id[]=109739290485102920&id[]=109330282577556324&id[]=109280646010767217&id[]=109722335836985403&id[]=109542013632346871&id[]=109278739925137927&id[]=109659515794606337&id[]=109292570383233152&id[]=109660244192213202&id[]=109303521370666602&id[]=109523867267929049&id[]=109643780720044907&id[]=109386436202793665&id[]=109501996699619458&id[]=109632939061534470&id[]=109621031128728719&id[]=109620790782200477&id[]=139144&id[]=109592762903342668&id[]=109603261782470086&id[]=109591788539379136&id[]=109570049875530270&id[]=109381927764082328&id[]=109554213128019255 -// exemple d'account: - /** - { - "id": "109484382634211819", - "username": "GalmeshRosewood", - "acct": "GalmeshRosewood@mastodon.art", - "display_name": "Galmesh Rosewood", - "locked": false, - "bot": false, - "discoverable": true, - "group": false, - "created_at": "2022-12-05T00:00:00.000Z", - "note": "

I'm Galmesh Rosewood and I want to be a lewd artist. (It's a Monkey Island ref). Male from France. Some content won't be family-friendly.

", - "url": "https://mastodon.art/@GalmeshRosewood", - "avatar": "https://mastodon.cipherbliss.com/system/cache/accounts/avatars/109/484/382/634/211/819/original/4d3c4ded9ae95202.jpg", - "avatar_static": "https://mastodon.cipherbliss.com/system/cache/accounts/avatars/109/484/382/634/211/819/original/4d3c4ded9ae95202.jpg", - "header": "https://mastodon.cipherbliss.com/system/cache/accounts/headers/109/484/382/634/211/819/original/5b1822520e4ae3b3.png", - "header_static": "https://mastodon.cipherbliss.com/system/cache/accounts/headers/109/484/382/634/211/819/original/5b1822520e4ae3b3.png", - "followers_count": 762, - "following_count": 195, - "statuses_count": 327, - "last_status_at": "2023-03-04", - "emojis": [], - "fields": [ - { - "name": "Linktree", - "value": "https://linktr.ee/galmeshrosewood", - "verified_at": null - } - ] - } - */ - - // faire un repost de média - // POST /api/v1/statuses/109965725969165853/reblog - - // autre action: - // faire une liste de recommandation de 3 gens à follow au hasard pris dans cette liste, - // avec en image attachée un des médias postés par les comptes en question - - -// console.log("envoi de post des articles afis sciences publiés depuis " + days_back_in_rss_feed + " jours par le compte afis91") -// -// let parsedFeed = await parseRssFeed(afis_rss_feed_url) -// let articles = await getArticlesFromDaysInRssFeed(parsedFeed, days_back_in_rss_feed) -// console.log('articles', articles) -// let contentOfPost = 'Articles des ' + days_back_in_rss_feed + ' derniers jours sur le site web de l\'AFIS: \n' -// + makeTitleContentFromRss(articles) -// -// let configPost = { -// author: 'afis91', -// website: 'afis.org', -// // disable_slugify: true, -// slug: "afis_picture", -// content_type: "text/markdown", -// folder_image: process.cwd() + '/assets/', -// image: "afis_picture_of_the_day.jpg", -// message: `# ${contentOfPost} -// -// #afis #science #pseudoScience #hebdo`, -// } -// sendPostMastodon(configPost) -} - -postLink(); \ No newline at end of file diff --git a/package.json b/package.json index fa74f98..bc6c7a5 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "express": "~4.16.1", "http-errors": "~1.6.3", "jade": "~1.11.0", + "jimp": "^0.22.10", "mastodon": "^1.2.2", "moment": "^2.29.4", "morgan": "~1.9.1", @@ -26,7 +27,7 @@ "webpage": "^0.3.0" }, "devDependencies": { - "axios": "^1.6.2", + "axios": "^1.6.7", "cheerio": "^1.0.0-rc.12", "fs": "^0.0.1-security", "https": "^1.0.0", diff --git a/helpers/wip/curation_following_recommendation.mjs b/wip/curation_following_recommendation.mjs similarity index 100% rename from helpers/wip/curation_following_recommendation.mjs rename to wip/curation_following_recommendation.mjs diff --git a/helpers/wip/curation_image_random.mjs b/wip/curation_image_random.mjs similarity index 100% rename from helpers/wip/curation_image_random.mjs rename to wip/curation_image_random.mjs diff --git a/helpers/wip/find_first_picture_of_post.mjs b/wip/find_first_picture_of_post.mjs similarity index 100% rename from helpers/wip/find_first_picture_of_post.mjs rename to wip/find_first_picture_of_post.mjs diff --git a/helpers/wip/rasterize.js b/wip/rasterize.js similarity index 100% rename from helpers/wip/rasterize.js rename to wip/rasterize.js diff --git a/wip/recommandations_curator.mjs b/wip/recommandations_curator.mjs new file mode 100644 index 0000000..086b2d8 --- /dev/null +++ b/wip/recommandations_curator.mjs @@ -0,0 +1,229 @@ +// selectionner un compte parmi les gens suivis dans une liste + +// export des abonnements utilisateur https://mastodon.cipherbliss.com/settings/exports/follows.csv/home/cipherbliss/Nextcloud/inbox/following_accounts.csv + +import axios from 'axios' +import Masto from 'mastodon' + +/** + * picture generation + */ +import Jimp from 'jimp' +import { getRequestOptions, sendGetRequest } from '../helpers/libs/utils.mjs' +import fs from 'fs' +import path from 'path' + +let reallySendPost = false +reallySendPost = true + +async function getFollowers (username, instance) { + const url = `${instance}/api/v1/accounts/${username}/following` + + try { + const response = await axios.get(url) + + return response.data + } catch (error) { + console.error(error) + } +} + +// Function to look up the user account number using webfinger +async function getUserAccountNumberFromMastodonUsername (username) { + const parsedUsername = username.split('@') + if (parsedUsername.length !== 2) { + throw new Error('Invalid Mastodon username format.') + } + + const localPart = parsedUsername[0] + const domain = parsedUsername[1] + console.log('localPart, domain', localPart, domain) + + const acctPath = '/.well-known/webfinger?resource=' + encodeURIComponent('acct:' + localPart + '@' + domain) + const options = getRequestOptions(domain, 443, acctPath) + + console.log('options', options) + try { + const fingerResult = await sendGetRequest(options) + const actorResource = fingerResult['subject'] || fingerResult.links?.find((item) => item.rel === 'self').href + + if (!actorResource) { + throw new Error('Failed to obtain the resource identifier.') + } + + const accountHost = actorResource.split('/')[2] + const accountPath = actorResource.split('/').pop() + + const accountInfoReqOptions = getRequestOptions(accountHost, 443, '/api/v1/accounts/' + accountPath) + const accountInfo = await sendGetRequest(accountInfoReqOptions) + + return accountInfo.id + } catch (error) { + throw error + } +} + +async function main () { + + const userIdOnInstance = '1' + + const instance = 'mastodon.cipherbliss.com' + + const followers = await getFollowers(userIdOnInstance, instance) + + console.log('followers.length', followers.length) + + const randomFollowers = followers?.sort(() => Math.random() - 0.5)?.slice(0, 3) + + // console.log('Random followers:', randomFollowers) + let message = '\n Les personnes que l\'on vous recommande de suivre aujourd\'hui:' + + let avatars_urls = [] + randomFollowers.forEach(account => { + message += '\n' + displayDataAboutFollower(account) + + console.log('account', account) + avatars_urls.push(account.avatar_static) + }) + message += '\n #fedifollows #curatorRecommendations' + + generateAvatarComposite(avatars_urls) + return message +} + +/** + * displays username, acct, avatar and url for one account + * @param follower + */ +function displayDataAboutFollower (follower) { + + let text = '' + if (follower.note) { + text = follower.note.trim().substring(0, 150) + if (follower.note.trim() > 150) { + text += '...' + } + } + return ` * _${follower.display_name}_: [${follower.acct}](${follower.url}) + ${text.trim()}` + +} + +let folderUnpublished = '' +let compositeFileName = '' + +// Function to maintain aspect ratio while scaling an image down. +function scaleDownPreserveAspectRatio (image, newWidth, newHeight) { + const originalWidth = image.bitmap.width + const originalHeight = image.bitmap.height + + const scaleFactor = Math.min(newWidth / originalWidth, newHeight / originalHeight) + + const newWidthScaled = Math.round(originalWidth * scaleFactor) + const newHeightScaled = Math.round(originalHeight * scaleFactor) + + return image.scaleToFit(newWidthScaled, newHeightScaled) +} + +/** + * Prend trois URL d'image d'avatar et génère une image composite JPG avec celles-ci, + * enregistrée sous le format «YYYY-MM-DDTHH-MM-SS.jpg». + */ +async function generateAvatarComposite (avatarUrls) { + if (!Array.isArray(avatarUrls) || avatarUrls.length !== 3) { + throw new Error('Veuillez fournir exactement trois URL d’avatar.') + } + + // Télécharger chaque avatar + const avatarImagesPromises = avatarUrls.map((url) => downloadImage(url)) + const avatarImages = await Promise.all(avatarImagesPromises) + + // Combiner les images horizontalement + // Resize avatars to a consistent dimension of 400x400 pixels while maintaining aspect ratio + const resizedAvatarImages = avatarImages.map((image) => scaleDownPreserveAspectRatio(image, 400, 400)) + + // Combine the images horizontally + const combinedWidth = 3 * resizedAvatarImages[0].bitmap.width + const combinedHeight = Math.max(...resizedAvatarImages.map((image) => image.bitmap.height)) + const composite = new Jimp(combinedWidth, combinedHeight) + + for (let i = 0; i < resizedAvatarImages.length; i++) { + const xOffset = i * resizedAvatarImages[0].bitmap.width + composite.composite(resizedAvatarImages[i], xOffset, 0) + } + + // Enregistrer l'image composite + compositeFileName = `avatars_reccommendations_${Date.now().toString()}.jpg` + await composite.writeAsync(compositeFileName) + console.log(`L'image composite a été enregistrée sous le nom "${compositeFileName}".`) + return compositeFileName + +} + +/** + * Télécharge une image depuis l'URL spécifiée et renvoie une instance Jimp. + */ +async function downloadImage (url) { + return await Jimp.read(url) +} + +function publishOnMastodon (folderUnpublished, configPost) { + + let accessToken = process.env['TOKEN_' + configPost.author.toUpperCase()] + console.log('accessToken', accessToken) + const masto = new Masto({ + access_token: accessToken, + api_url: process.env.INSTANCE_MASTODON + '/api/v1/', + }) + + if (configPost.reallySendPost) { + + let imagePath = path.resolve() + configPost.image + console.log('imagePath', imagePath) + /** + * poster le média, puis faire un toot avec le média lié + */ + masto.post('media', { file: fs.createReadStream(imagePath) }) + .then(resp => { + let id = resp.data.id + configPost.media_ids = [id] + console.log('\n\n id du média pour le post:', id) + masto.post('statuses', configPost).then(rep => { + // console.log('rep', rep) + console.log(`\n\n posté avec une nouvelle image, ${configPost.image} WOOT`) + }, err => { + console.error(err) + console.log('\n\n erreur T_T') + }) + }, err => { + console.error(err) + }) + } else { + console.log('envoi désactivé avec configPost.reallySendPost') + } +} + +/** + * run all + */ + +main().then(message => { + // let md_message = convertHTMLtoMD(message) + let md_message = message.trim() + '\n' + console.log('md_message', md_message) + // upload de fileName et création du post par le Curator + let configPost = { + author: 'curator', + website: 'cipherbliss', + postObject: {}, + folder_image: '.', + image: compositeFileName, + message: md_message, + reallySendPost + } + + publishOnMastodon(folderUnpublished, configPost) + +}, err => { + console.error(err) +}) diff --git a/helpers/wip/tykayn_art_random.mjs b/wip/tykayn_art_random.mjs similarity index 100% rename from helpers/wip/tykayn_art_random.mjs rename to wip/tykayn_art_random.mjs diff --git a/yarn.lock b/yarn.lock index dff0e2d..1666f81 100644 --- a/yarn.lock +++ b/yarn.lock @@ -62,6 +62,397 @@ __metadata: languageName: node linkType: hard +"@jimp/bmp@npm:^0.22.10": + version: 0.22.10 + resolution: "@jimp/bmp@npm:0.22.10" + dependencies: + "@jimp/utils": ^0.22.10 + bmp-js: ^0.1.0 + peerDependencies: + "@jimp/custom": ">=0.3.5" + checksum: 33ab7e686331082e38c1ba0e214a62377d8bb9dd816b5c100f1f92c6d9a4e30cc62b2636da6ff2625d8af27a0421d88757d9c56f6a9bf00b31f1b0ca7110ab9d + languageName: node + linkType: hard + +"@jimp/core@npm:^0.22.10": + version: 0.22.10 + resolution: "@jimp/core@npm:0.22.10" + dependencies: + "@jimp/utils": ^0.22.10 + any-base: ^1.1.0 + buffer: ^5.2.0 + exif-parser: ^0.1.12 + file-type: ^16.5.4 + isomorphic-fetch: ^3.0.0 + pixelmatch: ^4.0.2 + tinycolor2: ^1.6.0 + checksum: 88d16bb4411d2a1f39d706d69be9f4ad2dcdb9d8b289a98e401e3896a628fd5f440288e14c0f6f5dd100d5b786df2050784f91a01db032dae1442ecc57ed052e + languageName: node + linkType: hard + +"@jimp/custom@npm:^0.22.10": + version: 0.22.10 + resolution: "@jimp/custom@npm:0.22.10" + dependencies: + "@jimp/core": ^0.22.10 + checksum: e9a2dfefcf793f0c2da86ee71eafa33d8b5185bf7ae3711400bd979e60ecde2db57f1544c307ab5589712d67212b93238d0e0962a7080aea4de667e2936fa7dc + languageName: node + linkType: hard + +"@jimp/gif@npm:^0.22.10": + version: 0.22.10 + resolution: "@jimp/gif@npm:0.22.10" + dependencies: + "@jimp/utils": ^0.22.10 + gifwrap: ^0.10.1 + omggif: ^1.0.9 + peerDependencies: + "@jimp/custom": ">=0.3.5" + checksum: 7a3c5f49590d90aac4b8bfc05d01410f4e25a0223c55df31e1736a9aac375a8dd9b4e0833c379ed1c52bec229bf3728c0cf3729c56a94918d4c105f519bc9138 + languageName: node + linkType: hard + +"@jimp/jpeg@npm:^0.22.10": + version: 0.22.10 + resolution: "@jimp/jpeg@npm:0.22.10" + dependencies: + "@jimp/utils": ^0.22.10 + jpeg-js: ^0.4.4 + peerDependencies: + "@jimp/custom": ">=0.3.5" + checksum: 60ae140919a5dd1f4afcf712ae999ccdefb5cb9d728c6348bdd9bee3cd75e7be1a5e83b80b5877d0c6c7432b8f6ff57d7246dfa0ab41c3b56c87b7ca8bb30053 + languageName: node + linkType: hard + +"@jimp/plugin-blit@npm:^0.22.10": + version: 0.22.10 + resolution: "@jimp/plugin-blit@npm:0.22.10" + dependencies: + "@jimp/utils": ^0.22.10 + peerDependencies: + "@jimp/custom": ">=0.3.5" + checksum: dda546548e626dc664234cb45e7ab2216fb24b3b15a5bf3f29cc9e08cb588c286dae11a07f4c1d96da9322640b82547b65ba1093d7425cdb687b2cfcfb228744 + languageName: node + linkType: hard + +"@jimp/plugin-blur@npm:^0.22.10": + version: 0.22.10 + resolution: "@jimp/plugin-blur@npm:0.22.10" + dependencies: + "@jimp/utils": ^0.22.10 + peerDependencies: + "@jimp/custom": ">=0.3.5" + checksum: 49fbb2094512c9229e448e921ae393dead0287d1c19549b37da4acc3c1fe7b5832d91064e0c5cf585d1acdb55c5ed404ef5f5c516549fb4f160e6926ad8720cf + languageName: node + linkType: hard + +"@jimp/plugin-circle@npm:^0.22.10": + version: 0.22.10 + resolution: "@jimp/plugin-circle@npm:0.22.10" + dependencies: + "@jimp/utils": ^0.22.10 + peerDependencies: + "@jimp/custom": ">=0.3.5" + checksum: 117813b226c13fe7372dcb899d4c5eefa5cd2ce9b3fe2449958f27285f341560d02a2bf3c1ff772703f15d2cc706817a6b6ce6d21ca2812fded5585ebc746d48 + languageName: node + linkType: hard + +"@jimp/plugin-color@npm:^0.22.10": + version: 0.22.10 + resolution: "@jimp/plugin-color@npm:0.22.10" + dependencies: + "@jimp/utils": ^0.22.10 + tinycolor2: ^1.6.0 + peerDependencies: + "@jimp/custom": ">=0.3.5" + checksum: 5fb9a9a0393ece7833145e19270fbafc19b43a90c4ff7c5ee20caab535aff3b52d92e0bc5884a27608ae8aef62b5a0f56fc3e2121e398eae3fa850bd74e4f54d + languageName: node + linkType: hard + +"@jimp/plugin-contain@npm:^0.22.10": + version: 0.22.10 + resolution: "@jimp/plugin-contain@npm:0.22.10" + dependencies: + "@jimp/utils": ^0.22.10 + peerDependencies: + "@jimp/custom": ">=0.3.5" + "@jimp/plugin-blit": ">=0.3.5" + "@jimp/plugin-resize": ">=0.3.5" + "@jimp/plugin-scale": ">=0.3.5" + checksum: 8bc652738441b3d387cdc3be429549a27ff0294eb2d2d933dfdca5502dc1b08ab90514e012c8639f7ca020270277cb7ba68a4ceaf799392d6088c64790a8ca9b + languageName: node + linkType: hard + +"@jimp/plugin-cover@npm:^0.22.10": + version: 0.22.10 + resolution: "@jimp/plugin-cover@npm:0.22.10" + dependencies: + "@jimp/utils": ^0.22.10 + peerDependencies: + "@jimp/custom": ">=0.3.5" + "@jimp/plugin-crop": ">=0.3.5" + "@jimp/plugin-resize": ">=0.3.5" + "@jimp/plugin-scale": ">=0.3.5" + checksum: 61607f4b61efeabefc9b5674bf5f6222140b9e4a41d23fba3e42d98cadd516c877274f63c1a2ba2dfba18f3f8ece6fa4ad3dcea881698e19ce2bf58d4094b46b + languageName: node + linkType: hard + +"@jimp/plugin-crop@npm:^0.22.10": + version: 0.22.10 + resolution: "@jimp/plugin-crop@npm:0.22.10" + dependencies: + "@jimp/utils": ^0.22.10 + peerDependencies: + "@jimp/custom": ">=0.3.5" + checksum: d5f70b478afd31c257aa32038623bfabae647a7e2d2958be9f6487b5b556b8fcc7b1a3f51d170f7e83198720ae6709a345f7f66c38cb662e375dba4fa96c3999 + languageName: node + linkType: hard + +"@jimp/plugin-displace@npm:^0.22.10": + version: 0.22.10 + resolution: "@jimp/plugin-displace@npm:0.22.10" + dependencies: + "@jimp/utils": ^0.22.10 + peerDependencies: + "@jimp/custom": ">=0.3.5" + checksum: 6121375b5ef723f7d6dbb400f0f1c303b009f97761bcb75df23818dfeb29ca58794d08f6feeb0edbaf5fcc4e7623a76d1e11a34dafaaa65721349093d288086e + languageName: node + linkType: hard + +"@jimp/plugin-dither@npm:^0.22.10": + version: 0.22.10 + resolution: "@jimp/plugin-dither@npm:0.22.10" + dependencies: + "@jimp/utils": ^0.22.10 + peerDependencies: + "@jimp/custom": ">=0.3.5" + checksum: 91453f7bd289a85946267c99173a841e71bdb77d12497d3bb6b423e606a24048bdc777b40602fc62b270d877c467fd23ab863e47b7fd63124020ddf0893538d5 + languageName: node + linkType: hard + +"@jimp/plugin-fisheye@npm:^0.22.10": + version: 0.22.10 + resolution: "@jimp/plugin-fisheye@npm:0.22.10" + dependencies: + "@jimp/utils": ^0.22.10 + peerDependencies: + "@jimp/custom": ">=0.3.5" + checksum: dee2350a1eaa98bb9f49e1706f064c85abca8880a718cf3b151e5beb17df9f52045f1aadbb9b591aa7abdfe3108b516a6a0677ff191e968dd3ed206c371edd4b + languageName: node + linkType: hard + +"@jimp/plugin-flip@npm:^0.22.10": + version: 0.22.10 + resolution: "@jimp/plugin-flip@npm:0.22.10" + dependencies: + "@jimp/utils": ^0.22.10 + peerDependencies: + "@jimp/custom": ">=0.3.5" + "@jimp/plugin-rotate": ">=0.3.5" + checksum: ef3371ba34fade4d48587b442dbb850dff73caa51f4de5ba4a96dea1ab9efe26a1d854fa6605f55f8fae55bedc9797a64bc12be0dfb3d0872d421656457fc34c + languageName: node + linkType: hard + +"@jimp/plugin-gaussian@npm:^0.22.10": + version: 0.22.10 + resolution: "@jimp/plugin-gaussian@npm:0.22.10" + dependencies: + "@jimp/utils": ^0.22.10 + peerDependencies: + "@jimp/custom": ">=0.3.5" + checksum: e9f012ffb04781e025bcc800b88a1f9a6676775207ed2b3686b2b354d5248bcbf2918719997058157de81802c063d356f0f96d68fe28a9f4ca6ff2f63647a445 + languageName: node + linkType: hard + +"@jimp/plugin-invert@npm:^0.22.10": + version: 0.22.10 + resolution: "@jimp/plugin-invert@npm:0.22.10" + dependencies: + "@jimp/utils": ^0.22.10 + peerDependencies: + "@jimp/custom": ">=0.3.5" + checksum: 0874b269931d5c6de8b462fbcf1b097366482b1830e077e52375cdb191ee1ff63db23c3553df3ee3bc4e72df40e3181848dbf982461cb0a357b8e4c5ac4bdf94 + languageName: node + linkType: hard + +"@jimp/plugin-mask@npm:^0.22.10": + version: 0.22.10 + resolution: "@jimp/plugin-mask@npm:0.22.10" + dependencies: + "@jimp/utils": ^0.22.10 + peerDependencies: + "@jimp/custom": ">=0.3.5" + checksum: 6fb7edda32277dc47d94f3ff70e0aae3e3487820f6d6429761d2a413fba786122b77920975721306c2115a7938beeea1ab858beb5e11c0f2f040aaae5eaf391e + languageName: node + linkType: hard + +"@jimp/plugin-normalize@npm:^0.22.10": + version: 0.22.10 + resolution: "@jimp/plugin-normalize@npm:0.22.10" + dependencies: + "@jimp/utils": ^0.22.10 + peerDependencies: + "@jimp/custom": ">=0.3.5" + checksum: 66873475bdc6739da1a12aa66a4587ad2eeebf5374e195f541b490ebc3f9ff5c8bbb7ef898d35600f5a4ee0154d6a8975f1ecb3f26f62daf0d762e5e1182acb8 + languageName: node + linkType: hard + +"@jimp/plugin-print@npm:^0.22.10": + version: 0.22.10 + resolution: "@jimp/plugin-print@npm:0.22.10" + dependencies: + "@jimp/utils": ^0.22.10 + load-bmfont: ^1.4.1 + peerDependencies: + "@jimp/custom": ">=0.3.5" + "@jimp/plugin-blit": ">=0.3.5" + checksum: 4a3ad6bccd8d673805e07bcbd3a9eabc0021c498a1d8f231369e8dc3d884b8364e772de8f97b637da6abb0657b0cc68961ba2311cd75f52e47da6657a74f9348 + languageName: node + linkType: hard + +"@jimp/plugin-resize@npm:^0.22.10": + version: 0.22.10 + resolution: "@jimp/plugin-resize@npm:0.22.10" + dependencies: + "@jimp/utils": ^0.22.10 + peerDependencies: + "@jimp/custom": ">=0.3.5" + checksum: 1d74e4624ca6f3b1894d18c824795106ac00e9445f635b11e3d47b7c839752a086a113b0969560b652de8a65b6c20085dc8f4fc4f99db9d1fdedec229b6e5edd + languageName: node + linkType: hard + +"@jimp/plugin-rotate@npm:^0.22.10": + version: 0.22.10 + resolution: "@jimp/plugin-rotate@npm:0.22.10" + dependencies: + "@jimp/utils": ^0.22.10 + peerDependencies: + "@jimp/custom": ">=0.3.5" + "@jimp/plugin-blit": ">=0.3.5" + "@jimp/plugin-crop": ">=0.3.5" + "@jimp/plugin-resize": ">=0.3.5" + checksum: dfc91fa10520bcf4340f47a9190987d4010797054a6c9dc9cbcc1cc4d86592f22c54f5a27d22f2628a804e00b6b35b27f59ff532112e296ef2c53c1df220236d + languageName: node + linkType: hard + +"@jimp/plugin-scale@npm:^0.22.10": + version: 0.22.10 + resolution: "@jimp/plugin-scale@npm:0.22.10" + dependencies: + "@jimp/utils": ^0.22.10 + peerDependencies: + "@jimp/custom": ">=0.3.5" + "@jimp/plugin-resize": ">=0.3.5" + checksum: bdd187bab363440863907d6b747db42bc3122e3ca5e796b2b4cf3c3b1ebf99d009224a3953ab6a9cd67b0c782304eda1faf86bce73f4d689943374375a7014fa + languageName: node + linkType: hard + +"@jimp/plugin-shadow@npm:^0.22.10": + version: 0.22.10 + resolution: "@jimp/plugin-shadow@npm:0.22.10" + dependencies: + "@jimp/utils": ^0.22.10 + peerDependencies: + "@jimp/custom": ">=0.3.5" + "@jimp/plugin-blur": ">=0.3.5" + "@jimp/plugin-resize": ">=0.3.5" + checksum: e9075691ae0c348f9bd1ccb12c0a7891c2f60b81ce29587a3a822e53c5ddaec680ad3b9ce581b731c22cfd1d3e50aadc2ebf75b94a71651555785638f24bf470 + languageName: node + linkType: hard + +"@jimp/plugin-threshold@npm:^0.22.10": + version: 0.22.10 + resolution: "@jimp/plugin-threshold@npm:0.22.10" + dependencies: + "@jimp/utils": ^0.22.10 + peerDependencies: + "@jimp/custom": ">=0.3.5" + "@jimp/plugin-color": ">=0.8.0" + "@jimp/plugin-resize": ">=0.8.0" + checksum: 43419a9411f51a34a2fcfc259c0bdfc907dd29d610f1ae4918c3da30f407e1eb617a091ba2246521b581ea06216e912cd8608285d753b3e0ef96afd4a47f8d65 + languageName: node + linkType: hard + +"@jimp/plugins@npm:^0.22.10": + version: 0.22.10 + resolution: "@jimp/plugins@npm:0.22.10" + dependencies: + "@jimp/plugin-blit": ^0.22.10 + "@jimp/plugin-blur": ^0.22.10 + "@jimp/plugin-circle": ^0.22.10 + "@jimp/plugin-color": ^0.22.10 + "@jimp/plugin-contain": ^0.22.10 + "@jimp/plugin-cover": ^0.22.10 + "@jimp/plugin-crop": ^0.22.10 + "@jimp/plugin-displace": ^0.22.10 + "@jimp/plugin-dither": ^0.22.10 + "@jimp/plugin-fisheye": ^0.22.10 + "@jimp/plugin-flip": ^0.22.10 + "@jimp/plugin-gaussian": ^0.22.10 + "@jimp/plugin-invert": ^0.22.10 + "@jimp/plugin-mask": ^0.22.10 + "@jimp/plugin-normalize": ^0.22.10 + "@jimp/plugin-print": ^0.22.10 + "@jimp/plugin-resize": ^0.22.10 + "@jimp/plugin-rotate": ^0.22.10 + "@jimp/plugin-scale": ^0.22.10 + "@jimp/plugin-shadow": ^0.22.10 + "@jimp/plugin-threshold": ^0.22.10 + timm: ^1.6.1 + peerDependencies: + "@jimp/custom": ">=0.3.5" + checksum: c7157df47e9a38a82eb7c9921a078623520ba78ba8d69da83a6f028f727fef3e578bfd75ae428d74e5174fa7438786ab7979a3ae7ac24a02214c7f9fa64fcaef + languageName: node + linkType: hard + +"@jimp/png@npm:^0.22.10": + version: 0.22.10 + resolution: "@jimp/png@npm:0.22.10" + dependencies: + "@jimp/utils": ^0.22.10 + pngjs: ^6.0.0 + peerDependencies: + "@jimp/custom": ">=0.3.5" + checksum: d704e4553e285abef313b10de3e6b4c1ad43663631c86cb3032334f4ed122950e7b9b68c842763d7224fb3a0aa1fa6319f21b64902da209ecf1a28adcd7b59f9 + languageName: node + linkType: hard + +"@jimp/tiff@npm:^0.22.10": + version: 0.22.10 + resolution: "@jimp/tiff@npm:0.22.10" + dependencies: + utif2: ^4.0.1 + peerDependencies: + "@jimp/custom": ">=0.3.5" + checksum: ff8d8c14b3ef04d73971e9718fb860c993913b31e0560f82c1e7e0bfa7f0aab831c2d4b7b5693fb79a89b96a9295c1ff30b1006b2e95ec5f5b52af59bda87136 + languageName: node + linkType: hard + +"@jimp/types@npm:^0.22.10": + version: 0.22.10 + resolution: "@jimp/types@npm:0.22.10" + dependencies: + "@jimp/bmp": ^0.22.10 + "@jimp/gif": ^0.22.10 + "@jimp/jpeg": ^0.22.10 + "@jimp/png": ^0.22.10 + "@jimp/tiff": ^0.22.10 + timm: ^1.6.1 + peerDependencies: + "@jimp/custom": ">=0.3.5" + checksum: 1636f0d2c0b3f7f936c60ee5e148f4b928e843223b8af156282d69fca8c0e70326dd6aa2bf43f9ac44c4dde2fc384bfdfd157b7c69e54cb5469f46a658d8e46f + languageName: node + linkType: hard + +"@jimp/utils@npm:^0.22.10": + version: 0.22.10 + resolution: "@jimp/utils@npm:0.22.10" + dependencies: + regenerator-runtime: ^0.13.3 + checksum: 65c0f225e5d3821cbc8c5fdf4e316c61923ca7da5c2baa69af87f8b9c51d76aeec3f54d549ad934ebb931ff4457e77b0b350a489e9fa5010abeb0e900c47117c + languageName: node + linkType: hard + "@mapbox/node-pre-gyp@npm:^1.0.0": version: 1.0.9 resolution: "@mapbox/node-pre-gyp@npm:1.0.9" @@ -150,6 +541,13 @@ __metadata: languageName: node linkType: hard +"@tokenizer/token@npm:^0.3.0": + version: 0.3.0 + resolution: "@tokenizer/token@npm:0.3.0" + checksum: 1d575d02d2a9f0c5a4ca5180635ebd2ad59e0f18b42a65f3d04844148b49b3db35cf00b6012a1af2d59c2ab3caca59451c5689f747ba8667ee586ad717ee58e1 + languageName: node + linkType: hard + "@tootallnate/once@npm:1": version: 1.1.2 resolution: "@tootallnate/once@npm:1.1.2" @@ -181,6 +579,13 @@ __metadata: languageName: node linkType: hard +"@types/node@npm:16.9.1": + version: 16.9.1 + resolution: "@types/node@npm:16.9.1" + checksum: 41afcf183a22d59323a0199dd7e0f46591247f45fc08a4434edb26d56dc279ae4fdb80f37989ddd7a0f45e3857c4933e6e82057ede09c5a829f77e373e680375 + languageName: node + linkType: hard + "@types/sqlite3@npm:^3.1.5": version: 3.1.8 resolution: "@types/sqlite3@npm:3.1.8" @@ -349,6 +754,13 @@ __metadata: languageName: node linkType: hard +"any-base@npm:^1.1.0": + version: 1.1.0 + resolution: "any-base@npm:1.1.0" + checksum: c1fd040de52e710e2de7d9ae4df52bac589f35622adb24686c98ce21c7b824859a8db9614bc119ed8614f42fd08918b2612e6a6c385480462b3100a1af59289d + languageName: node + linkType: hard + "anymatch@npm:~3.1.2": version: 3.1.2 resolution: "anymatch@npm:3.1.2" @@ -444,14 +856,14 @@ __metadata: languageName: node linkType: hard -"axios@npm:^1.6.2": - version: 1.6.2 - resolution: "axios@npm:1.6.2" +"axios@npm:^1.6.7": + version: 1.6.7 + resolution: "axios@npm:1.6.7" dependencies: - follow-redirects: ^1.15.0 + follow-redirects: ^1.15.4 form-data: ^4.0.0 proxy-from-env: ^1.1.0 - checksum: 4a7429e2b784be0f2902ca2680964391eae7236faa3967715f30ea45464b98ae3f1c6f631303b13dfe721b17126b01f486c7644b9ef276bfc63112db9fd379f8 + checksum: 87d4d429927d09942771f3b3a6c13580c183e31d7be0ee12f09be6d5655304996bb033d85e54be81606f4e89684df43be7bf52d14becb73a12727bf33298a082 languageName: node linkType: hard @@ -532,6 +944,13 @@ __metadata: languageName: node linkType: hard +"bmp-js@npm:^0.1.0": + version: 0.1.0 + resolution: "bmp-js@npm:0.1.0" + checksum: 2f6cf7eeabae2aa50eb768122f59e9752caa97248028cb8b5cf0d9db7cf8fb3a60262aeb2c6889dd21357ab061b2fb318f21f20d2b24963ba36ead8e264c6654 + languageName: node + linkType: hard + "body-parser@npm:1.18.3": version: 1.18.3 resolution: "body-parser@npm:1.18.3" @@ -592,7 +1011,14 @@ __metadata: languageName: node linkType: hard -"buffer@npm:^5.2.1, buffer@npm:^5.5.0": +"buffer-equal@npm:0.0.1": + version: 0.0.1 + resolution: "buffer-equal@npm:0.0.1" + checksum: ca4b52e6c01143529d957a78cb9a93e4257f172bbab30d9eb87c20ae085ed23c5e07f236ac051202dacbf3d17aba42e1455f84cba21ea79b67d57f2b05e9a613 + languageName: node + linkType: hard + +"buffer@npm:^5.2.0, buffer@npm:^5.2.1, buffer@npm:^5.5.0": version: 5.7.1 resolution: "buffer@npm:5.7.1" dependencies: @@ -1143,6 +1569,13 @@ __metadata: languageName: node linkType: hard +"dom-walk@npm:^0.1.0": + version: 0.1.2 + resolution: "dom-walk@npm:0.1.2" + checksum: 19eb0ce9c6de39d5e231530685248545d9cd2bd97b2cb3486e0bfc0f2a393a9addddfd5557463a932b52fdfcf68ad2a619020cd2c74a5fe46fbecaa8e80872f3 + languageName: node + linkType: hard + "domelementtype@npm:^2.3.0": version: 2.3.0 resolution: "domelementtype@npm:2.3.0" @@ -1303,6 +1736,13 @@ __metadata: languageName: node linkType: hard +"exif-parser@npm:^0.1.12": + version: 0.1.12 + resolution: "exif-parser@npm:0.1.12" + checksum: 6ba50cb9e0b45a6efa37e966a9582ecd171b5c5b3ef0c47542f2b862c521f70d2f656dde85b4d2a5dd8e1163486b09049f4c412e9c6176bfbda1654a5b2f021c + languageName: node + linkType: hard + "expand-template@npm:^2.0.3": version: 2.0.3 resolution: "expand-template@npm:2.0.3" @@ -1433,6 +1873,17 @@ __metadata: languageName: node linkType: hard +"file-type@npm:^16.5.4": + version: 16.5.4 + resolution: "file-type@npm:16.5.4" + dependencies: + readable-web-to-node-stream: ^3.0.0 + strtok3: ^6.2.4 + token-types: ^4.1.1 + checksum: d983c0f36491c57fcb6cc70fcb02c36d6b53f312a15053263e1924e28ca8314adf0db32170801ad777f09432c32155f31715ceaee66310947731588120d7ec27 + languageName: node + linkType: hard + "fill-range@npm:^7.0.1": version: 7.0.1 resolution: "fill-range@npm:7.0.1" @@ -1467,13 +1918,13 @@ __metadata: languageName: node linkType: hard -"follow-redirects@npm:^1.15.0": - version: 1.15.3 - resolution: "follow-redirects@npm:1.15.3" +"follow-redirects@npm:^1.15.4": + version: 1.15.5 + resolution: "follow-redirects@npm:1.15.5" peerDependenciesMeta: debug: optional: true - checksum: 584da22ec5420c837bd096559ebfb8fe69d82512d5585004e36a3b4a6ef6d5905780e0c74508c7b72f907d1fa2b7bd339e613859e9c304d0dc96af2027fd0231 + checksum: 5ca49b5ce6f44338cbfc3546823357e7a70813cecc9b7b768158a1d32c1e62e7407c944402a918ea8c38ae2e78266312d617dc68783fac502cbb55e1047b34ec languageName: node linkType: hard @@ -1655,6 +2106,16 @@ __metadata: languageName: node linkType: hard +"gifwrap@npm:^0.10.1": + version: 0.10.1 + resolution: "gifwrap@npm:0.10.1" + dependencies: + image-q: ^4.0.0 + omggif: ^1.0.10 + checksum: eac8cb4b9657b284ebce935ab541c5a2acbb0bdd062ca6ae900169ff2d48d0dec0f903940eafa639a849c9d4f43c0317422b57a1b50dc3a86aab4e634c6b4258 + languageName: node + linkType: hard + "github-from-package@npm:0.0.0": version: 0.0.0 resolution: "github-from-package@npm:0.0.0" @@ -1700,6 +2161,16 @@ __metadata: languageName: node linkType: hard +"global@npm:~4.4.0": + version: 4.4.0 + resolution: "global@npm:4.4.0" + dependencies: + min-document: ^2.19.0 + process: ^0.11.10 + checksum: 9c057557c8f5a5bcfbeb9378ba4fe2255d04679452be504608dd5f13b54edf79f7be1db1031ea06a4ec6edd3b9f5f17d2d172fb47e6c69dae57fd84b7e72b77f + languageName: node + linkType: hard + "graceful-fs@npm:^4.2.6": version: 4.2.10 resolution: "graceful-fs@npm:4.2.10" @@ -1886,7 +2357,7 @@ __metadata: languageName: node linkType: hard -"ieee754@npm:^1.1.13": +"ieee754@npm:^1.1.13, ieee754@npm:^1.2.1": version: 1.2.1 resolution: "ieee754@npm:1.2.1" checksum: 5144c0c9815e54ada181d80a0b810221a253562422e7c6c3a60b1901154184f49326ec239d618c416c1c5945a2e197107aee8d986a3dd836b53dffefd99b5e7e @@ -1900,6 +2371,15 @@ __metadata: languageName: node linkType: hard +"image-q@npm:^4.0.0": + version: 4.0.0 + resolution: "image-q@npm:4.0.0" + dependencies: + "@types/node": 16.9.1 + checksum: 6c6a1dd8467833161f46cc17b4a43218d30a3899ff71a4ffb895f71a14ca29de12f79d824d4d2174070924cbd97faa018b2ded8d690483ab7eb269f364cd97cc + languageName: node + linkType: hard + "imurmurhash@npm:^0.1.4": version: 0.1.4 resolution: "imurmurhash@npm:0.1.4" @@ -2010,6 +2490,13 @@ __metadata: languageName: node linkType: hard +"is-function@npm:^1.0.1": + version: 1.0.2 + resolution: "is-function@npm:1.0.2" + checksum: 7d564562e07b4b51359547d3ccc10fb93bb392fd1b8177ae2601ee4982a0ece86d952323fc172a9000743a3971f09689495ab78a1d49a9b14fc97a7e28521dc0 + languageName: node + linkType: hard + "is-glob@npm:^4.0.1, is-glob@npm:~4.0.1": version: 4.0.3 resolution: "is-glob@npm:4.0.3" @@ -2075,6 +2562,16 @@ __metadata: languageName: node linkType: hard +"isomorphic-fetch@npm:^3.0.0": + version: 3.0.0 + resolution: "isomorphic-fetch@npm:3.0.0" + dependencies: + node-fetch: ^2.6.1 + whatwg-fetch: ^3.4.1 + checksum: e5ab79a56ce5af6ddd21265f59312ad9a4bc5a72cebc98b54797b42cb30441d5c5f8d17c5cd84a99e18101c8af6f90c081ecb8d12fd79e332be1778d58486d75 + languageName: node + linkType: hard + "isstream@npm:~0.1.2": version: 0.1.2 resolution: "isstream@npm:0.1.2" @@ -2115,6 +2612,25 @@ __metadata: languageName: node linkType: hard +"jimp@npm:^0.22.10": + version: 0.22.10 + resolution: "jimp@npm:0.22.10" + dependencies: + "@jimp/custom": ^0.22.10 + "@jimp/plugins": ^0.22.10 + "@jimp/types": ^0.22.10 + regenerator-runtime: ^0.13.3 + checksum: 1001ec8ed939ba25f24f15e1b3acd794f184ec4511a9808e8de8422eb7e0fd4032788f101c3b2cff71afd2dea27a904ca012f2ebbb1b87d6154b99e39af6b4c3 + languageName: node + linkType: hard + +"jpeg-js@npm:^0.4.4": + version: 0.4.4 + resolution: "jpeg-js@npm:0.4.4" + checksum: bd7cb61aa8df40a9ee2c2106839c3df6054891e56cfc22c0ac581402e06c6295f962a4754b0b2ac50a401789131b1c6dc9df8d24400f1352168be1894833c590 + languageName: node + linkType: hard + "jsbn@npm:~0.1.0": version: 0.1.1 resolution: "jsbn@npm:0.1.1" @@ -2181,6 +2697,22 @@ __metadata: languageName: node linkType: hard +"load-bmfont@npm:^1.4.1": + version: 1.4.1 + resolution: "load-bmfont@npm:1.4.1" + 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 + checksum: 688d932fb0dc4c9333747736ccd926261f0b91734b7bdb6ff24f8659ef068a0f0b2278084b208851afac0beec79af7bd6664fe2ed5b6c5e1db88755fc25f785e + languageName: node + linkType: hard + "locate-path@npm:^5.0.0": version: 5.0.0 resolution: "locate-path@npm:5.0.0" @@ -2295,7 +2827,7 @@ __metadata: resolution: "mastodon-multi-account@workspace:." dependencies: "@databases/sqlite": ^4.0.0 - axios: ^1.6.2 + axios: ^1.6.7 cheerio: ^1.0.0-rc.12 cookie-parser: ~1.4.4 debug: ~2.6.9 @@ -2305,6 +2837,7 @@ __metadata: http-errors: ~1.6.3 https: ^1.0.0 jade: ~1.11.0 + jimp: ^0.22.10 mastodon: ^1.2.2 moment: ^2.29.4 morgan: ~1.9.1 @@ -2395,6 +2928,15 @@ __metadata: languageName: node linkType: hard +"min-document@npm:^2.19.0": + version: 2.19.0 + resolution: "min-document@npm:2.19.0" + dependencies: + dom-walk: ^0.1.0 + checksum: da6437562ea2228041542a2384528e74e22d1daa1a4ec439c165abf0b9d8a63e17e3b8a6dc6e0c731845e85301198730426932a0e813d23f932ca668340c9623 + languageName: node + linkType: hard + "minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": version: 3.1.2 resolution: "minimatch@npm:3.1.2" @@ -2644,6 +3186,20 @@ __metadata: languageName: node linkType: hard +"node-fetch@npm:^2.6.1": + version: 2.7.0 + resolution: "node-fetch@npm:2.7.0" + dependencies: + whatwg-url: ^5.0.0 + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + checksum: d76d2f5edb451a3f05b15115ec89fc6be39de37c6089f1b6368df03b91e1633fd379a7e01b7ab05089a25034b2023d959b47e59759cb38d88341b2459e89d6e5 + languageName: node + linkType: hard + "node-fetch@npm:^2.6.7": version: 2.6.7 resolution: "node-fetch@npm:2.6.7" @@ -2831,6 +3387,13 @@ __metadata: languageName: node linkType: hard +"omggif@npm:^1.0.10, omggif@npm:^1.0.9": + version: 1.0.10 + resolution: "omggif@npm:1.0.10" + checksum: 15102e46b6fa0fba32d7e948f702623cdc3cdcdfd64b2d33c6e29a61f366ffd0f250da55d66f5217dce5b93ba9c67763fa998652791a5c7f2201a3bde2c4db45 + languageName: node + linkType: hard + "on-finished@npm:~2.3.0": version: 2.3.0 resolution: "on-finished@npm:2.3.0" @@ -2932,6 +3495,44 @@ __metadata: languageName: node linkType: hard +"pako@npm:^1.0.11": + version: 1.0.11 + resolution: "pako@npm:1.0.11" + checksum: 1be2bfa1f807608c7538afa15d6f25baa523c30ec870a3228a89579e474a4d992f4293859524e46d5d87fd30fa17c5edf34dbef0671251d9749820b488660b16 + languageName: node + linkType: hard + +"parse-bmfont-ascii@npm:^1.0.3": + version: 1.0.6 + resolution: "parse-bmfont-ascii@npm:1.0.6" + checksum: de3f6671f183c3e9d64bb4812b0407693b5fd0d24e9d16b2e106bb9eef809d64a6cc061f39ca29bb10c5c2e47e241e91b7aeefa587391fff7ccb27ab9db5012e + languageName: node + linkType: hard + +"parse-bmfont-binary@npm:^1.0.5": + version: 1.0.6 + resolution: "parse-bmfont-binary@npm:1.0.6" + checksum: ca37fb1e92f5941fddc5342b45857fafd27f00d2bd5fa44dd504bec6faeab97536c95ad45260c2dd5fc4c63de71e525663d3cdac09d038cbca803d97c669add5 + languageName: node + linkType: hard + +"parse-bmfont-xml@npm:^1.1.4": + version: 1.1.4 + resolution: "parse-bmfont-xml@npm:1.1.4" + dependencies: + xml-parse-from-string: ^1.0.0 + xml2js: ^0.4.5 + checksum: 879e5435be44f22b8c4934e2e1d2754a6d90a9ddb16309360daff965e1428d877b673f3d1fafaab4fef437c912a0db9f85545e0dd375ec62df7d4d328450d257 + languageName: node + linkType: hard + +"parse-headers@npm:^2.0.0": + version: 2.0.5 + resolution: "parse-headers@npm:2.0.5" + checksum: 3e97f01e4c7f960bfbfd0ee489f0bd8d3c72b6c814f1f79b66abec2cca8eaf8e4ecd89deba0b6e61266469aed87350bc932001181c01ff8c29a59e696abe251f + languageName: node + linkType: hard + "parse5-htmlparser2-tree-adapter@npm:^7.0.0": version: 7.0.0 resolution: "parse5-htmlparser2-tree-adapter@npm:7.0.0" @@ -3006,6 +3607,13 @@ __metadata: languageName: node linkType: hard +"peek-readable@npm:^4.1.0": + version: 4.1.0 + resolution: "peek-readable@npm:4.1.0" + checksum: 02c673f9bc816f8e4e74a054c097225ad38d457d745b775e2b96faf404a54473b2f62f5bcd496f5ebc28696708bcc5e95bed409856f4bef5ed62eae9b4ac0dab + languageName: node + linkType: hard + "pend@npm:~1.2.0": version: 1.2.0 resolution: "pend@npm:1.2.0" @@ -3020,6 +3628,13 @@ __metadata: languageName: node linkType: hard +"phin@npm:^2.9.1": + version: 2.9.3 + resolution: "phin@npm:2.9.3" + checksum: 7e2abd7be74a54eb7be92dccb1d7a019725c8adaa79ac22a38f25220f9a859393e654ea753a559d326aed7bbc966fadac88270cc8c39d78896f7784219560c47 + languageName: node + linkType: hard + "picomatch@npm:^2.0.4, picomatch@npm:^2.2.1": version: 2.3.1 resolution: "picomatch@npm:2.3.1" @@ -3027,6 +3642,17 @@ __metadata: languageName: node linkType: hard +"pixelmatch@npm:^4.0.2": + version: 4.0.2 + resolution: "pixelmatch@npm:4.0.2" + dependencies: + pngjs: ^3.0.0 + bin: + pixelmatch: bin/pixelmatch + checksum: 9c5c1329001938cae6d01e2bb84a909ba767f8256bcafc075422cea2a4dbaa8bebd44fceaa4b4ce7cdc36d11f20d4f1ba0cf669851d5649b32d8d1d27e4f5a36 + languageName: node + linkType: hard + "pkg-dir@npm:4.2.0": version: 4.2.0 resolution: "pkg-dir@npm:4.2.0" @@ -3057,6 +3683,20 @@ __metadata: languageName: node linkType: hard +"pngjs@npm:^3.0.0": + version: 3.4.0 + resolution: "pngjs@npm:3.4.0" + checksum: 8bd40bd698abd16b72c97b85cb858c80894fbedc76277ce72a784aa441e14795d45d9856e97333ca469b34b67528860ffc8a7317ca6beea349b645366df00bcd + languageName: node + linkType: hard + +"pngjs@npm:^6.0.0": + version: 6.0.0 + resolution: "pngjs@npm:6.0.0" + checksum: ab6c285086060087097eab9fe6b5a528a24f9e79c03dea2b4fd6264ed4fdb5beff4a3257eeeaf2a9dc18249b539609c2a4e4013c567164a1f6b5ba2c974d5ecb + languageName: node + linkType: hard + "prebuild-install@npm:^7.1.1": version: 7.1.1 resolution: "prebuild-install@npm:7.1.1" @@ -3096,7 +3736,7 @@ __metadata: languageName: node linkType: hard -"process@npm:^0.11.1": +"process@npm:^0.11.1, process@npm:^0.11.10": version: 0.11.10 resolution: "process@npm:0.11.10" checksum: bfcce49814f7d172a6e6a14d5fa3ac92cc3d0c3b9feb1279774708a719e19acd673995226351a082a9ae99978254e320ccda4240ddc474ba31a76c79491ca7c3 @@ -3299,6 +3939,15 @@ __metadata: languageName: node linkType: hard +"readable-web-to-node-stream@npm:^3.0.0": + version: 3.0.2 + resolution: "readable-web-to-node-stream@npm:3.0.2" + dependencies: + readable-stream: ^3.6.0 + checksum: 8c56cc62c68513425ddfa721954875b382768f83fa20e6b31e365ee00cbe7a3d6296f66f7f1107b16cd3416d33aa9f1680475376400d62a081a88f81f0ea7f9c + languageName: node + linkType: hard + "readdirp@npm:~3.6.0": version: 3.6.0 resolution: "readdirp@npm:3.6.0" @@ -3308,6 +3957,13 @@ __metadata: languageName: node linkType: hard +"regenerator-runtime@npm:^0.13.3": + version: 0.13.11 + resolution: "regenerator-runtime@npm:0.13.11" + checksum: 27481628d22a1c4e3ff551096a683b424242a216fee44685467307f14d58020af1e19660bf2e26064de946bad7eff28950eae9f8209d55723e2d9351e632bbb4 + languageName: node + linkType: hard + "repeat-string@npm:^1.5.2": version: 1.6.1 resolution: "repeat-string@npm:1.6.1" @@ -3879,6 +4535,16 @@ __metadata: languageName: node linkType: hard +"strtok3@npm:^6.2.4": + version: 6.3.0 + resolution: "strtok3@npm:6.3.0" + dependencies: + "@tokenizer/token": ^0.3.0 + peek-readable: ^4.1.0 + checksum: 90732cff3f325aef7c47c511f609b593e0873ec77b5081810071cde941344e6a0ee3ccb0cae1a9f5b4e12c81a2546fd6b322fabcdfbd1dd08362c2ce5291334a + languageName: node + linkType: hard + "supports-color@npm:^5.5.0": version: 5.5.0 resolution: "supports-color@npm:5.5.0" @@ -3986,6 +4652,20 @@ __metadata: languageName: node linkType: hard +"timm@npm:^1.6.1": + version: 1.7.1 + resolution: "timm@npm:1.7.1" + checksum: c80df538ec7fae50a0e3183931b20fbe97f6f2c06907d9675eb7b9d90b3f788af7742285c730192db3b066c4ab22ebae75f8d21970c5b03f38d928d5bb2a0339 + languageName: node + linkType: hard + +"tinycolor2@npm:^1.6.0": + version: 1.6.0 + resolution: "tinycolor2@npm:1.6.0" + checksum: 6df4d07fceeedc0a878d7bac47e2cd47c1ceeb1078340a9eb8a295bc0651e17c750f73d47b3028d829f30b85c15e0572c0fd4142083e4c21a30a597e47f47230 + languageName: node + linkType: hard + "to-regex-range@npm:^5.0.1": version: 5.0.1 resolution: "to-regex-range@npm:5.0.1" @@ -3995,6 +4675,16 @@ __metadata: languageName: node linkType: hard +"token-types@npm:^4.1.1": + version: 4.2.1 + resolution: "token-types@npm:4.2.1" + dependencies: + "@tokenizer/token": ^0.3.0 + ieee754: ^1.2.1 + checksum: cce256766b33e0f08ceffefa2198fb4961a417866d00780e58625999ab5c0699821407053e64eadc41b00bbb6c0d0c4d02fbd2199940d8a3ccb71e1b148ab9a2 + languageName: node + linkType: hard + "touch@npm:^3.1.0": version: 3.1.0 resolution: "touch@npm:3.1.0" @@ -4171,6 +4861,15 @@ __metadata: languageName: node linkType: hard +"utif2@npm:^4.0.1": + version: 4.1.0 + resolution: "utif2@npm:4.1.0" + dependencies: + pako: ^1.0.11 + checksum: b8a7ba68c503c95dd3137eb20c677553dab7641f4539a75dacc2a94ad7e3d1b5b62b547daa559b07cbeb4b9e2f54c15130ced97667775e320bfdccfba9843edd + languageName: node + linkType: hard + "util-deprecate@npm:^1.0.1": version: 1.0.2 resolution: "util-deprecate@npm:1.0.2" @@ -4249,6 +4948,13 @@ __metadata: languageName: node linkType: hard +"whatwg-fetch@npm:^3.4.1": + version: 3.6.20 + resolution: "whatwg-fetch@npm:3.6.20" + checksum: c58851ea2c4efe5c2235f13450f426824cf0253c1d45da28f45900290ae602a20aff2ab43346f16ec58917d5562e159cd691efa368354b2e82918c2146a519c5 + languageName: node + linkType: hard + "whatwg-url@npm:^5.0.0": version: 5.0.0 resolution: "whatwg-url@npm:5.0.0" @@ -4365,7 +5071,26 @@ __metadata: languageName: node linkType: hard -"xml2js@npm:^0.4.19": +"xhr@npm:^2.0.1": + version: 2.6.0 + resolution: "xhr@npm:2.6.0" + dependencies: + global: ~4.4.0 + is-function: ^1.0.1 + parse-headers: ^2.0.0 + xtend: ^4.0.0 + checksum: a1db277e37737caf3ed363d2a33ce4b4ea5b5fc190b663a6f70bc252799185b840ccaa166eaeeea4841c9c60b87741f0a24e29cbcf6708dd425986d4df186d2f + languageName: node + linkType: hard + +"xml-parse-from-string@npm:^1.0.0": + version: 1.0.1 + resolution: "xml-parse-from-string@npm:1.0.1" + checksum: 5155cb98e428409829f4060ce542c55438b2f7646d11fd306d850eaf12d35c06ffd9e86d76aa5230121a533b958fd1a319d6f90a5c113391853d0ff01f4da7bb + languageName: node + linkType: hard + +"xml2js@npm:^0.4.19, xml2js@npm:^0.4.5": version: 0.4.23 resolution: "xml2js@npm:0.4.23" dependencies: @@ -4382,6 +5107,13 @@ __metadata: languageName: node linkType: hard +"xtend@npm:^4.0.0": + version: 4.0.2 + resolution: "xtend@npm:4.0.2" + checksum: ac5dfa738b21f6e7f0dd6e65e1b3155036d68104e67e5d5d1bde74892e327d7e5636a076f625599dc394330a731861e87343ff184b0047fef1360a7ec0a5a36a + languageName: node + linkType: hard + "yallist@npm:^4.0.0": version: 4.0.0 resolution: "yallist@npm:4.0.0"