Merge branch 'master' into master

main
Elbert Alias 7 years ago committed by GitHub
commit c9c6286184
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,2 @@
**/lib/*
node_modules

@ -0,0 +1,6 @@
module.exports = {
"extends": "airbnb-base",
"rules": {
"no-param-reassign": 0
}
};

4
.gitignore vendored

@ -4,6 +4,8 @@
/npm-debug.log
/npm-debug.log
package-lock.json
!.gitkeep
# Junk files
@ -13,3 +15,5 @@ Desktop.ini
._*
tags
tags.*
.idea
/nbproject/private/

@ -3,6 +3,9 @@ sudo: required
services:
- docker
before_install: npm install -g npm@latest
install: npm ci
after_success:
- sha256sum build/* > build/SHA256SUMS
- cat build/SHA256SUMS

@ -1,6 +1,6 @@
FROM alpine
MAINTAINER Elbert Alias <elbert@alias.io>
LABEL maintainer="elbert@alias.io"
ENV WAPPALYZER_DIR=/opt/wappalyzer
@ -8,7 +8,6 @@ RUN apk update && apk add --no-cache \
bash \
curl \
fontconfig \
nodejs \
nodejs-npm \
optipng \
zip
@ -17,14 +16,15 @@ RUN apk update && apk add --no-cache \
# https://github.com/dustinblackman/phantomized
RUN curl -Ls "https://github.com/dustinblackman/phantomized/releases/download/2.1.1a/dockerized-phantomjs.tar.gz" | tar xz -C /
RUN apk del \
curl
RUN apk del curl
RUN npm i -g \
RUN npm i -g n npm@latest
RUN n stable
RUN npm i --unsafe-perm --silent -g \
jsonlint-cli \
manifoldjs \
svg2png-many \
yarn
svg2png-many
RUN mkdir -p $WAPPALYZER_DIR

@ -1,4 +1,4 @@
# Wappalyzer [![Travis](https://img.shields.io/travis/AliasIO/Wappalyzer.svg)](https://travis-ci.org/AliasIO/Wappalyzer/) [![Scrutinizer](https://scrutinizer-ci.com/g/AliasIO/Wappalyzer/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/AliasIO/Wappalyzer/?branch=master)
# Wappalyzer [![Travis](https://travis-ci.org/AliasIO/Wappalyzer.svg?branch=master)](https://travis-ci.org/AliasIO/Wappalyzer/) [![Scrutinizer](https://scrutinizer-ci.com/g/AliasIO/Wappalyzer/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/AliasIO/Wappalyzer/?branch=master)
[Wappalyzer](https://www.wappalyzer.com/) is a
[cross-platform](https://github.com/AliasIO/Wappalyzer/wiki/Drivers) utility that uncovers the

@ -22,7 +22,7 @@ find . -name ".DS_Store" -exec rm {} \;
echo "Prettifying apps.json..."
jsonlint-cli -ist $'\t' src/apps.json
sed -e 's/\\\\/{{ESCAPE}}/g' src/apps.json | jsonlint-cli -ps | sed -e 's/{{ESCAPE}}/\\\\/g' > /tmp/apps.json && cat /tmp/apps.json > src/apps.json
echo "Converting SVG icons to PNG..."
@ -60,6 +60,7 @@ zip -qr ../../../build/wappalyzer_webextension.zip . \
-x \*.gitkeep \
-x \*.js.map \
-x \*.min.js \
-x \*.spec.js \
-x \*.yarn-integrity \
-x \*package.json \
-x \*LICENSE \

@ -6,7 +6,7 @@ set -eu
echo "Validating apps.json..."
jsonlint-cli -tps schema.json src/apps.json > /tmp/apps.json && mv /tmp/apps.json src/apps.json
jsonlint-cli -s schema.json src/apps.json
echo "Validating regular expressions..."
@ -15,3 +15,7 @@ echo "Validating regular expressions..."
echo "Validating icons..."
./bin/validate-icons
echo "Running tests..."
npm run test

@ -16,7 +16,7 @@ var
for (app in json.apps) {
(function(app) {
var
iconPath = json.apps[app].icon || 'default.svg';
iconPath = json.apps[app].icon || 'default.svg',
path = basePath + iconPath,
ext = iconPath.substr(iconPath.length - 4);

@ -0,0 +1,16 @@
<!--
If you need technical help please read https://www.wappalyzer.com/docs before opening an issue.
It also explains well how to add a new application detection.
-->
**Do you want to request a *feature*, a *new application detection* or report a *bug*?**
**Is your issue about WebExtension driver (Chrome & Firefox), the website, the NPM driver or the bookmarklet ?**
**What is the current behavior ?**
**If the current behavior is a bug, please provide the steps to reproduce and if possible a demo of the problem.**
**What is the expected behavior ?**
**Which versions of Wappalyzer, and which browser / OS are affected by this issue ? Did this work in previous versions ?**

1781
npm-shrinkwrap.json generated

File diff suppressed because it is too large Load Diff

@ -1,8 +1,19 @@
{
"dependencies": {
"file-type": "3.8.*",
"is-svg": "2.0.*",
"read-chunk": "2.0.*"
"file-type": "7.4.*",
"is-svg": "2.1.*",
"read-chunk": "2.1.*"
},
"devDependencies": {
"chai": "^4.1.2",
"eslint": "^4.19.1",
"eslint-config-airbnb-base": "^13.0.0",
"eslint-plugin-import": "^2.13.0",
"mocha": "^5.2.0"
},
"scripts": {
"test": "mocha -R spec src",
"lint": "eslint src",
"lint:fix": "eslint src --fix"
}
}

@ -0,0 +1,11 @@
--- src/drivers/npm/node_modules/zombie/lib/document.js 2018-04-20 14:36:04.097829977 +1000
+++ src/drivers/npm/node_modules/zombie/lib/document.js 2018-04-20 14:34:25.699317000 +1000
@@ -281,7 +281,7 @@
// The current window, postMessage and window.close need this
browser._windowInScope = window;
var result = undefined;
- if (typeof code === 'string' || code instanceof String) result = VM.runInContext(code, window, { filename: filename });else if (code) result = code.call(window);
+ if (typeof code === 'string' || code instanceof String) result = VM.runInContext(code, window, { filename: filename, timeout: 1000 });else if (code) result = code.call(window);
browser.emit('evaluated', code, result, filename);
return result;
} catch (error) {

12
run

@ -10,7 +10,17 @@ fi
cmd="docker run --rm -v "$(pwd):/opt/wappalyzer" -it wappalyzer/dev"
$cmd sh -c "yarn install; cd src/drivers/webextension; yarn install"
$cmd sh -c "\
npm i; \
npm shrinkwrap; \
cd src/drivers/webextension; \
npm i; \
npm shrinkwrap; \
cd ../npm; \
npm i; \
npm shrinkwrap"
$cmd sh -c "cat patches/*.patch | patch -p0"
$cmd ./bin/run links
$cmd ./bin/run $@

@ -3,6 +3,9 @@
"type": "object",
"additionalProperties": false,
"properties": {
"$schema": {
"type": "string"
},
"categories": {
"type": "object",
"required": true,
@ -13,7 +16,7 @@
"required": true,
"properties": {
"priority": {
"type": "string"
"type": "number"
},
"name": {
"type": "string"
@ -31,10 +34,16 @@
"cats": {
"type": "array",
"items": {
"type": "string"
"type": "number"
},
"required": true
},
"cookies": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"js": {
"type": "object",
"additionalProperties": {
@ -48,19 +57,28 @@
}
},
"html": {
"type": [ "string", "array" ],
"type": [
"string",
"array"
],
"items": {
"type": "string"
}
},
"excludes": {
"type": [ "string", "array" ],
"type": [
"string",
"array"
],
"items": {
"type": "string"
}
},
"implies": {
"type": [ "string", "array" ],
"type": [
"string",
"array"
],
"items": {
"type": "string"
}
@ -72,7 +90,10 @@
}
},
"script": {
"type": [ "string", "array" ],
"type": [
"string",
"array"
],
"items": {
"type": "string"
}

File diff suppressed because it is too large Load Diff

@ -5,76 +5,78 @@
/** global: wappalyzer */
/** global: XMLHttpRequest */
(function() {
const container = document.getElementById('wappalyzer-container');
const domain = top.location.host;
const url = top.location.href.replace(/#.*$/, '');
const hasOwn = Object.prototype.hasOwnProperty;
(function () {
wappalyzer.driver.document = document;
const container = document.getElementById('wappalyzer-container');
const url = wappalyzer.parseUrl(window.top.location.href);
const hasOwn = Object.prototype.hasOwnProperty;
/**
* Log messages to console
*/
wappalyzer.driver.log = (message, source, type) => {
console.log('[wappalyzer ' + type + ']', '[' + source + ']', message);
console.log(`[wappalyzer ${type}]`, `[${source}]`, message);
};
function getPageContent() {
wappalyzer.log('func: getPageContent');
var env = [];
wappalyzer.log('func: getPageContent', 'driver');
for ( let i in window ) {
env.push(i);
}
var scripts = Array.prototype.slice
const scripts = Array.prototype.slice
.apply(document.scripts)
.filter(s => s.src)
.map(s => s.src);
wappalyzer.analyze(domain, url, {
html: document.documentElement.innerHTML,
env: env,
scripts: scripts
let html = new window.XMLSerializer().serializeToString(document).split('\n');
html = html
.slice(0, 1000).concat(html.slice(html.length - 1000))
.map(line => line.substring(0, 1000))
.join('\n');
wappalyzer.analyze(url, {
html,
scripts,
});
}
function getResponseHeaders() {
wappalyzer.log('func: getResponseHeaders');
function getResponseHeaders() {
wappalyzer.log('func: getResponseHeaders', 'driver');
var xhr = new XMLHttpRequest();
const xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onreadystatechange = () => {
if ( xhr.readyState === 4 && xhr.status ) {
var headers = xhr.getAllResponseHeaders().split("\n");
if (xhr.readyState === 4 && xhr.status) {
const headers = xhr.getAllResponseHeaders().split('\n');
if ( headers.length > 0 && headers[0] != '' ) {
wappalyzer.log('responseHeaders: ' + xhr.getAllResponseHeaders());
if (headers.length > 0 && headers[0] != '') {
wappalyzer.log(`responseHeaders: ${xhr.getAllResponseHeaders()}`, 'driver');
var responseHeaders = {};
const responseHeaders = {};
headers.forEach(line => {
var name, value;
headers.forEach((line) => {
let name,
value;
if ( line ) {
name = line.substring(0, line.indexOf(': '));
if (line) {
name = line.substring(0, line.indexOf(': '));
value = line.substring(line.indexOf(': ') + 2, line.length - 1);
if ( !responseHeaders[name.toLowerCase()] ){
responseHeaders[name.toLowerCase()] = []
if (!responseHeaders[name.toLowerCase()]) {
responseHeaders[name.toLowerCase()] = [];
}
responseHeaders[name.toLowerCase()].push(value);
}
});
wappalyzer.analyze(domain, url, {
headers: responseHeaders
wappalyzer.analyze(url, {
headers: responseHeaders,
});
}
}
}
};
xhr.send();
}
@ -82,46 +84,45 @@
/**
* Display apps
*/
wappalyzer.driver.displayApps = detected => {
wappalyzer.log('func: diplayApps');
var first = true;
var app;
var category;
var html;
html =
'<a id="wappalyzer-close" href="javascript: document.body.removeChild(document.getElementById(\'wappalyzer-container\')); void(0);">' +
'Close' +
'</a>' +
'<div id="wappalyzer-apps">';
if ( detected != null && Object.keys(detected).length ) {
for ( app in detected ) {
if ( !hasOwn.call(detected, app) ) {
wappalyzer.driver.displayApps = (detected) => {
wappalyzer.log('func: diplayApps', 'driver');
let first = true;
let app;
let category;
let html;
html = '<a id="wappalyzer-close" href="javascript: document.body.removeChild(document.getElementById(\'wappalyzer-container\')); void(0);">'
+ 'Close'
+ '</a>'
+ '<div id="wappalyzer-apps">';
if (detected != null && Object.keys(detected).length) {
for (app in detected) {
if (!hasOwn.call(detected, app)) {
continue;
}
var version = detected[app].version,
let version = detected[app].version,
confidence = detected[app].confidence;
html +=
'<div class="wappalyzer-app' + ( first ? ' wappalyzer-first' : '' ) + '">' +
'<a target="_blank" class="wappalyzer-application" href="' + wappalyzer.config.websiteURL + 'applications/' + app.toLowerCase().replace(/ /g, '-').replace(/[^a-z0-9-]/g, '') + '">' +
'<strong>' +
'<img src="' + wappalyzer.config.websiteURL + 'images/icons/' + (wappalyzer.apps[app].icon || 'default.svg') + '" width="16" height="16"/> ' + app +
'</strong>' +
( version ? ' ' + version : '' ) + ( confidence < 100 ? ' (' + confidence + '% sure)' : '' ) +
'</a>';
for ( let i in wappalyzer.apps[app].cats ) {
if ( !hasOwn.call(wappalyzer.apps[app].cats, i) ) {
html
+= `<div class="wappalyzer-app${first ? ' wappalyzer-first' : ''}">`
+ `<a target="_blank" class="wappalyzer-application" href="${wappalyzer.config.websiteURL}applications/${app.toLowerCase().replace(/ /g, '-').replace(/[^a-z0-9-]/g, '')}">`
+ '<strong>'
+ `<img src="${wappalyzer.config.websiteURL}images/icons/${wappalyzer.apps[app].icon || 'default.svg'}" width="16" height="16"/> ${app
}</strong>${
version ? ` ${version}` : ''}${confidence < 100 ? ` (${confidence}% sure)` : ''
}</a>`;
for (const i in wappalyzer.apps[app].cats) {
if (!hasOwn.call(wappalyzer.apps[app].cats, i)) {
continue;
}
category = wappalyzer.categories[wappalyzer.apps[app].cats[i]].name;
html += '<a target="_blank" class="wappalyzer-category" href="' + wappalyzer.config.websiteURL + 'categories/' + slugify(category) + '">' + category + '</a>';
html += `<a target="_blank" class="wappalyzer-category" href="${wappalyzer.config.websiteURL}categories/${slugify(category)}">${category}</a>`;
}
html += '</div>';
@ -142,7 +143,7 @@
*/
function openTab(args) {
open(args.url);
}
};
function slugify(string) {
return string.toLowerCase().replace(/[^a-z0-9-]/g, '-').replace(/--+/g, '-').replace(/(?:^-|-$)/, '');
@ -150,4 +151,4 @@
getPageContent();
getResponseHeaders();
})();
}());

@ -27,19 +27,30 @@ node index.js [url] [options]
### Options
```
--debug=0|1 Output debug messages.
--delay=ms Wait for ms milliseconds between requests.
--max-depth=num Don't analyze pages more than num levels deep.
--max-urls=num Exit when num URLs have been analyzed.
--max-wait=ms Wait no more than ms milliseconds for page resources to load.
--recursive=0|1 Follow links on pages (crawler).
--user-agent=str Set the user agent string.
--password Password to be used for basic HTTP authentication
--proxy Proxy URL, e.g. 'http://user:pass@proxy:8080'
--username Username to be used for basic HTTP authentication
--chunk-size=num Process links in chunks.
--debug=0|1 Output debug messages.
--delay=ms Wait for ms milliseconds between requests.
--html-max-cols=num Limit the number of HTML characters per line processed.
--html-max-rows=num Limit the number of HTML lines processed.
--max-depth=num Don't analyse pages more than num levels deep.
--max-urls=num Exit when num URLs have been analysed.
--max-wait=ms Wait no more than ms milliseconds for page resources to load.
--recursive=0|1 Follow links on pages (crawler).
--user-agent=str Set the user agent string.
```
## Run from a script
```javascript
const Wappalyzer = require('./driver');
const Browser = require('./browsers/zombie');
const url = 'https://www.wappalyzer.com';
const options = {
debug: false,
delay: 500,
@ -48,18 +59,30 @@ const options = {
maxWait: 5000,
recursive: true,
userAgent: 'Wappalyzer',
htmlMaxCols: 2000,
htmlMaxRows: 2000,
};
const wappalyzer = new Wappalyzer('https://www.wappalyzer.com', options);
const wappalyzer = new Wappalyzer(Browser, url, options);
// Optional: capture log output
// wappalyzer.on('log', params => {
// const { message, source, type } = params;
// });
// Optional: do something on page visit
// wappalyzer.on('visit', params => {
// const { browser, pageUrl } = params;
// });
wappalyzer.analyze()
.then(json => {
process.stdout.write(JSON.stringify(json, null, 2) + '\n')
process.stdout.write(`${JSON.stringify(json, null, 2)}\n`);
process.exit(0);
})
.catch(error => {
process.stderr.write(error + '\n')
process.stderr.write(`${error}\n`);
process.exit(1);
});

@ -0,0 +1,20 @@
class Browser {
constructor(options) {
this.options = options;
this.window = null;
this.document = null;
this.statusCode = null;
this.contentType = null;
this.headers = null;
this.statusCode = null;
this.contentType = null;
this.html = null;
this.js = null;
this.links = null;
this.scripts = null;
this.cookies = null;
}
}
module.exports = Browser;

@ -0,0 +1,121 @@
const Zombie = require('zombie');
const Browser = require('../browser');
class ZombieBrowser extends Browser {
constructor(options) {
super(options);
this.browser = new Zombie({
proxy: options.proxy,
silent: true,
strictSSL: false,
userAgent: options.userAgent,
waitDuration: options.maxWait,
});
this.browser.on('authenticate', (auth) => {
auth.username = this.options.username;
auth.password = this.options.password;
});
}
visit(url) {
return new Promise((resolve) => {
this.browser.visit(url, () => {
const resource = this.browser.resources.length
? this.browser.resources.filter(_resource => _resource.response).shift() : null;
this.window = this.browser.window;
this.document = this.browser.document;
this.headers = this.getHeaders();
this.statusCode = resource ? resource.response.status : 0;
this.contentType = this.headers['content-type'] ? this.headers['content-type'].shift() : null;
this.html = this.getHtml();
this.js = this.getJs();
this.links = this.getLinks();
this.scripts = this.getScripts();
this.cookies = this.getCookies();
resolve();
});
});
}
getHeaders() {
const headers = {};
const resource = this.browser.resources.length
? this.browser.resources.filter(_resource => _resource.response).shift() : null;
if (resource) {
// eslint-disable-next-line no-underscore-dangle
resource.response.headers._headers.forEach((header) => {
if (!headers[header[0]]) {
headers[header[0]] = [];
}
headers[header[0]].push(header[1]);
});
}
return headers;
}
getHtml() {
let html = '';
if (this.browser.document && this.browser.document.documentElement) {
try {
html = this.browser.html();
} catch (error) {
this.log(error.message, 'error');
}
}
return html;
}
getScripts() {
let scripts = [];
if (this.browser.document && this.browser.document.scripts) {
scripts = Array.prototype.slice
.apply(this.browser.document.scripts)
.filter(script => script.src)
.map(script => script.src);
}
return scripts;
}
getJs() {
return this.browser.window;
}
getLinks() {
let links = [];
if (this.browser.document) {
links = Array.from(this.browser.document.getElementsByTagName('a'));
}
return links;
}
getCookies() {
const cookies = [];
if (this.browser.cookies) {
this.browser.cookies.forEach(cookie => cookies.push({
name: cookie.key,
value: cookie.value,
domain: cookie.domain,
path: cookie.path,
}));
}
return cookies;
}
}
module.exports = ZombieBrowser;

@ -1,20 +1,80 @@
'use strict';
const Wappalyzer = require('./wappalyzer');
const request = require('request');
const url = require('url');
const fs = require('fs');
const Browser = require('zombie');
const path = require('path');
const Wappalyzer = require('./wappalyzer');
const json = JSON.parse(fs.readFileSync(__dirname + '/apps.json'));
const json = JSON.parse(fs.readFileSync(path.resolve(`${__dirname}/apps.json`)));
const extensions = /^([^.]+$|\.(asp|aspx|cgi|htm|html|jsp|php)$)/;
const errorTypes = {
RESPONSE_NOT_OK: 'Response was not ok',
NO_RESPONSE: 'No response from server',
NO_HTML_DOCUMENT: 'No HTML document',
};
function sleep(ms) {
return ms ? new Promise(resolve => setTimeout(resolve, ms)) : Promise.resolve();
}
function processJs(window, patterns) {
const js = {};
Object.keys(patterns).forEach((appName) => {
js[appName] = {};
Object.keys(patterns[appName]).forEach((chain) => {
js[appName][chain] = {};
patterns[appName][chain].forEach((pattern, index) => {
const properties = chain.split('.');
let value = properties
.reduce((parent, property) => (parent && parent[property]
? parent[property] : null), window);
value = typeof value === 'string' || typeof value === 'number' ? value : !!value;
if (value) {
js[appName][chain][index] = value;
}
});
});
});
return js;
}
function processHtml(html, maxCols, maxRows) {
if (maxCols || maxRows) {
const chunks = [];
const rows = html.length / maxCols;
let i;
for (i = 0; i < rows; i += 1) {
if (i < maxRows / 2 || i > rows - maxRows / 2) {
chunks.push(html.slice(i * maxCols, (i + 1) * maxCols));
}
}
html = chunks.join('\n');
}
return html;
}
class Driver {
constructor(pageUrl, options) {
constructor(Browser, pageUrl, options) {
this.options = Object.assign({}, {
password: '',
proxy: null,
username: '',
chunkSize: 5,
debug: false,
delay: 500,
htmlMaxCols: 2000,
htmlMaxRows: 3000,
maxDepth: 3,
maxUrls: 10,
maxWait: 5000,
@ -22,17 +82,22 @@ class Driver {
userAgent: 'Mozilla/5.0 (compatible; Wappalyzer)',
}, options || {});
this.options.debug = Boolean(this.options.debug);
this.options.debug = Boolean(+this.options.debug);
this.options.recursive = Boolean(+this.options.recursive);
this.options.delay = this.options.recursive ? parseInt(this.options.delay, 10) : 0;
this.options.maxDepth = parseInt(this.options.maxDepth, 10);
this.options.maxUrls = parseInt(this.options.maxUrls, 10);
this.options.maxWait = parseInt(this.options.maxWait, 10);
this.options.recursive = Boolean(this.options.recursive);
this.options.htmlMaxCols = parseInt(this.options.htmlMaxCols, 10);
this.options.htmlMaxRows = parseInt(this.options.htmlMaxRows, 10);
this.origPageUrl = url.parse(pageUrl);
this.analyzedPageUrls = [];
this.analyzedPageUrls = {};
this.apps = [];
this.meta = {};
this.listeners = {};
this.Browser = Browser;
this.wappalyzer = new Wappalyzer();
@ -42,46 +107,67 @@ class Driver {
this.wappalyzer.parseJsPatterns();
this.wappalyzer.driver.log = (message, source, type) => this.log(message, source, type);
this.wappalyzer.driver.displayApps = (detected, meta, context) => this.displayApps(detected, meta, context);
this.wappalyzer.driver
.displayApps = (detected, meta, context) => this.displayApps(detected, meta, context);
process.on('uncaughtException', e => this.wappalyzer.log(`Uncaught exception: ${e.message}`, 'driver', 'error'));
}
on(event, callback) {
if (!this.listeners[event]) {
this.listeners[event] = [];
}
this.listeners[event].push(callback);
}
emit(event, params) {
if (this.listeners[event]) {
this.listeners[event].forEach(listener => listener(params));
}
}
analyze() {
this.time = {
start: new Date().getTime(),
last: new Date().getTime(),
}
};
return this.crawl(this.origPageUrl);
}
log(message, source, type) {
this.options.debug && console.log('[wappalyzer ' + type + ']', '[' + source + ']', message);
if (this.options.debug) {
console.log(`[wappalyzer ${type}]`, `[${source}]`, message);
}
this.emit('log', { message, source, type });
}
displayApps(detected, meta) {
this.meta = meta;
Object.keys(detected).forEach(appName => {
Object.keys(detected).forEach((appName) => {
const app = detected[appName];
var categories = [];
const categories = [];
app.props.cats.forEach(id => {
var category = {};
app.props.cats.forEach((id) => {
const category = {};
category[id] = json.categories[id].name;
categories.push(category)
categories.push(category);
});
if ( !this.apps.some(detectedApp => detectedApp.name === app.name) ) {
if (!this.apps.some(detectedApp => detectedApp.name === app.name)) {
this.apps.push({
name: app.name,
confidence: app.confidenceTotal.toString(),
version: app.version,
version: app.version || null,
icon: app.props.icon || 'default.svg',
website: app.props.website,
categories
categories,
});
}
});
@ -89,209 +175,147 @@ class Driver {
fetch(pageUrl, index, depth) {
// Return when the URL is a duplicate or maxUrls has been reached
if ( this.analyzedPageUrls.indexOf(pageUrl.href) !== -1 || this.analyzedPageUrls.length >= this.options.maxUrls ) {
if (
this.analyzedPageUrls[pageUrl.href]
|| this.analyzedPageUrls.length >= this.options.maxUrls
) {
return Promise.resolve();
}
this.analyzedPageUrls.push(pageUrl.href);
this.analyzedPageUrls[pageUrl.href] = {
status: 0,
};
const timerScope = {
last: new Date().getTime()
last: new Date().getTime(),
};
this.timer('fetch; url: ' + pageUrl.href + '; depth: ' + depth + '; delay: ' + ( this.options.delay * index ) + 'ms', timerScope);
this.timer(`fetch; url: ${pageUrl.href}; depth: ${depth}; delay: ${this.options.delay * index}ms`, timerScope);
return new Promise(resolve => this.sleep(this.options.delay * index).then(() => this.visit(pageUrl, timerScope, resolve)));
}
return new Promise(async (resolve, reject) => {
await sleep(this.options.delay * index);
visit(pageUrl, timerScope, resolve) {
const browser = new Browser({
silent: true,
userAgent: this.options.userAgent,
waitDuration: this.options.maxWait,
this.visit(pageUrl, timerScope, resolve, reject);
});
}
this.timer('browser.visit start; url: ' + pageUrl.href, timerScope);
browser.visit(pageUrl.href, () => {
this.timer('browser.visit end; url: ' + pageUrl.href, timerScope);
async visit(pageUrl, timerScope, resolve, reject) {
const browser = new this.Browser(this.options);
if ( !this.responseOk(browser, pageUrl) ) {
return resolve();
}
browser.log = (message, type) => this.wappalyzer.log(message, 'browser', type);
const headers = this.getHeaders(browser);
const html = this.getHtml(browser);
const scripts = this.getScripts(browser);
const js = this.getJs(browser);
this.timer(`visit start; url: ${pageUrl.href}`, timerScope);
this.wappalyzer.analyze(pageUrl, {
headers,
html,
scripts,
js
});
await browser.visit(pageUrl.href);
const links = Array.from(browser.document.getElementsByTagName('a'))
.filter(link => link.hostname === this.origPageUrl.hostname)
.filter(link => extensions.test(link.pathname))
.map(link => { link.hash = ''; return url.parse(link.href) });
this.timer(`visit end; url: ${pageUrl.href}`, timerScope);
return resolve(links);
});
}
this.analyzedPageUrls[pageUrl.href].status = browser.statusCode;
responseOk(browser, pageUrl) {
// Validate response
const resource = browser.resources.length ? browser.resources.filter(resource => resource.response).shift() : null;
if ( !resource ) {
this.wappalyzer.log('No response from server; url: ' + pageUrl.href, 'driver', 'error');
if (!browser.statusCode) {
return reject(new Error('NO_RESPONSE'));
}
return false;
if (browser.statusCode !== 200) {
return reject(new Error('RESPONSE_NOT_OK'));
}
if ( resource.response.status !== 200 ) {
this.wappalyzer.log('Response was not OK; status: ' + resource.response.status + ' ' + resource.response.statusText + '; url: ' + pageUrl.href, 'driver', 'error');
if (!browser.contentType || !/\btext\/html\b/.test(browser.contentType)) {
this.wappalyzer.log(`Skipping; url: ${pageUrl.href}; content type: ${browser.contentType}`, 'driver');
return false;
delete this.analyzedPageUrls[pageUrl.href];
}
const headers = this.getHeaders(browser);
const { cookies, headers, scripts } = browser;
// Validate content type
const contentType = headers.hasOwnProperty('content-type') ? headers['content-type'].shift() : null;
const html = processHtml(browser.html, this.options.htmlMaxCols, this.options.htmlMaxRows);
const js = processJs(browser.js, this.wappalyzer.jsPatterns);
if ( !contentType || !/\btext\/html\b/.test(contentType) ) {
this.wappalyzer.log('Skipping; url: ' + pageUrl.href + '; content type: ' + contentType, 'driver');
await this.wappalyzer.analyze(pageUrl, {
cookies,
headers,
html,
js,
scripts,
});
this.analyzedPageUrls.splice(this.analyzedPageUrls.indexOf(pageUrl.href), 1);
const reducedLinks = Array.prototype.reduce.call(
browser.links, (results, link) => {
if (link.protocol.match(/https?:/) && link.hostname === this.origPageUrl.hostname && extensions.test(link.pathname)) {
link.hash = '';
return false;
}
results.push(url.parse(link.href));
}
// Validate document
if ( !browser.document || !browser.document.documentElement ) {
this.wappalyzer.log('No HTML document; url: ' + pageUrl.href, 'driver', 'error');
return results;
}, [],
);
return false;
}
this.emit('visit', { browser, pageUrl });
return true;
return resolve(reducedLinks);
}
getHeaders(browser) {
const headers = {};
const resource = browser.resources.length ? browser.resources.filter(resource => resource.response).shift() : null;
if ( resource ) {
resource.response.headers._headers.forEach(header => {
if ( !headers[header[0]] ){
headers[header[0]] = [];
}
crawl(pageUrl, index = 1, depth = 1) {
pageUrl.canonical = `${pageUrl.protocol}//${pageUrl.host}${pageUrl.pathname}`;
headers[header[0]].push(header[1]);
});
}
return new Promise(async (resolve) => {
let links;
return headers;
}
try {
links = await this.fetch(pageUrl, index, depth);
} catch (error) {
const type = error.message && errorTypes[error.message] ? error.message : 'UNKNOWN_ERROR';
const message = error.message && errorTypes[error.message] ? errorTypes[error.message] : 'Unknown error';
getHtml(browser) {
let html = '';
this.analyzedPageUrls[pageUrl.href].error = {
type,
message,
};
try {
html = browser.html();
this.wappalyzer.log(`${message}; url: ${pageUrl.href}`, 'driver', 'error');
}
if ( html.length > 50000 ) {
html = html.substring(0, 25000) + html.substring(html.length - 25000, html.length);
if (links && this.options.recursive && depth < this.options.maxDepth) {
await this.chunk(links.slice(0, this.options.maxUrls), depth + 1);
}
} catch ( error ) {
this.wappalyzer.log(error.message, 'browser', 'error');
}
return html;
return resolve({
urls: this.analyzedPageUrls,
applications: this.apps,
meta: this.meta,
});
});
}
getScripts(browser) {
if ( !browser.document || !browser.document.scripts ) {
return [];
chunk(links, depth, chunk = 0) {
if (links.length === 0) {
return Promise.resolve();
}
const scripts = Array.prototype.slice
.apply(browser.document.scripts)
.filter(script => script.src)
.map(script => script.src);
return scripts;
}
getJs(browser) {
const patterns = this.wappalyzer.jsPatterns;
const js = {};
Object.keys(patterns).forEach(appName => {
js[appName] = {};
Object.keys(patterns[appName]).forEach(chain => {
js[appName][chain] = {};
patterns[appName][chain].forEach((pattern, index) => {
const properties = chain.split('.');
let value = properties.reduce((parent, property) => {
return parent && parent.hasOwnProperty(property) ? parent[property] : null;
}, browser.window);
const chunked = links.splice(0, this.options.chunkSize);
value = typeof value === 'string' ? value : !!value;
return new Promise(async (resolve) => {
await Promise.all(chunked.map((link, index) => this.crawl(link, index, depth)));
if ( value ) {
js[appName][chain][index] = value;
}
});
});
});
return js;
}
await this.chunk(links, depth, chunk + 1);
crawl(pageUrl, index = 1, depth = 1) {
pageUrl.canonical = pageUrl.protocol + '//' + pageUrl.host + pageUrl.pathname;
return new Promise(resolve => {
this.fetch(pageUrl, index, depth)
.catch(() => {})
.then(links => {
if ( links && Boolean(this.options.recursive) && depth < this.options.maxDepth ) {
return Promise.all(links.map((link, index) => this.crawl(link, index + 1, depth + 1)));
} else {
return Promise.resolve();
}
})
.then(() => {
resolve({
urls: this.analyzedPageUrls,
applications: this.apps,
meta: this.meta
});
});
resolve();
});
}
sleep(ms) {
return ms ? new Promise(resolve => setTimeout(resolve, ms)) : Promise.resolve();
}
timer(message, scope) {
const time = new Date().getTime();
const sinceStart = ( Math.round(( time - this.time.start ) / 10) / 100) + 's';
const sinceLast = ( Math.round(( time - scope.last ) / 10) / 100) + 's';
const sinceStart = `${Math.round((time - this.time.start) / 10) / 100}s`;
const sinceLast = `${Math.round((time - scope.last) / 10) / 100}s`;
this.wappalyzer.log('[timer] ' + message + '; lapsed: ' + sinceLast + ' / ' + sinceStart, 'driver');
this.wappalyzer.log(`[timer] ${message}; lapsed: ${sinceLast} / ${sinceStart}`, 'driver');
scope.last = time;
}
};
}
module.exports = Driver;
module.exports.processJs = processJs;
module.exports.processHtml = processHtml;

@ -1,41 +1,45 @@
'use strict';
#!/usr/bin/env node
const Wappalyzer = require('./driver');
const Browser = require('./browsers/zombie');
const args = process.argv.slice(2);
const url = args.shift() || '';
if ( !url ) {
if (!url) {
process.stderr.write('No URL specified\n');
process.exit(1);
}
var options = {};
var arg;
const options = {};
while ( arg = args.shift() ) {
var matches = /--([^=]+)=(.+)/.exec(arg);
let arg;
if ( matches ) {
var key = matches[1].replace(/-\w/g, matches => matches[1].toUpperCase());
var value = matches[2];
do {
arg = args.shift();
const matches = /--([^=]+)=(.+)/.exec(arg);
if (matches) {
const key = matches[1].replace(/-\w/g, _matches => _matches[1].toUpperCase());
const value = matches[2];
options[key] = value;
}
}
} while (arg);
const wappalyzer = new Wappalyzer(url, options);
const wappalyzer = new Wappalyzer(Browser, url, options);
wappalyzer.analyze()
.then(json => {
process.stdout.write(JSON.stringify(json) + '\n')
.then((json) => {
process.stdout.write(`${JSON.stringify(json)}\n`);
process.exit(0);
})
.catch(error => {
process.stderr.write(error + '\n')
.catch((error) => {
process.stderr.write(`${error}\n`);
process.exit(1);
});

@ -0,0 +1,767 @@
{
"name": "wappalyzer",
"version": "5.7.1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@types/node": {
"version": "10.5.7",
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.5.7.tgz",
"integrity": "sha512-VkKcfuitP+Nc/TaTFH0B8qNmn+6NbI6crLkQonbedViVz7O2w8QV/GERPlkJ4bg42VGHiEWa31CoTOPs1q6z1w=="
},
"abab": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/abab/-/abab-1.0.4.tgz",
"integrity": "sha1-X6rZwsB/YN12dw9xzwJbYqY8/U4="
},
"acorn": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.1.tgz",
"integrity": "sha512-d+nbxBUGKg7Arpsvbnlq61mc12ek3EY8EQldM3GPAhWJ1UVxC6TDGbIvUMNU6obBX3i1+ptCIzV4vq0gFPEGVQ=="
},
"acorn-globals": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.1.0.tgz",
"integrity": "sha512-KjZwU26uG3u6eZcfGbTULzFcsoz6pegNKtHPksZPOUsiKo5bUmiBPa38FuHZ/Eun+XYh/JCCkS9AS3Lu4McQOQ==",
"requires": {
"acorn": "^5.0.0"
}
},
"ajv": {
"version": "5.5.2",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
"integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
"requires": {
"co": "^4.6.0",
"fast-deep-equal": "^1.0.0",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.3.0"
}
},
"array-equal": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz",
"integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM="
},
"asn1": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
"integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y="
},
"assert-plus": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
},
"async-limiter": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
"integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg=="
},
"asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
},
"aws-sign2": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
"integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
},
"aws4": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz",
"integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w=="
},
"babel-runtime": {
"version": "6.26.0",
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
"integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
"requires": {
"core-js": "^2.4.0",
"regenerator-runtime": "^0.11.0"
}
},
"bcrypt-pbkdf": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
"integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
"optional": true,
"requires": {
"tweetnacl": "^0.14.3"
}
},
"bluebird": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
"integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA=="
},
"browser-process-hrtime": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.2.tgz",
"integrity": "sha1-Ql1opY00R/AqBKqJQYf86K+Le44="
},
"caseless": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
"integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
},
"co": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
"integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ="
},
"combined-stream": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz",
"integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=",
"requires": {
"delayed-stream": "~1.0.0"
}
},
"content-type-parser": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/content-type-parser/-/content-type-parser-1.0.2.tgz",
"integrity": "sha512-lM4l4CnMEwOLHAHr/P6MEZwZFPJFtAAKgL6pogbXmVZggIqXhdB6RbBtPOTsw2FcXwYhehRGERJmRrjOiIB8pQ=="
},
"core-js": {
"version": "2.5.7",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz",
"integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw=="
},
"core-util-is": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
},
"cssom": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.3.tgz",
"integrity": "sha512-pjE/I/NSp3iyeoxXN5QaoJpgzYUMj2dJHx9OSufoTliJLDx+kuOQaMCJW8OwvrKJswhXUHnHN6eUmUSETN0msg=="
},
"cssstyle": {
"version": "0.2.37",
"resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-0.2.37.tgz",
"integrity": "sha1-VBCXI0yyUTyDzu06zdwn/yeYfVQ=",
"requires": {
"cssom": "0.3.x"
}
},
"dashdash": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
"integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
"requires": {
"assert-plus": "^1.0.0"
}
},
"debug": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"requires": {
"ms": "2.0.0"
},
"dependencies": {
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
}
}
},
"deep-is": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
"integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ="
},
"delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
},
"domexception": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz",
"integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==",
"requires": {
"webidl-conversions": "^4.0.2"
}
},
"ecc-jsbn": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
"integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
"optional": true,
"requires": {
"jsbn": "~0.1.0"
}
},
"escodegen": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.10.0.tgz",
"integrity": "sha512-fjUOf8johsv23WuIKdNQU4P9t9jhQ4Qzx6pC2uW890OloK3Zs1ZAoCNpg/2larNF501jLl3UNy0kIRcF6VI22g==",
"requires": {
"esprima": "^3.1.3",
"estraverse": "^4.2.0",
"esutils": "^2.0.2",
"optionator": "^0.8.1",
"source-map": "~0.6.1"
}
},
"esprima": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz",
"integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM="
},
"estraverse": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
"integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM="
},
"esutils": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
"integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs="
},
"eventsource": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.0.5.tgz",
"integrity": "sha512-IzjLaND9GBK3+fBPhmvG/Yq3FhSDGHnucJCDWhNsneLlN+HX5jeaSpl3Folr2PipGmyUsd/T2Vrua+s6I2aTgQ==",
"requires": {
"original": "^1.0.0"
}
},
"extend": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
"integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ="
},
"extsprintf": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
"integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
},
"fast-deep-equal": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz",
"integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ="
},
"fast-json-stable-stringify": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
"integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I="
},
"fast-levenshtein": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc="
},
"forever-agent": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
"integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
},
"form-data": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz",
"integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=",
"requires": {
"asynckit": "^0.4.0",
"combined-stream": "1.0.6",
"mime-types": "^2.1.12"
}
},
"getpass": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
"integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
"requires": {
"assert-plus": "^1.0.0"
}
},
"har-schema": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
"integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
},
"har-validator": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz",
"integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=",
"requires": {
"ajv": "^5.1.0",
"har-schema": "^2.0.0"
}
},
"html-encoding-sniffer": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz",
"integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==",
"requires": {
"whatwg-encoding": "^1.0.1"
}
},
"http-signature": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
"integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
"requires": {
"assert-plus": "^1.0.0",
"jsprim": "^1.2.2",
"sshpk": "^1.7.0"
}
},
"iconv-lite": {
"version": "0.4.23",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz",
"integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==",
"requires": {
"safer-buffer": ">= 2.1.2 < 3"
}
},
"is-typedarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
},
"isstream": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
},
"jsbn": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
"optional": true
},
"jsdom": {
"version": "11.5.1",
"resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.5.1.tgz",
"integrity": "sha512-89ztIZ03aYK9f1uUrLXLsZndRge/JnZjzjpaN+lrse3coqz+8PR/dX4WLHpbF5fIKTXhDjFODOJw2328lPJ90g==",
"requires": {
"abab": "^1.0.3",
"acorn": "^5.1.2",
"acorn-globals": "^4.0.0",
"array-equal": "^1.0.0",
"browser-process-hrtime": "^0.1.2",
"content-type-parser": "^1.0.1",
"cssom": ">= 0.3.2 < 0.4.0",
"cssstyle": ">= 0.2.37 < 0.3.0",
"domexception": "^1.0.0",
"escodegen": "^1.9.0",
"html-encoding-sniffer": "^1.0.1",
"left-pad": "^1.2.0",
"nwmatcher": "^1.4.3",
"parse5": "^3.0.2",
"pn": "^1.0.0",
"request": "^2.83.0",
"request-promise-native": "^1.0.3",
"sax": "^1.2.1",
"symbol-tree": "^3.2.1",
"tough-cookie": "^2.3.3",
"webidl-conversions": "^4.0.2",
"whatwg-encoding": "^1.0.1",
"whatwg-url": "^6.3.0",
"xml-name-validator": "^2.0.1"
}
},
"json-schema": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
"integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
},
"json-schema-traverse": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
"integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A="
},
"json-stringify-safe": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
"integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
},
"jsprim": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
"integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
"requires": {
"assert-plus": "1.0.0",
"extsprintf": "1.3.0",
"json-schema": "0.2.3",
"verror": "1.10.0"
}
},
"left-pad": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz",
"integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA=="
},
"levn": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
"integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
"requires": {
"prelude-ls": "~1.1.2",
"type-check": "~0.3.2"
}
},
"lodash": {
"version": "4.17.10",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz",
"integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg=="
},
"lodash.sortby": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
"integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg="
},
"mime": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/mime/-/mime-2.3.1.tgz",
"integrity": "sha512-OEUllcVoydBHGN1z84yfQDimn58pZNNNXgZlHXSboxMlFvgI6MXSWpWKpFRra7H1HxpVhHTkrghfRW49k6yjeg=="
},
"mime-db": {
"version": "1.33.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz",
"integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ=="
},
"mime-types": {
"version": "2.1.18",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz",
"integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==",
"requires": {
"mime-db": "~1.33.0"
}
},
"ms": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
},
"nwmatcher": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.4.tgz",
"integrity": "sha512-3iuY4N5dhgMpCUrOVnuAdGrgxVqV2cJpM+XNccjR2DKOB1RUP0aA+wGXEiNziG/UKboFyGBIoKOaNlJxx8bciQ=="
},
"oauth-sign": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
"integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM="
},
"optionator": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
"integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=",
"requires": {
"deep-is": "~0.1.3",
"fast-levenshtein": "~2.0.4",
"levn": "~0.3.0",
"prelude-ls": "~1.1.2",
"type-check": "~0.3.2",
"wordwrap": "~1.0.0"
}
},
"original": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/original/-/original-1.0.1.tgz",
"integrity": "sha512-IEvtB5vM5ULvwnqMxWBLxkS13JIEXbakizMSo3yoPNPCIWzg8TG3Usn/UhXoZFM/m+FuEA20KdzPSFq/0rS+UA==",
"requires": {
"url-parse": "~1.4.0"
}
},
"parse5": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz",
"integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==",
"requires": {
"@types/node": "*"
}
},
"performance-now": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
},
"pn": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz",
"integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA=="
},
"prelude-ls": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
"integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ="
},
"psl": {
"version": "1.1.28",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.1.28.tgz",
"integrity": "sha512-+AqO1Ae+N/4r7Rvchrdm432afjT9hqJRyBN3DQv9At0tPz4hIFSGKbq64fN9dVoCow4oggIIax5/iONx0r9hZw=="
},
"punycode": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
"integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
},
"qs": {
"version": "6.5.2",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
},
"querystringify": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.0.0.tgz",
"integrity": "sha512-eTPo5t/4bgaMNZxyjWx6N2a6AuE0mq51KWvpc7nU/MAqixcI6v6KrGUKES0HaomdnolQBBXU/++X6/QQ9KL4tw=="
},
"regenerator-runtime": {
"version": "0.11.1",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
"integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg=="
},
"request": {
"version": "2.87.0",
"resolved": "https://registry.npmjs.org/request/-/request-2.87.0.tgz",
"integrity": "sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw==",
"requires": {
"aws-sign2": "~0.7.0",
"aws4": "^1.6.0",
"caseless": "~0.12.0",
"combined-stream": "~1.0.5",
"extend": "~3.0.1",
"forever-agent": "~0.6.1",
"form-data": "~2.3.1",
"har-validator": "~5.0.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.17",
"oauth-sign": "~0.8.2",
"performance-now": "^2.1.0",
"qs": "~6.5.1",
"safe-buffer": "^5.1.1",
"tough-cookie": "~2.3.3",
"tunnel-agent": "^0.6.0",
"uuid": "^3.1.0"
},
"dependencies": {
"tough-cookie": {
"version": "2.3.4",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz",
"integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==",
"requires": {
"punycode": "^1.4.1"
}
}
}
},
"request-promise-core": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.1.tgz",
"integrity": "sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY=",
"requires": {
"lodash": "^4.13.1"
}
},
"request-promise-native": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.5.tgz",
"integrity": "sha1-UoF3D2jgyXGeUWP9P6tIIhX0/aU=",
"requires": {
"request-promise-core": "1.1.1",
"stealthy-require": "^1.1.0",
"tough-cookie": ">=2.3.3"
}
},
"requires-port": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8="
},
"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=="
},
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"optional": true
},
"sshpk": {
"version": "1.14.2",
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz",
"integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=",
"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"
}
},
"stealthy-require": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
"integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks="
},
"symbol-tree": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz",
"integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY="
},
"tough-cookie": {
"version": "2.4.3",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
"integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
"requires": {
"psl": "^1.1.24",
"punycode": "^1.4.1"
}
},
"tr46": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz",
"integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=",
"requires": {
"punycode": "^2.1.0"
},
"dependencies": {
"punycode": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
}
}
},
"tunnel-agent": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
"integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
"requires": {
"safe-buffer": "^5.0.1"
}
},
"tweetnacl": {
"version": "0.14.5",
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
"optional": true
},
"type-check": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
"integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
"requires": {
"prelude-ls": "~1.1.2"
}
},
"url-parse": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.3.tgz",
"integrity": "sha512-rh+KuAW36YKo0vClhQzLLveoj8FwPJNu65xLb7Mrt+eZht0IPT0IXgSv8gcMegZ6NvjJUALf6Mf25POlMwD1Fw==",
"requires": {
"querystringify": "^2.0.0",
"requires-port": "^1.0.0"
}
},
"uuid": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
"integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA=="
},
"verror": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
"integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
"requires": {
"assert-plus": "^1.0.0",
"core-util-is": "1.0.2",
"extsprintf": "^1.2.0"
}
},
"webidl-conversions": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
"integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg=="
},
"whatwg-encoding": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.3.tgz",
"integrity": "sha512-jLBwwKUhi8WtBfsMQlL4bUUcT8sMkAtQinscJAe/M4KHCkHuUJAF6vuB0tueNIw4c8ziO6AkRmgY+jL3a0iiPw==",
"requires": {
"iconv-lite": "0.4.19"
},
"dependencies": {
"iconv-lite": {
"version": "0.4.19",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
"integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ=="
}
}
},
"whatwg-url": {
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz",
"integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==",
"requires": {
"lodash.sortby": "^4.7.0",
"tr46": "^1.0.1",
"webidl-conversions": "^4.0.2"
}
},
"wordwrap": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
"integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus="
},
"ws": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz",
"integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==",
"requires": {
"async-limiter": "~1.0.0"
}
},
"xml-name-validator": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-2.0.1.tgz",
"integrity": "sha1-TYuPHszTQZqjYgYb7O9RXh5VljU="
},
"zombie": {
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/zombie/-/zombie-6.1.2.tgz",
"integrity": "sha512-p2KZ1ThrORbOUpEjf9zV4gpcyzwAu1zDrrKF7O2PmeYIsAdh7PjUoKaqJnxLj9FDOyUGPAPxZCrYf54pQM9y7w==",
"requires": {
"babel-runtime": "6.26.0",
"bluebird": "^3.5.1",
"debug": "^3.1.0",
"eventsource": "^1.0.5",
"iconv-lite": "^0.4.21",
"jsdom": "11.5.1",
"lodash": "^4.17.10",
"mime": "^2.3.1",
"ms": "^2.1.1",
"request": "^2.85.0",
"tough-cookie": "^2.3.4",
"ws": "^5.1.1"
}
}
}
}

@ -1,686 +0,0 @@
{
"name": "wappalyzer",
"version": "5.3.1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"abab": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/abab/-/abab-1.0.4.tgz",
"integrity": "sha1-X6rZwsB/YN12dw9xzwJbYqY8/U4="
},
"acorn": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-2.7.0.tgz",
"integrity": "sha1-q259nYhqrKiwhbwzEreaGYQz8Oc="
},
"acorn-globals": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-1.0.9.tgz",
"integrity": "sha1-VbtemGkVB7dFedBRNBMhfDgMVM8=",
"requires": {
"acorn": "2.7.0"
}
},
"ajv": {
"version": "5.5.2",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
"integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
"requires": {
"co": "4.6.0",
"fast-deep-equal": "1.0.0",
"fast-json-stable-stringify": "2.0.0",
"json-schema-traverse": "0.3.1"
}
},
"asn1": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
"integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y="
},
"assert-plus": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
},
"asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
},
"aws-sign2": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
"integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
},
"aws4": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
"integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4="
},
"babel-runtime": {
"version": "5.8.29",
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-5.8.29.tgz",
"integrity": "sha1-SiBSy8/1MXiNOp1rA81/RIKF+CU=",
"requires": {
"core-js": "1.2.7"
}
},
"bcrypt-pbkdf": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
"integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=",
"optional": true,
"requires": {
"tweetnacl": "0.14.5"
}
},
"bluebird": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
"integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA=="
},
"boom": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz",
"integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=",
"requires": {
"hoek": "4.2.0"
}
},
"caseless": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
"integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
},
"co": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
"integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ="
},
"combined-stream": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz",
"integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=",
"requires": {
"delayed-stream": "1.0.0"
}
},
"core-js": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
"integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY="
},
"core-util-is": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
},
"cryptiles": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz",
"integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=",
"requires": {
"boom": "5.2.0"
},
"dependencies": {
"boom": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz",
"integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==",
"requires": {
"hoek": "4.2.0"
}
}
}
},
"cssom": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.2.tgz",
"integrity": "sha1-uANhcMefB6kP8vFuIihAJ6JDhIs="
},
"cssstyle": {
"version": "0.2.37",
"resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-0.2.37.tgz",
"integrity": "sha1-VBCXI0yyUTyDzu06zdwn/yeYfVQ=",
"requires": {
"cssom": "0.3.2"
}
},
"dashdash": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
"integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
"requires": {
"assert-plus": "1.0.0"
}
},
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"requires": {
"ms": "2.0.0"
}
},
"deep-is": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
"integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ="
},
"delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
},
"ecc-jsbn": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
"integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
"optional": true,
"requires": {
"jsbn": "0.1.1"
}
},
"escodegen": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.9.0.tgz",
"integrity": "sha512-v0MYvNQ32bzwoG2OSFzWAkuahDQHK92JBN0pTAALJ4RIxEZe766QJPDR8Hqy7XNUy5K3fnVL76OqYAdc4TZEIw==",
"requires": {
"esprima": "3.1.3",
"estraverse": "4.2.0",
"esutils": "2.0.2",
"optionator": "0.8.2",
"source-map": "0.5.7"
}
},
"esprima": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz",
"integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM="
},
"estraverse": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
"integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM="
},
"esutils": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
"integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs="
},
"eventsource": {
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/eventsource/-/eventsource-0.1.6.tgz",
"integrity": "sha1-Cs7ehJ7X3RzMMsgRuxG5RNTykjI=",
"requires": {
"original": "1.0.0"
}
},
"extend": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
"integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ="
},
"extsprintf": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
"integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
},
"fast-deep-equal": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz",
"integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8="
},
"fast-json-stable-stringify": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
"integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I="
},
"fast-levenshtein": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc="
},
"forever-agent": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
"integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
},
"form-data": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz",
"integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=",
"requires": {
"asynckit": "0.4.0",
"combined-stream": "1.0.5",
"mime-types": "2.1.17"
}
},
"getpass": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
"integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
"requires": {
"assert-plus": "1.0.0"
}
},
"har-schema": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
"integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
},
"har-validator": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz",
"integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=",
"requires": {
"ajv": "5.5.2",
"har-schema": "2.0.0"
}
},
"hawk": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz",
"integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==",
"requires": {
"boom": "4.3.1",
"cryptiles": "3.1.2",
"hoek": "4.2.0",
"sntp": "2.1.0"
}
},
"hoek": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz",
"integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ=="
},
"http-signature": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
"integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
"requires": {
"assert-plus": "1.0.0",
"jsprim": "1.4.1",
"sshpk": "1.13.1"
}
},
"iconv-lite": {
"version": "0.4.19",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
"integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ=="
},
"is-typedarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
},
"isstream": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
},
"jsbn": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
"optional": true
},
"jsdom": {
"version": "7.2.2",
"resolved": "https://registry.npmjs.org/jsdom/-/jsdom-7.2.2.tgz",
"integrity": "sha1-QLQCdwwr2iNGkJa+6Rq2deOx/G4=",
"requires": {
"abab": "1.0.4",
"acorn": "2.7.0",
"acorn-globals": "1.0.9",
"cssom": "0.3.2",
"cssstyle": "0.2.37",
"escodegen": "1.9.0",
"nwmatcher": "1.4.3",
"parse5": "1.5.1",
"request": "2.83.0",
"sax": "1.2.4",
"symbol-tree": "3.2.2",
"tough-cookie": "2.3.3",
"webidl-conversions": "2.0.1",
"whatwg-url-compat": "0.6.5",
"xml-name-validator": "2.0.1"
}
},
"json-schema": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
"integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
},
"json-schema-traverse": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
"integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A="
},
"json-stringify-safe": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
"integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
},
"jsprim": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
"integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
"requires": {
"assert-plus": "1.0.0",
"extsprintf": "1.3.0",
"json-schema": "0.2.3",
"verror": "1.10.0"
}
},
"levn": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
"integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
"requires": {
"prelude-ls": "1.1.2",
"type-check": "0.3.2"
}
},
"lodash": {
"version": "3.10.1",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
"integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y="
},
"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.30.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz",
"integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE="
},
"mime-types": {
"version": "2.1.17",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz",
"integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=",
"requires": {
"mime-db": "1.30.0"
}
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
},
"nwmatcher": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.3.tgz",
"integrity": "sha512-IKdSTiDWCarf2JTS5e9e2+5tPZGdkRJ79XjYV0pzK8Q9BpsFyBq1RGKxzs7Q8UBushGw7m6TzVKz6fcY99iSWw=="
},
"oauth-sign": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
"integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM="
},
"optionator": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
"integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=",
"requires": {
"deep-is": "0.1.3",
"fast-levenshtein": "2.0.6",
"levn": "0.3.0",
"prelude-ls": "1.1.2",
"type-check": "0.3.2",
"wordwrap": "1.0.0"
}
},
"options": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz",
"integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8="
},
"original": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/original/-/original-1.0.0.tgz",
"integrity": "sha1-kUf5P6FpbQS+YeAb1QuurKZWvTs=",
"requires": {
"url-parse": "1.0.5"
}
},
"parse5": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-1.5.1.tgz",
"integrity": "sha1-m387DeMr543CQBsXVzzK8Pb1nZQ="
},
"performance-now": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
},
"prelude-ls": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
"integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ="
},
"punycode": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
"integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
},
"qs": {
"version": "6.5.1",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
"integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A=="
},
"querystringify": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-0.0.4.tgz",
"integrity": "sha1-DPf4T5Rj/wrlHExLFC2VvjdyTZw="
},
"request": {
"version": "2.83.0",
"resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz",
"integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==",
"requires": {
"aws-sign2": "0.7.0",
"aws4": "1.6.0",
"caseless": "0.12.0",
"combined-stream": "1.0.5",
"extend": "3.0.1",
"forever-agent": "0.6.1",
"form-data": "2.3.1",
"har-validator": "5.0.3",
"hawk": "6.0.2",
"http-signature": "1.2.0",
"is-typedarray": "1.0.0",
"isstream": "0.1.2",
"json-stringify-safe": "5.0.1",
"mime-types": "2.1.17",
"oauth-sign": "0.8.2",
"performance-now": "2.1.0",
"qs": "6.5.1",
"safe-buffer": "5.1.1",
"stringstream": "0.0.5",
"tough-cookie": "2.3.3",
"tunnel-agent": "0.6.0",
"uuid": "3.1.0"
}
},
"requires-port": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8="
},
"safe-buffer": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
"integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
},
"sax": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
},
"sntp": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz",
"integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==",
"requires": {
"hoek": "4.2.0"
}
},
"source-map": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
"integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
"optional": true
},
"sshpk": {
"version": "1.13.1",
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz",
"integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=",
"requires": {
"asn1": "0.2.3",
"assert-plus": "1.0.0",
"bcrypt-pbkdf": "1.0.1",
"dashdash": "1.14.1",
"ecc-jsbn": "0.1.1",
"getpass": "0.1.7",
"jsbn": "0.1.1",
"tweetnacl": "0.14.5"
}
},
"stringstream": {
"version": "0.0.5",
"resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
"integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg="
},
"symbol-tree": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz",
"integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY="
},
"tough-cookie": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz",
"integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=",
"requires": {
"punycode": "1.4.1"
}
},
"tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
},
"tunnel-agent": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
"integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
"requires": {
"safe-buffer": "5.1.1"
}
},
"tweetnacl": {
"version": "0.14.5",
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
"optional": true
},
"type-check": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
"integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
"requires": {
"prelude-ls": "1.1.2"
}
},
"url-parse": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.0.5.tgz",
"integrity": "sha1-CFSGBCKv3P7+tsllxmLUgAFpkns=",
"requires": {
"querystringify": "0.0.4",
"requires-port": "1.0.0"
}
},
"uuid": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz",
"integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g=="
},
"verror": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
"integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
"requires": {
"assert-plus": "1.0.0",
"core-util-is": "1.0.2",
"extsprintf": "1.3.0"
}
},
"webidl-conversions": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-2.0.1.tgz",
"integrity": "sha1-O/glj30xjHRDw28uFpQCoaZwNQY="
},
"whatwg-url-compat": {
"version": "0.6.5",
"resolved": "https://registry.npmjs.org/whatwg-url-compat/-/whatwg-url-compat-0.6.5.tgz",
"integrity": "sha1-AImBEa9om7CXVBzVpFymyHmERb8=",
"requires": {
"tr46": "0.0.3"
}
},
"wordwrap": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
"integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus="
},
"xml-name-validator": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-2.0.1.tgz",
"integrity": "sha1-TYuPHszTQZqjYgYb7O9RXh5VljU="
},
"zombie": {
"version": "5.0.7",
"resolved": "https://registry.npmjs.org/zombie/-/zombie-5.0.7.tgz",
"integrity": "sha512-zrYFTD5iWxI3EJohmZ8F2sNafo44F/132wLj5WHLSHmytds60s+JiXLomflQ8sbNuWCZJAuszvf6+eUiVsUqPQ==",
"requires": {
"babel-runtime": "5.8.29",
"bluebird": "3.5.1",
"debug": "2.6.9",
"eventsource": "0.1.6",
"iconv-lite": "0.4.19",
"jsdom": "7.2.2",
"lodash": "3.10.1",
"mime": "1.6.0",
"ms": "0.7.3",
"request": "2.83.0",
"tough-cookie": "2.3.3",
"ws": "1.1.5"
},
"dependencies": {
"ms": {
"version": "0.7.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-0.7.3.tgz",
"integrity": "sha1-cIFVpeROM/X9D8U+gdDUCpG+H/8="
},
"ultron": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz",
"integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po="
},
"ws": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/ws/-/ws-1.1.5.tgz",
"integrity": "sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w==",
"requires": {
"options": "0.0.6",
"ultron": "1.0.2"
}
}
}
}
}
}

@ -2,7 +2,7 @@
"name": "wappalyzer",
"description": "Uncovers the technologies used on websites",
"homepage": "https://github.com/AliasIO/Wappalyzer",
"version": "5.4.3",
"version": "5.7.2",
"author": "Elbert Alias",
"license": "GPL-3.0",
"repository": {
@ -12,12 +12,16 @@
"main": "driver.js",
"files": [
"apps.json",
"index.js",
"browser.js",
"browsers/zombie.js",
"driver.js",
"index.js",
"wappalyzer.js"
],
"bin": {
"wappalyzer": "./index.js"
},
"dependencies": {
"request": "^2.81.0",
"zombie": "^5.0.7"
"zombie": "^6.1.2"
}
}

@ -1,542 +0,0 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
abab@^1.0.0:
version "1.0.4"
resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.4.tgz#5faad9c2c07f60dd76770f71cf025b62a63cfd4e"
acorn-globals@^1.0.4:
version "1.0.9"
resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-1.0.9.tgz#55bb5e98691507b74579d0513413217c380c54cf"
dependencies:
acorn "^2.1.0"
acorn@^2.1.0, acorn@^2.4.0:
version "2.7.0"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-2.7.0.tgz#ab6e7d9d886aaca8b085bc3312b79a198433f0e7"
ajv@^5.1.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.3.0.tgz#4414ff74a50879c208ee5fdc826e32c303549eda"
dependencies:
co "^4.6.0"
fast-deep-equal "^1.0.0"
fast-json-stable-stringify "^2.0.0"
json-schema-traverse "^0.3.0"
asn1@~0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86"
assert-plus@1.0.0, assert-plus@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
aws-sign2@~0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
aws4@^1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e"
babel-runtime@5.8.29:
version "5.8.29"
resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-5.8.29.tgz#4a2052cbcff531788d3a9d6b03cd7f448285f825"
dependencies:
core-js "^1.0.0"
bcrypt-pbkdf@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d"
dependencies:
tweetnacl "^0.14.3"
bluebird@^3.0:
version "3.5.1"
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9"
boom@4.x.x:
version "4.3.1"
resolved "https://registry.yarnpkg.com/boom/-/boom-4.3.1.tgz#4f8a3005cb4a7e3889f749030fd25b96e01d2e31"
dependencies:
hoek "4.x.x"
boom@5.x.x:
version "5.2.0"
resolved "https://registry.yarnpkg.com/boom/-/boom-5.2.0.tgz#5dd9da6ee3a5f302077436290cb717d3f4a54e02"
dependencies:
hoek "4.x.x"
caseless@~0.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
co@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
combined-stream@^1.0.5, combined-stream@~1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009"
dependencies:
delayed-stream "~1.0.0"
core-js@^1.0.0:
version "1.2.7"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636"
core-util-is@1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
cryptiles@3.x.x:
version "3.1.2"
resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-3.1.2.tgz#a89fbb220f5ce25ec56e8c4aa8a4fd7b5b0d29fe"
dependencies:
boom "5.x.x"
cssom@0.3.x, "cssom@>= 0.3.0 < 0.4.0":
version "0.3.2"
resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.2.tgz#b8036170c79f07a90ff2f16e22284027a243848b"
"cssstyle@>= 0.2.29 < 0.3.0":
version "0.2.37"
resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-0.2.37.tgz#541097234cb2513c83ceed3acddc27ff27987d54"
dependencies:
cssom "0.3.x"
dashdash@^1.12.0:
version "1.14.1"
resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
dependencies:
assert-plus "^1.0.0"
debug@^2.2:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
dependencies:
ms "2.0.0"
deep-is@~0.1.3:
version "0.1.3"
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
ecc-jsbn@~0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505"
dependencies:
jsbn "~0.1.0"
escodegen@^1.6.1:
version "1.9.0"
resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.9.0.tgz#9811a2f265dc1cd3894420ee3717064b632b8852"
dependencies:
esprima "^3.1.3"
estraverse "^4.2.0"
esutils "^2.0.2"
optionator "^0.8.1"
optionalDependencies:
source-map "~0.5.6"
esprima@^3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633"
estraverse@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13"
esutils@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b"
eventsource@^0.1.6:
version "0.1.6"
resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-0.1.6.tgz#0acede849ed7dd1ccc32c811bb11b944d4f29232"
dependencies:
original ">=0.0.5"
extend@~3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444"
extsprintf@1.3.0, extsprintf@^1.2.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
fast-deep-equal@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff"
fast-json-stable-stringify@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
fast-levenshtein@~2.0.4:
version "2.0.6"
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
forever-agent@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
form-data@~2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.1.tgz#6fb94fbd71885306d73d15cc497fe4cc4ecd44bf"
dependencies:
asynckit "^0.4.0"
combined-stream "^1.0.5"
mime-types "^2.1.12"
getpass@^0.1.1:
version "0.1.7"
resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
dependencies:
assert-plus "^1.0.0"
har-schema@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
har-validator@~5.0.3:
version "5.0.3"
resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd"
dependencies:
ajv "^5.1.0"
har-schema "^2.0.0"
hawk@~6.0.2:
version "6.0.2"
resolved "https://registry.yarnpkg.com/hawk/-/hawk-6.0.2.tgz#af4d914eb065f9b5ce4d9d11c1cb2126eecc3038"
dependencies:
boom "4.x.x"
cryptiles "3.x.x"
hoek "4.x.x"
sntp "2.x.x"
hoek@4.x.x:
version "4.2.0"
resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d"
http-signature@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
dependencies:
assert-plus "^1.0.0"
jsprim "^1.2.2"
sshpk "^1.7.0"
iconv-lite@^0.4.13:
version "0.4.19"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b"
is-typedarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
isstream@~0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
jsbn@~0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
jsdom@^7.2.2:
version "7.2.2"
resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-7.2.2.tgz#40b402770c2bda23469096bee91ab675e3b1fc6e"
dependencies:
abab "^1.0.0"
acorn "^2.4.0"
acorn-globals "^1.0.4"
cssom ">= 0.3.0 < 0.4.0"
cssstyle ">= 0.2.29 < 0.3.0"
escodegen "^1.6.1"
nwmatcher ">= 1.3.7 < 2.0.0"
parse5 "^1.5.1"
request "^2.55.0"
sax "^1.1.4"
symbol-tree ">= 3.1.0 < 4.0.0"
tough-cookie "^2.2.0"
webidl-conversions "^2.0.0"
whatwg-url-compat "~0.6.5"
xml-name-validator ">= 2.0.1 < 3.0.0"
json-schema-traverse@^0.3.0:
version "0.3.1"
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340"
json-schema@0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
json-stringify-safe@~5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
jsprim@^1.2.2:
version "1.4.1"
resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
dependencies:
assert-plus "1.0.0"
extsprintf "1.3.0"
json-schema "0.2.3"
verror "1.10.0"
levn@~0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee"
dependencies:
prelude-ls "~1.1.2"
type-check "~0.3.2"
lodash@^3.10.1:
version "3.10.1"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6"
mime-db@~1.30.0:
version "1.30.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01"
mime-types@^2.1.12, mime-types@~2.1.17:
version "2.1.17"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a"
dependencies:
mime-db "~1.30.0"
mime@^1.3.4:
version "1.4.1"
resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6"
ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
ms@^0.7.1:
version "0.7.3"
resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.3.tgz#708155a5e44e33f5fd0fc53e81d0d40a91be1fff"
"nwmatcher@>= 1.3.7 < 2.0.0":
version "1.4.3"
resolved "https://registry.yarnpkg.com/nwmatcher/-/nwmatcher-1.4.3.tgz#64348e3b3d80f035b40ac11563d278f8b72db89c"
oauth-sign@~0.8.2:
version "0.8.2"
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
optionator@^0.8.1:
version "0.8.2"
resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64"
dependencies:
deep-is "~0.1.3"
fast-levenshtein "~2.0.4"
levn "~0.3.0"
prelude-ls "~1.1.2"
type-check "~0.3.2"
wordwrap "~1.0.0"
options@>=0.0.5:
version "0.0.6"
resolved "https://registry.yarnpkg.com/options/-/options-0.0.6.tgz#ec22d312806bb53e731773e7cdaefcf1c643128f"
original@>=0.0.5:
version "1.0.0"
resolved "https://registry.yarnpkg.com/original/-/original-1.0.0.tgz#9147f93fa1696d04be61e01bd50baeaca656bd3b"
dependencies:
url-parse "1.0.x"
parse5@^1.5.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/parse5/-/parse5-1.5.1.tgz#9b7f3b0de32be78dc2401b17573ccaf0f6f59d94"
performance-now@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
prelude-ls@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
punycode@^1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
qs@~6.5.1:
version "6.5.1"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8"
querystringify@0.0.x:
version "0.0.4"
resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-0.0.4.tgz#0cf7f84f9463ff0ae51c4c4b142d95be37724d9c"
request@^2.55.0, request@^2.65.0, request@^2.81.0:
version "2.83.0"
resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356"
dependencies:
aws-sign2 "~0.7.0"
aws4 "^1.6.0"
caseless "~0.12.0"
combined-stream "~1.0.5"
extend "~3.0.1"
forever-agent "~0.6.1"
form-data "~2.3.1"
har-validator "~5.0.3"
hawk "~6.0.2"
http-signature "~1.2.0"
is-typedarray "~1.0.0"
isstream "~0.1.2"
json-stringify-safe "~5.0.1"
mime-types "~2.1.17"
oauth-sign "~0.8.2"
performance-now "^2.1.0"
qs "~6.5.1"
safe-buffer "^5.1.1"
stringstream "~0.0.5"
tough-cookie "~2.3.3"
tunnel-agent "^0.6.0"
uuid "^3.1.0"
requires-port@1.0.x:
version "1.0.0"
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
safe-buffer@^5.0.1, safe-buffer@^5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"
sax@^1.1.4:
version "1.2.4"
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
sntp@2.x.x:
version "2.1.0"
resolved "https://registry.yarnpkg.com/sntp/-/sntp-2.1.0.tgz#2c6cec14fedc2222739caf9b5c3d85d1cc5a2cc8"
dependencies:
hoek "4.x.x"
source-map@~0.5.6:
version "0.5.7"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
sshpk@^1.7.0:
version "1.13.1"
resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3"
dependencies:
asn1 "~0.2.3"
assert-plus "^1.0.0"
dashdash "^1.12.0"
getpass "^0.1.1"
optionalDependencies:
bcrypt-pbkdf "^1.0.0"
ecc-jsbn "~0.1.1"
jsbn "~0.1.0"
tweetnacl "~0.14.0"
stringstream@~0.0.5:
version "0.0.5"
resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878"
"symbol-tree@>= 3.1.0 < 4.0.0":
version "3.2.2"
resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6"
tough-cookie@^2.2.0, tough-cookie@~2.3.3:
version "2.3.3"
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561"
dependencies:
punycode "^1.4.1"
tr46@~0.0.1:
version "0.0.3"
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
tunnel-agent@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
dependencies:
safe-buffer "^5.0.1"
tweetnacl@^0.14.3, tweetnacl@~0.14.0:
version "0.14.5"
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
type-check@~0.3.2:
version "0.3.2"
resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72"
dependencies:
prelude-ls "~1.1.2"
ultron@1.0.x:
version "1.0.2"
resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.0.2.tgz#ace116ab557cd197386a4e88f4685378c8b2e4fa"
url-parse@1.0.x:
version "1.0.5"
resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.0.5.tgz#0854860422afdcfefeb6c965c662d4800169927b"
dependencies:
querystringify "0.0.x"
requires-port "1.0.x"
uuid@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04"
verror@1.10.0:
version "1.10.0"
resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
dependencies:
assert-plus "^1.0.0"
core-util-is "1.0.2"
extsprintf "^1.2.0"
webidl-conversions@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-2.0.1.tgz#3bf8258f7d318c7443c36f2e169402a1a6703506"
whatwg-url-compat@~0.6.5:
version "0.6.5"
resolved "https://registry.yarnpkg.com/whatwg-url-compat/-/whatwg-url-compat-0.6.5.tgz#00898111af689bb097541cd5a45ca6c8798445bf"
dependencies:
tr46 "~0.0.1"
wordwrap@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
ws@^1.0.1:
version "1.1.4"
resolved "https://registry.yarnpkg.com/ws/-/ws-1.1.4.tgz#57f40d036832e5f5055662a397c4de76ed66bf61"
dependencies:
options ">=0.0.5"
ultron "1.0.x"
"xml-name-validator@>= 2.0.1 < 3.0.0":
version "2.0.1"
resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-2.0.1.tgz#4d8b8f1eccd3419aa362061becef515e1e559635"
zombie@^5.0.7:
version "5.0.7"
resolved "https://registry.yarnpkg.com/zombie/-/zombie-5.0.7.tgz#215ba90b4b97f75b796c935affcc63d68cbac772"
dependencies:
babel-runtime "5.8.29"
bluebird "^3.0"
debug "^2.2"
eventsource "^0.1.6"
iconv-lite "^0.4.13"
jsdom "^7.2.2"
lodash "^3.10.1"
mime "^1.3.4"
ms "^0.7.1"
request "^2.65.0"
tough-cookie "^2.2.0"
ws "^1.0.1"

@ -10,6 +10,9 @@
"optionTracking": { "message": "Anonyme Statistiken an wappalyzer.com übermitteln" },
"nothingToDo": { "message": "Nichts zu tun." },
"noAppsDetected": { "message": "Keine Applikation entdeckt." },
"categoryPin": { "message": "Immer Icon anzeigen" },
"termsAccept": { "message": "Accept" },
"termsContent": { "message": "This extension sends anonymous information about websites you visit, including domain name and identified technologies, to <a href='https://www.wappalyzer.com'>wappalyzer.com</a>. This can be disabled in the settings." },
"categoryName1": { "message": "CMS" },
"categoryName2": { "message": "Nachrichten Board" },
"categoryName3": { "message": "Datenbankverwaltung" },
@ -64,5 +67,13 @@
"categoryName52": { "message": "Live-Chat" },
"categoryName53": { "message": "CRM" },
"categoryName54": { "message": "SEO" },
"categoryName55": { "message": "Buchhaltung" }
"categoryName55": { "message": "Buchhaltung" },
"categoryName56": { "message": "Cryptominer" },
"categoryName57": { "message": "Statischer Seitengenerator" },
"categoryName58": { "message": "Benutzer-Einbindung" },
"categoryName59": { "message": "JavaScript Bibliotheken" },
"categoryName60": { "message": "Containers" },
"categoryName61": { "message": "SaaS" },
"categoryName62": { "message": "PaaS" },
"categoryName63": { "message": "IaaS" }
}

@ -10,6 +10,9 @@
"optionTracking": { "message": "Ανώνυμη αποστολή αναφορών για εντοπισμένες εφαρμογές στο wappalyzer.com για έρευνα" },
"nothingToDo": { "message": "Καμία ενέργεια." },
"noAppsDetected": { "message": "Δεν ανιχνεύθηκαν εφαρμογές." },
"categoryPin": { "message": "Always show icon" },
"termsAccept": { "message": "Accept" },
"termsContent": { "message": "This extension sends anonymous information about websites you visit, including domain name and identified technologies, to <a href='https://www.wappalyzer.com'>wappalyzer.com</a>. This can be disabled in the settings." },
"categoryName1": { "message": "CMS" },
"categoryName2": { "message": "Διαδικτυακό Φόρουμ" },
"categoryName3": { "message": "Διαχειριστής Βάσης Δεδομένων" },
@ -59,5 +62,14 @@
"categoryName51": { "message": "Σύστημα Κατασκευής Σελίδων Υποδοχής" },
"categoryName52": { "message": "Live Chat" },
"categoryName53": { "message": "CRM" },
"categoryName54": { "message": "SEO" }
"categoryName54": { "message": "SEO" },
"categoryName55": { "message": "Accounting" },
"categoryName56": { "message": "Cryptominer" },
"categoryName57": { "message": "Static Site Generator" },
"categoryName58": { "message": "User Onboarding" },
"categoryName59": { "message": "JavaScript Libraries" },
"categoryName60": { "message": "Containers" },
"categoryName61": { "message": "SaaS" },
"categoryName62": { "message": "PaaS" },
"categoryName63": { "message": "IaaS" }
}

@ -6,10 +6,14 @@
"optionsSave": { "message": "Save options" },
"optionsSaved": { "message": "Saved" },
"optionUpgradeMessage": { "message": "Tell me about upgrades" },
"optionDynamicIcon": { "message": "Use application icon instead of Wappalyzer logo" },
"optionTracking": { "message": "Anonymously send reports on detected applications to wappalyzer.com for research" },
"optionDynamicIcon": { "message": "Use technology icon instead of Wappalyzer logo" },
"optionTracking": { "message": "Anonymously send identified technologies to wappalyzer.com" },
"nothingToDo": { "message": "Nothing to do here." },
"noAppsDetected": { "message": "No applications detected." },
"noAppsDetected": { "message": "No technologies detected." },
"categoryPin": { "message": "Always show icon" },
"termsAccept": { "message": "Accept" },
"termsContent": { "message": "This extension sends anonymous information about websites you visit, including domain name and identified technologies, to <a href='https://www.wappalyzer.com'>wappalyzer.com</a>. This can be disabled in the settings." },
"privacyPolicy": { "message": "Privacy policy" },
"categoryName1": { "message": "CMS" },
"categoryName2": { "message": "Message Board" },
"categoryName3": { "message": "Database Manager" },
@ -64,5 +68,13 @@
"categoryName52": { "message": "Live Chat" },
"categoryName53": { "message": "CRM" },
"categoryName54": { "message": "SEO" },
"categoryName55": { "message": "Accounting" }
"categoryName55": { "message": "Accounting" },
"categoryName56": { "message": "Cryptominer" },
"categoryName57": { "message": "Static Site Generator" },
"categoryName58": { "message": "User Onboarding" },
"categoryName59": { "message": "JavaScript Libraries" },
"categoryName60": { "message": "Containers" },
"categoryName61": { "message": "SaaS" },
"categoryName62": { "message": "PaaS" },
"categoryName63": { "message": "IaaS" }
}

@ -10,6 +10,9 @@
"optionTracking": { "message": "Enviar informes anónimos sobre las aplicaciones detectadas a wappalyzer.com para análisis" },
"nothingToDo": { "message": "Nada que hacer aquí." },
"noAppsDetected": { "message": "Aplicaciones no detectadas." },
"categoryPin": { "message": "Always show icon" },
"termsAccept": { "message": "Accept" },
"termsContent": { "message": "This extension sends anonymous information about websites you visit, including domain name and identified technologies, to <a href='https://www.wappalyzer.com'>wappalyzer.com</a>. This can be disabled in the settings." },
"categoryName1": { "message": "Gestor de Contenido" },
"categoryName2": { "message": "Foro" },
"categoryName3": { "message": "Gestor de Bases de Datos" },
@ -63,5 +66,14 @@
"categoryName51": { "message": "Landing Page Builder" },
"categoryName52": { "message": "Live Chat" },
"categoryName53": { "message": "CRM" },
"categoryName54": { "message": "SEO" }
"categoryName54": { "message": "SEO" },
"categoryName55": { "message": "Accounting" },
"categoryName56": { "message": "Cryptominer" },
"categoryName57": { "message": "Static Site Generator" },
"categoryName58": { "message": "User Onboarding" },
"categoryName59": { "message": "JavaScript Libraries" },
"categoryName60": { "message": "Containers" },
"categoryName61": { "message": "SaaS" },
"categoryName62": { "message": "PaaS" },
"categoryName63": { "message": "IaaS" }
}

@ -0,0 +1,79 @@
{
"github": { "message": "چنگال زدن Wappalyzer در GitHub!" },
"twitter": { "message": "دنبال کردن Wappalyzer در Twitter" },
"website": { "message": "رفتن به wappalyzer.com" },
"options": { "message": "گزینه ها" },
"optionsSave": { "message": "گزینه های ذخیره" },
"optionsSaved": { "message": "ذخیره شده" },
"optionUpgradeMessage": { "message": "درباره ارتقا به من بگویید" },
"optionDynamicIcon": { "message": "از نماد فن آوری به جای علامت Wappalyzer استفاده شود" },
"optionTracking": { "message": "ارسال فن آوری های شناسایی شده به صورت ناشناس به wappalyzer.com" },
"nothingToDo": { "message": "هیچ چیز برای انجام اینجا نیست." },
"noAppsDetected": { "message": "هیچ فن آوری شناسایی نشده است." },
"categoryPin": { "message": "همیشه نماد را نشان بده" },
"termsAccept": { "message": "Accept" },
"termsContent": { "message": "This extension sends anonymous information about websites you visit, including domain name and identified technologies, to <a href='https://www.wappalyzer.com'>wappalyzer.com</a>. This can be disabled in the settings." },
"categoryName1": { "message": "سیستم مدیریت محتوا" },
"categoryName2": { "message": "انجمن پیام" },
"categoryName3": { "message": "مدیر پایگاه داده" },
"categoryName4": { "message": "ابزار مستند سازی" },
"categoryName5": { "message": "ابزارک" },
"categoryName6": { "message": "تجارت الکترونیک" },
"categoryName7": { "message": "گالری تصویر" },
"categoryName8": { "message": "ویکی ها" },
"categoryName9": { "message": "پنل های میزبانی" },
"categoryName10": { "message": "تجزیه و تحلیل ها" },
"categoryName11": { "message": "بلاگ" },
"categoryName12": { "message": "چارچوب جاوا اسکریپت" },
"categoryName13": { "message": "ردیاب مشکل" },
"categoryName14": { "message": "پخش کننده ویدیویی" },
"categoryName15": { "message": "سیستم نظرسنجی" },
"categoryName16": { "message": "Captcha" },
"categoryName17": { "message": "اسکریپ فونت" },
"categoryName18": { "message": "چارچوب وب" },
"categoryName19": { "message": "متفرقه" },
"categoryName20": { "message": "ویرایشگر" },
"categoryName21": { "message": "سامانه مدیریت آموزشی" },
"categoryName22": { "message": "وب سرور" },
"categoryName23": { "message": "ابزار کش" },
"categoryName24": { "message": "ویرایشگر متن توانمند" },
"categoryName25": { "message": "گرافیک های جاوا اسکریپت" },
"categoryName26": { "message": "چارچوب موبایل" },
"categoryName27": { "message": "زبان برنامه نویسی" },
"categoryName28": { "message": "سیستم عامل" },
"categoryName29": { "message": "موتور جستجو" },
"categoryName30": { "message": "پست الکترونیکی تحت وب" },
"categoryName31": { "message": "شبکه تحویل محتوا" },
"categoryName32": { "message": "اتوماسیون بازاریابی" },
"categoryName33": { "message": "افزودنی وب سرور" },
"categoryName34": { "message": "پایگاه داده" },
"categoryName35": { "message": "نقشه" },
"categoryName36": { "message": "شبکه تبلیغاتی" },
"categoryName37": { "message": "خدمات شبکه" },
"categoryName38": { "message": "سرور رسانه" },
"categoryName39": { "message": "وبکم" },
"categoryName40": { "message": "پرینتر" },
"categoryName41": { "message": "پردازنده پرداخت" },
"categoryName42": { "message": "مدیر برچسب" },
"categoryName43": { "message": "Paywall" },
"categoryName44": { "message": "سیستم ساخت/CI" },
"categoryName45": { "message": "سیستم SCADA" },
"categoryName46": { "message": "دسترسی از راه دور" },
"categoryName47": { "message": "ابزار توسعه" },
"categoryName48": { "message": "ذخیره سازی شبکه" },
"categoryName49": { "message": "خواننده های خوراک" },
"categoryName50": { "message": "سیستم مدیریت سند" },
"categoryName51": { "message": "سازنده صفحات Landing" },
"categoryName52": { "message": "گفتگوی زنده" },
"categoryName53": { "message": "مدیریت ارتباط با مشتری" },
"categoryName54": { "message": "بهینه سازی موتور جستجو" },
"categoryName55": { "message": "حسابداری" },
"categoryName56": { "message": "کریپتوماینر" },
"categoryName57": { "message": "تولید کننده سایت ایستا" },
"categoryName58": { "message": "آن بوردینگ کاربر" },
"categoryName59": { "message": "کتابخانه های جاوا اسکریپت" },
"categoryName60": { "message": "Containers" },
"categoryName61": { "message": "SaaS" },
"categoryName62": { "message": "PaaS" },
"categoryName63": { "message": "IaaS" }
}

@ -1,67 +1,79 @@
{
"github": { "message": "Forker Wappalyzer sur GitHub!" },
"noAppsDetected": { "message": "Pas d'applications détectées." },
"nothingToDo": { "message": "Rien à faire ici." },
"optionTracking": { "message": "Envoyer anonymement des rapports sur les applications détectées à wappalyzer.com pour la recherche" },
"optionUpgradeMessage": { "message": "M'afficher les mises à jour" },
"optionDynamicIcon": { "message": "Utiliser l'icône de l'application au lieu du logo Wappalyzer" },
"options": { "message": "Options" },
"optionsSave": { "message": "Sauvegarder les options" },
"optionsSaved": { "message": "Sauvegardé" },
"twitter": { "message": "Suivre Wappalyzer sur Twitter" },
"website": { "message": "Aller sur wappalyzer.com" },
"categoryName1": { "message": "CMS" },
"categoryName2": { "message": "Forum" },
"categoryName3": { "message": "Gestionnaire de base de données" },
"categoryName4": { "message": "Outil de documentation" },
"categoryName5": { "message": "Widget" },
"categoryName6": { "message": "Boutique en ligne" },
"categoryName7": { "message": "Galerie photo" },
"categoryName8": { "message": "Wiki" },
"categoryName9": { "message": "Gestionnaires de serveur" },
"categoryName10": { "message": "Outil de statistiques" },
"categoryName11": { "message": "Blog" },
"categoryName12": { "message": "Framework JavaScript" },
"categoryName13": { "message": "Outil de suivi de problèmes" },
"categoryName14": { "message": "Lecteur de vidéos" },
"categoryName15": { "message": "Système de commentaires" },
"categoryName16": { "message": "Captcha" },
"categoryName17": { "message": "Script de police" },
"categoryName18": { "message": "Framework web" },
"categoryName19": { "message": "Divers" },
"categoryName20": { "message": "Editeur" },
"categoryName21": { "message": "LMS" },
"categoryName22": { "message": "Serveur web" },
"categoryName23": { "message": "Outil de cache" },
"categoryName24": { "message": "Editeur WYSIWYG" },
"categoryName25": { "message": "Graphismes JavaScript" },
"categoryName26": { "message": "Framework pour mobiles" },
"categoryName27": { "message": "Langage de programmation" },
"categoryName28": { "message": "Système d'exploitation" },
"categoryName29": { "message": "Moteur de recherche" },
"categoryName30": { "message": "Web Mail" },
"categoryName31": { "message": "CDN" },
"categoryName32": { "message": "Logiciel de marketing" },
"categoryName33": { "message": "Extension de serveur web" },
"categoryName34": { "message": "Base de données" },
"categoryName35": { "message": "Carte" },
"categoryName36": { "message": "Régie publicitaire" },
"categoryName37": { "message": "Périphérique réseau" },
"categoryName38": { "message": "Serveur multimédia" },
"categoryName39": { "message": "Webcam" },
"categoryName40": { "message": "Imprimante" },
"categoryName41": { "message": "Service de paiement" },
"categoryName42": { "message": "Tag Manager" },
"categoryName43": { "message": "Paywall" },
"categoryName44": { "message": "Système CI" },
"categoryName45": { "message": "Système SCADA" },
"categoryName46": { "message": "Accès à distance" },
"categoryName47": { "message": "Outil de développement" },
"categoryName48": { "message": "Stockage réseau" },
"categoryName49": { "message": "Lecteur RSS" },
"categoryName50": { "message": "Système de gestion de documents" },
"categoryName51": { "message": "Landing Page Builder" },
"categoryName52": { "message": "Chat en direct" },
"categoryName53": { "message": "CRM" },
"categoryName54": { "message": "SEO" }
"github": { "message": "Forker Wappalyzer sur GitHub!" },
"noAppsDetected": { "message": "Pas d'applications détectées." },
"nothingToDo": { "message": "Rien à faire ici." },
"optionTracking": { "message": "Envoyer anonymement des rapports sur les applications détectées à wappalyzer.com pour la recherche" },
"optionUpgradeMessage": { "message": "M'afficher les mises à jour" },
"optionDynamicIcon": { "message": "Utiliser l'icône de l'application au lieu du logo Wappalyzer" },
"options": { "message": "Options" },
"optionsSave": { "message": "Sauvegarder les options" },
"optionsSaved": { "message": "Sauvegardé" },
"twitter": { "message": "Suivre Wappalyzer sur Twitter" },
"website": { "message": "Aller sur wappalyzer.com" },
"categoryPin": { "message": " Toujours afficher l'icône" },
"termsAccept": { "message": "Accept" },
"termsContent": { "message": "This extension sends anonymous information about websites you visit, including domain name and identified technologies, to <a href='https://www.wappalyzer.com'>wappalyzer.com</a>. This can be disabled in the settings." },
"categoryName1": { "message": "CMS" },
"categoryName2": { "message": "Forum" },
"categoryName3": { "message": "Gestionnaire de base de données" },
"categoryName4": { "message": "Outil de documentation" },
"categoryName5": { "message": "Widget" },
"categoryName6": { "message": "Boutique en ligne" },
"categoryName7": { "message": "Galerie photo" },
"categoryName8": { "message": "Wiki" },
"categoryName9": { "message": "Gestionnaires de serveur" },
"categoryName10": { "message": "Outil de statistiques" },
"categoryName11": { "message": "Blog" },
"categoryName12": { "message": "Framework JavaScript" },
"categoryName13": { "message": "Outil de suivi de problèmes" },
"categoryName14": { "message": "Lecteur de vidéos" },
"categoryName15": { "message": "Système de commentaires" },
"categoryName16": { "message": "Captcha" },
"categoryName17": { "message": "Script de police" },
"categoryName18": { "message": "Framework web" },
"categoryName19": { "message": "Divers" },
"categoryName20": { "message": "Éditeur" },
"categoryName21": { "message": "LMS" },
"categoryName22": { "message": "Serveur web" },
"categoryName23": { "message": "Outil de cache" },
"categoryName24": { "message": "Éditeur WYSIWYG" },
"categoryName25": { "message": "Graphismes JavaScript" },
"categoryName26": { "message": "Framework pour mobiles" },
"categoryName27": { "message": "Langage de programmation" },
"categoryName28": { "message": "Système d'exploitation" },
"categoryName29": { "message": "Moteur de recherche" },
"categoryName30": { "message": "Webmail" },
"categoryName31": { "message": "CDN" },
"categoryName32": { "message": "Logiciel de marketing" },
"categoryName33": { "message": "Extension de serveur web" },
"categoryName34": { "message": "Base de données" },
"categoryName35": { "message": "Carte" },
"categoryName36": { "message": "Régie publicitaire" },
"categoryName37": { "message": "Périphérique réseau" },
"categoryName38": { "message": "Serveur multimédia" },
"categoryName39": { "message": "Webcam" },
"categoryName40": { "message": "Imprimante" },
"categoryName41": { "message": "Service de paiement" },
"categoryName42": { "message": "Gestionnaire de balises" },
"categoryName43": { "message": "Paywall" },
"categoryName44": { "message": "Système CI" },
"categoryName45": { "message": "Système SCADA" },
"categoryName46": { "message": "Accès à distance" },
"categoryName47": { "message": "Outil de développement" },
"categoryName48": { "message": "Stockage réseau" },
"categoryName49": { "message": "Lecteur de flux RSS" },
"categoryName51": { "message": "Créateur de Landing Page" },
"categoryName50": { "message": "Système de gestion de documents" },
"categoryName52": { "message": "Chat en direct" },
"categoryName53": { "message": "CRM" },
"categoryName54": { "message": "SEO" },
"categoryName55": { "message": "Comptabilité" },
"categoryName56": { "message": "Crypto-mineur" },
"categoryName57": { "message": "Générateur de site statique" },
"categoryName58": { "message": "User Onboarding" },
"categoryName59": { "message": "JavaScript Libraries" },
"categoryName60": { "message": "Containers" },
"categoryName61": { "message": "SaaS" },
"categoryName62": { "message": "PaaS" },
"categoryName63": { "message": "IaaS" }
}

@ -10,6 +10,9 @@
"optionTracking": { "message": "Ανώνυμη αποστολή αναφορών για εντοπισμένες εφαρμογές στο wappalyzer.com για έρευνα" },
"nothingToDo": { "message": "Καμία ενέργεια." },
"noAppsDetected": { "message": "Δεν ανιχνεύθηκαν εφαρμογές." },
"categoryPin": { "message": "Always show icon" },
"termsAccept": { "message": "Accept" },
"termsContent": { "message": "This extension sends anonymous information about websites you visit, including domain name and identified technologies, to <a href='https://www.wappalyzer.com'>wappalyzer.com</a>. This can be disabled in the settings." },
"categoryName1": { "message": "CMS" },
"categoryName2": { "message": "Διαδικτυακό Φόρουμ" },
"categoryName3": { "message": "Διαχειριστής Βάσης Δεδομένων" },
@ -59,5 +62,14 @@
"categoryName51": { "message": "Σύστημα Κατασκευής Σελίδων Υποδοχής" },
"categoryName52": { "message": "Live Chat" },
"categoryName53": { "message": "CRM" },
"categoryName54": { "message": "SEO" }
"categoryName54": { "message": "SEO" },
"categoryName55": { "message": "Accounting" },
"categoryName56": { "message": "Cryptominer" },
"categoryName57": { "message": "Static Site Generator" },
"categoryName58": { "message": "User Onboarding" },
"categoryName59": { "message": "JavaScript Libraries" },
"categoryName60": { "message": "Containers" },
"categoryName61": { "message": "SaaS" },
"categoryName62": { "message": "PaaS" },
"categoryName63": { "message": "IaaS" }
}

@ -10,6 +10,9 @@
"optionTracking": { "message": "Secara anonim kirimkan laporan tentang aplikasi yang terdeteksi ke wappalyzer.com untuk penelitian" },
"nothingToDo": { "message": "Tak ada yang dilakukan disini." },
"noAppsDetected": { "message": "Tidak ada aplikasi yang terdeteksi." },
"categoryPin": { "message": "Always show icon" },
"termsAccept": { "message": "Accept" },
"termsContent": { "message": "This extension sends anonymous information about websites you visit, including domain name and identified technologies, to <a href='https://www.wappalyzer.com'>wappalyzer.com</a>. This can be disabled in the settings." },
"categoryName1": { "message": "Sistem Pengelola Konten" },
"categoryName2": { "message": "Papan Pesan" },
"categoryName3": { "message": "Pengelola Basis Data" },
@ -63,5 +66,14 @@
"categoryName51": { "message": "Pembuat Laman Landas" },
"categoryName52": { "message": "Chat Langsung" },
"categoryName53": { "message": "CRM" },
"categoryName54": { "message": "SEO" }
"categoryName54": { "message": "SEO" },
"categoryName55": { "message": "Accounting" },
"categoryName56": { "message": "Cryptominer" },
"categoryName57": { "message": "Static Site Generator" },
"categoryName58": { "message": "User Onboarding" },
"categoryName59": { "message": "JavaScript Libraries" },
"categoryName60": { "message": "Containers" },
"categoryName61": { "message": "SaaS" },
"categoryName62": { "message": "PaaS" },
"categoryName63": { "message": "IaaS" }
}

@ -10,6 +10,9 @@
"optionTracking": { "message": "Inviare anonimamente un report sulle applicazioni rilevate a wappalyzer.com per l'analisi" },
"nothingToDo": { "message": "Niente da fare qui." },
"noAppsDetected": { "message": "Nessuna applicazione rilevata." },
"categoryPin": { "message": "Always show icon" },
"termsAccept": { "message": "Accept" },
"termsContent": { "message": "This extension sends anonymous information about websites you visit, including domain name and identified technologies, to <a href='https://www.wappalyzer.com'>wappalyzer.com</a>. This can be disabled in the settings." },
"categoryName1": { "message": "CMS" },
"categoryName2": { "message": "Forum" },
"categoryName3": { "message": "Gestore di Database" },
@ -63,6 +66,14 @@
"categoryName51": { "message": "Landing Page Builder" },
"categoryName52": { "message": "Live Chat" },
"categoryName53": { "message": "CRM" },
"categoryName54": { "message": "SEO" }
"categoryName54": { "message": "SEO" },
"categoryName55": { "message": "Accounting" },
"categoryName56": { "message": "Cryptominer" },
"categoryName57": { "message": "Static Site Generator" },
"categoryName58": { "message": "User Onboarding" },
"categoryName59": { "message": "JavaScript Libraries" },
"categoryName60": { "message": "Containers" },
"categoryName61": { "message": "SaaS" },
"categoryName62": { "message": "PaaS" },
"categoryName63": { "message": "IaaS" }
}

@ -10,6 +10,9 @@
"optionTracking": { "message": "Przesyłaj anonimowe statystyki aplikacji wykrytych przez Wappalyzer do twórców" },
"nothingToDo": { "message": "Nic tu nie ma." },
"noAppsDetected": { "message": "Nie wykryto żadnych aplikacji." },
"categoryPin": { "message": "Zawsze pokazuj tą ikonę" },
"termsAccept": { "message": "Accept" },
"termsContent": { "message": "This extension sends anonymous information about websites you visit, including domain name and identified technologies, to <a href='https://www.wappalyzer.com'>wappalyzer.com</a>. This can be disabled in the settings." },
"categoryName1": { "message": "System zarządzania treścią" },
"categoryName2": { "message": "Forum" },
"categoryName3": { "message": "Menedżer baz danych" },
@ -64,5 +67,13 @@
"categoryName52": { "message": "Czat na żywo" },
"categoryName53": { "message": "Zarządzanie relacjami z klientami" },
"categoryName54": { "message": "SEO" },
"categoryName55": { "message": "Księgowość" }
"categoryName55": { "message": "Księgowość" },
"categoryName56": { "message": "Koparka kryptowalut" },
"categoryName57": { "message": "Generator stron statycznych" },
"categoryName58": { "message": "Wdrażanie użytkownika" },
"categoryName59": { "message": "Biblioteki JavaScript" },
"categoryName60": { "message": "Containers" },
"categoryName61": { "message": "SaaS" },
"categoryName62": { "message": "PaaS" },
"categoryName63": { "message": "IaaS" }
}

@ -1,67 +1,79 @@
{
"github": { "message": "Fork Wappalyzer no GitHub!" },
"noAppsDetected": { "message": "Não foi detetada nenhuma apliação." },
"nothingToDo": { "message": "Nada a fazer aqui." },
"optionTracking": { "message": "Enviar anonimamente relatorios sobre as apliações detetadas ao wappalyzer.com para investigação" },
"optionUpgradeMessage": { "message": "Atualizações automaticas" },
"optionDynamicIcon": { "message": "Utilizar o icone da aplicação em vez do logotido do Wappalyzer" },
"options": { "message": "Definições" },
"optionsSave": { "message": "Guardar as opções" },
"optionsSaved": { "message": "Guardado" },
"twitter": { "message": "Seguir o Wappalyzer no Twitter" },
"website": { "message": "Ir para wappalyzer.com" },
"categoryName1": { "message": "Sistema de gerenciamento de conteudo(CMS)" },
"categoryName2": { "message": "Forum" },
"categoryName3": { "message": "Gestor de base de dados" },
"categoryName4": { "message": "Ferramenta de documentação" },
"categoryName5": { "message": "Widget" },
"categoryName6": { "message": "Loja online" },
"categoryName7": { "message": "Galeria de fotografias" },
"categoryName8": { "message": "Wiki" },
"categoryName9": { "message": "Gestor de servidores" },
"categoryName10": { "message": "Ferramenta de estatisticas" },
"categoryName11": { "message": "Blog" },
"categoryName12": { "message": "Framework JavaScript" },
"categoryName13": { "message": "Ferramenta de seguimento de problemas" },
"categoryName14": { "message": "Leitor de videos" },
"categoryName15": { "message": "Sistemas de comentários" },
"categoryName16": { "message": "Captcha" },
"categoryName17": { "message": "Script de policia" },
"categoryName18": { "message": "Framework WEB" },
"categoryName19": { "message": "Diversos" },
"categoryName20": { "message": "Editor" },
"categoryName21": { "message": "Sistema de gestão de Aprendizagem(LMS)" },
"categoryName22": { "message": "Servidor WEB" },
"categoryName23": { "message": "Ferramenta de cache" },
"categoryName24": { "message": "Editor WYSIWYG" },
"categoryName25": { "message": "Grafismo JavaScript" },
"categoryName26": { "message": "Framework para dispositivos mobile" },
"categoryName27": { "message": "Linguagem de programação" },
"categoryName28": { "message": "Sistema Operativo" },
"categoryName29": { "message": "Motor de pesquisa" },
"categoryName30": { "message": "WebMail" },
"categoryName31": { "message": "Rede de distribuição de conteudo(CDN)" },
"categoryName32": { "message": "Sistema de vendas" },
"categoryName33": { "message": "Extensão do servidor WEB" },
"categoryName34": { "message": "Base de dados" },
"categoryName35": { "message": "Mapa" },
"categoryName36": { "message": "Rede de publicidade" },
"categoryName37": { "message": "Dispositivo de rede" },
"categoryName38": { "message": "Servidor multimédia" },
"categoryName39": { "message": "Webcam" },
"categoryName40": { "message": "Impressora" },
"categoryName41": { "message": "Serviço de pagamento" },
"categoryName42": { "message": "Gestor de Tags" },
"categoryName43": { "message": "Sistema de assinaturas paga(Paywall)" },
"categoryName44": { "message": "Sistema CI" },
"categoryName45": { "message": "Sistema SCADA" },
"categoryName46": { "message": "Acesso à distancia" },
"categoryName47": { "message": "Ferramenta de desenvolvimento" },
"categoryName48": { "message": "Rede de armazenamento" },
"categoryName49": { "message": "Leitor RSS" },
"categoryName50": { "message": "Sistema de gestão de documentos" },
"categoryName51": { "message": "Landing Page Builder" },
"categoryName52": { "message": "Chat em direto" },
"categoryName53": { "message": "Sistemas de relação com o cliente(CRM)" },
"categoryName54": { "message": "Otimização para motores de pesquisa(SEO)" }
"github": { "message": "Fork Wappalyzer no GitHub!" },
"noAppsDetected": { "message": "Não foi detectada nenhuma tecnologia." },
"nothingToDo": { "message": "Nada a fazer aqui." },
"optionDynamicIcon": { "message": "Utilizar o ícone da tecnologia em vez do logótipo do Wappalyzer" },
"optionTracking": { "message": "Envie anonimamente tecnologias identificadas para wappalyzer.com" },
"optionUpgradeMessage": { "message": "Fale-me sobre actualizações" },
"options": { "message": "Opções" },
"optionsSave": { "message": "Opções de Guardar" },
"optionsSaved": { "message": "Guardado" },
"twitter": { "message": "Seguir Wappalyzer no Twitter" },
"website": { "message": "Ir para wappalyzer.com" },
"categoryPin": { "message": "Mostrar sempre ícone" },
"termsAccept": { "message": "Accept" },
"termsContent": { "message": "This extension sends anonymous information about websites you visit, including domain name and identified technologies, to <a href='https://www.wappalyzer.com'>wappalyzer.com</a>. This can be disabled in the settings." },
"categoryName1": { "message": "CMS" },
"categoryName2": { "message": "Fórum" },
"categoryName3": { "message": "Gestor de Base de Dados" },
"categoryName4": { "message": "Ferramenta de Documentação" },
"categoryName5": { "message": "Widget" },
"categoryName6": { "message": "Comércio Eletrónico" },
"categoryName7": { "message": "Galeria de Fotos" },
"categoryName8": { "message": "Wikis" },
"categoryName9": { "message": "Painéis de Hospedagem" },
"categoryName10": { "message": "Analítica" },
"categoryName11": { "message": "Blog" },
"categoryName12": { "message": "Framework JavaScript" },
"categoryName13": { "message": "Rastreador de Problemas" },
"categoryName14": { "message": "Leitor Vídeo" },
"categoryName15": { "message": "Sistema de Comentários" },
"categoryName16": { "message": "Captcha" },
"categoryName17": { "message": "Script de Tipos de Letra" },
"categoryName18": { "message": "Framework Web" },
"categoryName19": { "message": "Diversos" },
"categoryName20": { "message": "Editor" },
"categoryName21": { "message": "LMS" },
"categoryName22": { "message": "Servidor Web" },
"categoryName23": { "message": "Ferramenta de Cache" },
"categoryName24": { "message": "Editor WYSIWYG" },
"categoryName25": { "message": "Gráficos JavaScript" },
"categoryName26": { "message": "Framework Mobile" },
"categoryName27": { "message": "Linguagem de Programação" },
"categoryName28": { "message": "Sistema Operativo" },
"categoryName29": { "message": "Motor de Busca" },
"categoryName30": { "message": "Web Mail" },
"categoryName31": { "message": "CDN" },
"categoryName32": { "message": "Automação de Marketing" },
"categoryName33": { "message": "Extensão de Servidor Web" },
"categoryName34": { "message": "Base de Dados" },
"categoryName35": { "message": "Mapa" },
"categoryName36": { "message": "Rede de Publicidade" },
"categoryName37": { "message": "Serviço de Rede" },
"categoryName38": { "message": "Servidor de Média" },
"categoryName39": { "message": "Webcam" },
"categoryName40": { "message": "Impressão" },
"categoryName41": { "message": "Processador de Pagamento" },
"categoryName42": { "message": "Gestor de Etiquetas" },
"categoryName43": { "message": "Sistema de Subscrição Paga" },
"categoryName44": { "message": "Sistema Build/CI" },
"categoryName45": { "message": "Sistema SCADA" },
"categoryName46": { "message": "Acesso Remoto" },
"categoryName47": { "message": "Ferramenta de Desenvolvimento" },
"categoryName48": { "message": "Rede de Armazenamento" },
"categoryName49": { "message": "Leitores de Feed" },
"categoryName50": { "message": "Sistema de Gestão de Documentos" },
"categoryName51": { "message": "Criador de Páginas de Destino" },
"categoryName52": { "message": "Chat ao Vivo" },
"categoryName53": { "message": "CRM" },
"categoryName54": { "message": "SEO" },
"categoryName55": { "message": "Contabilidade" },
"categoryName56": { "message": "Cryptominer" },
"categoryName57": { "message": "Gerador de Site Estático" },
"categoryName58": { "message": "User Onboarding" },
"categoryName59": { "message": "JavaScript Libraries" },
"categoryName60": { "message": "Containers" },
"categoryName61": { "message": "SaaS" },
"categoryName62": { "message": "PaaS" },
"categoryName63": { "message": "IaaS" }
}

@ -0,0 +1,79 @@
{
"github": { "message": "Fork Wappalyzer no GitHub!" },
"twitter": { "message": "Seguir o Wappalyzer no Twitter" },
"website": { "message": "Ir para wappalyzer.com" },
"options": { "message": "Configurações" },
"optionsSave": { "message": "Salvar configurações" },
"optionsSaved": { "message": "Salvo" },
"optionUpgradeMessage": { "message": "Atualizações automáticas" },
"optionDynamicIcon": { "message": "Utilizar o ícone da tecnologia ao invés da logo do Wappalyzer" },
"optionTracking": { "message": "Enviar relatórios anônimos para wappalyzer.com sobre tecnologias identificadas" },
"nothingToDo": { "message": "Nada a fazer aqui." },
"noAppsDetected": { "message": "Nenhuma tecnologia identificada." },
"categoryPin": { "message": "Sempre mostrar ícone" },
"termsAccept": { "message": "Accept" },
"termsContent": { "message": "This extension sends anonymous information about websites you visit, including domain name and identified technologies, to <a href='https://www.wappalyzer.com'>wappalyzer.com</a>. This can be disabled in the settings." },
"categoryName1": { "message": "CMS" },
"categoryName2": { "message": "Fórum" },
"categoryName3": { "message": "Gestão de banco de dados" },
"categoryName4": { "message": "Ferramenta de documentação" },
"categoryName5": { "message": "Widget" },
"categoryName6": { "message": "Ecommerce" },
"categoryName7": { "message": "Galeria de fotografias" },
"categoryName8": { "message": "Wiki" },
"categoryName9": { "message": "Gestão de servidores" },
"categoryName10": { "message": "Ferramenta estatística" },
"categoryName11": { "message": "Blog" },
"categoryName12": { "message": "Framework JavaScript" },
"categoryName13": { "message": "Rastreamento de problemas" },
"categoryName14": { "message": "Reprodutor de vídeo" },
"categoryName15": { "message": "Sistema de comentários" },
"categoryName16": { "message": "Captcha" },
"categoryName17": { "message": "Script de fonte" },
"categoryName18": { "message": "Framework web" },
"categoryName19": { "message": "Diversos" },
"categoryName20": { "message": "Editor" },
"categoryName21": { "message": "LMS" },
"categoryName22": { "message": "Servidor web" },
"categoryName23": { "message": "Ferramenta de cache" },
"categoryName24": { "message": "Editor WYSIWYG" },
"categoryName25": { "message": "Gráfico JavaScript" },
"categoryName26": { "message": "Framework mobile" },
"categoryName27": { "message": "Linguagem de programação" },
"categoryName28": { "message": "Sistema Operacional" },
"categoryName29": { "message": "Motor de pesquisa" },
"categoryName30": { "message": "Web Mail" },
"categoryName31": { "message": "CDN" },
"categoryName32": { "message": "Automação de marketing" },
"categoryName33": { "message": "Extensão de servidor web" },
"categoryName34": { "message": "Banco de dados" },
"categoryName35": { "message": "Mapa" },
"categoryName36": { "message": "Rede de publicidade" },
"categoryName37": { "message": "Serviço de rede" },
"categoryName38": { "message": "Servidor de mídia" },
"categoryName39": { "message": "Webcam" },
"categoryName40": { "message": "Impressora" },
"categoryName41": { "message": "Serviço de pagamento" },
"categoryName42": { "message": "Gestor de Tags" },
"categoryName43": { "message": "Paywall" },
"categoryName44": { "message": "Sistema de Build/CI" },
"categoryName45": { "message": "Sistema SCADA" },
"categoryName46": { "message": "Acesso remoto" },
"categoryName47": { "message": "Ferramenta de desenvolvimento" },
"categoryName48": { "message": "Armazenamento na rede" },
"categoryName49": { "message": "Leitor de feed" },
"categoryName50": { "message": "Sistema de gestão de documentos" },
"categoryName51": { "message": "Landing Page Builder" },
"categoryName52": { "message": "Chat direto" },
"categoryName53": { "message": "CRM" },
"categoryName54": { "message": "SEO" },
"categoryName55": { "message": "Contabilidade" },
"categoryName56": { "message": "Minerador de cryptomoedas" },
"categoryName57": { "message": "Gerador de sites estáticos" },
"categoryName58": { "message": "Integração com usuário" },
"categoryName59": { "message": "Biblioteca JavaScript" },
"categoryName60": { "message": "Containers" },
"categoryName61": { "message": "SaaS" },
"categoryName62": { "message": "PaaS" },
"categoryName63": { "message": "IaaS" }
}

@ -10,6 +10,9 @@
"optionTracking": { "message": "Trimite rapoarte anonime despre aplicațiile detectate către wappalyzer.com pentru cercetare" },
"nothingToDo": { "message": "Nimic de făcut pe pagina curentă." },
"noAppsDetected": { "message": "Nici o aplicație detectată." },
"categoryPin": { "message": "Afișează icon tot timpul" },
"termsAccept": { "message": "Accept" },
"termsContent": { "message": "This extension sends anonymous information about websites you visit, including domain name and identified technologies, to <a href='https://www.wappalyzer.com'>wappalyzer.com</a>. This can be disabled in the settings." },
"categoryName1": { "message": "CMS" },
"categoryName2": { "message": "Forum de discuții" },
"categoryName3": { "message": "Manager baze de date" },
@ -60,5 +63,13 @@
"categoryName52": { "message": "Chat Live" },
"categoryName53": { "message": "CRM" },
"categoryName54": { "message": "SEO" },
"categoryName55": { "message": "Contabilitate" }
"categoryName55": { "message": "Accounting" },
"categoryName56": { "message": "Cryptominer" },
"categoryName57": { "message": "Static Site Generator" },
"categoryName58": { "message": "User Onboarding" },
"categoryName59": { "message": "JavaScript Libraries" },
"categoryName60": { "message": "Containers" },
"categoryName61": { "message": "SaaS" },
"categoryName62": { "message": "PaaS" },
"categoryName63": { "message": "IaaS" }
}

@ -1,67 +1,79 @@
{
"categoryName1" : { "message" : "CMS" },
"categoryName2" : { "message" : "Форум" },
"categoryName3" : { "message" : "Менеджер БД" },
"categoryName4" : { "message" : "Документация" },
"categoryName5" : { "message" : "Виджет" },
"categoryName6" : { "message" : "Электронная коммерция" },
"categoryName7" : { "message" : "Фотогалерея" },
"categoryName8" : { "message" : "Вики" },
"categoryName9" : { "message" : "Панель управления хостингом" },
"categoryName10" : { "message" : "Аналитика" },
"categoryName11" : { "message" : "Блог" },
"categoryName12" : { "message" : "JS фреймворк" },
"categoryName13" : { "message" : "Баг трекер" },
"categoryName14" : { "message" : "Видео плеер" },
"categoryName15" : { "message" : "Система комментариев" },
"categoryName16" : { "message" : "Капча" },
"categoryName17" : { "message" : "Шрифт" },
"categoryName18" : { "message" : "Веб фреймворк" },
"categoryName19" : { "message" : "Прочее" },
"categoryName20" : { "message" : "HTML редактор" },
"categoryName21" : { "message" : "LMS" },
"categoryName22" : { "message" : "Веб сервер" },
"categoryName23" : { "message" : "Кеширование" },
"categoryName24" : { "message" : "WYSIWYG редактор" },
"categoryName25" : { "message" : "JS графика" },
"categoryName26" : { "message" : "Мобильный фреймворк" },
"categoryName27" : { "message" : "Язык программирования" },
"categoryName28" : { "message" : "Операционная система" },
"categoryName29" : { "message" : "Поисковый движок" },
"categoryName30" : { "message" : "Веб почта" },
"categoryName31" : { "message" : "CDN" },
"categoryName32" : { "message" : "Управление маркетингом" },
"categoryName33" : { "message" : "Расширение Веб сервера" },
"categoryName34" : { "message" : "База данных" },
"categoryName35" : { "message" : "Карта" },
"categoryName36" : { "message" : "Рекламная сеть" },
"categoryName37" : { "message" : "Сетевая служба" },
"categoryName38" : { "message" : "Медиа сервер" },
"categoryName39" : { "message" : "Вебкамера" },
"categoryName40" : { "message" : "Принтер" },
"categoryName41" : { "message" : "Платёжная система" },
"categoryName42" : { "message" : "Менеджер тэгов" },
"categoryName43" : { "message" : "Paywall" },
"categoryName44" : { "message" : "Система непрерывной интеграции" },
"categoryName45" : { "message" : "Система SCADA" },
"categoryName46" : { "message" : "Удаленное управление" },
"categoryName47" : { "message" : "Утилита для разработчиков" },
"categoryName48" : { "message" : "Сетевое хранилище" },
"categoryName49" : { "message" : "Граббер контента" },
"categoryName50" : { "message" : "Управление документами" },
"categoryName51" : { "message": "Генератор лендингов" },
"categoryName52" : { "message": "Live Chat" },
"categoryName53" : { "message": "CRM" },
"github" : { "message" : "Форкнуть на GitHub!" },
"noAppsDetected" : { "message" : "Нет данных о сайте" },
"nothingToDo" : { "message" : "Тут нечего искать" },
"optionTracking" : { "message" : "Анонимно отправлять статистику распознанных данных на сервер (для исследований)" },
"optionDynamicIcon" : { "message": "Использовать значок приложения вместо логотипа Wappalyzer" },
"optionUpgradeMessage" : { "message" : "Оповещать меня об обновлениях" },
"options" : { "message" : "Настройки" },
"optionsSave" : { "message" : "Сохранить" },
"optionsSaved" : { "message" : "Успешно сохранено!" },
"twitter" : { "message" : "Следите за новостями в Твиттере" },
"website" : { "message" : "Перейти на Wappalyzer.com" },
"categoryName54": { "message": "SEO" }
"categoryName1": { "message": "CMS" },
"categoryName2": { "message": "Форум" },
"categoryName3": { "message": "Менеджер БД" },
"categoryName4": { "message": "Документация" },
"categoryName5": { "message": "Виджет" },
"categoryName6": { "message": "Электронная коммерция" },
"categoryName7": { "message": "Фотогалерея" },
"categoryName8": { "message": "Вики" },
"categoryName9": { "message": "Панель управления хостингом" },
"categoryName10": { "message": "Аналитика" },
"categoryName11": { "message": "Блог" },
"categoryName12": { "message": "JS фреймворк" },
"categoryName13": { "message": "Баг трекер" },
"categoryName14": { "message": "Видео плеер" },
"categoryName15": { "message": "Система комментариев" },
"categoryName16": { "message": "Капча" },
"categoryName17": { "message": "Шрифт" },
"categoryName18": { "message": "Веб фреймворк" },
"categoryName19": { "message": "Прочее" },
"categoryName20": { "message": "HTML редактор" },
"categoryName21": { "message": "LMS" },
"categoryName22": { "message": "Веб сервер" },
"categoryName23": { "message": "Кеширование" },
"categoryName24": { "message": "WYSIWYG редактор" },
"categoryName25": { "message": "JS графика" },
"categoryName26": { "message": "Мобильный фреймворк" },
"categoryName27": { "message": "Язык программирования" },
"categoryName28": { "message": "Операционная система" },
"categoryName29": { "message": "Поисковый движок" },
"categoryName30": { "message": "Веб почта" },
"categoryName31": { "message": "CDN" },
"categoryName32": { "message": "Управление маркетингом" },
"categoryName33": { "message": "Расширение Веб сервера" },
"categoryName34": { "message": "База данных" },
"categoryName35": { "message": "Карта" },
"categoryName36": { "message": "Рекламная сеть" },
"categoryName37": { "message": "Сетевая служба" },
"categoryName38": { "message": "Медиа сервер" },
"categoryName39": { "message": "Вебкамера" },
"categoryName40": { "message": "Принтер" },
"categoryName41": { "message": "Платёжная система" },
"categoryName42": { "message": "Менеджер тэгов" },
"categoryName43": { "message": "Paywall" },
"categoryName44": { "message": "Система непрерывной интеграции" },
"categoryName45": { "message": "Система SCADA" },
"categoryName46": { "message": "Удаленное управление" },
"categoryName47": { "message": "Утилита для разработчиков" },
"categoryName48": { "message": "Сетевое хранилище" },
"categoryName49": { "message": "Граббер контента" },
"categoryName50": { "message": "Управление документами" },
"categoryName51": { "message": "Генератор лендингов" },
"categoryName52": { "message": "Live Chat" },
"categoryName53": { "message": "CRM" },
"github": { "message": "Форкнуть на GitHub!" },
"noAppsDetected": { "message": "Нет данных о сайте" },
"nothingToDo": { "message": "Тут нечего искать" },
"optionTracking": { "message": "Анонимно отправлять статистику распознанных данных на сервер (для исследований)" },
"optionDynamicIcon": { "message": "Использовать значок приложения вместо логотипа Wappalyzer" },
"optionUpgradeMessage": { "message": "Оповещать меня об обновлениях" },
"options": { "message": "Настройки" },
"optionsSave": { "message": "Сохранить" },
"optionsSaved": { "message": "Успешно сохранено!" },
"twitter": { "message": "Следите за новостями в Твиттере" },
"website": { "message": "Перейти на Wappalyzer.com" },
"categoryPin": { "message": "Always show icon" },
"termsAccept": { "message": "Accept" },
"termsContent": { "message": "This extension sends anonymous information about websites you visit, including domain name and identified technologies, to <a href='https://www.wappalyzer.com'>wappalyzer.com</a>. This can be disabled in the settings." },
"categoryName54": { "message": "SEO" },
"categoryName55": { "message": "Бухгалтерский учёт" },
"categoryName56": { "message": "Криптомайнер" },
"categoryName57": { "message": "Генератор статических сайтов" },
"categoryName58": { "message": "User Onboarding" },
"categoryName59": { "message": "JavaScript Libraries" },
"categoryName60": { "message": "Containers" },
"categoryName61": { "message": "SaaS" },
"categoryName62": { "message": "PaaS" },
"categoryName63": { "message": "IaaS" }
}

@ -1,67 +1,79 @@
{
"github": { "message": "Forknite Wappalyzer na GitHube!" },
"twitter": { "message": "Sledujte Wappalyzer na Twitteri" },
"website": { "message": "Prejdite na adresu wappalyzer.com" },
"options": { "message": "Možnosti" },
"optionsSave": { "message": "Uložiť možnosti" },
"optionsSaved": { "message": "Uložené" },
"optionUpgradeMessage": { "message": "Povedzte mi o upgradoch" },
"optionDynamicIcon": { "message": "Použiť ikonu aplikácie namiesto loga Wappalyzer" },
"optionTracking": { "message": "Anonymne posielať správy o zistených aplikáciách na wappalyzer.com pre výskum" },
"nothingToDo": { "message": "Nie je tu čo robiť." },
"noAppsDetected": { "message": "Žiadne aplikácie neboli zistené." },
"categoryName1": { "message": "CMS" },
"categoryName2": { "message": "Message Board" },
"categoryName3": { "message": "Správca databáz" },
"categoryName4": { "message": "Dokumentačný nástroj" },
"categoryName5": { "message": "Widget" },
"categoryName6": { "message": "E-commerce" },
"categoryName7": { "message": "Fotogalérie" },
"categoryName8": { "message": "Wiki" },
"categoryName9": { "message": "Hosting panely" },
"categoryName10": { "message": "Analytika" },
"categoryName11": { "message": "Blog" },
"categoryName12": { "message": "JavaScript Framework" },
"categoryName13": { "message": "Issue Tracker" },
"categoryName14": { "message": "Video prehrávač" },
"categoryName15": { "message": "Systém komentárov" },
"categoryName16": { "message": "Captcha" },
"categoryName17": { "message": "Font Script" },
"categoryName18": { "message": "Web Framework" },
"categoryName19": { "message": "Rôzne" },
"categoryName20": { "message": "Editor" },
"categoryName21": { "message": "LMS" },
"categoryName22": { "message": "Webový server" },
"categoryName23": { "message": "Cache nástroj" },
"categoryName24": { "message": "Rich Text editor" },
"categoryName25": { "message": "JavaScript Grafika" },
"categoryName26": { "message": "Mobile Framework" },
"categoryName27": { "message": "Programovací jazyk" },
"categoryName28": { "message": "Operačný systém" },
"categoryName29": { "message": "Vyhľadávač" },
"categoryName30": { "message": "Webmail" },
"categoryName31": { "message": "CDN" },
"categoryName32": { "message": "Marketingová automatizácia" },
"categoryName33": { "message": "Rozšírenie webového servera" },
"categoryName34": { "message": "Databáza" },
"categoryName35": { "message": "Mapa" },
"categoryName36": { "message": "Reklamná sieť" },
"categoryName37": { "message": "Sieťová služba" },
"categoryName38": { "message": "Media Server" },
"categoryName39": { "message": "Webkamera" },
"categoryName40": { "message": "Tlačiareň" },
"categoryName41": { "message": "Platobný procesor" },
"categoryName42": { "message": "Správca tagov" },
"categoryName43": { "message": "Platobná brána" },
"categoryName44": { "message": "Build/CI systém" },
"categoryName45": { "message": "SCADA systém" },
"categoryName46": { "message": "Vzdialený prístup" },
"categoryName47": { "message": "Vývojový nástroj" },
"categoryName48": { "message": "Sieťové úložisko" },
"categoryName49": { "message": "Čítačky feedu" },
"categoryName50": { "message": "Systémy správy dokumentov" },
"categoryName51": { "message": "Nástroj na tvorbu vstupnej stránky" },
"categoryName52": { "message": "Živý chat" },
"categoryName53": { "message": "CRM" },
"categoryName54": { "message": "SEO" }
"github": { "message": "Forknite Wappalyzer na GitHube!" },
"twitter": { "message": "Sledujte Wappalyzer na Twitteri" },
"website": { "message": "Prejdite na adresu wappalyzer.com" },
"options": { "message": "Možnosti" },
"optionsSave": { "message": "Uložiť možnosti" },
"optionsSaved": { "message": "Uložené" },
"optionUpgradeMessage": { "message": "Povedzte mi o upgradoch" },
"optionDynamicIcon": { "message": "Použiť ikonu aplikácie namiesto loga Wappalyzer" },
"optionTracking": { "message": "Anonymne posielať správy o zistených aplikáciách na wappalyzer.com pre výskum" },
"nothingToDo": { "message": "Nie je tu čo robiť." },
"noAppsDetected": { "message": "Žiadne aplikácie neboli zistené." },
"categoryPin": { "message": "Always show icon" },
"termsAccept": { "message": "Accept" },
"termsContent": { "message": "This extension sends anonymous information about websites you visit, including domain name and identified technologies, to <a href='https://www.wappalyzer.com'>wappalyzer.com</a>. This can be disabled in the settings." },
"categoryName1": { "message": "CMS" },
"categoryName2": { "message": "Message Board" },
"categoryName3": { "message": "Správca databáz" },
"categoryName4": { "message": "Dokumentačný nástroj" },
"categoryName5": { "message": "Widget" },
"categoryName6": { "message": "E-commerce" },
"categoryName7": { "message": "Fotogalérie" },
"categoryName8": { "message": "Wiki" },
"categoryName9": { "message": "Hosting panely" },
"categoryName10": { "message": "Analytika" },
"categoryName11": { "message": "Blog" },
"categoryName12": { "message": "JavaScript Framework" },
"categoryName13": { "message": "Issue Tracker" },
"categoryName14": { "message": "Video prehrávač" },
"categoryName15": { "message": "Systém komentárov" },
"categoryName16": { "message": "Captcha" },
"categoryName17": { "message": "Font Script" },
"categoryName18": { "message": "Web Framework" },
"categoryName19": { "message": "Rôzne" },
"categoryName20": { "message": "Editor" },
"categoryName21": { "message": "LMS" },
"categoryName22": { "message": "Webový server" },
"categoryName23": { "message": "Cache nástroj" },
"categoryName24": { "message": "Rich Text editor" },
"categoryName25": { "message": "JavaScript Grafika" },
"categoryName26": { "message": "Mobile Framework" },
"categoryName27": { "message": "Programovací jazyk" },
"categoryName28": { "message": "Operačný systém" },
"categoryName29": { "message": "Vyhľadávač" },
"categoryName30": { "message": "Webmail" },
"categoryName31": { "message": "CDN" },
"categoryName32": { "message": "Marketingová automatizácia" },
"categoryName33": { "message": "Rozšírenie webového servera" },
"categoryName34": { "message": "Databáza" },
"categoryName35": { "message": "Mapa" },
"categoryName36": { "message": "Reklamná sieť" },
"categoryName37": { "message": "Sieťová služba" },
"categoryName38": { "message": "Media Server" },
"categoryName39": { "message": "Webkamera" },
"categoryName40": { "message": "Tlačiareň" },
"categoryName41": { "message": "Platobný procesor" },
"categoryName42": { "message": "Správca tagov" },
"categoryName43": { "message": "Platobná brána" },
"categoryName44": { "message": "Build/CI systém" },
"categoryName45": { "message": "SCADA systém" },
"categoryName46": { "message": "Vzdialený prístup" },
"categoryName47": { "message": "Vývojový nástroj" },
"categoryName48": { "message": "Sieťové úložisko" },
"categoryName49": { "message": "Čítačky feedu" },
"categoryName50": { "message": "Systémy správy dokumentov" },
"categoryName51": { "message": "Nástroj na tvorbu vstupnej stránky" },
"categoryName52": { "message": "Živý chat" },
"categoryName53": { "message": "CRM" },
"categoryName54": { "message": "SEO" },
"categoryName55": { "message": "Accounting" },
"categoryName56": { "message": "Cryptominer" },
"categoryName57": { "message": "Static Site Generator" },
"categoryName58": { "message": "User Onboarding" },
"categoryName59": { "message": "JavaScript Libraries" },
"categoryName60": { "message": "Containers" },
"categoryName61": { "message": "SaaS" },
"categoryName62": { "message": "PaaS" },
"categoryName63": { "message": "IaaS" }
}

@ -10,6 +10,9 @@
"optionTracking": { "message": "Anonim olarak tespit edilen uygulamalar hakkında wappalyzer.com'a araştırma raporları gönderin" },
"nothingToDo": { "message": "Burada yapacak birşey yok." },
"noAppsDetected": { "message": "Uygulamalar tespit edilemedi." },
"categoryPin": { "message": "Always show icon" },
"termsAccept": { "message": "Accept" },
"termsContent": { "message": "This extension sends anonymous information about websites you visit, including domain name and identified technologies, to <a href='https://www.wappalyzer.com'>wappalyzer.com</a>. This can be disabled in the settings." },
"categoryName1": { "message": "CMS" },
"categoryName2": { "message": "Mesaj Tahtası" },
"categoryName3": { "message": "Veritabanı Yöneticisi" },
@ -64,5 +67,13 @@
"categoryName52": { "message": "Canlı Sohbet" },
"categoryName53": { "message": "CRM" },
"categoryName54": { "message": "SEO" },
"categoryName55": { "message": "Muhasebe" }
"categoryName55": { "message": "Muhasebe" },
"categoryName56": { "message": "Cryptominer" },
"categoryName57": { "message": "Static Site Generator" },
"categoryName58": { "message": "User Onboarding" },
"categoryName59": { "message": "JavaScript Libraries" },
"categoryName60": { "message": "Containers" },
"categoryName61": { "message": "SaaS" },
"categoryName62": { "message": "PaaS" },
"categoryName63": { "message": "IaaS" }
}

@ -10,6 +10,9 @@
"optionTracking": { "message": "Анонімно надсилати статистику розпізнавань на сервер для досліджень" },
"nothingToDo": { "message": "Тут нічого робити." },
"noAppsDetected": { "message": "Нічого не знайдено." },
"categoryPin": { "message": "Always show icon" },
"termsAccept": { "message": "Accept" },
"termsContent": { "message": "This extension sends anonymous information about websites you visit, including domain name and identified technologies, to <a href='https://www.wappalyzer.com'>wappalyzer.com</a>. This can be disabled in the settings." },
"categoryName1": { "message": "CMS" },
"categoryName2": { "message": "Форум" },
"categoryName3": { "message": "Менеджер БД" },
@ -63,5 +66,14 @@
"categoryName51": { "message": "Генератор лендінгів" },
"categoryName52": { "message": "Чат реального часу" },
"categoryName53": { "message": "CRM" },
"categoryName54": { "message": "SEO" }
"categoryName54": { "message": "SEO" },
"categoryName55": { "message": "Accounting" },
"categoryName56": { "message": "Cryptominer" },
"categoryName57": { "message": "Static Site Generator" },
"categoryName58": { "message": "User Onboarding" },
"categoryName59": { "message": "JavaScript Libraries" },
"categoryName60": { "message": "Containers" },
"categoryName61": { "message": "SaaS" },
"categoryName62": { "message": "PaaS" },
"categoryName63": { "message": "IaaS" }
}

@ -10,6 +10,9 @@
"optionTracking": { "message": "Wappalyzer takomillashtirish uchun hisobotlarni maxfiy ravishda serverga jo'natish" },
"nothingToDo": { "message": "Bu yerda tekshirib bolmaydi." },
"noAppsDetected": { "message": "Hech qanday dastur aniqlanmadi." },
"categoryPin": { "message": "Always show icon" },
"termsAccept": { "message": "Accept" },
"termsContent": { "message": "This extension sends anonymous information about websites you visit, including domain name and identified technologies, to <a href='https://www.wappalyzer.com'>wappalyzer.com</a>. This can be disabled in the settings." },
"categoryName1": { "message": "CMS (KBT)" },
"categoryName2": { "message": "Forum" },
"categoryName3": { "message": "MB boshqaruvi" },
@ -63,5 +66,14 @@
"categoryName51": { "message": "Sahifa generatorlari" },
"categoryName52": { "message": "Live Chat" },
"categoryName53": { "message": "CRM" },
"categoryName54": { "message": "SEO" }
"categoryName54": { "message": "SEO" },
"categoryName55": { "message": "Accounting" },
"categoryName56": { "message": "Cryptominer" },
"categoryName57": { "message": "Static Site Generator" },
"categoryName58": { "message": "User Onboarding" },
"categoryName59": { "message": "JavaScript Libraries" },
"categoryName60": { "message": "Containers" },
"categoryName61": { "message": "SaaS" },
"categoryName62": { "message": "PaaS" },
"categoryName63": { "message": "IaaS" }
}

@ -1,68 +1,79 @@
{
"github": { "message": "查看 GitHub 上的 Wappalyzer" },
"twitter": { "message": "关注 Twitter 上的 Wappalyzer" },
"website": { "message": "访问 wappalyzer.com" },
"options": { "message": "选项" },
"optionsSave": { "message": "保存选项" },
"optionsSaved": { "message": "已保存" },
"optionUpgradeMessage": { "message": "通知我更新详情" },
"optionDynamicIcon": { "message": "使用应用程序而非 Wappalyzer 的标志" },
"optionTracking": { "message": "发送匿名的应用报告到 wappalyzer.com 供研究使用" },
"nothingToDo": { "message": "这儿啥也没有。" },
"noAppsDetected": { "message": "未检测到任何应用。" },
"categoryName1": { "message": "内容管理系统CMS" },
"categoryName2": { "message": "消息板" },
"categoryName3": { "message": "数据库管理器" },
"categoryName4": { "message": "文档工具" },
"categoryName5": { "message": "插件" },
"categoryName6": { "message": "电子商务" },
"categoryName7": { "message": "照片相册" },
"categoryName8": { "message": "维基" },
"categoryName9": { "message": "主机面板" },
"categoryName10": { "message": "分析" },
"categoryName11": { "message": "博客" },
"categoryName12": { "message": "JavaScript 框架" },
"categoryName13": { "message": "问题跟踪器" },
"categoryName14": { "message": "视频播放器" },
"categoryName15": { "message": "评论系统" },
"categoryName16": { "message": "验证码" },
"categoryName17": { "message": "字体脚本" },
"categoryName18": { "message": "Web 框架" },
"categoryName19": { "message": "杂项" },
"categoryName20": { "message": "编辑器" },
"categoryName21": { "message": "学习管理系统LMS" },
"categoryName22": { "message": "Web 服务器" },
"categoryName23": { "message": "缓存工具" },
"categoryName24": { "message": "富文本编辑器" },
"categoryName25": { "message": "JavaScript 图形库" },
"categoryName26": { "message": "移动框架" },
"categoryName27": { "message": "编程语言" },
"categoryName28": { "message": "操作系统" },
"categoryName29": { "message": "搜索引擎" },
"categoryName30": { "message": "网页邮箱" },
"categoryName31": { "message": "内容分发网络CDN" },
"categoryName32": { "message": "营销自动化" },
"categoryName33": { "message": "Web 服务器扩展" },
"categoryName34": { "message": "数据库" },
"categoryName35": { "message": "地图" },
"categoryName36": { "message": "广告网络" },
"categoryName37": { "message": "网络服务" },
"categoryName38": { "message": "媒体服务器" },
"categoryName39": { "message": "网络摄像头" },
"categoryName40": { "message": "打印机" },
"categoryName41": { "message": "支付处理器" },
"categoryName42": { "message": "标签管理器" },
"categoryName43": { "message": "付费壁障Paywall" },
"categoryName44": { "message": "构建/持续集成系统" },
"categoryName45": { "message": "数据采集与监控系统" },
"categoryName46": { "message": "远程访问" },
"categoryName47": { "message": "开发工具" },
"categoryName48": { "message": "网络存储" },
"categoryName49": { "message": "信息流Feed阅读器" },
"categoryName50": { "message": "文档管理系统" },
"categoryName51": { "message": "着陆页构建器" },
"categoryName52": { "message": "在线聊天" },
"categoryName53": { "message": "客户关系管理CRM" },
"categoryName54": { "message": "搜索引擎优化SEO" },
"categoryName55": { "message": "财务" }
"github": { "message": "查看 GitHub 上的 Wappalyzer" },
"twitter": { "message": "关注 Twitter 上的 Wappalyzer" },
"website": { "message": "访问 wappalyzer.com" },
"options": { "message": "选项" },
"optionsSave": { "message": "保存选项" },
"optionsSaved": { "message": "已保存" },
"optionUpgradeMessage": { "message": "通知我更新详情" },
"optionDynamicIcon": { "message": "使用应用程序而非 Wappalyzer 的标志" },
"optionTracking": { "message": "发送匿名的应用报告到 wappalyzer.com 供研究使用" },
"nothingToDo": { "message": "这儿啥也没有。" },
"noAppsDetected": { "message": "未检测到任何应用。" },
"categoryPin": { "message": "Always show icon" },
"termsAccept": { "message": "Accept" },
"termsContent": { "message": "This extension sends anonymous information about websites you visit, including domain name and identified technologies, to <a href='https://www.wappalyzer.com'>wappalyzer.com</a>. This can be disabled in the settings." },
"categoryName1": { "message": "内容管理系统CMS" },
"categoryName2": { "message": "消息板" },
"categoryName3": { "message": "数据库管理器" },
"categoryName4": { "message": "文档工具" },
"categoryName5": { "message": "插件" },
"categoryName6": { "message": "电子商务" },
"categoryName7": { "message": "照片相册" },
"categoryName8": { "message": "维基" },
"categoryName9": { "message": "主机面板" },
"categoryName10": { "message": "分析" },
"categoryName11": { "message": "博客" },
"categoryName12": { "message": "JavaScript 框架" },
"categoryName13": { "message": "问题跟踪器" },
"categoryName14": { "message": "视频播放器" },
"categoryName15": { "message": "评论系统" },
"categoryName16": { "message": "验证码" },
"categoryName17": { "message": "字体脚本" },
"categoryName18": { "message": "Web 框架" },
"categoryName19": { "message": "杂项" },
"categoryName20": { "message": "编辑器" },
"categoryName21": { "message": "学习管理系统LMS" },
"categoryName22": { "message": "Web 服务器" },
"categoryName23": { "message": "缓存工具" },
"categoryName24": { "message": "富文本编辑器" },
"categoryName25": { "message": "JavaScript 图形库" },
"categoryName26": { "message": "移动框架" },
"categoryName27": { "message": "编程语言" },
"categoryName28": { "message": "操作系统" },
"categoryName29": { "message": "搜索引擎" },
"categoryName30": { "message": "网页邮箱" },
"categoryName31": { "message": "内容分发网络CDN" },
"categoryName32": { "message": "营销自动化" },
"categoryName33": { "message": "Web 服务器扩展" },
"categoryName34": { "message": "数据库" },
"categoryName35": { "message": "地图" },
"categoryName36": { "message": "广告网络" },
"categoryName37": { "message": "网络服务" },
"categoryName38": { "message": "媒体服务器" },
"categoryName39": { "message": "网络摄像头" },
"categoryName40": { "message": "打印机" },
"categoryName41": { "message": "支付处理器" },
"categoryName42": { "message": "标签管理器" },
"categoryName43": { "message": "付费壁障Paywall" },
"categoryName44": { "message": "构建/持续集成系统" },
"categoryName45": { "message": "数据采集与监控系统" },
"categoryName46": { "message": "远程访问" },
"categoryName47": { "message": "开发工具" },
"categoryName48": { "message": "网络存储" },
"categoryName49": { "message": "信息流Feed阅读器" },
"categoryName50": { "message": "文档管理系统" },
"categoryName51": { "message": "着陆页构建器" },
"categoryName52": { "message": "在线聊天" },
"categoryName53": { "message": "客户关系管理CRM" },
"categoryName54": { "message": "搜索引擎优化SEO" },
"categoryName55": { "message": "财务" },
"categoryName56": { "message": "加密货币挖矿器" },
"categoryName57": { "message": "静态网站生成器" },
"categoryName58": { "message": "用户引导" },
"categoryName59": { "message": "JavaScript 库" },
"categoryName60": { "message": "Containers" },
"categoryName61": { "message": "SaaS" },
"categoryName62": { "message": "PaaS" },
"categoryName63": { "message": "IaaS" }
}

@ -1,67 +1,79 @@
{
"github": { "message": "在 GitHub 上 fork Wappalyzer" },
"twitter": { "message": "追隨 Wappalyzer 的 Twitter" },
"website": { "message": "前往 wappalyzer.com" },
"options": { "message": "選項" },
"optionsSave": { "message": "保存選項" },
"optionsSaved": { "message": "選項已保存" },
"optionUpgradeMessage": { "message": "通知我更新內容" },
"optionDynamicIcon": { "message": "使用應用程式圖示取代 Wappalyzer 的 logo" },
"optionTracking": { "message": "匿名傳送應用程式偵測報告至 wappalyzer.com 作為研究用途" },
"nothingToDo": { "message": "這裡什麼也沒有。" },
"noAppsDetected": { "message": "未偵測到應用程式。" },
"categoryName1": { "message": "內容管理系統CMS" },
"categoryName2": { "message": "留言板/討論區" },
"categoryName3": { "message": "資料庫管理" },
"categoryName4": { "message": "文書處理工具" },
"categoryName5": { "message": "外掛/小工具" },
"categoryName6": { "message": "電子商務" },
"categoryName7": { "message": "相簿" },
"categoryName8": { "message": "維基" },
"categoryName9": { "message": "伺服器控制面板" },
"categoryName10": { "message": "分析" },
"categoryName11": { "message": "部落格" },
"categoryName12": { "message": "JavaScript 框架" },
"categoryName13": { "message": "Issue 追蹤" },
"categoryName14": { "message": "影音撥放器" },
"categoryName15": { "message": "評論系統" },
"categoryName16": { "message": "驗證碼" },
"categoryName17": { "message": "字型" },
"categoryName18": { "message": "網頁框架" },
"categoryName19": { "message": "其他" },
"categoryName20": { "message": "編輯器" },
"categoryName21": { "message": "學習管理系統LMS" },
"categoryName22": { "message": "網頁伺服器" },
"categoryName23": { "message": "快取工具" },
"categoryName24": { "message": "高級文字編輯器" },
"categoryName25": { "message": "JavaScript 圖形庫" },
"categoryName26": { "message": "行動框架" },
"categoryName27": { "message": "程式語言" },
"categoryName28": { "message": "作業系統" },
"categoryName29": { "message": "搜尋引擎" },
"categoryName30": { "message": "網路信箱" },
"categoryName31": { "message": "內容傳遞網路CDN" },
"categoryName32": { "message": "行銷自動化" },
"categoryName33": { "message": "網頁伺服器擴充功能" },
"categoryName34": { "message": "資料庫" },
"categoryName35": { "message": "地圖" },
"categoryName36": { "message": "廣告聯播" },
"categoryName37": { "message": "網路服務" },
"categoryName38": { "message": "媒體伺服器" },
"categoryName39": { "message": "網路攝影機" },
"categoryName40": { "message": "印表機" },
"categoryName41": { "message": "付款處理" },
"categoryName42": { "message": "標籤管理" },
"categoryName43": { "message": "付費牆" },
"categoryName44": { "message": "建立/整合系統" },
"categoryName45": { "message": "監控與資料擷取系統SCADA" },
"categoryName46": { "message": "遠端" },
"categoryName47": { "message": "開發工具" },
"categoryName48": { "message": "網路儲存設備" },
"categoryName49": { "message": "Feed 閱讀器" },
"categoryName50": { "message": "文件管理系統" },
"categoryName51": { "message": "著陸頁產生器" },
"categoryName52": { "message": "線上聊天" },
"categoryName53": { "message": "客戶關係管理系統CRM" },
"categoryName54": { "message": "SEO" }
"github": { "message": "在 GitHub 上 fork Wappalyzer" },
"twitter": { "message": "在 Twitter 上追隨 Wappalyzer" },
"website": { "message": "前往 wappalyzer.com" },
"options": { "message": "選項" },
"optionsSave": { "message": "保存選項" },
"optionsSaved": { "message": "選項已保存" },
"optionUpgradeMessage": { "message": "通知我更新內容" },
"optionDynamicIcon": { "message": "使用網頁中使用技術的圖示取代 Wappalyzer 的標誌" },
"optionTracking": { "message": "匿名傳送已識別的技術至 wappalyzer.com" },
"nothingToDo": { "message": "這裡什麼也沒有。" },
"noAppsDetected": { "message": "未識別到技術。" },
"categoryPin": { "message": "永遠顯示圖示" },
"termsAccept": { "message": "Accept" },
"termsContent": { "message": "This extension sends anonymous information about websites you visit, including domain name and identified technologies, to <a href='https://www.wappalyzer.com'>wappalyzer.com</a>. This can be disabled in the settings." },
"categoryName1": { "message": "內容管理系統CMS" },
"categoryName2": { "message": "留言板/討論區" },
"categoryName3": { "message": "資料庫管理" },
"categoryName4": { "message": "文書處理工具" },
"categoryName5": { "message": "外掛/小工具" },
"categoryName6": { "message": "電子商務" },
"categoryName7": { "message": "相簿" },
"categoryName8": { "message": "維基" },
"categoryName9": { "message": "伺服器控制面板" },
"categoryName10": { "message": "分析" },
"categoryName11": { "message": "部落格" },
"categoryName12": { "message": "JavaScript 框架" },
"categoryName13": { "message": "問題追蹤" },
"categoryName14": { "message": "影音撥放器" },
"categoryName15": { "message": "評論系統" },
"categoryName16": { "message": "驗證碼" },
"categoryName17": { "message": "字型" },
"categoryName18": { "message": "網頁框架" },
"categoryName19": { "message": "其他" },
"categoryName20": { "message": "編輯器" },
"categoryName21": { "message": "學習管理系統LMS" },
"categoryName22": { "message": "網頁伺服器" },
"categoryName23": { "message": "快取工具" },
"categoryName24": { "message": "高級文字編輯器" },
"categoryName25": { "message": "JavaScript 圖形庫" },
"categoryName26": { "message": "行動框架" },
"categoryName27": { "message": "程式語言" },
"categoryName28": { "message": "作業系統" },
"categoryName29": { "message": "搜尋引擎" },
"categoryName30": { "message": "網路信箱" },
"categoryName31": { "message": "內容傳遞網路CDN" },
"categoryName32": { "message": "行銷自動化" },
"categoryName33": { "message": "網頁伺服器擴充功能" },
"categoryName34": { "message": "資料庫" },
"categoryName35": { "message": "地圖" },
"categoryName36": { "message": "廣告聯播" },
"categoryName37": { "message": "網路服務" },
"categoryName38": { "message": "媒體伺服器" },
"categoryName39": { "message": "網路攝影機" },
"categoryName40": { "message": "印表機" },
"categoryName41": { "message": "付款處理" },
"categoryName42": { "message": "標籤管理" },
"categoryName43": { "message": "付費牆" },
"categoryName44": { "message": "建立/整合系統" },
"categoryName45": { "message": "監控與資料擷取系統SCADA" },
"categoryName46": { "message": "遠端" },
"categoryName47": { "message": "開發工具" },
"categoryName48": { "message": "網路儲存設備" },
"categoryName49": { "message": "Feed 閱讀器" },
"categoryName50": { "message": "文件管理系統" },
"categoryName51": { "message": "著陸頁產生器" },
"categoryName52": { "message": "線上聊天" },
"categoryName53": { "message": "客戶關係管理系統CRM" },
"categoryName54": { "message": "SEO" },
"categoryName55": { "message": "帳務" },
"categoryName56": { "message": "加密貨幣礦工" },
"categoryName57": { "message": "靜態網站產生器" },
"categoryName58": { "message": "使用者指引" },
"categoryName59": { "message": "JavaScript 函式庫" },
"categoryName60": { "message": "容器" },
"categoryName61": { "message": "軟體即服務SaaS" },
"categoryName62": { "message": "平台即服務PaaS" },
"categoryName63": { "message": "基礎設施即服務IaaS" }
}

@ -46,25 +46,52 @@ body {
padding-bottom: 1rem;
}
.detected__category-link {
.detected__category-name {
border-bottom: 1px solid #dbdbdb;
display: block;
margin-bottom: .5rem;
text-decoration: none;
}
.detected__category-name {
.detected__category-link {
color: #4608ad;
display: block;
font-weight: bold;
line-height: 2rem;
text-decoration: none;
}
.detected__category-link:hover .detected__category-name {
.detected__category-link:hover {
color: #4a4a4a;
}
.detected__category-pin-wrapper {
margin-left: .2rem;
}
.detected__category-pin {
cursor: pointer;
display: none;
height: 16px;
margin-left: .2rem;
width: 16px;
vertical-align: middle;
}
.detected__category:hover .detected__category-pin--inactive {
display: inline-block;
}
.detected__category-pin-wrapper--active .detected__category-pin--inactive,
.detected__category-pin-wrapper:hover .detected__category-pin--inactive {
display: none !important;
}
.detected__category-pin-wrapper--active .detected__category-pin--active,
.detected__category-pin-wrapper:hover .detected__category-pin--active {
display: inline-block;
}
.detected__app {
color: #4a4a4a;
display: block;
line-height: 1.7rem;
text-decoration: none;
@ -84,13 +111,28 @@ body {
}
.detected__app-name {
color: #4a4a4a;
}
.detected__app-version, .detected__app-confidence {
background: #eee;
border-radius: 3px;
font-size: .7rem;
margin-left: .3rem;
padding: .1rem .2rem;
}
.detected__app:hover .detected__app-name {
border-bottom: 1px solid #4a4a4a;
}
.detected__app:hover .detected__app-version {
border-bottom: 1px solid white;
}
.detected__app:hover .detected__app-confidence {
border-bottom: 1px solid white;
}
.detected-app {
padding: 7px 0;
}
@ -106,10 +148,55 @@ body {
.empty {
display: flex;
height: 16rem;
height: 14.5rem;
align-items: center;
justify-content: center;
}
.empty__text {
}
.terms {
align-items: center;
display: flex;
flex-direction: column;
justify-content: center;
height: 100%;
width: 100%;
}
.terms__wrapper {
display: none;
height: 100%;
width: 100%;
}
.terms__wrapper--active {
display: block;
}
.terms__content {
font-size: .9rem;
line-height: 150%;
text-align: center;
margin-bottom: 1rem;
width: 80%;
}
.terms__accept {
background-color: #4608ad;
border: none;
border-radius: 3px;
color: white;
cursor: pointer;
font-size: .9rem;
padding: .8rem 3rem;
}
.terms__accept:hover {
background-color: #4107a1;
}
.terms__privacy {
margin-top: 1rem;
}

@ -7,7 +7,7 @@
<script src="../node_modules/webextension-polyfill/dist/browser-polyfill.js"></script>
<script src="../js/wappalyzer.js"></script>
<script src="../js/driver.js"></script>
<script src="../js/network.js"></script>
<script src="../js/lib/network.js"></script>
</head>
<body>
</body>

@ -7,7 +7,7 @@
<link rel="stylesheet" href="../css/popup.css">
<script src="../node_modules/webextension-polyfill/dist/browser-polyfill.js"></script>
<script src="../js/jsontodom.js"></script>
<script src="../js/lib/jsontodom.js"></script>
<script src="../js/popup.js"></script>
</head>
<body>
@ -17,6 +17,16 @@
</a>
</div>
<div class="container"></div>
<div class="container">
<div class="terms__wrapper">
<div class="terms">
<div class="terms__content" data-i18n="termsContent"></div>
<button class="terms__accept" data-i18n="termsAccept"></button>
<a class="terms__privacy" href="https://www.wappalyzer.com/privacy" data-i18n="privacyPolicy"></a>
</div>
</div>
</div>
</body>
</html>

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 193.826 193.826" style="enable-background:new 0 0 193.826 193.826;" xml:space="preserve">
<path fill="#4608ad" d="M191.495,55.511L137.449,1.465c-1.951-1.953-5.119-1.953-7.07,0l-0.229,0.229c-3.314,3.313-5.14,7.72-5.14,12.406
c0,3.019,0.767,5.916,2.192,8.485l-56.55,48.533c-4.328-3.868-9.852-5.985-15.703-5.985c-6.305,0-12.232,2.455-16.689,6.913
l-0.339,0.339c-1.953,1.952-1.953,5.118,0,7.07l32.378,32.378l-31.534,31.533c-0.631,0.649-15.557,16.03-25.37,28.27
c-9.345,11.653-11.193,13.788-11.289,13.898c-1.735,1.976-1.639,4.956,0.218,6.822c0.973,0.977,2.256,1.471,3.543,1.471
c1.173,0,2.349-0.41,3.295-1.237c0.083-0.072,2.169-1.885,13.898-11.289c12.238-9.813,27.619-24.74,28.318-25.421l31.483-31.483
l30.644,30.644c0.976,0.977,2.256,1.465,3.535,1.465s2.56-0.488,3.535-1.465l0.339-0.339c4.458-4.457,6.913-10.385,6.913-16.689
c0-5.851-2.118-11.375-5.985-15.703l48.533-56.55c2.569,1.425,5.466,2.192,8.485,2.192c4.687,0,9.093-1.825,12.406-5.14l0.229-0.229
C193.448,60.629,193.448,57.463,191.495,55.511z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 193.826 193.826" style="enable-background:new 0 0 193.826 193.826;" xml:space="preserve">
<path fill="#dbdbdb" d="M191.495,55.511L137.449,1.465c-1.951-1.953-5.119-1.953-7.07,0l-0.229,0.229c-3.314,3.313-5.14,7.72-5.14,12.406
c0,3.019,0.767,5.916,2.192,8.485l-56.55,48.533c-4.328-3.868-9.852-5.985-15.703-5.985c-6.305,0-12.232,2.455-16.689,6.913
l-0.339,0.339c-1.953,1.952-1.953,5.118,0,7.07l32.378,32.378l-31.534,31.533c-0.631,0.649-15.557,16.03-25.37,28.27
c-9.345,11.653-11.193,13.788-11.289,13.898c-1.735,1.976-1.639,4.956,0.218,6.822c0.973,0.977,2.256,1.471,3.543,1.471
c1.173,0,2.349-0.41,3.295-1.237c0.083-0.072,2.169-1.885,13.898-11.289c12.238-9.813,27.619-24.74,28.318-25.421l31.483-31.483
l30.644,30.644c0.976,0.977,2.256,1.465,3.535,1.465s2.56-0.488,3.535-1.465l0.339-0.339c4.458-4.457,6.913-10.385,6.913-16.689
c0-5.851-2.118-11.375-5.985-15.703l48.533-56.55c2.569,1.425,5.466,2.192,8.485,2.192c4.687,0,9.093-1.825,12.406-5.14l0.229-0.229
C193.448,60.629,193.448,57.463,191.495,55.511z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

@ -1,69 +1,84 @@
/** global: browser */
/** global: XMLSerializer */
if ( typeof browser !== 'undefined' && typeof document.body !== 'undefined' ) {
/* global browser, chrome */
/* eslint-env browser */
function sendMessage(id, subject, callback) {
(chrome || browser).runtime.sendMessage({
id,
subject,
source: 'content.js',
}, callback || (() => {}));
}
if (typeof browser !== 'undefined' && typeof document.body !== 'undefined') {
try {
var html = new XMLSerializer().serializeToString(document);
sendMessage('init', {});
// HTML
let html = new XMLSerializer().serializeToString(document);
const chunks = [];
const maxCols = 2000;
const maxRows = 3000;
const rows = html.length / maxCols;
let i;
if ( html.length > 50000 ) {
html = html.substring(0, 25000) + html.substring(html.length - 25000, html.length);
for (i = 0; i < rows; i += 1) {
if (i < maxRows / 2 || i > rows - maxRows / 2) {
chunks.push(html.slice(i * maxCols, (i + 1) * maxCols));
}
}
html = chunks.join('\n');
// Scripts
const scripts = Array.prototype.slice
.apply(document.scripts)
.filter(script => script.src)
.map(script => script.src);
.map(script => script.src)
.filter(script => script.indexOf('data:text/javascript;') !== 0);
browser.runtime.sendMessage({
id: 'analyze',
subject: { html, scripts },
source: 'content.js'
});
sendMessage('analyze', { html, scripts });
// JavaScript variables
const script = document.createElement('script');
script.onload = () => {
addEventListener('message', event => {
if ( event.data.id !== 'js' ) {
const onMessage = (event) => {
if (event.data.id !== 'js') {
return;
}
browser.runtime.sendMessage({
id: 'analyze',
subject: {
js: event.data.js
},
source: 'content.js'
});
}, true);
( chrome || browser ).runtime.sendMessage({
id: 'init_js',
subject: {},
source: 'content.js'
}, response => {
if ( response ) {
window.removeEventListener('message', onMessage);
sendMessage('analyze', { js: event.data.js });
script.remove();
};
window.addEventListener('message', onMessage);
sendMessage('get_js_patterns', {}, (response) => {
if (response) {
postMessage({
id: 'patterns',
patterns: response.patterns
}, '*');
patterns: response.patterns,
}, window.location.href);
}
});
};
script.setAttribute('id', 'wappalyzer');
script.setAttribute('src', browser.extension.getURL('js/inject.js'));
document.body.appendChild(script);
} catch (e) {
log(e);
sendMessage('log', e);
}
}
function log(message) {
browser.runtime.sendMessage({
id: 'log',
message,
source: 'content.js'
});
}
// https://stackoverflow.com/a/44774834
// https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/tabs/executeScript#Return_value
undefined; // eslint-disable-line no-unused-expressions

@ -2,31 +2,61 @@
* WebExtension driver
*/
/* eslint-env browser */
/* global browser, chrome, fetch, Wappalyzer */
/** global: browser */
/** global: chrome */
/** global: fetch */
/** global: Wappalyzer */
const wappalyzer = new Wappalyzer();
var tabCache = {};
var headersCache = {};
var categoryOrder = [];
const tabCache = {};
const robotsTxtQueue = {};
let categoryOrder = [];
browser.tabs.onRemoved.addListener(tabId => {
browser.tabs.onRemoved.addListener((tabId) => {
tabCache[tabId] = null;
});
function userAgent() {
const url = chrome.extension.getURL('/');
if (url.match(/^chrome-/)) {
return 'chrome';
}
if (url.match(/^moz-/)) {
return 'firefox';
}
if (url.match(/^ms-browser-/)) {
return 'edge';
}
}
/**
* Get a value from localStorage
*/
function getOption(name, defaultValue) {
return new Promise((resolve, reject) => {
const callback = item => {
resolve(item.hasOwnProperty(name) ? item[name] : defaultValue);
};
browser.storage.local.get(name)
.then(callback)
.catch(error => wappalyzer.log(error, 'driver', 'error'));
function getOption(name, defaultValue = null) {
return new Promise(async (resolve, reject) => {
let value = defaultValue;
try {
const option = await browser.storage.local.get(name);
if (option[name] !== undefined) {
value = option[name];
}
} catch (error) {
wappalyzer.log(error.message, 'driver', 'error');
return reject(error.message);
}
return resolve(value);
});
}
@ -34,11 +64,17 @@ function getOption(name, defaultValue) {
* Set a value in localStorage
*/
function setOption(name, value) {
var option = {};
return new Promise(async (resolve, reject) => {
try {
await browser.storage.local.set({ [name]: value });
} catch (error) {
wappalyzer.log(error.message, 'driver', 'error');
option[name] = value;
return reject(error.message);
}
browser.storage.local.set(option);
return resolve();
});
}
/**
@ -47,160 +83,118 @@ function setOption(name, value) {
function openTab(args) {
browser.tabs.create({
url: args.url,
active: args.background === undefined || !args.background
active: args.background === undefined || !args.background,
});
}
/**
* Make a POST request
*/
function post(url, body) {
fetch(url, {
method: 'POST',
body: JSON.stringify(body)
})
.then(response => {
wappalyzer.log('POST ' + url + ': ' + response.status, 'driver');
})
.catch(error => {
wappalyzer.log('POST ' + url + ': ' + error, 'driver', 'error');
async function post(url, body) {
try {
const response = await fetch(url, {
method: 'POST',
body: JSON.stringify(body),
});
}
fetch('../apps.json')
.then(response => {
return response.json();
})
.then(json => {
wappalyzer.apps = json.apps;
wappalyzer.categories = json.categories;
wappalyzer.log(`POST ${url}: ${response.status}`, 'driver');
} catch (error) {
wappalyzer.log(`POST ${url}: ${error}`, 'driver', 'error');
}
}
categoryOrder = Object.keys(wappalyzer.categories).sort((a, b) => wappalyzer.categories[a].priority - wappalyzer.categories[b].priority);
// Capture response headers
browser.webRequest.onCompleted.addListener(async (request) => {
const headers = {};
wappalyzer.parseJsPatterns();
})
.catch(error => {
wappalyzer.log('GET apps.json: ' + error, 'driver', 'error');
});
if (request.responseHeaders) {
const url = wappalyzer.parseUrl(request.url);
// Version check
var version = browser.runtime.getManifest().version;
let tab;
getOption('version')
.then(previousVersion => {
if ( previousVersion === null ) {
openTab({
url: wappalyzer.config.websiteURL + 'installed'
});
} else if ( version !== previousVersion ) {
getOption('upgradeMessage', true)
.then(upgradeMessage => {
if ( upgradeMessage ) {
openTab({
url: wappalyzer.config.websiteURL + 'upgraded?v' + version,
background: true
});
}
});
try {
[tab] = await browser.tabs.query({ url: [url.href] });
} catch (error) {
wappalyzer.log(error, 'driver', 'error');
}
setOption('version', version);
});
if (tab) {
request.responseHeaders.forEach((header) => {
const name = header.name.toLowerCase();
// Run content script
var callback = tabs => {
tabs.forEach(tab => {
if ( tab.url.match(/^https?:\/\//) ) {
browser.tabs.executeScript(tab.id, {
file: 'js/content.js'
headers[name] = headers[name] || [];
headers[name].push((header.value || header.binaryValue || '').toString());
});
if (headers['content-type'] && /\/x?html/.test(headers['content-type'][0])) {
wappalyzer.analyze(url, { headers }, { tab });
}
}
})
};
}
}, { urls: ['http://*/*', 'https://*/*'], types: ['main_frame'] }, ['responseHeaders']);
browser.tabs.query({})
.then(callback)
.catch(error => wappalyzer.log(error, 'driver', 'error'));
// Listen for messages
browser.runtime.onMessage.addListener(async (message, sender) => {
if (message.id === undefined) {
return Promise.resolve();
}
// Capture response headers
browser.webRequest.onCompleted.addListener(request => {
var responseHeaders = {};
if (message.id !== 'log') {
wappalyzer.log(`Message${message.source ? ` from ${message.source}` : ''}: ${message.id}`, 'driver');
}
if ( request.responseHeaders ) {
var url = wappalyzer.parseUrl(request.url);
const pinnedCategory = await getOption('pinnedCategory');
request.responseHeaders.forEach(function(header) {
if ( !responseHeaders[header.name.toLowerCase()] ) {
responseHeaders[header.name.toLowerCase()] = []
}
responseHeaders[header.name.toLowerCase()].push(header.value || '' + header.binaryValue);
});
const url = wappalyzer.parseUrl(sender.tab ? sender.tab.url : '');
if ( headersCache.length > 50 ) {
headersCache = {};
}
const cookies = await browser.cookies.getAll({ domain: `.${url.hostname}` });
if ( /text\/html/.test(responseHeaders['content-type'][0]) ) {
if ( headersCache[url.canonical] === undefined ) {
headersCache[url.canonical] = {};
}
let response;
Object.keys(responseHeaders).forEach(header => {
headersCache[url.canonical][header] = responseHeaders[header].slice();
});
}
}
}, { urls: [ 'http://*/*', 'https://*/*' ], types: [ 'main_frame' ] }, [ 'responseHeaders' ]);
switch (message.id) {
case 'log':
wappalyzer.log(message.subject, message.source);
// Listen for messages
( chrome || browser ).runtime.onMessage.addListener((message, sender, sendResponse) => {
if ( typeof message.id != 'undefined' ) {
if ( message.id !== 'log' ) {
wappalyzer.log('Message received' + ( message.source ? ' from ' + message.source : '' ) + ': ' + message.id, 'driver');
}
break;
case 'init':
wappalyzer.analyze(url, { cookies }, { tab: sender.tab });
var response;
break;
case 'analyze':
wappalyzer.analyze(url, message.subject, { tab: sender.tab });
switch ( message.id ) {
case 'log':
wappalyzer.log(message.message, message.source);
await setOption('hostnameCache', wappalyzer.hostnameCache);
break;
case 'analyze':
var url = wappalyzer.parseUrl(sender.tab.url);
break;
case 'ad_log':
wappalyzer.cacheDetectedAds(message.subject);
if ( headersCache[url.canonical] !== undefined ) {
message.subject.headers = headersCache[url.canonical];
}
break;
case 'get_apps':
response = {
tabCache: tabCache[message.tab.id],
apps: wappalyzer.apps,
categories: wappalyzer.categories,
pinnedCategory,
termsAccepted: userAgent() === 'chrome' || await getOption('termsAccepted', false),
};
wappalyzer.analyze(url, message.subject, {
tab: sender.tab
});
break;
case 'ad_log':
wappalyzer.cacheDetectedAds(message.subject);
break;
case 'get_apps':
response = {
tabCache: tabCache[message.tab.id],
apps: wappalyzer.apps,
categories: wappalyzer.categories
};
break;
case 'init_js':
response = {
patterns: wappalyzer.jsPatterns
};
break;
default:
}
break;
case 'set_option':
await setOption(message.key, message.value);
sendResponse(response);
break;
case 'get_js_patterns':
response = {
patterns: wappalyzer.jsPatterns,
};
break;
default:
}
return Promise.resolve(response);
});
wappalyzer.driver.document = document;
@ -209,128 +203,181 @@ wappalyzer.driver.document = document;
* Log messages to console
*/
wappalyzer.driver.log = (message, source, type) => {
console.log('[wappalyzer ' + type + ']', '[' + source + ']', message);
const log = ['warn', 'error'].indexOf(type) !== -1 ? type : 'log';
console[log](`[wappalyzer ${type}]`, `[${source}]`, message);
};
/**
* Display apps
*/
wappalyzer.driver.displayApps = (detected, meta, context) => {
var tab = context.tab;
wappalyzer.driver.displayApps = async (detected, meta, context) => {
const { tab } = context;
tabCache[tab.id] = tabCache[tab.id] || { detected: [] };
if (tab === undefined) {
return;
}
tabCache[tab.id] = tabCache[tab.id] || {
detected: [],
};
tabCache[tab.id].detected = detected;
if ( Object.keys(detected).length ) {
getOption('dynamicIcon', true)
.then(dynamicIcon => {
var appName, found = false;
// Find the main application to display
categoryOrder.forEach(match => {
Object.keys(detected).forEach(appName => {
var app = detected[appName];
app.props.cats.forEach(category => {
if ( category === match && !found ) {
var icon = app.props.icon || 'default.svg';
if ( !dynamicIcon ) {
icon = 'default.svg';
}
if ( /\.svg$/i.test(icon) ) {
icon = 'converted/' + icon.replace(/\.svg$/, '.png');
}
try {
browser.pageAction.setIcon({
tabId: tab.id,
path: '../images/icons/' + icon
});
} catch(e) {
// Firefox for Android does not support setIcon see https://bugzilla.mozilla.org/show_bug.cgi?id=1331746
}
found = true;
}
const pinnedCategory = await getOption('pinnedCategory');
const dynamicIcon = await getOption('dynamicIcon', true);
let found = false;
// Find the main application to display
[pinnedCategory].concat(categoryOrder).forEach((match) => {
Object.keys(detected).forEach((appName) => {
const app = detected[appName];
app.props.cats.forEach((category) => {
if (category === match && !found) {
let icon = app.props.icon && dynamicIcon ? app.props.icon : 'default.svg';
if (/\.svg$/i.test(icon)) {
icon = `converted/${icon.replace(/\.svg$/, '.png')}`;
}
try {
browser.pageAction.setIcon({
tabId: tab.id,
path: `../images/icons/${icon}`,
});
});
});
if ( typeof chrome !== 'undefined' ) {
// Browser polyfill doesn't seem to work here
chrome.pageAction.show(tab.id);
} else {
browser.pageAction.show(tab.id);
} catch (e) {
// Firefox for Android does not support setIcon see https://bugzilla.mozilla.org/show_bug.cgi?id=1331746
}
found = true;
}
});
}
});
});
browser.pageAction.show(tab.id);
};
/**
* Fetch and cache robots.txt for host
*/
wappalyzer.driver.getRobotsTxt = (host, secure = false) => {
return new Promise((resolve, reject) => {
getOption('tracking', true)
.then(tracking => {
if ( !tracking ) {
return resolve([]);
}
wappalyzer.driver.getRobotsTxt = async (host, secure = false) => {
if (robotsTxtQueue[host]) {
return robotsTxtQueue[host];
}
getOption('robotsTxtCache')
.then(robotsTxtCache => {
robotsTxtCache = robotsTxtCache || {};
if ( host in robotsTxtCache ) {
resolve(robotsTxtCache[host]);
} else {
const url = 'http' + ( secure ? 's' : '' ) + '://' + host + '/robots.txt';
fetch('http' + ( secure ? 's' : '' ) + '://' + host + '/robots.txt')
.then(response => {
if ( !response.ok ) {
if ( response.status === 404 ) {
return '';
} else {
throw 'GET ' + response.url + ' was not ok';
}
}
return response.text();
})
.then(robotsTxt => {
robotsTxtCache[host] = wappalyzer.parseRobotsTxt(robotsTxt);
setOption('robotsTxtCache', robotsTxtCache);
resolve(robotsTxtCache[host]);
})
.catch(reject);
}
});
});
const tracking = await getOption('tracking', true);
const robotsTxtCache = await getOption('robotsTxtCache', {});
robotsTxtQueue[host] = new Promise(async (resolve) => {
if (!tracking) {
return resolve([]);
}
if (host in robotsTxtCache) {
return resolve(robotsTxtCache[host]);
}
const timeout = setTimeout(() => resolve([]), 3000);
let response;
try {
response = await fetch(`http${secure ? 's' : ''}://${host}/robots.txt`, { redirect: 'follow' });
} catch (error) {
wappalyzer.log(error, 'driver', 'error');
return resolve([]);
}
clearTimeout(timeout);
const robotsTxt = response.ok ? await response.text() : '';
robotsTxtCache[host] = Wappalyzer.parseRobotsTxt(robotsTxt);
await setOption('robotsTxtCache', robotsTxtCache);
delete robotsTxtQueue[host];
return resolve(robotsTxtCache[host]);
});
return robotsTxtQueue[host];
};
/**
* Anonymously track detected applications for research purposes
*/
wappalyzer.driver.ping = (hostnameCache, adCache) => {
getOption('tracking', true)
.then(tracking => {
if ( tracking ) {
if ( Object.keys(hostnameCache).length ) {
post('https://api.wappalyzer.com/ping/v1/', hostnameCache);
}
wappalyzer.driver.ping = async (hostnameCache = {}, adCache = []) => {
const tracking = await getOption('tracking', true);
const termsAccepted = userAgent() === 'chrome' || await getOption('termsAccepted', false);
if ( adCache.length ) {
post('https://ad.wappalyzer.com/log/wp/', adCache);
}
if (tracking && termsAccepted) {
if (Object.keys(hostnameCache).length) {
post('https://api.wappalyzer.com/ping/v1/', hostnameCache);
}
setOption('robotsTxtCache', {});
}
});
if (adCache.length) {
post('https://ad.wappalyzer.com/log/wp/', adCache);
}
await setOption('robotsTxtCache', {});
}
};
// Init
(async () => {
// Technologies
try {
const response = await fetch('../apps.json');
const json = await response.json();
wappalyzer.apps = json.apps;
wappalyzer.categories = json.categories;
} catch (error) {
wappalyzer.log(`GET apps.json: ${error.message}`, 'driver', 'error');
}
wappalyzer.parseJsPatterns();
categoryOrder = Object.keys(wappalyzer.categories)
.map(categoryId => parseInt(categoryId, 10))
.sort((a, b) => wappalyzer.categories[a].priority - wappalyzer.categories[b].priority);
// Version check
const { version } = browser.runtime.getManifest();
const previousVersion = await getOption('version');
const upgradeMessage = await getOption('upgradeMessage', true);
if (previousVersion === null) {
openTab({
url: `${wappalyzer.config.websiteURL}installed`,
});
} else if (version !== previousVersion && upgradeMessage) {
openTab({
url: `${wappalyzer.config.websiteURL}upgraded?v${version}`,
background: true,
});
}
await setOption('version', version);
// Hostname cache
wappalyzer.hostnameCache = await getOption('hostnameCache', {});
// Run content script on all tabs
try {
const tabs = await browser.tabs.query({ url: ['http://*/*', 'https://*/*'] });
tabs.forEach((tab) => {
browser.tabs.executeScript(tab.id, {
file: '../js/content.js',
});
});
} catch (error) {
wappalyzer.log(error, 'driver', 'error');
}
})();

File diff suppressed because it is too large Load Diff

@ -1,26 +1,50 @@
(function() {
try {
addEventListener('message', (event => {
if ( event.data.id !== 'patterns' ) {
/* eslint-env browser */
(() => {
try {
const detectJs = (chain) => {
const properties = chain.split('.');
let value = properties.length ? window : null;
for (let i = 0; i < properties.length; i++) {
const property = properties[i];
if (value && value.hasOwnProperty(property)) {
value = value[property];
} else {
value = null;
break;
}
}
return typeof value === 'string' || typeof value === 'number' ? value : !!value;
};
const onMessage = (event) => {
if (event.data.id !== 'patterns') {
return;
}
removeEventListener('message', onMessage);
const patterns = event.data.patterns || {};
const js = {};
for ( let appName in patterns ) {
if ( patterns.hasOwnProperty(appName) ) {
for (const appName in patterns) {
if (patterns.hasOwnProperty(appName)) {
js[appName] = {};
for ( let chain in patterns[appName] ) {
if ( patterns[appName].hasOwnProperty(chain) ) {
for (const chain in patterns[appName]) {
if (patterns[appName].hasOwnProperty(chain)) {
js[appName][chain] = {};
for ( let index in patterns[appName][chain] ) {
for (const index in patterns[appName][chain]) {
const value = detectJs(chain);
if ( value ) {
if (value && patterns[appName][chain].hasOwnProperty(index)) {
js[appName][chain][index] = value;
}
}
@ -29,33 +53,11 @@
}
}
postMessage({ id: 'js', js }, '*');
}), false);
} catch(e) {
// Fail quietly
}
function detectJs(chain) {
try {
const properties = chain.split('.');
postMessage({ id: 'js', js }, window.location.href);
};
var value = properties.length ? window : null;
for ( let i = 0; i < properties.length; i ++ ) {
var property = properties[i];
if ( value.hasOwnProperty(property) ) {
value = value[property];
} else {
value = null;
break;
}
}
return typeof value === 'string' ? value : !!value;
} catch(e) {
// Fail quietly
}
addEventListener('message', onMessage);
} catch (e) {
// Fail quietly
}
}());
})();

@ -1,63 +0,0 @@
jsonToDOM.namespaces = {
html: "http://www.w3.org/1999/xhtml",
xul: "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
};
jsonToDOM.defaultNamespace = jsonToDOM.namespaces.html;
function jsonToDOM(jsonTemplate, doc, nodes) {
function namespace(name) {
var reElemNameParts = /^(?:(.*):)?(.*)$/.exec(name);
return { namespace: jsonToDOM.namespaces[reElemNameParts[1]], shortName: reElemNameParts[2] };
}
// Note that 'elemNameOrArray' is: either the full element name (eg. [html:]div) or an array of elements in JSON notation
function tag(elemNameOrArray, elemAttr) {
// Array of elements? Parse each one...
if (Array.isArray(elemNameOrArray)) {
var frag = doc.createDocumentFragment();
Array.prototype.forEach.call(arguments, function(thisElem) {
frag.appendChild(tag.apply(null, thisElem));
});
return frag;
}
// Single element? Parse element namespace prefix (if none exists, default to defaultNamespace), and create element
var elemNs = namespace(elemNameOrArray);
var elem = doc.createElementNS(elemNs.namespace || jsonToDOM.defaultNamespace, elemNs.shortName);
// Set element's attributes and/or callback functions (eg. onclick)
for (var key in elemAttr) {
var val = elemAttr[key];
if (nodes && key == "key") {
nodes[val] = elem;
continue;
}
var attrNs = namespace(key);
if (typeof val == "function") {
// Special case for function attributes; don't just add them as 'on...' attributes, but as events, using addEventListener
elem.addEventListener(key.replace(/^on/, ""), val, false);
}
else {
// Note that the default namespace for XML attributes is, and should be, blank (ie. they're not in any namespace)
elem.setAttributeNS(attrNs.namespace || "", attrNs.shortName, val);
}
}
// Create and append this element's children
var childElems = Array.prototype.slice.call(arguments, 2);
childElems.forEach(function(childElem) {
if (childElem != null) {
elem.appendChild(
childElem instanceof doc.defaultView.Node ? childElem :
Array.isArray(childElem) ? tag.apply(null, childElem) :
doc.createTextNode(childElem));
}
});
return elem;
}
return tag.apply(null, jsonTemplate);
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,63 @@
jsonToDOM.namespaces = {
html: 'http://www.w3.org/1999/xhtml',
xul: 'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul',
};
jsonToDOM.defaultNamespace = jsonToDOM.namespaces.html;
function jsonToDOM(jsonTemplate, doc, nodes) {
function namespace(name) {
const reElemNameParts = /^(?:(.*):)?(.*)$/.exec(name);
return { namespace: jsonToDOM.namespaces[reElemNameParts[1]], shortName: reElemNameParts[2] };
}
// Note that 'elemNameOrArray' is: either the full element name (eg. [html:]div) or an array of elements in JSON notation
function tag(elemNameOrArray, elemAttr) {
// Array of elements? Parse each one...
if (Array.isArray(elemNameOrArray)) {
const frag = doc.createDocumentFragment();
Array.prototype.forEach.call(arguments, (thisElem) => {
frag.appendChild(tag(...thisElem));
});
return frag;
}
// Single element? Parse element namespace prefix (if none exists, default to defaultNamespace), and create element
const elemNs = namespace(elemNameOrArray);
const elem = doc.createElementNS(elemNs.namespace || jsonToDOM.defaultNamespace, elemNs.shortName);
// Set element's attributes and/or callback functions (eg. onclick)
for (const key in elemAttr) {
const val = elemAttr[key];
if (nodes && key == 'key') {
nodes[val] = elem;
continue;
}
const attrNs = namespace(key);
if (typeof val === 'function') {
// Special case for function attributes; don't just add them as 'on...' attributes, but as events, using addEventListener
elem.addEventListener(key.replace(/^on/, ''), val, false);
} else {
// Note that the default namespace for XML attributes is, and should be, blank (ie. they're not in any namespace)
elem.setAttributeNS(attrNs.namespace || '', attrNs.shortName, val);
}
}
// Create and append this element's children
const childElems = Array.prototype.slice.call(arguments, 2);
childElems.forEach((childElem) => {
if (childElem != null) {
elem.appendChild(
childElem instanceof doc.defaultView.Node ? childElem
: Array.isArray(childElem) ? tag(...childElem)
: doc.createTextNode(childElem),
);
}
});
return elem;
}
return tag(...jsonTemplate);
}

@ -0,0 +1,792 @@
(function () {
function isChrome() {
return (typeof chrome !== 'undefined'
&& window.navigator.userAgent.match(/Chrom(?:e|ium)\/([0-9\.]+)/));
}
let browserProxy;
if (isChrome()) {
browserProxy = chrome;
} else {
browserProxy = browser;
}
const MIN_FF_MAJOR_VERSION = 51;
const requiredBrowserApis = [
browserProxy.webNavigation,
browserProxy.tabs,
browserProxy.webRequest,
browserProxy.runtime,
];
let areListenersRegistered = false;
const secBefore = 2000;
const secAfter = 5000;
const secBetweenDupAssets = 10e3;
const minVidSize = 500e3;
const maxVidSize = 25e6;
const maxContentRange = 25e6;
const videoExtensions = [
'af', '3gp', 'asf', 'avchd', 'avi', 'cam', 'dsh', 'flv', 'm1v', 'm2v',
'fla', 'flr', 'sol', 'm4v', 'mkv', 'wrap', 'mng', 'mov', 'mpeg', 'mpg',
'mpe', 'mp4', 'mxf', 'nsv', 'ogg', 'rm', 'svi', 'smi', 'wmv', 'webm',
];
const extensionsReg = new RegExp(`\\.${videoExtensions.join('$|\\.')}$`);
const videoContentTypesPrefixes = ['binary/octet-stream', 'video/', 'flv-application/', 'media'];
const bannedContentTypes = ['video/mp2t', 'video/f4m', 'video/f4f'];
const bannedFiletypes = ['ts'];
const bannedFiletypesReg = new RegExp(`\\.${bannedFiletypes.join('$|\\.')}$`);
const whitelistReqTypes = ['object', 'xmlhttprequest', 'other'];
const topVideoAssetDomains = [
'2mdn.net',
'adap.tv',
'adnxs.com',
'adsrvr.org',
'btrll.com',
'celtra.com',
'flashtalking.com',
'flite.com',
'innovid.com',
'jivox.com',
'mixpo.com',
'nytimes.com',
'playwire.com',
'selectmedia.asia',
'serving-sys.com',
'solvemedia.com',
'spotible.com',
'teads.tv',
'tribalfusion.com',
'tubemogul.com',
'videologygroup.com',
'washingtonpost.com',
];
const robotsTxtAllows = wappalyzer.robotsTxtAllows.bind(wappalyzer);
if (!String.prototype.endsWith) {
String.prototype.endsWith = function (searchString, position) {
const subjectString = this.toString();
if (typeof position !== 'number' || !isFinite(position)
|| Math.floor(position) !== position || position > subjectString.length) {
position = subjectString.length;
}
position -= searchString.length;
const lastIndex = subjectString.indexOf(searchString, position);
return lastIndex !== -1 && lastIndex === position;
};
}
function getFrame(getFrameDetails, callback) {
if (isChrome()) {
chrome.webNavigation.getFrame(getFrameDetails, callback);
} else if (typeof browser !== 'undefined') {
const gettingFrame = browser.webNavigation.getFrame(getFrameDetails);
gettingFrame.then(callback);
}
}
function ifBrowserValid(callback, elseCallback) {
if (isChrome()) {
callback();
} else if (typeof browser !== 'undefined') {
try {
const gettingInfo = browser.runtime.getBrowserInfo();
gettingInfo.then((browserInfo) => {
const browserVersion = parseInt(browserInfo.version.split('.')[0]);
if (browserInfo.name === 'Firefox'
&& browserVersion >= MIN_FF_MAJOR_VERSION) {
callback();
} else {
elseCallback();
}
});
} catch (err) {
elseCallback();
}
} else {
elseCallback();
}
}
function ifTrackingEnabled(details, ifCallback, elseCallback) {
const fullIfCallback = function () {
allowedByRobotsTxt(details, ifCallback, elseCallback);
};
browser.storage.local.get('tracking').then((item) => {
if (item.hasOwnProperty('tracking')) {
if (item.tracking) {
fullIfCallback();
} else {
elseCallback();
}
} else {
fullIfCallback();
}
});
}
function allowedByRobotsTxt(details, ifCallback, elseCallback) {
if (details.url && !details.url.startsWith('chrome://')) {
robotsTxtAllows(details.url).then(ifCallback, elseCallback);
} else {
elseCallback();
}
}
function isPixelRequest(request) {
return (request.type === 'image' || request.responseStatus === 204)
&& request.size <= 1000;
}
function isVpaidOrVastRequest(request) {
const lowerCaseUrl = request.url.toLowerCase();
return lowerCaseUrl.indexOf('vpaid') !== -1 || lowerCaseUrl.indexOf('vast') !== -1;
}
function hasValidRequestType(request) {
return whitelistReqTypes.indexOf(request.type) >= 0;
}
function stripQueryParams(url) {
return url.split('?', 1)[0];
}
function parseHostnameFromUrl(url) {
const parser = document.createElement('a');
parser.href = url;
return parser.hostname;
}
function hasDomain(url, domain) {
return parseHostnameFromUrl(url).endsWith(domain);
}
function findHeader(headers, key) {
let header;
for (let i = 0; i < headers.length; i += 1) {
header = headers[i];
if (header.name.toLowerCase() === key) {
return header;
}
}
return null;
}
function validVideoType(vtype) {
const goodType = videoContentTypesPrefixes.some(prefix => vtype.indexOf(prefix) === 0);
return goodType;
}
function assetMsgKey(assetReq) {
const url = stripQueryParams(assetReq.url);
const key = `${assetReq.frameId}-${url}`;
return key;
}
const PageNetworkTrafficCollector = function (tabId) {
this.tabId = tabId;
this.displayAdFound = false;
this.requests = {};
this.msgsBeingSent = {};
this.assetsSeen = {};
this.allRedirects = {};
};
var globalPageContainer = {
collectors: {},
dyingCollectors: {},
cleanupCollector(tabId) {
if (tabId in this.collectors) {
delete globalPageContainer.collectors[tabId];
}
},
onNewNavigation(details) {
const tabId = details.tabId;
this.cleanupCollector(tabId);
ifTrackingEnabled(
details,
() => {
if (!areListenersRegistered) {
registerListeners();
}
this.collectors[tabId] = new PageNetworkTrafficCollector(tabId);
},
() => {
if (areListenersRegistered) {
unregisterListeners();
}
},
);
},
onNavigationCommitted(details) {
},
onNavigationCompleted(details) {
},
onTabClose(tabId, closeInfo) {
this.cleanupCollector(tabId);
delete this.collectors[tabId];
},
onDisplayAdFound(tabId) {
this.collectors[tabId].displayAdFound = true;
},
getRandId() {
return String(Math.floor(Math.random() * 1e9));
},
getCollector(tabId) {
if (this.collectors.hasOwnProperty(tabId)) {
return this.collectors[tabId];
}
return null;
},
forwardCall(details, collectorMemberFunction) {
const collector = this.getCollector(details.tabId);
if (collector !== null) {
collectorMemberFunction.apply(collector, [details]);
}
},
};
PageNetworkTrafficCollector.prototype.sendLogMessageToTabConsole = function () {
const logMessage = Array.from(arguments).join(' ');
const message = { message: logMessage, event: 'console-log-message' };
browserProxy.tabs.sendMessage(this.tabId, message);
};
PageNetworkTrafficCollector.prototype.sendToTab = function (assetReq, reqs, curPageUrl, adTrackingEvent) {
const msg = {};
msg.assets = [];
msg.requests = [];
msg.event_data = {};
msg.event = adTrackingEvent;
if (adTrackingEvent === 'new-video-ad') {
msg.requests = reqs;
msg.requests.sort((reqA, reqB) => reqA.requestTimestamp - reqB.requestTimestamp);
if (assetReq) {
msg.assets = [assetReq];
}
} else if (adTrackingEvent === 'new-invalid-video-ad') {
msg.requests = reqs.map(request => parseHostnameFromUrl(request.url));
msg.assets = [{
url: parseHostnameFromUrl(assetReq.url),
contentType: assetReq.contentType,
size: assetReq.size,
}];
}
msg.origUrl = curPageUrl;
msg.displayAdFound = this.displayAdFound;
browserProxy.tabs.sendMessage(this.tabId, msg);
};
PageNetworkTrafficCollector.prototype.getRedirKey = function (url, frameId) {
return `${url}:${frameId}`;
};
PageNetworkTrafficCollector.prototype.seenBefore = function (request) {
const oldTime = this.assetsSeen[assetMsgKey(request)];
if (oldTime && (request.requestTimestamp - oldTime < secBetweenDupAssets)) {
return true;
}
return false;
};
PageNetworkTrafficCollector.prototype.recordSeenAsset = function (request) {
this.assetsSeen[assetMsgKey(request)] = request.requestTimestamp;
};
PageNetworkTrafficCollector.prototype.onBeforeRequest = function (details) {
const req = {
url: details.url,
type: details.type,
httpMethod: details.method,
frameId: details.frameId,
parentFrameId: details.parentFrameId,
requestTimestamp: details.timeStamp,
};
this.requests[details.requestId] = req;
};
PageNetworkTrafficCollector.prototype.onSendHeaders = function (details) {
let request,
header;
request = this.requests[details.requestId];
header = request && findHeader(details.requestHeaders, 'x-requested-with');
if (header && header.value.toLowerCase().indexOf('flash') > -1) {
request.from_flash = true;
}
};
PageNetworkTrafficCollector.prototype.onHeadersReceived = function (details) {
const getFrameDetails = {
tabId: details.tabId,
processId: null,
frameId: details.frameId,
};
const pageNetworkTrafficController = this;
getFrame(getFrameDetails, (frameDetails) => {
if (frameDetails && frameDetails.url) {
pageNetworkTrafficController._onHeadersReceived(details, frameDetails);
}
});
};
PageNetworkTrafficCollector.prototype._onHeadersReceived = function (details, frameDetails) {
let contentSize,
contentRange;
const request = this.requests[details.requestId];
if (request) {
const redirParent = this.allRedirects[this.getRedirKey(details.url, details.frameId)];
let header = request && findHeader(details.responseHeaders, 'content-type');
const contentType = header && header.value.toLowerCase();
if (contentType) {
request.contentType = contentType;
}
header = request && findHeader(details.responseHeaders, 'content-length');
contentSize = header && header.value;
if (contentSize) {
request.size = request.size || 0;
request.size += parseInt(contentSize);
}
header = request && findHeader(details.responseHeaders, 'content-range');
contentRange = header && header.value;
if (contentRange) {
request.contentRange = parseInt(contentRange.split('/')[1]);
}
let frameUrl = null;
if (frameDetails && frameDetails.url) {
frameUrl = frameDetails.url;
}
if (!this.bannedRequest(request)
&& (this.isVideoReq(frameUrl, request) || (redirParent && redirParent.isVideo))) {
request.isVideo = true;
}
}
};
PageNetworkTrafficCollector.prototype.onBeforeRedirect = function (details) {
const request = this.requests[details.requestId];
if (request) {
if (request.redirects) {
request.redirects.push(details.redirectUrl);
} else {
request.redirects = [details.redirectUrl];
}
this.allRedirects[this.getRedirKey(details.redirectUrl, details.frameId)] = request;
}
};
PageNetworkTrafficCollector.prototype.isYoutubeMastheadRequest = function (url) {
const re = /video_masthead/;
return this.hasYoutubeDomain(url) && re.test(url);
};
PageNetworkTrafficCollector.prototype.isYoutubeVideoRequest = function (srcUrl, destUrl) {
if (!this.hasYoutubeDomain(srcUrl)) {
return false;
}
const re = /https?:\/\/r.*?\.googlevideo\.com\/videoplayback\?/;
return re.test(destUrl);
};
PageNetworkTrafficCollector.prototype.processResponse = function (requestDetails, frameDetails) {
let request;
if (requestDetails) {
request = this.requests[requestDetails.requestId];
if (request) {
request.responseStatus = requestDetails.statusCode;
request.responseTimestamp = requestDetails.timeStamp;
let frameUrl = null;
if (frameDetails && frameDetails.url) {
frameUrl = frameDetails.url;
}
let requestUrl = null;
if (request.url) {
requestUrl = request.url;
}
if (this.isYoutubeAdReq(frameUrl, requestUrl)) {
const destVideoId = this.parseYoutubeVideoIdFromUrl(requestUrl);
const srcVideoId = this.parseYoutubeVideoIdFromUrl(frameUrl);
if (srcVideoId && destVideoId) {
request.isYoutubeAd = true;
request.isVideo = true;
request.rawSrcUrl = frameUrl;
request.rawDestUrl = requestUrl;
request.url = `https://www.youtube.com/watch?v=${this.parseYoutubeVideoIdFromUrl(requestUrl)}`;
}
} else if (!this.bannedRequest(request)
&& (this.isVideo || this.isVideoReq(frameUrl, request))) {
request.isVideo = true;
}
if (request.isVideo) {
const msgKey = assetMsgKey(request);
this.msgsBeingSent[msgKey] = request;
if (!this.seenBefore(request)) {
this.sendMsgWhenQuiet(msgKey);
}
this.recordSeenAsset(request);
}
}
}
};
PageNetworkTrafficCollector.prototype.onResponseStarted = function (responseDetails) {
if (responseDetails.frameId < 0) {
responseDetails.frameId = 99999;
}
const getFrameDetails = {
tabId: responseDetails.tabId,
processId: null,
frameId: responseDetails.frameId,
};
const pageNetworkTrafficController = this;
getFrame(getFrameDetails, (frameDetails) => {
if (frameDetails && frameDetails.url) {
pageNetworkTrafficController.processResponse(responseDetails, frameDetails);
}
});
};
PageNetworkTrafficCollector.prototype.hasBannedFiletype = function (request) {
const url = stripQueryParams(request.url);
if (bannedFiletypesReg.exec(url)) {
return true;
}
return false;
};
PageNetworkTrafficCollector.prototype.checkContentHeaders = function (request) {
if (request.contentType && validVideoType(request.contentType)) {
return true;
}
return false;
};
PageNetworkTrafficCollector.prototype.checkUrlExtension = function (request) {
const url = stripQueryParams(request.url);
if (extensionsReg.exec(url)) {
return true;
}
return false;
};
PageNetworkTrafficCollector.prototype.isVideoReq = function (srcUrl, request) {
if (this.isYoutubeVideoRequest(srcUrl, request.url)) {
return false;
}
return this.checkUrlExtension(request) || this.checkContentHeaders(request);
};
PageNetworkTrafficCollector.prototype.hasYoutubeDomain = function (url) {
const hostname = parseHostnameFromUrl(url);
if (hostname === 'www.youtube.com') {
return true;
}
return false;
};
PageNetworkTrafficCollector.prototype.parseYoutubeVideoIdFromUrl = function (url) {
let re = /^https?:\/\/www\.youtube\.com\/get_video_info.*(?:\?|&)video_id=(.*?)(?:$|&)/;
let match = re.exec(url);
if (match && match.length > 1) {
return match[1];
}
re = /^https?:\/\/www\.youtube\.com\/embed\/(.*?)(?:$|\?)/;
match = re.exec(url);
if (match && match.length > 1) {
return match[1];
}
re = /^https?:\/\/www\.youtube\.com\/watch.*(\?|&)v=([^&]*)/;
match = re.exec(url);
if (match && match.length > 1) {
return match[1];
}
return null;
};
PageNetworkTrafficCollector.prototype.isYoutubeGetVideoInfoReq = function (url) {
const re = /^https?:\/\/www\.youtube\.com\/get_video_info\?/;
return re.test(url);
};
PageNetworkTrafficCollector.prototype.isYoutubeAdReq = function (srcUrl, destUrl) {
if (!this.hasYoutubeDomain(srcUrl)
|| !this.isYoutubeGetVideoInfoReq(destUrl)) {
return false;
}
if (this.parseYoutubeVideoIdFromUrl(srcUrl)
=== this.parseYoutubeVideoIdFromUrl(destUrl)
&& !this.isYoutubeMastheadRequest(destUrl)) {
return false;
}
return true;
};
PageNetworkTrafficCollector.prototype.bannedRequest = function (request) {
return this.bannedVideoType(request) || this.hasBannedFiletype(request) || this.bannedVideoSize(request);
};
PageNetworkTrafficCollector.prototype.bannedVideoType = function (request) {
let badType = false;
if (request.contentType) {
badType = bannedContentTypes.some(prefix => request.contentType.indexOf(prefix) >= 0);
}
return badType;
};
PageNetworkTrafficCollector.prototype.bannedVideoSize = function (request) {
if (request.size !== null) {
if (request.size < minVidSize || request.size > maxVidSize || request.contentRange > maxContentRange) {
return true;
}
}
return false;
};
PageNetworkTrafficCollector.prototype.grabTagReqs = function (tabRequests, assetRequest) {
let minTimestamp,
maxTimestamp;
minTimestamp = assetRequest.requestTimestamp - secBefore;
maxTimestamp = assetRequest.requestTimestamp + secAfter;
const filteredRequests = tabRequests.filter(request => (request.requestTimestamp > minTimestamp
&& request.requestTimestamp < maxTimestamp
&& request.frameId === assetRequest.frameId
&& request.url !== assetRequest.url
&& (hasValidRequestType(request)
|| isPixelRequest(request))));
return filteredRequests;
};
PageNetworkTrafficCollector.prototype.isValidVideoAd = function (assetRequest, tagRequests) {
const hasVpaidOrVastRequest = tagRequests.some(tagRequest => isVpaidOrVastRequest(tagRequest));
if (assetRequest.isYoutubeAd) {
return true;
}
if (hasVpaidOrVastRequest) {
return true;
}
const hasTopVideoAssetDomain = topVideoAssetDomains.some(assetDomain => hasDomain(assetRequest.url, assetDomain));
return hasTopVideoAssetDomain;
};
PageNetworkTrafficCollector.prototype.sendMsgWhenQuiet = function (msgKey) {
let _this = this,
origPageUrl,
msgAssetReq;
msgAssetReq = this.msgsBeingSent[msgKey];
browserProxy.tabs.get(this.tabId, (tab) => { origPageUrl = tab.url; });
setTimeout(() => {
const rawRequests = [];
if (globalPageContainer.collectors[_this.tabId] === _this) {
for (const reqId in _this.requests) {
rawRequests.push(_this.requests[reqId]);
}
const tagReqs = _this.grabTagReqs(rawRequests, msgAssetReq);
if (_this.isValidVideoAd(msgAssetReq, tagReqs)) {
_this.sendToTab(msgAssetReq, tagReqs, origPageUrl, 'new-video-ad');
} else {
_this.sendToTab(msgAssetReq, tagReqs, origPageUrl, 'new-invalid-video-ad');
}
} else {
}
delete _this.msgsBeingSent[msgKey];
}, secAfter + secBefore);
};
PageNetworkTrafficCollector.prototype.existingMessage = function (candidateRequest) {
const frameMsg = this.msgsBeingSent[candidateRequest.frameId];
if (frameMsg) {
return frameMsg;
}
return null;
};
function onBeforeRequestListener(details) {
globalPageContainer.forwardCall(details, PageNetworkTrafficCollector.prototype.onBeforeRequest);
}
function onSendHeadersListener(details) {
globalPageContainer.forwardCall(details, PageNetworkTrafficCollector.prototype.onSendHeaders);
}
function onHeadersReceivedListener(details) {
globalPageContainer.forwardCall(details, PageNetworkTrafficCollector.prototype.onHeadersReceived);
}
function onBeforeRedirectListener(details) {
globalPageContainer.forwardCall(details, PageNetworkTrafficCollector.prototype.onBeforeRedirect);
}
function onResponseStartedListener(details) {
globalPageContainer.forwardCall(details, PageNetworkTrafficCollector.prototype.onResponseStarted);
}
function onCommittedListener(details) {
if (details.frameId === 0) {
globalPageContainer.onNavigationCommitted(details);
}
}
function onCompletedListener(details) {
if (details.frameId === 0) {
globalPageContainer.onNavigationCompleted(details);
}
}
function onRemovedListener(tabId, closeInfo) {
globalPageContainer.onTabClose(tabId, closeInfo);
}
function onMessageListener(message, sender, sendResponse) {
if (message.event === 'new-ad' && message.data.event === 'ad') {
const tabId = sender.tab.id;
if (tabId) {
globalPageContainer.onDisplayAdFound(tabId);
}
}
}
function registerListeners() {
browserProxy.webRequest.onBeforeRequest.addListener(
onBeforeRequestListener,
{ urls: ['http://*/*', 'https://*/*'] },
[],
);
browserProxy.webRequest.onSendHeaders.addListener(
onSendHeadersListener,
{ urls: ['http://*/*', 'https://*/*'] },
['requestHeaders'],
);
browserProxy.webRequest.onHeadersReceived.addListener(
onHeadersReceivedListener,
{ urls: ['http://*/*', 'https://*/*'] },
['responseHeaders'],
);
browserProxy.webRequest.onBeforeRedirect.addListener(
onBeforeRedirectListener,
{ urls: ['http://*/*', 'https://*/*'] },
[],
);
browserProxy.webRequest.onResponseStarted.addListener(
onResponseStartedListener,
{ urls: ['http://*/*', 'https://*/*'] },
['responseHeaders'],
);
browserProxy.webNavigation.onCommitted.addListener(onCommittedListener);
browserProxy.webNavigation.onCompleted.addListener(onCompletedListener);
browserProxy.tabs.onRemoved.addListener(onRemovedListener);
browserProxy.runtime.onMessage.addListener(onMessageListener);
areListenersRegistered = true;
}
function unregisterListeners() {
browserProxy.webRequest.onBeforeRequest.removeListener(
onBeforeRequestListener,
);
browserProxy.webRequest.onSendHeaders.removeListener(
onSendHeadersListener,
);
browserProxy.webRequest.onHeadersReceived.removeListener(
onHeadersReceivedListener,
);
browserProxy.webRequest.onBeforeRedirect.removeListener(
onBeforeRedirectListener,
);
browserProxy.webRequest.onResponseStarted.removeListener(
onResponseStartedListener,
);
browserProxy.webNavigation.onCommitted.removeListener(onCommittedListener);
browserProxy.webNavigation.onCompleted.removeListener(onCompletedListener);
browserProxy.tabs.onRemoved.removeListener(onRemovedListener);
browserProxy.runtime.onMessage.removeListener(onMessageListener);
areListenersRegistered = false;
}
function areRequiredBrowserApisAvailable() {
return requiredBrowserApis.every(api => typeof api !== 'undefined');
}
if (areRequiredBrowserApisAvailable()) {
ifBrowserValid(
() => {
browserProxy.webNavigation.onBeforeNavigate.addListener(
(details) => {
if (details.frameId === 0) {
globalPageContainer.onNewNavigation(details);
}
},
{
url: [{ urlMatches: 'http://*/*' }, { urlMatches: 'https://*/*' }],
},
);
}, () => {
},
);
}
browserProxy.runtime.onMessage.addListener((request, sender, sendResponse) => {
if (request === 'is_browser_valid') {
ifBrowserValid(
sendResponse({ browser_valid: true }),
sendResponse({ browser_valid: false }),
);
}
});
browserProxy.runtime.onMessage.addListener((request, sender, sendResponse) => {
if (request === 'is_tracking_enabled') {
ifTrackingEnabled(
sender.tab,
() => {
try { sendResponse({ tracking_enabled: true }); } catch (err) {}
},
() => {
try { sendResponse({ tracking_enabled: false }); } catch (err) {}
},
);
}
return true;
});
}());

@ -1,824 +0,0 @@
'use strict';
(function() {
function isChrome() {
return (typeof chrome !== 'undefined' &&
window.navigator.userAgent.match(/Chrom(?:e|ium)\/([0-9\.]+)/));
}
var browserProxy;
if ( isChrome() ) {
browserProxy = chrome;
} else {
browserProxy = browser;
}
var MIN_FF_MAJOR_VERSION = 51;
var requiredBrowserApis = [
browserProxy.webNavigation,
browserProxy.tabs,
browserProxy.webRequest,
browserProxy.runtime
];
var areListenersRegistered = false;
var secBefore = 2000;
var secAfter = 5000;
var secBetweenDupAssets = 10e3;
var minVidSize = 500e3;
var maxVidSize = 25e6;
var maxContentRange = 25e6;
var videoExtensions = [
'af', '3gp', 'asf', 'avchd', 'avi', 'cam', 'dsh', 'flv', 'm1v', 'm2v',
'fla', 'flr', 'sol', 'm4v', 'mkv', 'wrap', 'mng', 'mov', 'mpeg', 'mpg',
'mpe', 'mp4', 'mxf', 'nsv', 'ogg', 'rm', 'svi', 'smi', 'wmv', 'webm'
];
var extensionsReg = new RegExp('\\.' + videoExtensions.join('$|\\.') + '$');
var videoContentTypesPrefixes = ['binary/octet-stream', 'video/', 'flv-application/', 'media'];
var bannedContentTypes = ['video/mp2t','video/f4m','video/f4f'];
var bannedFiletypes = ['ts'];
var bannedFiletypesReg = new RegExp('\\.' + bannedFiletypes.join('$|\\.') + '$');
var whitelistReqTypes = ['object', 'xmlhttprequest', 'other'];
var topVideoAssetDomains = [
'2mdn.net',
'adap.tv',
'adnxs.com',
'adsrvr.org',
'btrll.com',
'celtra.com',
'flashtalking.com',
'flite.com',
'innovid.com',
'jivox.com',
'mixpo.com',
'nytimes.com',
'playwire.com',
'selectmedia.asia',
'serving-sys.com',
'solvemedia.com',
'spotible.com',
'teads.tv',
'tribalfusion.com',
'tubemogul.com',
'videologygroup.com',
'washingtonpost.com'
];
var robotsTxtAllows = wappalyzer.robotsTxtAllows.bind(wappalyzer);
if ( !String.prototype.endsWith ) {
String.prototype.endsWith = function(searchString, position) {
var subjectString = this.toString();
if ( typeof position !== 'number' || !isFinite(position) ||
Math.floor(position) !== position || position > subjectString.length) {
position = subjectString.length;
}
position -= searchString.length;
var lastIndex = subjectString.indexOf(searchString, position);
return lastIndex !== -1 && lastIndex === position;
};
}
function getFrame(getFrameDetails, callback) {
if ( typeof chrome !== 'undefined' ) {
chrome.webNavigation.getFrame(getFrameDetails, callback);
} else if ( typeof browser !== 'undefined' ) {
var gettingFrame = browser.webNavigation.getFrame(getFrameDetails);
gettingFrame.then(callback);
}
}
function ifBrowserValid(callback, elseCallback) {
if ( isChrome() ) {
callback();
} else if ( typeof browser !== 'undefined' ) {
try {
var gettingInfo = browser.runtime.getBrowserInfo();
gettingInfo.then(function(browserInfo) {
var browserVersion = parseInt(browserInfo.version.split('.')[0]);
if ( browserInfo.name === 'Firefox' &&
browserVersion >= MIN_FF_MAJOR_VERSION) {
callback();
} else {
elseCallback();
}
});
} catch (err) {
elseCallback();
}
} else {
elseCallback();
}
}
function ifTrackingEnabled(details, ifCallback, elseCallback) {
var fullIfCallback = function() {
allowedByRobotsTxt(details, ifCallback, elseCallback);
};
browser.storage.local.get('tracking').then(function(item) {
if ( item.hasOwnProperty('tracking') ) {
if ( item.tracking ) {
fullIfCallback();
} else {
elseCallback();
}
} else {
fullIfCallback();
}
});
}
function allowedByRobotsTxt(details, ifCallback, elseCallback) {
if ( details.url && !details.url.startsWith('chrome://') ) {
robotsTxtAllows(details.url).then(ifCallback, elseCallback);
} else {
elseCallback();
}
}
function isPixelRequest(request) {
return (request.type === 'image' || request.responseStatus === 204) &&
request.size <= 1000;
}
function isVpaidOrVastRequest(request) {
var lowerCaseUrl = request.url.toLowerCase();
return lowerCaseUrl.indexOf('vpaid') !== -1 || lowerCaseUrl.indexOf('vast') !== -1;
}
function hasValidRequestType(request) {
return whitelistReqTypes.indexOf(request.type) >= 0;
}
function stripQueryParams(url) {
return url.split('?', 1)[0];
}
function parseHostnameFromUrl(url) {
var parser = document.createElement('a');
parser.href = url;
return parser.hostname;
}
function hasDomain(url, domain) {
return parseHostnameFromUrl(url).endsWith(domain);
}
function findHeader(headers, key) {
var header;
for ( var i = 0; i < headers.length; i += 1 ) {
header = headers[i];
if ( header.name.toLowerCase() === key ) {
return header;
}
}
return null;
}
function validVideoType(vtype) {
var goodType = videoContentTypesPrefixes.some(function(prefix) {
return vtype.indexOf(prefix) === 0;
});
return goodType;
}
function assetMsgKey(assetReq) {
var url = stripQueryParams(assetReq.url);
var key = assetReq.frameId + '-' + url;
return key;
}
var PageNetworkTrafficCollector = function(tabId) {
this.tabId = tabId;
this.displayAdFound = false;
this.requests = {};
this.msgsBeingSent = {};
this.assetsSeen = {};
this.allRedirects = {};
};
var globalPageContainer = {
collectors: {},
dyingCollectors: {},
cleanupCollector: function(tabId) {
if ( tabId in this.collectors ) {
delete globalPageContainer.collectors[tabId];
}
},
onNewNavigation: function(details) {
var tabId = details.tabId;
this.cleanupCollector(tabId);
ifTrackingEnabled(
details,
function() {
if ( !areListenersRegistered ) {
registerListeners();
}
this.collectors[tabId] = new PageNetworkTrafficCollector(tabId);
}.bind(this),
function() {
if ( areListenersRegistered ) {
unregisterListeners();
}
}
);
},
onNavigationCommitted: function(details) {
},
onNavigationCompleted: function(details) {
},
onTabClose: function(tabId, closeInfo) {
this.cleanupCollector(tabId);
delete this.collectors[tabId];
},
onDisplayAdFound: function(tabId) {
this.collectors[tabId].displayAdFound = true;
},
getRandId: function() {
return String(Math.floor(Math.random() * 1e9));
},
getCollector: function(tabId) {
if ( this.collectors.hasOwnProperty(tabId) ) {
return this.collectors[tabId];
}
return null;
},
forwardCall: function(details, collectorMemberFunction) {
var collector = this.getCollector(details.tabId);
if ( collector !== null ) {
collectorMemberFunction.apply(collector, [details]);
}
}
};
PageNetworkTrafficCollector.prototype.sendLogMessageToTabConsole = function() {
var logMessage = Array.from(arguments).join(' ');
var message = {message: logMessage, event: 'console-log-message'};
browserProxy.tabs.sendMessage(this.tabId, message);
};
PageNetworkTrafficCollector.prototype.sendToTab = function(assetReq, reqs, curPageUrl, adTrackingEvent) {
var msg = {};
msg.assets = [];
msg.requests = [];
msg.event_data = {};
msg.event = adTrackingEvent;
if ( adTrackingEvent === 'new-video-ad' ) {
msg.requests = reqs;
msg.requests.sort(function(reqA, reqB) {return reqA.requestTimestamp - reqB.requestTimestamp;});
if ( assetReq ) {
msg.assets = [assetReq];
}
} else if ( adTrackingEvent === 'new-invalid-video-ad' ) {
msg.requests = reqs.map(function(request) {
return parseHostnameFromUrl(request.url);
});
msg.assets = [{
url: parseHostnameFromUrl(assetReq.url),
contentType: assetReq.contentType,
size: assetReq.size
}];
}
msg.origUrl = curPageUrl;
msg.displayAdFound = this.displayAdFound;
browserProxy.tabs.sendMessage(this.tabId, msg);
};
PageNetworkTrafficCollector.prototype.getRedirKey = function(url, frameId) {
return url + ':' + frameId;
};
PageNetworkTrafficCollector.prototype.seenBefore = function(request) {
var oldTime = this.assetsSeen[assetMsgKey(request)];
if ( oldTime && (request.requestTimestamp-oldTime < secBetweenDupAssets)){
return true;
}
return false;
};
PageNetworkTrafficCollector.prototype.recordSeenAsset = function(request) {
this.assetsSeen[assetMsgKey(request)] = request.requestTimestamp;
};
PageNetworkTrafficCollector.prototype.onBeforeRequest = function(details) {
var req = {
url: details.url,
type: details.type,
httpMethod: details.method,
frameId: details.frameId,
parentFrameId: details.parentFrameId,
requestTimestamp: details.timeStamp,
};
this.requests[details.requestId] = req;
};
PageNetworkTrafficCollector.prototype.onSendHeaders = function(details) {
var request, header;
request = this.requests[details.requestId];
header = request && findHeader(details.requestHeaders, 'x-requested-with');
if ( header && header.value.toLowerCase().indexOf('flash') > -1 ) {
request.from_flash = true;
}
};
PageNetworkTrafficCollector.prototype.onHeadersReceived = function(details) {
var getFrameDetails = {
tabId: details.tabId,
processId: null,
frameId: details.frameId
};
var pageNetworkTrafficController = this;
getFrame(getFrameDetails, function(frameDetails) {
if ( frameDetails && frameDetails.url ) {
pageNetworkTrafficController._onHeadersReceived(details, frameDetails);
}
});
};
PageNetworkTrafficCollector.prototype._onHeadersReceived = function(details, frameDetails) {
var contentSize, contentRange;
var request = this.requests[details.requestId];
if ( request ) {
var redirParent = this.allRedirects[this.getRedirKey(details.url, details.frameId)];
var header = request && findHeader(details.responseHeaders, 'content-type');
var contentType = header && header.value.toLowerCase();
if ( contentType){
request.contentType = contentType;
}
header = request && findHeader(details.responseHeaders, 'content-length');
contentSize = header && header.value;
if ( contentSize ) {
request.size = request.size || 0;
request.size += parseInt(contentSize);
}
header = request && findHeader(details.responseHeaders, 'content-range');
contentRange = header && header.value;
if ( contentRange ) {
request.contentRange = parseInt(contentRange.split('/')[1]);
}
var frameUrl = null;
if ( frameDetails && frameDetails.url ) {
frameUrl = frameDetails.url;
}
if ( !this.bannedRequest(request) &&
(this.isVideoReq(frameUrl, request) || (redirParent && redirParent.isVideo))) {
request.isVideo = true;
}
}
};
PageNetworkTrafficCollector.prototype.onBeforeRedirect = function(details) {
var request = this.requests[details.requestId];
if ( request ) {
if ( request.redirects ) {
request.redirects.push(details.redirectUrl);
} else {
request.redirects = [details.redirectUrl];
}
this.allRedirects[this.getRedirKey(details.redirectUrl, details.frameId)] = request;
}
};
PageNetworkTrafficCollector.prototype.isYoutubeMastheadRequest = function(url) {
var re = /video_masthead/;
return this.hasYoutubeDomain(url) && re.test(url);
};
PageNetworkTrafficCollector.prototype.isYoutubeVideoRequest = function(srcUrl, destUrl) {
if ( !this.hasYoutubeDomain(srcUrl) ) {
return false;
}
var re = /https?:\/\/r.*?\.googlevideo\.com\/videoplayback\?/;
return re.test(destUrl);
};
PageNetworkTrafficCollector.prototype.processResponse = function(requestDetails, frameDetails) {
var request;
if ( requestDetails ) {
request = this.requests[requestDetails.requestId];
if ( request ) {
request.responseStatus = requestDetails.statusCode;
request.responseTimestamp = requestDetails.timeStamp;
var frameUrl = null;
if ( frameDetails && frameDetails.url ) {
frameUrl = frameDetails.url;
}
var requestUrl = null;
if ( request.url ) {
requestUrl = request.url;
}
if ( this.isYoutubeAdReq(frameUrl, requestUrl) ) {
var destVideoId = this.parseYoutubeVideoIdFromUrl(requestUrl);
var srcVideoId = this.parseYoutubeVideoIdFromUrl(frameUrl);
if ( srcVideoId && destVideoId ) {
request.isYoutubeAd = true;
request.isVideo = true;
request.rawSrcUrl = frameUrl;
request.rawDestUrl = requestUrl;
request.url = 'https://www.youtube.com/watch?v=' + this.parseYoutubeVideoIdFromUrl(requestUrl);
}
} else if ( !this.bannedRequest(request) &&
(this.isVideo || this.isVideoReq(frameUrl, request))) {
request.isVideo = true;
}
if ( request.isVideo ) {
var msgKey = assetMsgKey(request);
this.msgsBeingSent[msgKey] = request;
if ( !this.seenBefore(request) ) {
this.sendMsgWhenQuiet(msgKey);
}
this.recordSeenAsset(request);
}
}
}
};
PageNetworkTrafficCollector.prototype.onResponseStarted = function(responseDetails) {
if ( responseDetails.frameId < 0 ) {
responseDetails.frameId = 99999;
}
var getFrameDetails = {
tabId: responseDetails.tabId,
processId: null,
frameId: responseDetails.frameId
};
var pageNetworkTrafficController = this;
getFrame(getFrameDetails, function(frameDetails) {
if ( frameDetails && frameDetails.url ) {
pageNetworkTrafficController.processResponse(responseDetails, frameDetails);
}
});
};
PageNetworkTrafficCollector.prototype.hasBannedFiletype = function(request) {
var url = stripQueryParams(request.url);
if ( bannedFiletypesReg.exec(url) ) {
return true;
} else {
return false;
}
};
PageNetworkTrafficCollector.prototype.checkContentHeaders = function(request) {
if ( request.contentType && validVideoType(request.contentType) ) {
return true;
}
return false;
};
PageNetworkTrafficCollector.prototype.checkUrlExtension = function(request) {
var url = stripQueryParams(request.url);
if ( extensionsReg.exec(url) ) {
return true;
} else {
return false;
}
};
PageNetworkTrafficCollector.prototype.isVideoReq = function(srcUrl, request) {
if ( this.isYoutubeVideoRequest(srcUrl, request.url) ) {
return false;
}
return this.checkUrlExtension(request) || this.checkContentHeaders(request);
};
PageNetworkTrafficCollector.prototype.hasYoutubeDomain = function(url) {
var hostname = parseHostnameFromUrl(url) ;
if ( hostname === 'www.youtube.com' ) {
return true;
}
return false;
};
PageNetworkTrafficCollector.prototype.parseYoutubeVideoIdFromUrl = function(url) {
var re = /^https?:\/\/www\.youtube\.com\/get_video_info.*(?:\?|&)video_id=(.*?)(?:$|&)/;
var match = re.exec(url);
if ( match && match.length > 1 ) {
return match[1];
}
re = /^https?:\/\/www\.youtube\.com\/embed\/(.*?)(?:$|\?)/;
match = re.exec(url);
if ( match && match.length > 1 ) {
return match[1];
}
re = /^https?:\/\/www\.youtube\.com\/watch.*(\?|&)v=([^&]*)/;
match = re.exec(url);
if ( match && match.length > 1 ) {
return match[1];
}
return null;
};
PageNetworkTrafficCollector.prototype.isYoutubeGetVideoInfoReq = function(url) {
var re = /^https?:\/\/www\.youtube\.com\/get_video_info\?/;
return re.test(url);
};
PageNetworkTrafficCollector.prototype.isYoutubeAdReq = function(srcUrl, destUrl) {
if ( !this.hasYoutubeDomain(srcUrl) ||
!this.isYoutubeGetVideoInfoReq(destUrl)) {
return false;
}
if ( this.parseYoutubeVideoIdFromUrl(srcUrl) ===
this.parseYoutubeVideoIdFromUrl(destUrl) &&
!this.isYoutubeMastheadRequest(destUrl)) {
return false;
}
return true;
};
PageNetworkTrafficCollector.prototype.bannedRequest = function(request) {
return this.bannedVideoType(request) || this.hasBannedFiletype(request) || this.bannedVideoSize(request);
};
PageNetworkTrafficCollector.prototype.bannedVideoType = function(request) {
var badType = false;
if ( request.contentType ) {
badType = bannedContentTypes.some(function(prefix) {
return request.contentType.indexOf(prefix) >= 0;
});
}
return badType;
};
PageNetworkTrafficCollector.prototype.bannedVideoSize = function(request) {
if ( request.size !== null ) {
if ( request.size < minVidSize || request.size > maxVidSize || request.contentRange > maxContentRange ) {
return true;
}
}
return false;
};
PageNetworkTrafficCollector.prototype.grabTagReqs = function(tabRequests, assetRequest) {
var minTimestamp, maxTimestamp;
minTimestamp = assetRequest.requestTimestamp - secBefore;
maxTimestamp = assetRequest.requestTimestamp + secAfter;
var filteredRequests = tabRequests.filter(function(request) {
return (request.requestTimestamp > minTimestamp &&
request.requestTimestamp < maxTimestamp &&
request.frameId === assetRequest.frameId &&
request.url !== assetRequest.url &&
(hasValidRequestType(request) ||
isPixelRequest(request)));
});
return filteredRequests;
};
PageNetworkTrafficCollector.prototype.isValidVideoAd = function(assetRequest, tagRequests) {
var hasVpaidOrVastRequest = tagRequests.some(function(tagRequest) {
return isVpaidOrVastRequest(tagRequest);
});
if ( assetRequest.isYoutubeAd ) {
return true;
}
if ( hasVpaidOrVastRequest ) {
return true;
}
var hasTopVideoAssetDomain = topVideoAssetDomains.some(function(assetDomain) {
return hasDomain(assetRequest.url, assetDomain);
});
return hasTopVideoAssetDomain;
};
PageNetworkTrafficCollector.prototype.sendMsgWhenQuiet = function(msgKey) {
var _this = this,
origPageUrl, msgAssetReq;
msgAssetReq = this.msgsBeingSent[msgKey];
browserProxy.tabs.get(this.tabId, function(tab) {origPageUrl = tab.url;});
setTimeout(function() {
var rawRequests = [];
if ( globalPageContainer.collectors[_this.tabId] === _this ) {
for ( var reqId in _this.requests ) {
rawRequests.push(_this.requests[reqId]);
}
var tagReqs = _this.grabTagReqs(rawRequests, msgAssetReq);
if ( _this.isValidVideoAd(msgAssetReq, tagReqs) ) {
_this.sendToTab(msgAssetReq, tagReqs, origPageUrl, 'new-video-ad');
} else {
_this.sendToTab(msgAssetReq, tagReqs, origPageUrl, 'new-invalid-video-ad');
}
} else {
}
delete _this.msgsBeingSent[msgKey];
}, secAfter+secBefore);
};
PageNetworkTrafficCollector.prototype.existingMessage = function(candidateRequest) {
var frameMsg = this.msgsBeingSent[candidateRequest.frameId];
if ( frameMsg ) {
return frameMsg;
} else {
return null;
}
};
function onBeforeRequestListener(details) {
globalPageContainer.forwardCall(details, PageNetworkTrafficCollector.prototype.onBeforeRequest);
}
function onSendHeadersListener(details) {
globalPageContainer.forwardCall(details, PageNetworkTrafficCollector.prototype.onSendHeaders);
}
function onHeadersReceivedListener(details) {
globalPageContainer.forwardCall(details, PageNetworkTrafficCollector.prototype.onHeadersReceived);
}
function onBeforeRedirectListener(details) {
globalPageContainer.forwardCall(details, PageNetworkTrafficCollector.prototype.onBeforeRedirect);
}
function onResponseStartedListener(details) {
globalPageContainer.forwardCall(details, PageNetworkTrafficCollector.prototype.onResponseStarted);
}
function onCommittedListener(details) {
if ( details.frameId === 0 ) {
globalPageContainer.onNavigationCommitted(details);
}
}
function onCompletedListener(details) {
if ( details.frameId === 0 ) {
globalPageContainer.onNavigationCompleted(details);
}
}
function onRemovedListener(tabId, closeInfo) {
globalPageContainer.onTabClose(tabId, closeInfo);
}
function onMessageListener(message, sender, sendResponse) {
if ( message.event === 'new-ad' && message.data.event === 'ad' ) {
var tabId = sender.tab.id;
if ( tabId ) {
globalPageContainer.onDisplayAdFound(tabId);
}
}
}
function registerListeners() {
browserProxy.webRequest.onBeforeRequest.addListener(
onBeforeRequestListener,
{urls: ['http://*/*', 'https://*/*']},
[]
);
browserProxy.webRequest.onSendHeaders.addListener(
onSendHeadersListener,
{urls: ['http://*/*', 'https://*/*']},
['requestHeaders']
);
browserProxy.webRequest.onHeadersReceived.addListener(
onHeadersReceivedListener,
{urls: ['http://*/*', 'https://*/*']},
['responseHeaders']
);
browserProxy.webRequest.onBeforeRedirect.addListener(
onBeforeRedirectListener,
{urls: ['http://*/*', 'https://*/*']},
[]
);
browserProxy.webRequest.onResponseStarted.addListener(
onResponseStartedListener,
{urls: ['http://*/*', 'https://*/*']},
['responseHeaders']
);
browserProxy.webNavigation.onCommitted.addListener(onCommittedListener);
browserProxy.webNavigation.onCompleted.addListener(onCompletedListener);
browserProxy.tabs.onRemoved.addListener(onRemovedListener);
browserProxy.runtime.onMessage.addListener(onMessageListener);
areListenersRegistered = true;
}
function unregisterListeners() {
browserProxy.webRequest.onBeforeRequest.removeListener(
onBeforeRequestListener
);
browserProxy.webRequest.onSendHeaders.removeListener(
onSendHeadersListener
);
browserProxy.webRequest.onHeadersReceived.removeListener(
onHeadersReceivedListener
);
browserProxy.webRequest.onBeforeRedirect.removeListener(
onBeforeRedirectListener
);
browserProxy.webRequest.onResponseStarted.removeListener(
onResponseStartedListener
);
browserProxy.webNavigation.onCommitted.removeListener(onCommittedListener);
browserProxy.webNavigation.onCompleted.removeListener(onCompletedListener);
browserProxy.tabs.onRemoved.removeListener(onRemovedListener);
browserProxy.runtime.onMessage.removeListener(onMessageListener);
areListenersRegistered = false;
}
function areRequiredBrowserApisAvailable() {
return requiredBrowserApis.every(function(api) {
return typeof api !== 'undefined';
});
}
if ( areRequiredBrowserApisAvailable() ) {
ifBrowserValid(
function() {
browserProxy.webNavigation.onBeforeNavigate.addListener(
function(details) {
if ( details.frameId === 0 ) {
globalPageContainer.onNewNavigation(details);
}
},
{
url: [{urlMatches: 'http://*/*'}, {urlMatches: 'https://*/*'}]
}
);
}, function() {
}
);
}
browserProxy.runtime.onMessage.addListener(function(request, sender, sendResponse) {
if ( request === 'is_browser_valid' ) {
ifBrowserValid(
sendResponse({'browser_valid': true}),
sendResponse({'browser_valid': false})
);
}
});
browserProxy.runtime.onMessage.addListener(function(request, sender, sendResponse) {
if ( request === 'is_tracking_enabled' ) {
ifTrackingEnabled(
sender.tab,
function() {
try {sendResponse({'tracking_enabled': true});}
catch(err) {} },
function() {
try {sendResponse({'tracking_enabled': false});}
catch(err) {}}
);
}
return true;
});
})();

@ -1,69 +1,96 @@
/** global: browser */
/** global: Wappalyzer */
/* globals browser Wappalyzer */
/* eslint-env browser */
const wappalyzer = new Wappalyzer();
function getOption(name, defaultValue, callback) {
browser.storage.local.get(name)
.then(item => {
callback(item.hasOwnProperty(name) ? item[name] : defaultValue);
});
/**
* Get a value from localStorage
*/
function getOption(name, defaultValue = null) {
return new Promise(async (resolve, reject) => {
let value = defaultValue;
try {
const option = await browser.storage.local.get(name);
if (option[name] !== undefined) {
value = option[name];
}
} catch (error) {
wappalyzer.log(error.message, 'driver', 'error');
return reject(error.message);
}
return resolve(value);
});
}
/**
* Set a value in localStorage
*/
function setOption(name, value) {
var option = {};
return new Promise(async (resolve, reject) => {
try {
await browser.storage.local.set({ [name]: value });
} catch (error) {
wappalyzer.log(error.message, 'driver', 'error');
option[name] = value;
return reject(error.message);
}
browser.storage.local.set(option);
return resolve();
});
}
document.addEventListener('DOMContentLoaded', () => {
var nodes = document.querySelectorAll('[data-i18n]');
document.addEventListener('DOMContentLoaded', async () => {
const nodes = document.querySelectorAll('[data-i18n]');
Array.prototype.forEach.call(nodes, node => {
Array.prototype.forEach.call(nodes, (node) => {
node.childNodes[0].nodeValue = browser.i18n.getMessage(node.dataset.i18n);
});
document.querySelector('#github').addEventListener('click', () => {
open(wappalyzer.config.githubURL);
window.open(wappalyzer.config.githubURL);
});
document.querySelector('#twitter').addEventListener('click', () => {
open(wappalyzer.config.twitterURL);
window.open(wappalyzer.config.twitterURL);
});
document.querySelector('#wappalyzer').addEventListener('click', () => {
open(wappalyzer.config.websiteURL);
window.open(wappalyzer.config.websiteURL);
});
getOption('upgradeMessage', true, value => {
const el = document.querySelector('#option-upgrade-message');
let el;
let value;
el.checked = value;
// Upgrade message
value = await getOption('upgradeMessage', true);
el.addEventListener('change', () => {
setOption('upgradeMessage', el.checked);
});
});
el = document.querySelector('#option-upgrade-message');
getOption('dynamicIcon', true, value => {
const el = document.querySelector('#option-dynamic-icon');
el.checked = value;
el.checked = value;
el.addEventListener('change', e => setOption('upgradeMessage', e.target.checked));
el.addEventListener('change', () => {
setOption('dynamicIcon', el.checked);
});
});
// Dynamic icon
value = await getOption('dynamicIcon', true);
getOption('tracking', true, value => {
const el = document.querySelector('#option-tracking');
el = document.querySelector('#option-dynamic-icon');
el.checked = value;
el.checked = value;
el.addEventListener('change', () => {
setOption('tracking', el.checked);
});
});
el.addEventListener('change', e => setOption('dynamicIcon', e.target.checked));
// Tracking
value = await getOption('tracking', true);
el = document.querySelector('#option-tracking');
el.checked = value;
el.addEventListener('change', e => setOption('tracking', e.target.checked));
});

@ -1,132 +1,184 @@
/* eslint-env browser */
/* global browser, chrome, jsonToDOM */
/** global: chrome */
/** global: browser */
/** global: jsonToDOM */
var func = tabs => {
( chrome || browser ).runtime.sendMessage({
id: 'get_apps',
tab: tabs[0],
source: 'popup.js'
}, response => {
replaceDomWhenReady(appsToDomTemplate(response));
});
};
let pinnedCategory = null;
let termsAccepted = false;
browser.tabs.query({ active: true, currentWindow: true })
.then(func)
.catch(console.error);
function slugify(string) {
return string.toLowerCase().replace(/[^a-z0-9-]/g, '-').replace(/--+/g, '-').replace(/(?:^-|-$)/, '');
}
function replaceDomWhenReady(dom) {
if ( /complete|interactive|loaded/.test(document.readyState) ) {
replaceDom(dom);
} else {
document.addEventListener('DOMContentLoaded', () => {
replaceDom(dom);
});
}
function i18n() {
const nodes = document.querySelectorAll('[data-i18n]');
Array.prototype.forEach.call(nodes, (node) => {
node.innerHTML = browser.i18n.getMessage(node.dataset.i18n);
});
}
function replaceDom(domTemplate) {
var container = document.getElementsByClassName('container')[0];
const container = document.getElementsByClassName('container')[0];
while ( container.firstChild ) {
while (container.firstChild) {
container.removeChild(container.firstChild);
}
container.appendChild(jsonToDOM(domTemplate, document, {}));
var nodes = document.querySelectorAll('[data-i18n]');
i18n();
Array.from(document.querySelectorAll('.detected__category-pin-wrapper')).forEach((pin) => {
pin.addEventListener('click', () => {
const categoryId = parseInt(pin.dataset.categoryId, 10);
if (categoryId === pinnedCategory) {
pin.className = 'detected__category-pin-wrapper';
Array.prototype.forEach.call(nodes, node => {
node.childNodes[0].nodeValue = browser.i18n.getMessage(node.dataset.i18n);
pinnedCategory = null;
} else {
const active = document.querySelector('.detected__category-pin-wrapper--active');
if (active) {
active.className = 'detected__category-pin-wrapper';
}
pin.className = 'detected__category-pin-wrapper detected__category-pin-wrapper--active';
pinnedCategory = categoryId;
}
(chrome || browser).runtime.sendMessage({
id: 'set_option',
key: 'pinnedCategory',
value: pinnedCategory,
});
});
});
}
function replaceDomWhenReady(dom) {
if (/complete|interactive|loaded/.test(document.readyState)) {
replaceDom(dom);
} else {
document.addEventListener('DOMContentLoaded', () => {
replaceDom(dom);
});
}
}
function appsToDomTemplate(response) {
var
appName, confidence, version, categories,
template = [];
let template = [];
if ( response.tabCache && Object.keys(response.tabCache.detected).length > 0 ) {
if (response.tabCache && Object.keys(response.tabCache.detected).length > 0) {
const categories = {};
// Group apps by category
for ( appName in response.tabCache.detected ) {
response.apps[appName].cats.forEach(cat => {
for (const appName in response.tabCache.detected) {
response.apps[appName].cats.forEach((cat) => {
categories[cat] = categories[cat] || { apps: [] };
categories[cat].apps[appName] = appName;
});
}
for ( cat in categories ) {
for (const cat in categories) {
const apps = [];
for ( appName in categories[cat].apps ) {
confidence = response.tabCache.detected[appName].confidenceTotal;
version = response.tabCache.detected[appName].version;
for (const appName in categories[cat].apps) {
const { confidence, version } = response.tabCache.detected[appName];
apps.push(
[
'a', {
class: 'detected__app',
target: '_blank',
href: 'https://www.wappalyzer.com/applications/' + slugify(appName)
href: `https://www.wappalyzer.com/technologies/${slugify(appName)}`,
}, [
'img', {
class: 'detected__app-icon',
src: '../images/icons/' + ( response.apps[appName].icon || 'default.svg' )
src: `../images/icons/${response.apps[appName].icon || 'default.svg'}`,
},
], [
'span', {
class: 'detected__app-name'
class: 'detected__app-name',
},
appName + ( version ? ' ' + version : '' ) + ( confidence < 100 ? ' (' + confidence + '% sure)' : '' )
]
]
appName,
], version ? [
'span', {
class: 'detected__app-version',
},
version,
] : null, confidence < 100 ? [
'span', {
class: 'detected__app-confidence',
},
`${confidence}% sure`,
] : null,
],
);
}
template.push(
[
'div', {
class: 'detected__category'
class: 'detected__category',
}, [
'a', {
class: 'detected__category-link',
target: '_blank',
href: 'https://www.wappalyzer.com/categories/' + slugify(response.categories[cat].name)
'div', {
class: 'detected__category-name',
}, [
'span', {
class: 'detected__category-name'
'a', {
class: 'detected__category-link',
target: '_blank',
href: `https://www.wappalyzer.com/categories/${slugify(response.categories[cat].name)}`,
},
browser.i18n.getMessage('categoryName' + cat)
]
browser.i18n.getMessage(`categoryName${cat}`),
], [
'span', {
class: `detected__category-pin-wrapper${pinnedCategory == cat ? ' detected__category-pin-wrapper--active' : ''}`,
'data-category-id': cat,
title: browser.i18n.getMessage('categoryPin'),
}, [
'img', {
class: 'detected__category-pin detected__category-pin--active',
src: '../images/pin-active.svg',
},
], [
'img', {
class: 'detected__category-pin detected__category-pin--inactive',
src: '../images/pin.svg',
},
],
],
], [
'div', {
class: 'detected__apps'
class: 'detected__apps',
},
apps
]
]
apps,
],
],
);
}
template = [
'div', {
class: 'detected'
class: 'detected',
},
template
template,
];
} else {
template = [
'div', {
class: 'empty'
class: 'empty',
},
[
'span', {
class: 'empty__text'
class: 'empty__text',
},
browser.i18n.getMessage('noAppsDetected')
browser.i18n.getMessage('noAppsDetected'),
],
];
}
@ -134,6 +186,39 @@ function appsToDomTemplate(response) {
return template;
}
function slugify(string) {
return string.toLowerCase().replace(/[^a-z0-9-]/g, '-').replace(/--+/g, '-').replace(/(?:^-|-$)/, '');
}
const func = (tabs) => {
(chrome || browser).runtime.sendMessage({
id: 'get_apps',
tab: tabs[0],
source: 'popup.js',
}, (response) => {
pinnedCategory = response.pinnedCategory;
termsAccepted = response.termsAccepted;
if (termsAccepted) {
replaceDomWhenReady(appsToDomTemplate(response));
} else {
i18n();
const wrapper = document.querySelector('.terms__wrapper');
document.querySelector('.terms__accept').addEventListener('click', () => {
(chrome || browser).runtime.sendMessage({
id: 'set_option',
key: 'termsAccepted',
value: true,
});
wrapper.classList.remove('terms__wrapper--active');
func(tabs);
});
wrapper.classList.add('terms__wrapper--active');
}
});
};
browser.tabs.query({ active: true, currentWindow: true })
.then(func)
.catch(console.error);

@ -1,75 +1,83 @@
{
"name": "Wappalyzer",
"short_name": "Wappalyzer",
"author": "Elbert Alias",
"homepage_url": "https://www.wappalyzer.com",
"description": "Identify web technologies",
"version": "5.4.3",
"default_locale": "en",
"manifest_version": 2,
"icons": {
"16": "images/icon_16.png",
"19": "images/icon_19.png",
"32": "images/icon_32.png",
"38": "images/icon_38.png",
"128": "images/icon_128.png"
},
"page_action": {
"default_icon": {
"16": "images/icon_16.png",
"19": "images/icon_19.png",
"32": "images/icon_32.png",
"38": "images/icon_38.png",
"128": "images/icon_128.png"
},
"default_title": "Wappalyzer",
"default_popup": "html/popup.html"
},
"background": {
"page": "html/background.html"
"name": "Wappalyzer",
"short_name": "Wappalyzer",
"author": "Elbert Alias",
"homepage_url": "https://www.wappalyzer.com",
"description": "Identify web technologies",
"version": "5.7.2",
"default_locale": "en",
"manifest_version": 2,
"icons": {
"16": "images/icon_16.png",
"19": "images/icon_19.png",
"32": "images/icon_32.png",
"38": "images/icon_38.png",
"128": "images/icon_128.png"
},
"page_action": {
"default_icon": {
"16": "images/icon_16.png",
"19": "images/icon_19.png",
"32": "images/icon_32.png",
"38": "images/icon_38.png",
"128": "images/icon_128.png"
},
"default_title": "Wappalyzer",
"default_popup": "html/popup.html"
},
"background": {
"page": "html/background.html"
},
"content_scripts": [
{
"matches": [
"http://*/*",
"https://*/*"
],
"js": [
"node_modules/webextension-polyfill/dist/browser-polyfill.js",
"js/content.js"
],
"run_at": "document_idle"
},
{
"matches": [
},
"content_scripts": [
{
"matches": [
"http://*/*",
"https://*/*"
],
"js": [
"js/iframe.js"
],
"run_at": "document_start",
"all_frames": true
}
],
"web_accessible_resources": [
"js/inject.js"
],
"options_page": "html/options.html",
"options_ui": {
"page": "html/options.html",
"open_in_tab": false
},
"permissions": [
"storage",
"tabs",
"webRequest",
"webNavigation",
"http://*/*",
"https://*/*"
],
"content_security_policy": "script-src 'self'; object-src 'self'"
"https://*/*"
],
"js": [
"node_modules/webextension-polyfill/dist/browser-polyfill.js",
"js/content.js"
],
"run_at": "document_idle"
},
{
"matches": [
"http://*/*",
"https://*/*"
],
"exclude_matches": [
"https://*.modirum.com/*",
"https://www.alphaecommerce.gr/*"
],
"js": [
"js/lib/iframe.js"
],
"run_at": "document_start",
"all_frames": true
}
],
"web_accessible_resources": [
"js/inject.js"
],
"options_ui": {
"page": "html/options.html",
"open_in_tab": false
},
"permissions": [
"cookies",
"storage",
"tabs",
"webRequest",
"webNavigation",
"http://*/*",
"https://*/*"
],
"content_security_policy": "script-src 'self'; object-src 'self'",
"applications": {
"gecko": {
"id": "wappalyzer@crunchlabz.com",
"strict_min_version": "60.0"
}
}
}

@ -0,0 +1,11 @@
{
"requires": true,
"lockfileVersion": 1,
"dependencies": {
"webextension-polyfill": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/webextension-polyfill/-/webextension-polyfill-0.3.1.tgz",
"integrity": "sha512-ISB42vlgMyM7xE1u6pREeCqmmXjLsYu/nqAR8Dl/gIAnylb+KpRpvKbVkUYNFePhhXn0Obkkc3jasOII9ztUtg=="
}
}
}

@ -1,5 +1,5 @@
{
"dependencies": {
"webextension-polyfill": "^0.1.1"
"webextension-polyfill": "^0.3.1"
}
}

@ -2,6 +2,6 @@
# yarn lockfile v1
webextension-polyfill@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/webextension-polyfill/-/webextension-polyfill-0.1.1.tgz#1d172e59b9ee8706d5ce2c55eebfe0cf23972d70"
webextension-polyfill@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/webextension-polyfill/-/webextension-polyfill-0.2.1.tgz#cdfc9126033039f1713553157d35beff1d4d6f4a"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 369 B

After

Width:  |  Height:  |  Size: 3.2 KiB

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 719.58002 655.81" height="655.81" width="719.58"><g transform="translate(48.361 -198.743)"><rect width="708.66" height="644.89" ry=".153" x="-42.901" y="204.203" fill="#002276" stroke="#fff" stroke-width="10.92" stroke-linecap="square"/><path d="M64.408 392.813v42.42h42.42v234.58h54.9v-277h-97.32zm354.36 0v42.42h44.92v234.58h54.9v-277h-99.82zm-130.54-5.91c-45.86 1.05-83 46.73-54.12 95.75l.03.03 19.72 26.4c-33.67 18.57-58.1 42.49-56.53 83.38 4.04 61.15 48.1 80.06 96.65 82.34 25.16-1.46 50.09-3.41 68.16-20.72l11.72 15.72h54.91c-11.18-14.9-22.68-30.27-34.22-45.72 23.1-25.95 22.49-62.49 21.72-96.5h-44.91c-.81 19.03 2.25 53.15-6.28 57.07a38974.36 38974.36 0 0 0-47.28-63.13c22.32-17.68 41.96-37.01 41.09-68.81 3.12-45.42-23.83-63.09-63.84-65.63-2.29-.17-4.56-.24-6.82-.18zm5.75 42.09c7.95.26 22.07-.75 22.47 21.22-1.59 16.95-12.89 26.19-24.43 37.06-3.75-4.97-7.53-9.99-11.16-14.78-3.01-3.97-6.38-7.7-8.94-11.72-.99-3.94-.79-7.13-.84-11.03-.17-3.97 4.19-18.89 22.9-20.75zm-13 116.44l52.5 70.28c-5.53 9.06-19.45 14.34-39.5 15.28-17.22-.4-44.37-5.61-47.4-36.03-.25-21.34 19.47-39.27 34.4-49.53z" fill="#fff"/></g></svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 529 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 631 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 631 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" version="1" viewBox="0 0 64 480"><g fill="#EE295F"><path d="M-192 240v240h480V0h-480v240zm312.7-1.5c32.6 97.9 59.3 178.3 59.3 178.8 0 .4-7.5.6-16.7.5l-16.8-.3-15.5-48.3-15.5-48.2-75 .2-74.9.3-15.6 48.2-15.5 48.3h-16.3c-12.7 0-16.3-.3-16-1.3.3-.6 27.2-81.2 59.9-179L21.5 60l19.9.2 19.9.3 59.4 178z"/><path d="M40.4 89.5c-.4 1.1-15.5 47.4-33.4 103l-32.7 101 66 .3c36.3.1 66.1.1 66.3-.1.2-.2-62.9-199.6-64.9-204.8-.3-1-.7-.8-1.3.6z"/></g></svg>

After

Width:  |  Height:  |  Size: 504 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 779 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 644 B

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="62px" height="62px" viewBox="0 0 62 62" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 39.1 (31720) - http://www.bohemiancoding.com/sketch -->
<title>AMP-Brand-Blue-Icon</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="amp-logo-internal-site" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="AMP-Brand-Blue-Icon" fill="#0379C4">
<path d="M41.6288667,28.1614333 L28.6243667,49.8035667 L26.2683667,49.8035667 L28.5975,35.7016667 L21.3838,35.7109667 C21.3838,35.7109667 21.3156,35.7130333 21.2835667,35.7130333 C20.6336,35.7130333 20.1076333,35.1870667 20.1076333,34.5371 C20.1076333,34.2581 20.367,33.7858667 20.367,33.7858667 L33.3291333,12.1695667 L35.7244,12.1799 L33.3363667,26.3035 L40.5872667,26.2942 C40.5872667,26.2942 40.6647667,26.2931667 40.7019667,26.2931667 C41.3519333,26.2931667 41.8779,26.8191333 41.8779,27.4691 C41.8779,27.7326 41.7745667,27.9640667 41.6278333,28.1604 L41.6288667,28.1614333 Z M31,0 C13.8787,0 0,13.8797333 0,31 C0,48.1213 13.8787,62 31,62 C48.1202667,62 62,48.1213 62,31 C62,13.8797333 48.1202667,0 31,0 L31,0 Z" id="Fill-1"></path>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 682 B

@ -0,0 +1,9 @@
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="" xml:space="preserve" width="18" height="18"><rect id="backgroundrect" width="100%" height="100%" x="0" y="0" fill="none" stroke="none"/>
<style type="text/css">
.st0{fill:#35B454;}
</style>
<path class="st0" d="M14.300000190734863,0 H0.30000001192092896 V4.5 l9.199999809265137,0 c0.6000000238418579,0 1,0.5 1,1 v7.900000095367432 h-2 c-0.6000000238418579,0 -1,-0.5 -1,-1 v-5.699999809265137 H3.5999999046325684 c-2,0 -3.5999999046325684,1.600000023841858 -3.5999999046325684,3.5999999046325684 v4 c0,2 1.600000023841858,3.5999999046325684 3.5999999046325684,3.5999999046325684 h14.300000190734863 V3.6000003814697266 C17.899999618530273,1.6000003814697266 16.299999237060547,0 14.300000190734863,0 z" id="svg_2"/>
</svg>

After

Width:  |  Height:  |  Size: 831 B

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 240 240">
<path fill="#00A5E9" d="M120 28.8l-89.4 32 13.7 118 75.7 42 75.7-42 13.7-118"/>
<path fill="#018BD1" d="M120 28.8V221l75.7-42 13.7-118"/>
<path fill="#FFF" d="M120 50L64 175.3h21l11.2-28h47.4l11.2 28h20.8L120 50zm16.3 80h-32.6L120 90.7l16.3 39.3z"/>
</svg>

After

Width:  |  Height:  |  Size: 326 B

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="355.809" height="355.809" viewBox="0 0 355.809 355.809"><path d="M177.367 0L9.964 58.913 36.416 278.24l141.129 77.568 141.856-78.619 26.444-219.32L177.367 0z" fill="#b3b3b3"/><path d="M329.149 70.545L176.976 18.654v318.622L304.504 266.7l24.645-196.154z" fill="#af2b2d"/><path d="M28.749 71.482l22.667 196.153 125.559 69.641V18.647L28.749 71.482z" fill="#df2e31"/><path d="M212.249 177.131l-34.995-73.08-30.808 73.08h65.803zm13.342 30.729h-92.764l-20.752 51.907-38.603.714L176.977 30.224 284.09 260.48h-35.779l-22.72-52.621z" fill="#f2f2f2"/><path d="M176.976 30.224l.276 73.827 34.96 73.136h-35.157l-.079 30.625 48.613.048 22.721 52.63 36.936.685-108.27-230.951z" fill="#b3b3b3"/></svg>

After

Width:  |  Height:  |  Size: 733 B

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="200px" height="200px" viewBox="0 0 200 200" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 47.1 (45422) - http://www.bohemiancoding.com/sketch -->
<title>Group 28 Copy 5</title>
<desc>Created with Sketch.</desc>
<defs>
<linearGradient x1="62.1023273%" y1="0%" x2="108.19718%" y2="37.8635764%" id="linearGradient-1">
<stop stop-color="#4285EB" offset="0%"></stop>
<stop stop-color="#2EC7FF" offset="100%"></stop>
</linearGradient>
<linearGradient x1="69.644116%" y1="0%" x2="54.0428975%" y2="108.456714%" id="linearGradient-2">
<stop stop-color="#29CDFF" offset="0%"></stop>
<stop stop-color="#148EFF" offset="37.8600687%"></stop>
<stop stop-color="#0A60FF" offset="100%"></stop>
</linearGradient>
<linearGradient x1="69.6908165%" y1="-12.9743587%" x2="16.7228981%" y2="117.391248%" id="linearGradient-3">
<stop stop-color="#FA816E" offset="0%"></stop>
<stop stop-color="#F74A5C" offset="41.472606%"></stop>
<stop stop-color="#F51D2C" offset="100%"></stop>
</linearGradient>
<linearGradient x1="68.1279872%" y1="-35.6905737%" x2="30.4400914%" y2="114.942679%" id="linearGradient-4">
<stop stop-color="#FA8E7D" offset="0%"></stop>
<stop stop-color="#F74A5C" offset="51.2635191%"></stop>
<stop stop-color="#F51D2C" offset="100%"></stop>
</linearGradient>
</defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="logo" transform="translate(-20.000000, -20.000000)">
<g id="Group-28-Copy-5" transform="translate(20.000000, 20.000000)">
<g id="Group-27-Copy-3">
<g id="Group-25" fill-rule="nonzero">
<g id="2">
<path d="M91.5880863,4.17652823 L4.17996544,91.5127728 C-0.519240605,96.2081146 -0.519240605,103.791885 4.17996544,108.487227 L91.5880863,195.823472 C96.2872923,200.518814 103.877304,200.518814 108.57651,195.823472 L145.225487,159.204632 C149.433969,154.999611 149.433969,148.181924 145.225487,143.976903 C141.017005,139.771881 134.193707,139.771881 129.985225,143.976903 L102.20193,171.737352 C101.032305,172.906015 99.2571609,172.906015 98.0875359,171.737352 L28.285908,101.993122 C27.1162831,100.824459 27.1162831,99.050775 28.285908,97.8821118 L98.0875359,28.1378823 C99.2571609,26.9692191 101.032305,26.9692191 102.20193,28.1378823 L129.985225,55.8983314 C134.193707,60.1033528 141.017005,60.1033528 145.225487,55.8983314 C149.433969,51.69331 149.433969,44.8756232 145.225487,40.6706018 L108.58055,4.05574592 C103.862049,-0.537986846 96.2692618,-0.500797906 91.5880863,4.17652823 Z" id="Shape" fill="url(#linearGradient-1)"></path>
<path d="M91.5880863,4.17652823 L4.17996544,91.5127728 C-0.519240605,96.2081146 -0.519240605,103.791885 4.17996544,108.487227 L91.5880863,195.823472 C96.2872923,200.518814 103.877304,200.518814 108.57651,195.823472 L145.225487,159.204632 C149.433969,154.999611 149.433969,148.181924 145.225487,143.976903 C141.017005,139.771881 134.193707,139.771881 129.985225,143.976903 L102.20193,171.737352 C101.032305,172.906015 99.2571609,172.906015 98.0875359,171.737352 L28.285908,101.993122 C27.1162831,100.824459 27.1162831,99.050775 28.285908,97.8821118 L98.0875359,28.1378823 C100.999864,25.6271836 105.751642,20.541824 112.729652,19.3524487 C117.915585,18.4685261 123.585219,20.4140239 129.738554,25.1889424 C125.624663,21.0784292 118.571995,14.0340304 108.58055,4.05574592 C103.862049,-0.537986846 96.2692618,-0.500797906 91.5880863,4.17652823 Z" id="Shape" fill="url(#linearGradient-2)"></path>
</g>
<path d="M153.685633,135.854579 C157.894115,140.0596 164.717412,140.0596 168.925894,135.854579 L195.959977,108.842726 C200.659183,104.147384 200.659183,96.5636133 195.960527,91.8688194 L168.690777,64.7181159 C164.472332,60.5180858 157.646868,60.5241425 153.435895,64.7316526 C149.227413,68.936674 149.227413,75.7543607 153.435895,79.9593821 L171.854035,98.3623765 C173.02366,99.5310396 173.02366,101.304724 171.854035,102.473387 L153.685633,120.626849 C149.47715,124.83187 149.47715,131.649557 153.685633,135.854579 Z" id="Shape" fill="url(#linearGradient-3)"></path>
</g>
<ellipse id="Combined-Shape" fill="url(#linearGradient-4)" cx="100.519339" cy="100.436681" rx="23.6001926" ry="23.580786"></ellipse>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.6 KiB

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="213px" height="213px" viewBox="0 0 213 213" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 47.1 (45422) - http://www.bohemiancoding.com/sketch -->
<title>Group</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Group">
<rect id="Rectangle" fill="#FFFFFF" x="0" y="0" width="213" height="213"></rect>
<path d="M174.043015,18.98918 C174.865266,17.9533389 176.532105,18.5340801 176.532105,19.8574997 L176.532105,193.145888 C176.532105,193.917884 175.908088,194.541901 175.136093,194.541901 L150.012062,194.541901 C149.054397,194.541901 148.162345,194.050504 147.651405,193.239423 L127.728915,161.67419 L99.1343972,116.365218 C98.5006076,115.361486 98.5704083,114.067382 99.3075028,113.139034 L174.043015,18.98918 Z M82.3247353,134.859448 C83.1469864,133.823607 84.815221,134.405744 84.815221,135.727768 L84.815221,193.14575 C84.815221,193.917744 84.1898074,194.541761 83.4192087,194.541761 L37.865935,194.541761 C36.6988688,194.541761 36.0469311,193.193213 36.7728573,192.278825 L82.3247353,134.859448 Z" id="Mark" fill="#EF4546" fill-rule="nonzero"></path>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 384 B

@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 1423.3867 867.05603"
height="867.05603"
width="1423.3867"
xml:space="preserve"
id="svg2"
version="1.1"><metadata
id="metadata8"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs6"><clipPath
id="clipPath18"
clipPathUnits="userSpaceOnUse"><path
id="path16"
d="M 0,650.292 H 1067.54 V 0 H 0 Z" /></clipPath></defs><g
transform="matrix(1.3333333,0,0,-1.3333333,0,867.056)"
id="g10"><g
id="g12"><g
clip-path="url(#clipPath18)"
id="g14"><g
transform="translate(321.5199,376.8768)"
id="g20"><path
id="path22"
style="fill:#0054a6;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 c -19.417,43.75 -56.917,76.25 -111.875,95.208 3.293,105.443 119.212,164.151 230.523,104.237 5.182,8.536 10.12,17.324 15.673,25.704 24.62,37.152 70.92,55.856 111.8,45.381 46.247,-11.851 84.023,-49.071 84.584,-94.011 l 0.013,-425.419 c -22.768,0 -53.205,-0.038 -78.47,0.007 -135.065,0.24 -270.144,-0.609 -405.191,1.127 -97.922,1.259 -170.073,77.053 -168.553,173.063 1.09,68.862 45.743,129.853 112.195,153.245 66.395,23.372 145.569,-0.596 189.707,-53.182" /></g><g
transform="translate(679.7488,549.7274)"
id="g24"><path
id="path26"
style="fill:#0054a6;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 c 107.306,0 214.612,-0.1 321.918,0.111 15.531,0.031 29.755,-2.911 42.227,-12.489 21.864,-16.791 28.329,-45.437 20.376,-67.146 -9.026,-24.64 -29.931,-40.704 -56.956,-40.852 -56.475,-0.309 -112.953,-0.107 -169.43,-0.11 C 105.424,-120.489 52.712,-120.487 0,-120.487 Z" /></g><g
transform="translate(679.7488,399.1187)"
id="g28"><path
id="path30"
style="fill:#0054a6;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 c 107.306,0 214.612,-0.1 321.918,0.111 15.531,0.031 29.755,-2.911 42.227,-12.489 21.864,-16.791 28.329,-45.437 20.376,-67.146 -9.026,-24.64 -29.931,-40.704 -56.956,-40.852 -56.475,-0.31 -112.953,-0.107 -169.43,-0.11 C 105.424,-120.489 52.712,-120.487 0,-120.487 Z" /></g><g
transform="translate(679.7488,248.5099)"
id="g32"><path
id="path34"
style="fill:#0054a6;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 c 107.306,0 214.612,-0.1 321.918,0.111 15.531,0.031 29.755,-2.911 42.227,-12.489 21.864,-16.791 28.329,-45.436 20.376,-67.146 -9.026,-24.64 -29.931,-40.704 -56.956,-40.852 -56.475,-0.309 -112.953,-0.107 -169.43,-0.11 C 105.424,-120.489 52.712,-120.487 0,-120.487 Z" /></g><g
transform="translate(379.3446,14.7246)"
id="g36"><path
id="path38"
style="fill:#0054a6;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 c 1.562,-0.828 4.112,-1.239 7.653,-1.239 h 18.43 c 7.496,0 11.245,2.685 11.245,8.059 v 13.175 c 0,5.166 -3.177,8.061 -9.527,8.681 H 6.091 C -0.366,27.951 -3.592,25.057 -3.592,19.995 V 6.82 C -3.592,3.512 -2.396,1.24 0,0 m -17.077,7.131 v 9.765 c 0,7.335 1.606,13.225 4.82,17.669 3.625,5.062 8.963,7.595 16.011,7.595 h 33.574 v 5.503 c 0,1.468 -0.518,2.751 -1.555,3.851 -1.036,1.099 -2.228,1.651 -3.574,1.651 H -17.077 V 66.65 h 48.205 c 10.642,0 17.101,-5.013 19.375,-15.035 0.206,-1.654 0.31,-2.893 0.31,-3.719 V 6.045 c 0,-3.72 -0.983,-7.183 -2.945,-10.385 -4.34,-6.924 -9.973,-10.385 -16.895,-10.385 H 3.848 c -4.03,0 -7.958,1.395 -11.78,4.185 -3.824,2.79 -6.459,6.097 -7.905,9.921 -0.828,2.271 -1.24,4.855 -1.24,7.75" /></g><g
transform="translate(440.096,20.6152)"
id="g40"><path
id="path42"
style="fill:#0054a6;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 v 40.3 c 0,6.716 2.51,11.882 7.537,15.5 4.655,3.305 11.028,4.96 19.117,4.96 H 63.601 V 47.274 H 26.51 c -7.014,0 -10.518,-2.901 -10.518,-8.704 V 3.129 c 0,-2.8 1.014,-5.21 3.045,-7.23 2.027,-2.019 4.704,-3.029 8.027,-3.029 H 63.785 V -20.615 H 27.021 c -5.393,0 -10.05,0.929 -13.97,2.79 C 4.348,-13.693 0,-7.75 0,0" /></g><g
transform="translate(527.9857,42.0049)"
id="g44"><path
id="path46"
style="fill:#0054a6;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 c 0,-2.274 1.085,-4.548 3.255,-6.82 l 33.79,-35.185 H 55.743 L 15.243,0.165 54.067,39.37 H 34.875 L 3.255,7.44 C 1.085,5.271 0,2.79 0,0 m -14.26,66.495 h 13.64 v -108.5 h -13.64 z" /></g><g
transform="translate(593.7211)"
id="g48"><path
id="path50"
style="fill:#0054a6;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="M 0,0 V 108.5 H 13.485 V 81.375 H 27.59 V 67.89 H 13.485 V 0 Z" /></g><g
transform="translate(654.8765,13.4854)"
id="g52"><path
id="path54"
style="fill:#0054a6;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 h 22.022 c 6.351,0 9.526,3.47 9.526,10.414 V 44.61 c 0,6.53 -3.175,9.794 -9.526,9.794 L 0,54.404 c -6.559,0 -9.837,-3.264 -9.837,-9.794 V 10.881 C -9.837,3.625 -6.559,0 0,0 m -23.322,6.51 v 42.314 c 0,11.16 6.045,17.462 18.135,18.91 0.412,0 1.032,0.051 1.86,0.156 h 26.66 c 0.722,0 1.807,-0.105 3.255,-0.31 12.296,-1.759 18.444,-8.01 18.444,-18.756 V 6.51 c 0,-7.441 -3.719,-13.28 -11.159,-17.515 -2.894,-1.654 -6.408,-2.48 -10.54,-2.48 h -25.42 c -10.335,0 -17.103,4.906 -20.306,14.724 -1.137,3.307 -1.448,5.063 -0.929,5.271" /></g><g
transform="translate(709.9087)"
id="g56"><path
id="path58"
style="fill:#0054a6;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 v 59.83 c 0,1.342 0.102,2.892 0.31,4.65 0.62,5.372 2.143,9.273 4.573,11.703 2.427,2.426 6.328,4.053 11.702,4.882 1.342,0.206 2.531,0.31 3.565,0.31 h 7.595 V 67.89 h -6.738 c -5.016,0 -7.522,-2.746 -7.522,-8.235 L 13.485,0 Z" /></g><g
transform="translate(747.6742,0.4951)"
id="g60"><path
id="path62"
style="fill:#0054a6;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 v 13.485 h 47.101 c 4.456,0.724 6.684,3.619 6.684,8.68 v 4.34 H 19.74 C 14.146,26.505 9.457,28.416 5.675,32.24 1.892,36.062 0,40.765 0,46.345 V 80.88 H 13.485 V 50.064 c 0,-6.717 3.228,-10.074 9.685,-10.074 h 21.242 c 6.249,0 9.373,2.892 9.373,8.68 V 80.88 H 67.27 V 22.939 C 67.27,15.914 65.512,10.385 62,6.354 58.176,2.119 52.802,0 45.88,0 Z" /></g><g
transform="translate(307.8782,13.4588)"
id="g64"><path
id="path66"
style="fill:#0054a6;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 h 23.853 c 0.728,0 1.196,0.051 1.404,0.155 3.22,0.723 5.195,3.256 5.925,7.602 0,0.102 0.05,0.258 0.154,0.467 V 45.3 c 0,6.001 -3.014,9 -9.042,9 H -1.559 c -4.885,0 -7.327,-2.896 -7.327,-8.687 V 9.775 c 0,-2.69 0.832,-4.992 2.495,-6.905 C -4.728,0.955 -2.599,0 0,0 M -22.345,9.437 V 94.831 H -8.886 V 67.759 H 22.61 c 12.514,0 19.754,-5.569 21.719,-16.707 0.309,-1.755 0.466,-2.993 0.466,-3.714 V 7.735 c 0,-9.181 -4.075,-15.574 -12.221,-19.183 -2.992,-1.341 -5.673,-2.011 -8.045,-2.011 H -2.079 c -5.777,0 -10.623,2.422 -14.542,7.271 -3.817,4.537 -5.724,9.746 -5.724,15.625" /></g></g></g></g></svg>

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

@ -1,6 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 612 612">
<g sodipodi:docname="twitter_bootstrap_logo.svg" inkscape:version="0.48.1 r9760" xmlns:svg="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape">
<path fill="#563D7C" d="M612 510c0 56.1-45.9 102-102 102H102C45.9 612 0 566.1 0 510V102C0 45.9 45.9 0 102 0h408c56.1 0 102 45.9 102 102v408z"/>
<path fill="#FFF" d="M166.3 133h173.5c32 0 57.7 7.3 77 22s29 36.8 29 66.5c0 18-4.4 33.4-13.2 46.2-8.8 12.8-21.4 22.8-37.8 29.8v1c22 4.7 38.7 15.1 50 31.2 11.3 16.2 17 36.4 17 60.8 0 14-2.5 27.1-7.5 39.2-5 12.2-12.8 22.7-23.5 31.5s-24.3 15.8-41 21-36.5 7.8-59.5 7.8h-164V133zm62.5 149.5h102c15 0 27.5-4.2 37.5-12.8s15-20.8 15-36.8c0-18-4.5-30.7-13.5-38s-22-11-39-11h-102v98.6zm0 156.5h110.5c19 0 33.8-4.9 44.2-14.8 10.5-9.8 15.8-23.8 15.8-41.8 0-17.7-5.2-31.2-15.8-40.8s-25.2-14.2-44.2-14.2H228.8V439z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="39px" height="40px" viewBox="0 0 39 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Brightspot-Logo" transform="translate(-239.000000, -2.000000)" fill="#EE2C42" fill-rule="nonzero">
<path d="M258.7,8.3 C266.3,8.3 272.5,14.5 272.5,22.1 C272.5,29.7 266.3,35.9 258.7,35.9 C251.1,35.9 244.9,29.7 244.9,22.1 C244.9,14.5 251.1,8.3 258.7,8.3 Z M258.7,2.8 C248,2.8 239.4,11.4 239.4,22.1 C239.4,32.8 248,41.4 258.7,41.4 C269.4,41.4 278,32.8 278,22.1 C278,11.5 269.4,2.8 258.7,2.8 Z" id="Shape"></path>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 732 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 210 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 274 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 743 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 642 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 706 B

After

Width:  |  Height:  |  Size: 763 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 678 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 678 B

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 714 B

Before

Width:  |  Height:  |  Size: 100 B

After

Width:  |  Height:  |  Size: 100 B

Some files were not shown because too many files have changed in this diff Show More