@ -0,0 +1,64 @@
|
||||
{
|
||||
"github": { "message": "Fork Wappalyzer su GitHub!" },
|
||||
"twitter": { "message": "Follow Wappalyzer su Twitter" },
|
||||
"website": { "message": "Vai su wappalyzer.com" },
|
||||
"options": { "message": "Opzioni Wappalyzer" },
|
||||
"optionsSave": { "message": "Salva opzioni" },
|
||||
"optionsSaved": { "message": "Salvato" },
|
||||
"optionUpgradeMessage": { "message": "Parlami dell'upgrade" },
|
||||
"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." },
|
||||
"categoryName1": { "message": "CMS" },
|
||||
"categoryName2": { "message": "Forum" },
|
||||
"categoryName3": { "message": "Gestore di Database" },
|
||||
"categoryName4": { "message": "Strumento di documentazione" },
|
||||
"categoryName5": { "message": "Widget" },
|
||||
"categoryName6": { "message": "eCommerce" },
|
||||
"categoryName7": { "message": "Galleria fotografica" },
|
||||
"categoryName8": { "message": "Wiki" },
|
||||
"categoryName9": { "message": "Pannello Hosting" },
|
||||
"categoryName10": { "message": "Analytics" },
|
||||
"categoryName11": { "message": "Blog" },
|
||||
"categoryName12": { "message": "Framework Javascript" },
|
||||
"categoryName13": { "message": "Issue Tracker" },
|
||||
"categoryName14": { "message": "Player Video" },
|
||||
"categoryName15": { "message": "Sistema di commenti" },
|
||||
"categoryName16": { "message": "Captcha" },
|
||||
"categoryName17": { "message": "Font Script" },
|
||||
"categoryName18": { "message": "Framework Web" },
|
||||
"categoryName19": { "message": "Miscellanea" },
|
||||
"categoryName20": { "message": "Editor" },
|
||||
"categoryName21": { "message": "LMS" },
|
||||
"categoryName22": { "message": "Web Server" },
|
||||
"categoryName23": { "message": "Cache Tool" },
|
||||
"categoryName24": { "message": "Editor di Testo Ricco" },
|
||||
"categoryName25": { "message": "Javascript Graphics" },
|
||||
"categoryName26": { "message": "Framework Mobile" },
|
||||
"categoryName27": { "message": "Linguaggio di programmazione" },
|
||||
"categoryName28": { "message": "Sistema Operativo" },
|
||||
"categoryName29": { "message": "Motore di Ricerca" },
|
||||
"categoryName30": { "message": "Web Mail" },
|
||||
"categoryName31": { "message": "CDN" },
|
||||
"categoryName32": { "message": "Marketing Automation" },
|
||||
"categoryName33": { "message": "Estensione Web Server" },
|
||||
"categoryName34": { "message": "Database" },
|
||||
"categoryName35": { "message": "Mappa" },
|
||||
"categoryName36": { "message": "Network Pubblicitario" },
|
||||
"categoryName37": { "message": "Network Service" },
|
||||
"categoryName38": { "message": "Media Server" },
|
||||
"categoryName39": { "message": "Webcam" },
|
||||
"categoryName40": { "message": "Stampante" },
|
||||
"categoryName41": { "message": "Payment Processor" },
|
||||
"categoryName42": { "message": "Tag Manager" },
|
||||
"categoryName43": { "message": "Paywall" },
|
||||
"categoryName44": { "message": "Sistema Build/CI" },
|
||||
"categoryName45": { "message": "SCADA System" },
|
||||
"categoryName46": { "message": "Accesso" },
|
||||
"categoryName47": { "message": "Strumenti di Sviluppo" },
|
||||
"categoryName48": { "message": "Network Storage" },
|
||||
"categoryName49": { "message": "Lettore di Feed" },
|
||||
"categoryName50": { "message": "Sistema di Gestione Documenti" },
|
||||
"categoryName51": { "message": "Landing Page Builder" }
|
||||
}
|
||||
|
@ -0,0 +1,699 @@
|
||||
'use strict';
|
||||
|
||||
var exports = {};
|
||||
|
||||
(function(exports) {
|
||||
var utils = {
|
||||
pageMeta: {
|
||||
url: window.location.hostname,
|
||||
isHP: window.location.pathname === '/',
|
||||
referrer: window.document.referrer,
|
||||
rand: Math.floor(Math.random() * 10e12),
|
||||
startTime: new Date().getTime()
|
||||
},
|
||||
|
||||
realArray: function(a) {
|
||||
return Array.prototype.slice.apply(a);
|
||||
},
|
||||
|
||||
SCRIPT_IN_WINDOW_TOP: window === window.top,
|
||||
|
||||
isFriendlyWindow: function(win) {
|
||||
var href;
|
||||
|
||||
try {
|
||||
href = win.location.href;
|
||||
} catch(e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
elementWindow: function(el) {
|
||||
return el.ownerDocument.defaultView;
|
||||
},
|
||||
|
||||
viewport: function(win) {
|
||||
return {width: win.innerWidth, height: win.innerHeight};
|
||||
},
|
||||
|
||||
parseQS: function(qs) {
|
||||
if (qs.indexOf('http') === 0) {
|
||||
qs = qs.split('?')[1];
|
||||
}
|
||||
|
||||
var i, kvs, key, val;
|
||||
|
||||
var dict = {};
|
||||
|
||||
qs = qs.split('&');
|
||||
|
||||
for ( i = 0; i < qs.length; i++ ) {
|
||||
kvs = qs[i].split('=');
|
||||
key = kvs[0];
|
||||
val = kvs.slice(1).join('=');
|
||||
|
||||
try {
|
||||
dict[key] = window.decodeURIComponent(val);
|
||||
} catch (e) {
|
||||
this.log('URI decode error', kvs);
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return dict;
|
||||
},
|
||||
|
||||
makeLog: function(opt_adData, opt_msgNum, opt_pageTags) {
|
||||
var assets = [opt_adData] || [];
|
||||
|
||||
return {
|
||||
doc: this.pageMeta,
|
||||
assets: assets,
|
||||
version: '3',
|
||||
msgNum: opt_msgNum || 0,
|
||||
pageTags: opt_pageTags || []
|
||||
};
|
||||
},
|
||||
|
||||
expBackoff: function(callback, initTimeoutMS, opt_maxTimeoutMS) {
|
||||
var curTimeout = initTimeoutMS;
|
||||
|
||||
var wrapped = function() {
|
||||
callback();
|
||||
|
||||
var nextTimeout = 2 * curTimeout;
|
||||
|
||||
curTimeout = opt_maxTimeoutMS ? Math.min(nextTimeout, opt_maxTimeoutMS) : nextTimeout;
|
||||
|
||||
setTimeout(wrapped, curTimeout);
|
||||
};
|
||||
|
||||
setTimeout(wrapped, curTimeout);
|
||||
},
|
||||
};
|
||||
|
||||
utils.SCRIPT_IN_FRIENDLY_IFRAME = !utils.SCRIPT_IN_WINDOW_TOP && utils.isFriendlyWindow(window.parent);
|
||||
utils.SCRIPT_IN_HOSTILE_IFRAME = !utils.SCRIPT_IN_WINDOW_TOP && !utils.SCRIPT_IN_FRIENDLY_IFRAME;
|
||||
|
||||
exports.utils = utils;
|
||||
})(exports);
|
||||
|
||||
(function(exports) {
|
||||
var VALID_AD_SIZES = [
|
||||
[160, 600],
|
||||
[300, 250],
|
||||
[300, 600],
|
||||
[300, 1050],
|
||||
[336, 280],
|
||||
[336, 850],
|
||||
[468, 60],
|
||||
[728, 90],
|
||||
[728, 270],
|
||||
[970, 66],
|
||||
[970, 90],
|
||||
[970, 250],
|
||||
[970, 400],
|
||||
[970, 415]
|
||||
];
|
||||
|
||||
var
|
||||
PX_SIZE_TOL = 10,
|
||||
MIN_WINDOW_PX = 10,
|
||||
MAX_SEARCHES_PER_WINDOW = 10,
|
||||
MAX_SEARCHES_PER_ELEMENT = 2;
|
||||
|
||||
var SIZE_SET = (function makeSizeSet() {
|
||||
var
|
||||
set = {},
|
||||
i,
|
||||
xfuz,
|
||||
yfuz,
|
||||
size,
|
||||
width,
|
||||
height;
|
||||
|
||||
for ( i = 0; i < VALID_AD_SIZES.length; i++ ) {
|
||||
for (xfuz = -PX_SIZE_TOL; xfuz <= PX_SIZE_TOL; xfuz++ ) {
|
||||
for ( yfuz = -PX_SIZE_TOL; yfuz <= PX_SIZE_TOL; yfuz++ ) {
|
||||
size = VALID_AD_SIZES[i];
|
||||
width = size[0] + xfuz;
|
||||
height = size[1] + yfuz;
|
||||
set[width] = set[width] || {};
|
||||
set[width][height] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return set;
|
||||
})();
|
||||
|
||||
function elementIsAd(el) {
|
||||
if ( typeof el.searches !== 'number' ) {
|
||||
el.searches = 0;
|
||||
}
|
||||
|
||||
if ( el.searches >= MAX_SEARCHES_PER_ELEMENT ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
el.searches ++;
|
||||
|
||||
var w = el.offsetWidth;
|
||||
|
||||
return SIZE_SET[w] && SIZE_SET[w][el.offsetHeight];
|
||||
}
|
||||
|
||||
function windowMightContainAds(win) {
|
||||
return win.innerWidth >= MIN_WINDOW_PX && win.innerHeight >= MIN_WINDOW_PX;
|
||||
}
|
||||
|
||||
function isNewAd(el) {
|
||||
return el.mp_adFound !== true;
|
||||
}
|
||||
|
||||
function getFriendlyIframes(win) {
|
||||
var iframes = win.document.querySelectorAll('iframe');
|
||||
|
||||
iframes = exports.utils.realArray(iframes);
|
||||
|
||||
var friendlyIframes = iframes.filter(function(ifr) {
|
||||
return exports.utils.isFriendlyWindow(ifr.contentWindow);
|
||||
});
|
||||
|
||||
return friendlyIframes;
|
||||
}
|
||||
|
||||
function findAds(win, opt_ads) {
|
||||
if ( !windowMightContainAds(win) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( typeof win.searches !== 'number' ) {
|
||||
win.searches = 0;
|
||||
}
|
||||
|
||||
var ads = opt_ads || [];
|
||||
|
||||
if ( exports.utils.SCRIPT_IN_WINDOW_TOP || win.searches < MAX_SEARCHES_PER_WINDOW ) {
|
||||
var adCandidates = win.document.querySelectorAll('img, object, embed');
|
||||
|
||||
adCandidates = exports.utils.realArray(adCandidates);
|
||||
|
||||
adCandidates.forEach(function(el) {
|
||||
if (elementIsAd(el) && isNewAd(el)) {
|
||||
el.mp_adFound = true;
|
||||
|
||||
ads.push(el);
|
||||
}
|
||||
});
|
||||
|
||||
win.searches ++;
|
||||
}
|
||||
|
||||
var iframes = getFriendlyIframes(win);
|
||||
|
||||
iframes.forEach(function(ifr) {
|
||||
findAds(ifr.contentWindow, ads);
|
||||
});
|
||||
|
||||
return ads;
|
||||
}
|
||||
|
||||
exports.adfinder = {
|
||||
findAds: findAds
|
||||
};
|
||||
})(exports);
|
||||
|
||||
(function(exports) {
|
||||
var parser = {
|
||||
TAGS_WITH_SRC_ATTR: {
|
||||
'IMG': true,
|
||||
'SCRIPT': true,
|
||||
'IFRAME': true,
|
||||
'EMBED': true
|
||||
},
|
||||
|
||||
MAX_ATTR_LEN: 100,
|
||||
|
||||
getUrl: function(el, params) {
|
||||
var url;
|
||||
|
||||
if ( this.TAGS_WITH_SRC_ATTR.hasOwnProperty(el.tagName) ) {
|
||||
url = el.src;
|
||||
} else if ( el.tagName === 'OBJECT' ) {
|
||||
url = el.data || (params && params.movie) || null;
|
||||
} else if ( el.tagName === 'A' ) {
|
||||
url = el.href;
|
||||
}
|
||||
|
||||
if ( url && url.indexOf('http') === 0 ) {
|
||||
return url;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
getParams: function(el) {
|
||||
if ( el.tagName !== 'OBJECT' ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var i, child;
|
||||
var params = {};
|
||||
var children = el.children;
|
||||
|
||||
for ( i = 0; i < children.length; i++ ) {
|
||||
child = children[i];
|
||||
|
||||
if ( child.tagName === 'PARAM' && child.name ) {
|
||||
params[child.name.toLowerCase()] = child.value;
|
||||
}
|
||||
}
|
||||
|
||||
return params;
|
||||
},
|
||||
|
||||
getPosition: function(el) {
|
||||
var rect = el.getBoundingClientRect();
|
||||
var win = exports.utils.elementWindow(el);
|
||||
|
||||
return {
|
||||
width: rect.width,
|
||||
height: rect.height,
|
||||
left: rect.left + win.pageXOffset,
|
||||
top: rect.top + win.pageYOffset
|
||||
};
|
||||
},
|
||||
|
||||
getFlashvars: function(el, params, url) {
|
||||
var flashvars;
|
||||
var urlQS = url && url.split('?')[1];
|
||||
|
||||
if ( el.tagName === 'EMBED' ) {
|
||||
flashvars = el.getAttribute('flashvars') || urlQS;
|
||||
} else if (el.tagName === 'OBJECT') {
|
||||
flashvars = params.flashvars || el.getAttribute('flashvars') || urlQS;
|
||||
}
|
||||
|
||||
return (flashvars && exports.utils.parseQS(flashvars)) || null;
|
||||
},
|
||||
|
||||
findClickThru: function(el, flashvars) {
|
||||
var key;
|
||||
|
||||
if ( el.tagName === 'IMG' && el.parentElement.tagName === 'A' ) {
|
||||
return el.parentElement.href;
|
||||
} else if ( flashvars ) {
|
||||
for ( key in flashvars ) {
|
||||
if ( flashvars.hasOwnProperty(key) ) {
|
||||
if (key.toLowerCase().indexOf('clicktag') === 0) {
|
||||
return flashvars[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
getAttr: function(el, name) {
|
||||
var val = el.getAttribute(name);
|
||||
|
||||
if ( val && val.slice && val.toString ) {
|
||||
return val.slice(0, this.MAX_ATTR_LEN).toString();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
putPropIfExists: function(obj, name, val) {
|
||||
if (val) {
|
||||
obj[name] = val;
|
||||
}
|
||||
},
|
||||
|
||||
putAttrIfExists: function(obj, el, name) {
|
||||
var val = this.getAttr(el, name);
|
||||
|
||||
this.putPropIfExists(obj, name, val);
|
||||
},
|
||||
|
||||
elementToJSON: function(el, opt_findClickThru) {
|
||||
var pos = this.getPosition(el);
|
||||
var params = this.getParams(el);
|
||||
var url = this.getUrl(el, params);
|
||||
var flashvars = this.getFlashvars(el, params, url);
|
||||
var clickThru = opt_findClickThru && this.findClickThru(el, flashvars);
|
||||
var json = {
|
||||
tagName: el.tagName,
|
||||
width: pos.width,
|
||||
height: pos.height,
|
||||
left: pos.left,
|
||||
top: pos.top,
|
||||
children: []
|
||||
};
|
||||
|
||||
if (params) {
|
||||
delete params.flashvars;
|
||||
}
|
||||
|
||||
this.putAttrIfExists(json, el, 'id');
|
||||
this.putAttrIfExists(json, el, 'class');
|
||||
this.putAttrIfExists(json, el, 'name');
|
||||
|
||||
this.putPropIfExists(json, 'flashvars', flashvars);
|
||||
this.putPropIfExists(json, 'url', url);
|
||||
this.putPropIfExists(json, 'params', params);
|
||||
this.putPropIfExists(json, 'clickThru', clickThru);
|
||||
|
||||
return json;
|
||||
}
|
||||
};
|
||||
|
||||
exports.parser = { elementToJSON: parser.elementToJSON.bind(parser) };
|
||||
})(exports);
|
||||
|
||||
(function(exports) {
|
||||
var ContextManager = function(adData) {
|
||||
this.adData = adData;
|
||||
};
|
||||
|
||||
ContextManager.prototype = {
|
||||
CONTAINER_SIZE_TOL: 0.4,
|
||||
ASPECT_RATIO_FOR_LEADERBOARDS: 2,
|
||||
|
||||
isValidContainer: function(el, opt_curWin) {
|
||||
var cWidth = el.clientWidth;
|
||||
var cHeight = el.clientHeight;
|
||||
|
||||
var adWidth = this.adData.width;
|
||||
var adHeight = this.adData.height;
|
||||
|
||||
var winWidth = opt_curWin && opt_curWin.innerWidth;
|
||||
var winHeight = opt_curWin && opt_curWin.innerHeight;
|
||||
var similarWin = opt_curWin && this.withinTol(adWidth, winWidth) && this.withinTol(adHeight, winHeight);
|
||||
|
||||
var similarSizeX = this.withinTol(adWidth, cWidth);
|
||||
var similarSizeY = this.withinTol(adHeight, cHeight);
|
||||
var adAspect = adWidth / adHeight;
|
||||
|
||||
return similarWin || el.tagName === 'A' || ( adAspect >= this.ASPECT_RATIO_FOR_LEADERBOARDS && similarSizeY ) || (similarSizeX && similarSizeY);
|
||||
},
|
||||
|
||||
withinTol: function(adlen, conlen) {
|
||||
var pct = (conlen - adlen) / adlen;
|
||||
|
||||
return pct <= this.CONTAINER_SIZE_TOL;
|
||||
},
|
||||
|
||||
serializeElements: function(el) {
|
||||
if ( !el ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var i;
|
||||
var ifrWin;
|
||||
var adId = this.adData.adId;
|
||||
var elIsAd = false;
|
||||
|
||||
if ( adId && el[adId] && el[adId].isAd === true ) {
|
||||
elIsAd = true;
|
||||
}
|
||||
|
||||
var json = exports.parser.elementToJSON(el, elIsAd);
|
||||
|
||||
if ( elIsAd ) {
|
||||
json.adId = adId;
|
||||
this.adData.element = json;
|
||||
}
|
||||
|
||||
var children = exports.utils.realArray(el.children).filter(function(el) {
|
||||
var param = el.tagName === 'PARAM';
|
||||
var inlineScript = el.tagName === 'SCRIPT' && !(el.src && el.src.indexOf('http') >= 0);
|
||||
var noScript = el.tagName === 'NOSCRIPT';
|
||||
|
||||
return !(param || inlineScript || noScript);
|
||||
});
|
||||
|
||||
for ( i = 0; i < children.length; i++ ) {
|
||||
json.children.push(this.serializeElements(children[i]));
|
||||
}
|
||||
|
||||
if ( el.tagName === 'IFRAME' ) {
|
||||
ifrWin = el.contentWindow;
|
||||
|
||||
if ( adId && el[adId] && el[adId].needsWindow ) {
|
||||
json.contents = this.adData.serializedIframeContents;
|
||||
|
||||
el[adId].needsWindow = false;
|
||||
|
||||
delete this.adData.serializedIframeContents;
|
||||
} else if ( exports.utils.isFriendlyWindow(ifrWin) ) {
|
||||
json.contents = this.serializeElements(ifrWin.document.documentElement);
|
||||
}
|
||||
}
|
||||
|
||||
return json;
|
||||
},
|
||||
|
||||
captureHTML: function(containerEl) {
|
||||
this.adData.context = this.serializeElements(containerEl);
|
||||
|
||||
if ( this.adData.html ) {
|
||||
this.adData.html.push(containerEl.outerHTML);
|
||||
}
|
||||
},
|
||||
|
||||
nodeCount: function(el) {
|
||||
return el.getElementsByTagName('*').length + 1;
|
||||
},
|
||||
|
||||
highestContainer: function(curWin, referenceElement) {
|
||||
var curContainer = referenceElement;
|
||||
var docEl = curWin.document.documentElement;
|
||||
var parentContainer;
|
||||
|
||||
if ( curWin !== curWin.top && this.isValidContainer(docEl, curWin) ) {
|
||||
return docEl;
|
||||
}
|
||||
|
||||
while ( true ) {
|
||||
parentContainer = curContainer.parentElement;
|
||||
|
||||
if (this.isValidContainer(parentContainer)) {
|
||||
curContainer = parentContainer;
|
||||
} else {
|
||||
return curContainer;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var tagfinder = {
|
||||
prepToSend: function(adData) {
|
||||
delete adData.width;
|
||||
delete adData.height;
|
||||
},
|
||||
|
||||
setPositions: function(adData, opt_el, opt_winPos) {
|
||||
var el = opt_el || adData.context;
|
||||
var winPos = opt_winPos || {left: 0, top: 0};
|
||||
var ifrPos;
|
||||
|
||||
el.left += winPos.left;
|
||||
el.top += winPos.top;
|
||||
|
||||
el.children.forEach(function(child) {
|
||||
this.setPositions(adData, child, winPos);
|
||||
}, this);
|
||||
|
||||
if ( el.contents ) {
|
||||
ifrPos = {left: el.left, top: el.top};
|
||||
this.setPositions(adData, el.contents, ifrPos);
|
||||
}
|
||||
|
||||
if ( el.adId === adData.adId ) {
|
||||
adData.element.left = el.left;
|
||||
adData.element.top = el.top;
|
||||
}
|
||||
},
|
||||
|
||||
appendTags: function(adData, referenceElement) {
|
||||
var mgr = new ContextManager(adData);
|
||||
var curWin = exports.utils.elementWindow(referenceElement);
|
||||
var highestContainer;
|
||||
|
||||
while (true) {
|
||||
highestContainer = mgr.highestContainer(curWin, referenceElement);
|
||||
mgr.captureHTML(highestContainer);
|
||||
|
||||
if (curWin === window.top) {
|
||||
break;
|
||||
} else {
|
||||
mgr.adData.serializedIframeContents = mgr.adData.context;
|
||||
|
||||
if (exports.utils.isFriendlyWindow(curWin.parent)) {
|
||||
referenceElement = curWin.frameElement;
|
||||
referenceElement[mgr.adData.adId] = { needsWindow: true };
|
||||
curWin = curWin.parent;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
referenceElement:referenceElement,
|
||||
highestContainer: highestContainer
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
exports.tagfinder = tagfinder;
|
||||
})(exports);
|
||||
|
||||
(function(exports) {
|
||||
var _onAdFound;
|
||||
var _getFullHTML;
|
||||
var _logsSent = 0;
|
||||
var _pageTags;
|
||||
var INIT_MS_BW_SEARCHES = 2000;
|
||||
var PAGE_TAG_RE = new RegExp('gpt|oascentral');
|
||||
|
||||
function getPageTags(doc) {
|
||||
var scripts = doc.getElementsByTagName('script');
|
||||
var pageTags = [];
|
||||
|
||||
scripts = exports.utils.realArray(scripts);
|
||||
|
||||
scripts.forEach(function(script) {
|
||||
if (PAGE_TAG_RE.exec(script.src)) {
|
||||
pageTags.push({'tagName': 'SCRIPT', 'url': script.src});
|
||||
}
|
||||
});
|
||||
|
||||
return pageTags;
|
||||
}
|
||||
|
||||
function messageAllParentFrames(adData) {
|
||||
adData.dummyId = true;
|
||||
|
||||
var win = window;
|
||||
|
||||
while ( win !== win.top ) {
|
||||
win = win.parent;
|
||||
win.postMessage(adData, '*');
|
||||
}
|
||||
}
|
||||
|
||||
function appendTagsAndSendToParent(adData, referenceElement) {
|
||||
var results = exports.tagfinder.appendTags(adData, referenceElement);
|
||||
|
||||
if ( exports.utils.SCRIPT_IN_HOSTILE_IFRAME ) {
|
||||
messageAllParentFrames(adData);
|
||||
} else if ( exports.utils.SCRIPT_IN_WINDOW_TOP ) {
|
||||
exports.tagfinder.setPositions(adData);
|
||||
exports.tagfinder.prepToSend(adData);
|
||||
|
||||
var html = adData.html;
|
||||
|
||||
delete adData.html;
|
||||
|
||||
adData.curPageUrl = window.location.href;
|
||||
_pageTags = _pageTags || getPageTags(document);
|
||||
|
||||
var log = exports.utils.makeLog(adData, _logsSent, _pageTags);
|
||||
|
||||
if ( _onAdFound ) {
|
||||
_onAdFound(log, html, results.referenceElement);
|
||||
_logsSent++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function extractAdsWrapper() {
|
||||
extractAds();
|
||||
setTimeout(extractAdsWrapper, INIT_MS_BW_SEARCHES);
|
||||
}
|
||||
|
||||
function extractAds() {
|
||||
var ads = exports.adfinder.findAds(window);
|
||||
|
||||
if ( !ads ) {
|
||||
return;
|
||||
}
|
||||
|
||||
ads.forEach(function(ad) {
|
||||
var startTime = new Date().getTime();
|
||||
var adId = startTime + '-' + Math.floor(Math.random() * 10e12);
|
||||
|
||||
var adData = {
|
||||
width: ad.offsetWidth,
|
||||
height: ad.offsetHeight,
|
||||
startTime: startTime,
|
||||
html: ( _getFullHTML && [] ) || null,
|
||||
adId: adId
|
||||
};
|
||||
|
||||
ad[adId] = { isAd: true };
|
||||
|
||||
appendTagsAndSendToParent(adData, ad);
|
||||
});
|
||||
}
|
||||
|
||||
function onPostMessage(event) {
|
||||
var adData = event.data;
|
||||
var ifrTag;
|
||||
|
||||
if ( !adData.dummyId ) {
|
||||
return;
|
||||
}
|
||||
|
||||
delete adData.dummyId;
|
||||
|
||||
try {
|
||||
ifrTag = event.source.frameElement;
|
||||
} catch(e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ifrTag[adData.adId] = {needsWindow: true};
|
||||
|
||||
appendTagsAndSendToParent(adData, ifrTag);
|
||||
}
|
||||
|
||||
exports.coordinator = {
|
||||
init: function(onAdFound, opt_getFullHTML) {
|
||||
if (exports.utils.SCRIPT_IN_FRIENDLY_IFRAME) {
|
||||
return false;
|
||||
}
|
||||
|
||||
_onAdFound = onAdFound;
|
||||
_getFullHTML = opt_getFullHTML;
|
||||
|
||||
if ( exports.utils.SCRIPT_IN_WINDOW_TOP ) {
|
||||
chrome.runtime.sendMessage({ event: 'new-page', url: window.location.href });
|
||||
}
|
||||
|
||||
window.addEventListener('message', onPostMessage, false);
|
||||
|
||||
if ( document.readyState !== 'loading' ) {
|
||||
extractAdsWrapper();
|
||||
} else {
|
||||
document.addEventListener('DOMContentLoaded', extractAdsWrapper);
|
||||
}
|
||||
}
|
||||
};
|
||||
})(exports);
|
||||
|
||||
(function(exports) {
|
||||
var onAdFound = function(log) {
|
||||
chrome.extension.sendRequest({ id: 'ad_log', subject: log });
|
||||
};
|
||||
|
||||
var getFullHTML = false;
|
||||
|
||||
exports.coordinator.init(onAdFound, getFullHTML);
|
||||
})(exports);
|
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 1.6 KiB |
@ -0,0 +1,529 @@
|
||||
/**
|
||||
* Wappalyzer v2
|
||||
*
|
||||
* Created by Elbert Alias <elbert@alias.io>
|
||||
*
|
||||
* License: GPLv3 http://www.gnu.org/licenses/gpl-3.0.txt
|
||||
*/
|
||||
|
||||
var wappalyzer = (function() {
|
||||
//'use strict';
|
||||
|
||||
/**
|
||||
* Application class
|
||||
*/
|
||||
var Application = function(app, detected) {
|
||||
this.app = app;
|
||||
this.confidence = {};
|
||||
this.confidenceTotal = 0;
|
||||
this.detected = Boolean(detected);
|
||||
this.excludes = [];
|
||||
this.version = '';
|
||||
this.versions = [];
|
||||
};
|
||||
|
||||
Application.prototype = {
|
||||
/**
|
||||
* Calculate confidence total
|
||||
*/
|
||||
getConfidence: function() {
|
||||
var total = 0, id;
|
||||
|
||||
for ( id in this.confidence ) {
|
||||
total += this.confidence[id];
|
||||
}
|
||||
|
||||
return this.confidenceTotal = Math.min(total, 100);
|
||||
},
|
||||
|
||||
/**
|
||||
* Resolve version number (find the longest version number that contains all shorter detected version numbers)
|
||||
*/
|
||||
getVersion: function() {
|
||||
var i, resolved;
|
||||
|
||||
if ( !this.versions.length ) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.versions.sort(function(a, b) {
|
||||
return a.length - b.length;
|
||||
});
|
||||
|
||||
resolved = this.versions[0];
|
||||
|
||||
for ( i = 1; i < this.versions.length; i++ ) {
|
||||
if ( this.versions[i].indexOf(resolved) === -1 ) {
|
||||
break;
|
||||
}
|
||||
|
||||
resolved = this.versions[i];
|
||||
}
|
||||
|
||||
return this.version = resolved;
|
||||
},
|
||||
|
||||
setDetected: function(pattern, type, value, key) {
|
||||
this.detected = true;
|
||||
|
||||
// Set confidence level
|
||||
this.confidence[type + ' ' + ( key ? key + ' ' : '' ) + pattern.regex] = pattern.confidence ? pattern.confidence : 100;
|
||||
|
||||
// Detect version number
|
||||
if ( pattern.version ) {
|
||||
var
|
||||
version = pattern.version,
|
||||
matches = pattern.regex.exec(value);
|
||||
|
||||
if ( matches ) {
|
||||
matches.forEach(function(match, i) {
|
||||
// Parse ternary operator
|
||||
var ternary = new RegExp('\\\\' + i + '\\?([^:]+):(.*)$').exec(version);
|
||||
|
||||
if ( ternary && ternary.length === 3 ) {
|
||||
w.log({ match: match, i: i, ternary: ternary });
|
||||
|
||||
version = version.replace(ternary[0], match ? ternary[1] : ternary[2]);
|
||||
|
||||
w.log({ version: version });
|
||||
}
|
||||
|
||||
// Replace back references
|
||||
version = version.replace(new RegExp('\\\\' + i, 'g'), match ? match : '');
|
||||
});
|
||||
|
||||
if ( version && this.versions.indexOf(version) < 0 ) {
|
||||
this.versions.push(version);
|
||||
}
|
||||
|
||||
this.getVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var Profiler = function() {
|
||||
this.regexCount = 0;
|
||||
this.startTime = new Date().getTime();
|
||||
this.lastTime = new Date().getTime();
|
||||
this.slowest = { duration: null, app: '', type: '', pattern: '' };
|
||||
this.timedOut = false;
|
||||
};
|
||||
|
||||
Profiler.prototype = {
|
||||
checkPoint: function(app, type, regex) {
|
||||
var duration = new Date().getTime() - this.lastTime;
|
||||
|
||||
if ( !this.slowest.duration || duration > this.slowest.duration ) {
|
||||
this.slowest.duration = duration;
|
||||
this.slowest.app = app;
|
||||
this.slowest.type = type;
|
||||
this.slowest.regex = regex;
|
||||
}
|
||||
|
||||
this.regexCount++;
|
||||
|
||||
this.lastTime = new Date().getTime();
|
||||
|
||||
this.timedOut = this.lastTime - this.startTime > 1000;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Call driver functions
|
||||
*/
|
||||
var driver = function(func, args) {
|
||||
if ( typeof w.driver[func] !== 'function' ) {
|
||||
w.log('not implemented: w.driver.' + func, 'warn');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( func !== 'log' ) {
|
||||
w.log('w.driver.' + func);
|
||||
}
|
||||
|
||||
return w.driver[func](args);
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse apps.json patterns
|
||||
*/
|
||||
var parse = function(patterns) {
|
||||
var
|
||||
attrs,
|
||||
parsed = [];
|
||||
|
||||
// Convert single patterns to an array
|
||||
if ( typeof patterns === 'string' ) {
|
||||
patterns = [ patterns ];
|
||||
}
|
||||
|
||||
patterns.forEach(function(pattern) {
|
||||
attrs = {};
|
||||
|
||||
pattern.split('\\;').forEach(function(attr, i) {
|
||||
if ( i ) {
|
||||
// Key value pairs
|
||||
attr = attr.split(':');
|
||||
|
||||
if ( attr.length > 1 ) {
|
||||
attrs[attr.shift()] = attr.join(':');
|
||||
}
|
||||
} else {
|
||||
attrs.string = attr;
|
||||
|
||||
try {
|
||||
attrs.regex = new RegExp(attr.replace('/', '\/'), 'i'); // Escape slashes in regular expression
|
||||
} catch (e) {
|
||||
attrs.regex = new RegExp();
|
||||
|
||||
w.log(e + ': ' + attr, 'error');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
parsed.push(attrs);
|
||||
});
|
||||
|
||||
return parsed;
|
||||
};
|
||||
|
||||
/**
|
||||
* Main script
|
||||
*/
|
||||
var w = {
|
||||
apps: {},
|
||||
cats: null,
|
||||
ping: { hostnames: {} },
|
||||
detected: {},
|
||||
|
||||
config: {
|
||||
websiteURL: 'https://wappalyzer.com/',
|
||||
twitterURL: 'https://twitter.com/Wappalyzer',
|
||||
githubURL: 'https://github.com/AliasIO/Wappalyzer',
|
||||
},
|
||||
|
||||
/**
|
||||
* Log messages to console
|
||||
*/
|
||||
log: function(message, type) {
|
||||
if ( type === undefined ) {
|
||||
type = 'debug';
|
||||
}
|
||||
|
||||
if ( typeof message === 'object' ) {
|
||||
message = JSON.stringify(message);
|
||||
}
|
||||
|
||||
driver('log', { message: '[wappalyzer ' + type + '] ' + message, type: type });
|
||||
},
|
||||
|
||||
/**
|
||||
* Initialize
|
||||
*/
|
||||
init: function() {
|
||||
w.log('w.init');
|
||||
|
||||
// Checks
|
||||
if ( w.driver === undefined ) {
|
||||
w.log('no driver, exiting');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize driver
|
||||
driver('init');
|
||||
},
|
||||
|
||||
/**
|
||||
* Analyze the request
|
||||
*/
|
||||
analyze: function(hostname, url, data) {
|
||||
var
|
||||
i, j, app, confidence, type, regexMeta, regexScript, match, content, meta, header, version, id,
|
||||
profiler = new Profiler(),
|
||||
apps = {},
|
||||
excludes = [],
|
||||
checkImplies = true;
|
||||
|
||||
w.log('w.analyze');
|
||||
|
||||
// Remove hash from URL
|
||||
data.url = url = url.split('#')[0];
|
||||
|
||||
if ( w.apps === undefined || w.categories === undefined ) {
|
||||
w.log('apps.json not loaded, check for syntax errors');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( w.detected[url] === undefined ) {
|
||||
w.detected[url] = {};
|
||||
}
|
||||
|
||||
for ( app in w.apps ) {
|
||||
// Exit loop after one second to prevent CPU hogging
|
||||
// Remaining patterns will not be evaluated
|
||||
if ( profiler.timedOut ) {
|
||||
w.log('Timeout, exiting loop');
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
apps[app] = w.detected[url] && w.detected[url][app] ? w.detected[url][app] : new Application(app);
|
||||
|
||||
for ( type in w.apps[app] ) {
|
||||
switch ( type ) {
|
||||
case 'url':
|
||||
parse(w.apps[app][type]).forEach(function(pattern) {
|
||||
if ( pattern.regex.test(url) ) {
|
||||
apps[app].setDetected(pattern, type, url);
|
||||
}
|
||||
|
||||
profiler.checkPoint(app, type, pattern.regex);
|
||||
});
|
||||
|
||||
break;
|
||||
case 'html':
|
||||
if ( typeof data[type] !== 'string' || !data.html ) {
|
||||
break;
|
||||
}
|
||||
|
||||
parse(w.apps[app][type]).forEach(function(pattern) {
|
||||
if ( pattern.regex.test(data[type]) ) {
|
||||
apps[app].setDetected(pattern, type, data[type]);
|
||||
}
|
||||
|
||||
profiler.checkPoint(app, type, pattern.regex);
|
||||
});
|
||||
|
||||
break;
|
||||
case 'script':
|
||||
if ( typeof data.html !== 'string' || !data.html ) {
|
||||
break;
|
||||
}
|
||||
|
||||
regexScript = new RegExp('<script[^>]+src=("|\')([^"\']+)', 'ig');
|
||||
|
||||
parse(w.apps[app][type]).forEach(function(pattern) {
|
||||
while ( match = regexScript.exec(data.html) ) {
|
||||
if ( pattern.regex.test(match[2]) ) {
|
||||
apps[app].setDetected(pattern, type, match[2]);
|
||||
}
|
||||
}
|
||||
|
||||
profiler.checkPoint(app, type, pattern.regex);
|
||||
});
|
||||
|
||||
break;
|
||||
case 'meta':
|
||||
if ( typeof data.html !== 'string' || !data.html ) {
|
||||
break;
|
||||
}
|
||||
|
||||
regexMeta = /<meta[^>]+>/ig;
|
||||
|
||||
while ( match = regexMeta.exec(data.html) ) {
|
||||
for ( meta in w.apps[app][type] ) {
|
||||
profiler.checkPoint(app, type, regexMeta);
|
||||
|
||||
if ( new RegExp('name=["\']' + meta + '["\']', 'i').test(match) ) {
|
||||
content = match.toString().match(/content=("|')([^"']+)("|')/i);
|
||||
|
||||
parse(w.apps[app].meta[meta]).forEach(function(pattern) {
|
||||
if ( content && content.length === 4 && pattern.regex.test(content[2]) ) {
|
||||
apps[app].setDetected(pattern, type, content[2], meta);
|
||||
}
|
||||
|
||||
profiler.checkPoint(app, type, pattern.regex);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case 'headers':
|
||||
if ( typeof data[type] !== 'object' || !data[type] ) {
|
||||
break;
|
||||
}
|
||||
|
||||
for ( header in w.apps[app].headers ) {
|
||||
parse(w.apps[app][type][header]).forEach(function(pattern) {
|
||||
if ( typeof data[type][header.toLowerCase()] === 'string' && pattern.regex.test(data[type][header.toLowerCase()]) ) {
|
||||
apps[app].setDetected(pattern, type, data[type][header.toLowerCase()], header);
|
||||
}
|
||||
|
||||
profiler.checkPoint(app, type, pattern.regex);
|
||||
});
|
||||
}
|
||||
|
||||
break;
|
||||
case 'env':
|
||||
if ( typeof data[type] !== 'object' || !data[type] ) {
|
||||
break;
|
||||
}
|
||||
|
||||
parse(w.apps[app][type]).forEach(function(pattern) {
|
||||
for ( i in data[type] ) {
|
||||
|
||||
if ( pattern.regex.test(data[type][i]) ) {
|
||||
apps[app].setDetected(pattern, type, data[type][i]);
|
||||
}
|
||||
}
|
||||
|
||||
profiler.checkPoint(app, type, pattern.regex);
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
w.log('[ profiler ] Tested ' + profiler.regexCount + ' regular expressions in ' + ( (new Date().getTime() - profiler.startTime) / 1000 ) + 's');
|
||||
w.log('[ profiler ] Slowest pattern took ' + ( profiler.slowest.duration / 1000 ) + 's: ' + profiler.slowest.app + ' | ' + profiler.slowest.type + ' | ' + profiler.slowest.regex);
|
||||
|
||||
for ( app in apps ) {
|
||||
if ( !apps[app].detected ) {
|
||||
delete apps[app];
|
||||
}
|
||||
}
|
||||
|
||||
// Exclude app in detected apps only
|
||||
for ( app in apps ) {
|
||||
if (w.apps[app].excludes ) {
|
||||
if ( typeof w.apps[app].excludes === 'string' ) {
|
||||
w.apps[app].excludes = [ w.apps[app].excludes ];
|
||||
}
|
||||
|
||||
w.apps[app].excludes.forEach(function(excluded) {
|
||||
excludes.push(excluded);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Remove excluded applications
|
||||
for ( app in apps ) {
|
||||
if ( excludes.indexOf(app) !== -1 ) {
|
||||
delete apps[app];
|
||||
}
|
||||
}
|
||||
|
||||
// Implied applications
|
||||
// Run several passes as implied apps may imply other apps
|
||||
while ( checkImplies ) {
|
||||
checkImplies = false;
|
||||
|
||||
for ( app in apps ) {
|
||||
confidence = apps[app].confidence;
|
||||
|
||||
if ( w.apps[app] && w.apps[app].implies ) {
|
||||
// Cast strings to an array
|
||||
if ( typeof w.apps[app].implies === 'string' ) {
|
||||
w.apps[app].implies = [ w.apps[app].implies ];
|
||||
}
|
||||
|
||||
w.apps[app].implies.forEach(function(implied) {
|
||||
implied = parse(implied)[0];
|
||||
|
||||
if ( !w.apps[implied.string] ) {
|
||||
w.log('Implied application ' + implied.string + ' does not exist', 'warn');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !apps.hasOwnProperty(implied.string) ) {
|
||||
apps[implied.string] = w.detected[url] && w.detected[url][implied.string] ? w.detected[url][implied.string] : new Application(implied.string, true);
|
||||
|
||||
checkImplies = true;
|
||||
}
|
||||
|
||||
// Apply app confidence to implied app
|
||||
for ( id in confidence ) {
|
||||
apps[implied.string].confidence[id + ' implied by ' + app] = confidence[id] * ( implied.confidence ? implied.confidence / 100 : 1 );
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
w.log(Object.keys(apps).length + ' apps detected: ' + Object.keys(apps).join(', ') + ' on ' + url);
|
||||
|
||||
// Keep history of detected apps
|
||||
for ( app in apps ) {
|
||||
confidence = apps[app].confidence;
|
||||
version = apps[app].version;
|
||||
|
||||
// Per URL
|
||||
w.detected[url][app] = apps[app];
|
||||
|
||||
for ( id in confidence ) {
|
||||
w.detected[url][app].confidence[id] = confidence[id];
|
||||
}
|
||||
|
||||
if ( w.detected[url][app].getConfidence() >= 100 ) {
|
||||
// Per hostname
|
||||
if ( /(www.)?((.+?)\.(([a-z]{2,3}\.)?[a-z]{2,6}))$/.test(hostname) && !/((local|dev(elopment)?|stag(e|ing)?|test(ing)?|demo(shop)?|admin|google|cache)\.|\/admin|\.local)/.test(url) ) {
|
||||
if ( !w.ping.hostnames.hasOwnProperty(hostname) ) {
|
||||
w.ping.hostnames[hostname] = { applications: {}, meta: {} };
|
||||
}
|
||||
|
||||
if ( !w.ping.hostnames[hostname].applications.hasOwnProperty(app) ) {
|
||||
w.ping.hostnames[hostname].applications[app] = { hits: 0 };
|
||||
}
|
||||
|
||||
w.ping.hostnames[hostname].applications[app].hits ++;
|
||||
|
||||
if ( version ) {
|
||||
w.ping.hostnames[hostname].applications[app].version = version;
|
||||
}
|
||||
} else {
|
||||
w.log('Ignoring hostname "' + hostname + '"');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Additional information
|
||||
if ( w.ping.hostnames.hasOwnProperty(hostname) ) {
|
||||
if ( typeof data.html === 'string' && data.html ) {
|
||||
match = data.html.match(/<html[^>]*[: ]lang="([a-z]{2}((-|_)[A-Z]{2})?)"/i);
|
||||
|
||||
if ( match && match.length ) {
|
||||
w.ping.hostnames[hostname].meta['language'] = match[1];
|
||||
}
|
||||
|
||||
regexMeta = /<meta[^>]+>/ig;
|
||||
|
||||
while ( match = regexMeta.exec(data.html) ) {
|
||||
if ( !match.length ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
match = match[0].match(/name="(author|copyright|country|description|keywords)"[^>]*content="([^"]+)"/i);
|
||||
|
||||
if ( match && match.length === 3 ) {
|
||||
w.ping.hostnames[hostname].meta[match[1]] = match[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( Object.keys(w.ping.hostnames).length >= 20 ) {
|
||||
driver('ping');
|
||||
}
|
||||
|
||||
apps = null;
|
||||
data = null;
|
||||
|
||||
driver('displayApps');
|
||||
}
|
||||
};
|
||||
|
||||
return w;
|
||||
})();
|
||||
|
||||
// CommonJS package
|
||||
// See http://wiki.commonjs.org/wiki/CommonJS
|
||||
if ( typeof exports === 'object' ) {
|
||||
exports.wappalyzer = wappalyzer;
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
name = Wappalyzer
|
||||
noAppsDetected = Nessuna applicazione rilevata
|
||||
clickForDetails = Clicca per i dettagli
|
||||
|
||||
preferences = Opzioni
|
||||
categories = Categorie
|
||||
tracking_title = Tracking
|
||||
tracking_description = Inviare anonimamente un report sulle applicazioni rilevate a wappalyzer.com per l'analisi
|
||||
urlbar_title = Mostra le icone nella barra delle URL
|
||||
urlbar_description = Deselezionare per visualizzare il pulsante nella barra degli strumenti.
|
||||
|
||||
feedback = Feedback
|
||||
github = Github
|
||||
twitter = Twitter
|
||||
website = Vai su wappalyzer.com
|
||||
|
||||
cat1 = CMS
|
||||
cat2 = Forum
|
||||
cat3 = Gestore di database
|
||||
cat4 = Strumento di documentazione
|
||||
cat5 = Widget
|
||||
cat6 = eCommerce
|
||||
cat7 = Galleria fotografica
|
||||
cat8 = Wiki
|
||||
cat9 = Pannello Hosting
|
||||
cat10 = Analytics
|
||||
cat11 = Blog
|
||||
cat12 = Framework JavaScript
|
||||
cat13 = Issue Tracker
|
||||
cat14 = Player Video
|
||||
cat15 = Sistema di commenti
|
||||
cat16 = CAPTCHA
|
||||
cat17 = Font Script
|
||||
cat18 = Framework Web
|
||||
cat19 = Miscellanea
|
||||
cat20 = Editor
|
||||
cat21 = LMS
|
||||
cat22 = Web Server
|
||||
cat23 = Cache Tool
|
||||
cat24 = Editor di Testo Ricco
|
||||
cat25 = Javascript Graphics
|
||||
cat26 = Framework Mobile
|
||||
cat27 = Linguaggio di Programmazione
|
||||
cat28 = Sistema Operativo
|
||||
cat29 = Motore di Ricerca
|
||||
cat30 = Web Mail
|
||||
cat31 = CDN
|
||||
cat32 = Marketing Automation
|
||||
cat33 = Estensione Web Server
|
||||
cat34 = Database
|
||||
cat35 = Mappa
|
||||
cat36 = Network Pubblicitario
|
||||
cat37 = Network Device
|
||||
cat38 = Media Server
|
||||
cat39 = Webcam
|
||||
cat40 = Stampante
|
||||
cat41 = Payment Processor
|
||||
cat42 = Tag Manager
|
||||
cat43 = Paywall
|
||||
cat44 = Sistema Build/CI
|
||||
cat45 = SCADA System
|
||||
cat46 = Accesso Remoto
|
||||
cat47 = Strumenti di Sviluppo
|
||||
cat48 = Network Storage
|
||||
cat49 = Lettore di Feed
|
||||
cat50 = Sistema di Gestione Documenti
|
||||
cat51 = Landing Page Builder
|
@ -0,0 +1,529 @@
|
||||
/**
|
||||
* Wappalyzer v2
|
||||
*
|
||||
* Created by Elbert Alias <elbert@alias.io>
|
||||
*
|
||||
* License: GPLv3 http://www.gnu.org/licenses/gpl-3.0.txt
|
||||
*/
|
||||
|
||||
var wappalyzer = (function() {
|
||||
//'use strict';
|
||||
|
||||
/**
|
||||
* Application class
|
||||
*/
|
||||
var Application = function(app, detected) {
|
||||
this.app = app;
|
||||
this.confidence = {};
|
||||
this.confidenceTotal = 0;
|
||||
this.detected = Boolean(detected);
|
||||
this.excludes = [];
|
||||
this.version = '';
|
||||
this.versions = [];
|
||||
};
|
||||
|
||||
Application.prototype = {
|
||||
/**
|
||||
* Calculate confidence total
|
||||
*/
|
||||
getConfidence: function() {
|
||||
var total = 0, id;
|
||||
|
||||
for ( id in this.confidence ) {
|
||||
total += this.confidence[id];
|
||||
}
|
||||
|
||||
return this.confidenceTotal = Math.min(total, 100);
|
||||
},
|
||||
|
||||
/**
|
||||
* Resolve version number (find the longest version number that contains all shorter detected version numbers)
|
||||
*/
|
||||
getVersion: function() {
|
||||
var i, resolved;
|
||||
|
||||
if ( !this.versions.length ) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.versions.sort(function(a, b) {
|
||||
return a.length - b.length;
|
||||
});
|
||||
|
||||
resolved = this.versions[0];
|
||||
|
||||
for ( i = 1; i < this.versions.length; i++ ) {
|
||||
if ( this.versions[i].indexOf(resolved) === -1 ) {
|
||||
break;
|
||||
}
|
||||
|
||||
resolved = this.versions[i];
|
||||
}
|
||||
|
||||
return this.version = resolved;
|
||||
},
|
||||
|
||||
setDetected: function(pattern, type, value, key) {
|
||||
this.detected = true;
|
||||
|
||||
// Set confidence level
|
||||
this.confidence[type + ' ' + ( key ? key + ' ' : '' ) + pattern.regex] = pattern.confidence ? pattern.confidence : 100;
|
||||
|
||||
// Detect version number
|
||||
if ( pattern.version ) {
|
||||
var
|
||||
version = pattern.version,
|
||||
matches = pattern.regex.exec(value);
|
||||
|
||||
if ( matches ) {
|
||||
matches.forEach(function(match, i) {
|
||||
// Parse ternary operator
|
||||
var ternary = new RegExp('\\\\' + i + '\\?([^:]+):(.*)$').exec(version);
|
||||
|
||||
if ( ternary && ternary.length === 3 ) {
|
||||
w.log({ match: match, i: i, ternary: ternary });
|
||||
|
||||
version = version.replace(ternary[0], match ? ternary[1] : ternary[2]);
|
||||
|
||||
w.log({ version: version });
|
||||
}
|
||||
|
||||
// Replace back references
|
||||
version = version.replace(new RegExp('\\\\' + i, 'g'), match ? match : '');
|
||||
});
|
||||
|
||||
if ( version && this.versions.indexOf(version) < 0 ) {
|
||||
this.versions.push(version);
|
||||
}
|
||||
|
||||
this.getVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var Profiler = function() {
|
||||
this.regexCount = 0;
|
||||
this.startTime = new Date().getTime();
|
||||
this.lastTime = new Date().getTime();
|
||||
this.slowest = { duration: null, app: '', type: '', pattern: '' };
|
||||
this.timedOut = false;
|
||||
};
|
||||
|
||||
Profiler.prototype = {
|
||||
checkPoint: function(app, type, regex) {
|
||||
var duration = new Date().getTime() - this.lastTime;
|
||||
|
||||
if ( !this.slowest.duration || duration > this.slowest.duration ) {
|
||||
this.slowest.duration = duration;
|
||||
this.slowest.app = app;
|
||||
this.slowest.type = type;
|
||||
this.slowest.regex = regex;
|
||||
}
|
||||
|
||||
this.regexCount++;
|
||||
|
||||
this.lastTime = new Date().getTime();
|
||||
|
||||
this.timedOut = this.lastTime - this.startTime > 1000;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Call driver functions
|
||||
*/
|
||||
var driver = function(func, args) {
|
||||
if ( typeof w.driver[func] !== 'function' ) {
|
||||
w.log('not implemented: w.driver.' + func, 'warn');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( func !== 'log' ) {
|
||||
w.log('w.driver.' + func);
|
||||
}
|
||||
|
||||
return w.driver[func](args);
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse apps.json patterns
|
||||
*/
|
||||
var parse = function(patterns) {
|
||||
var
|
||||
attrs,
|
||||
parsed = [];
|
||||
|
||||
// Convert single patterns to an array
|
||||
if ( typeof patterns === 'string' ) {
|
||||
patterns = [ patterns ];
|
||||
}
|
||||
|
||||
patterns.forEach(function(pattern) {
|
||||
attrs = {};
|
||||
|
||||
pattern.split('\\;').forEach(function(attr, i) {
|
||||
if ( i ) {
|
||||
// Key value pairs
|
||||
attr = attr.split(':');
|
||||
|
||||
if ( attr.length > 1 ) {
|
||||
attrs[attr.shift()] = attr.join(':');
|
||||
}
|
||||
} else {
|
||||
attrs.string = attr;
|
||||
|
||||
try {
|
||||
attrs.regex = new RegExp(attr.replace('/', '\/'), 'i'); // Escape slashes in regular expression
|
||||
} catch (e) {
|
||||
attrs.regex = new RegExp();
|
||||
|
||||
w.log(e + ': ' + attr, 'error');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
parsed.push(attrs);
|
||||
});
|
||||
|
||||
return parsed;
|
||||
};
|
||||
|
||||
/**
|
||||
* Main script
|
||||
*/
|
||||
var w = {
|
||||
apps: {},
|
||||
cats: null,
|
||||
ping: { hostnames: {} },
|
||||
detected: {},
|
||||
|
||||
config: {
|
||||
websiteURL: 'https://wappalyzer.com/',
|
||||
twitterURL: 'https://twitter.com/Wappalyzer',
|
||||
githubURL: 'https://github.com/AliasIO/Wappalyzer',
|
||||
},
|
||||
|
||||
/**
|
||||
* Log messages to console
|
||||
*/
|
||||
log: function(message, type) {
|
||||
if ( type === undefined ) {
|
||||
type = 'debug';
|
||||
}
|
||||
|
||||
if ( typeof message === 'object' ) {
|
||||
message = JSON.stringify(message);
|
||||
}
|
||||
|
||||
driver('log', { message: '[wappalyzer ' + type + '] ' + message, type: type });
|
||||
},
|
||||
|
||||
/**
|
||||
* Initialize
|
||||
*/
|
||||
init: function() {
|
||||
w.log('w.init');
|
||||
|
||||
// Checks
|
||||
if ( w.driver === undefined ) {
|
||||
w.log('no driver, exiting');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize driver
|
||||
driver('init');
|
||||
},
|
||||
|
||||
/**
|
||||
* Analyze the request
|
||||
*/
|
||||
analyze: function(hostname, url, data) {
|
||||
var
|
||||
i, j, app, confidence, type, regexMeta, regexScript, match, content, meta, header, version, id,
|
||||
profiler = new Profiler(),
|
||||
apps = {},
|
||||
excludes = [],
|
||||
checkImplies = true;
|
||||
|
||||
w.log('w.analyze');
|
||||
|
||||
// Remove hash from URL
|
||||
data.url = url = url.split('#')[0];
|
||||
|
||||
if ( w.apps === undefined || w.categories === undefined ) {
|
||||
w.log('apps.json not loaded, check for syntax errors');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( w.detected[url] === undefined ) {
|
||||
w.detected[url] = {};
|
||||
}
|
||||
|
||||
for ( app in w.apps ) {
|
||||
// Exit loop after one second to prevent CPU hogging
|
||||
// Remaining patterns will not be evaluated
|
||||
if ( profiler.timedOut ) {
|
||||
w.log('Timeout, exiting loop');
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
apps[app] = w.detected[url] && w.detected[url][app] ? w.detected[url][app] : new Application(app);
|
||||
|
||||
for ( type in w.apps[app] ) {
|
||||
switch ( type ) {
|
||||
case 'url':
|
||||
parse(w.apps[app][type]).forEach(function(pattern) {
|
||||
if ( pattern.regex.test(url) ) {
|
||||
apps[app].setDetected(pattern, type, url);
|
||||
}
|
||||
|
||||
profiler.checkPoint(app, type, pattern.regex);
|
||||
});
|
||||
|
||||
break;
|
||||
case 'html':
|
||||
if ( typeof data[type] !== 'string' || !data.html ) {
|
||||
break;
|
||||
}
|
||||
|
||||
parse(w.apps[app][type]).forEach(function(pattern) {
|
||||
if ( pattern.regex.test(data[type]) ) {
|
||||
apps[app].setDetected(pattern, type, data[type]);
|
||||
}
|
||||
|
||||
profiler.checkPoint(app, type, pattern.regex);
|
||||
});
|
||||
|
||||
break;
|
||||
case 'script':
|
||||
if ( typeof data.html !== 'string' || !data.html ) {
|
||||
break;
|
||||
}
|
||||
|
||||
regexScript = new RegExp('<script[^>]+src=("|\')([^"\']+)', 'ig');
|
||||
|
||||
parse(w.apps[app][type]).forEach(function(pattern) {
|
||||
while ( match = regexScript.exec(data.html) ) {
|
||||
if ( pattern.regex.test(match[2]) ) {
|
||||
apps[app].setDetected(pattern, type, match[2]);
|
||||
}
|
||||
}
|
||||
|
||||
profiler.checkPoint(app, type, pattern.regex);
|
||||
});
|
||||
|
||||
break;
|
||||
case 'meta':
|
||||
if ( typeof data.html !== 'string' || !data.html ) {
|
||||
break;
|
||||
}
|
||||
|
||||
regexMeta = /<meta[^>]+>/ig;
|
||||
|
||||
while ( match = regexMeta.exec(data.html) ) {
|
||||
for ( meta in w.apps[app][type] ) {
|
||||
profiler.checkPoint(app, type, regexMeta);
|
||||
|
||||
if ( new RegExp('name=["\']' + meta + '["\']', 'i').test(match) ) {
|
||||
content = match.toString().match(/content=("|')([^"']+)("|')/i);
|
||||
|
||||
parse(w.apps[app].meta[meta]).forEach(function(pattern) {
|
||||
if ( content && content.length === 4 && pattern.regex.test(content[2]) ) {
|
||||
apps[app].setDetected(pattern, type, content[2], meta);
|
||||
}
|
||||
|
||||
profiler.checkPoint(app, type, pattern.regex);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case 'headers':
|
||||
if ( typeof data[type] !== 'object' || !data[type] ) {
|
||||
break;
|
||||
}
|
||||
|
||||
for ( header in w.apps[app].headers ) {
|
||||
parse(w.apps[app][type][header]).forEach(function(pattern) {
|
||||
if ( typeof data[type][header.toLowerCase()] === 'string' && pattern.regex.test(data[type][header.toLowerCase()]) ) {
|
||||
apps[app].setDetected(pattern, type, data[type][header.toLowerCase()], header);
|
||||
}
|
||||
|
||||
profiler.checkPoint(app, type, pattern.regex);
|
||||
});
|
||||
}
|
||||
|
||||
break;
|
||||
case 'env':
|
||||
if ( typeof data[type] !== 'object' || !data[type] ) {
|
||||
break;
|
||||
}
|
||||
|
||||
parse(w.apps[app][type]).forEach(function(pattern) {
|
||||
for ( i in data[type] ) {
|
||||
|
||||
if ( pattern.regex.test(data[type][i]) ) {
|
||||
apps[app].setDetected(pattern, type, data[type][i]);
|
||||
}
|
||||
}
|
||||
|
||||
profiler.checkPoint(app, type, pattern.regex);
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
w.log('[ profiler ] Tested ' + profiler.regexCount + ' regular expressions in ' + ( (new Date().getTime() - profiler.startTime) / 1000 ) + 's');
|
||||
w.log('[ profiler ] Slowest pattern took ' + ( profiler.slowest.duration / 1000 ) + 's: ' + profiler.slowest.app + ' | ' + profiler.slowest.type + ' | ' + profiler.slowest.regex);
|
||||
|
||||
for ( app in apps ) {
|
||||
if ( !apps[app].detected ) {
|
||||
delete apps[app];
|
||||
}
|
||||
}
|
||||
|
||||
// Exclude app in detected apps only
|
||||
for ( app in apps ) {
|
||||
if (w.apps[app].excludes ) {
|
||||
if ( typeof w.apps[app].excludes === 'string' ) {
|
||||
w.apps[app].excludes = [ w.apps[app].excludes ];
|
||||
}
|
||||
|
||||
w.apps[app].excludes.forEach(function(excluded) {
|
||||
excludes.push(excluded);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Remove excluded applications
|
||||
for ( app in apps ) {
|
||||
if ( excludes.indexOf(app) !== -1 ) {
|
||||
delete apps[app];
|
||||
}
|
||||
}
|
||||
|
||||
// Implied applications
|
||||
// Run several passes as implied apps may imply other apps
|
||||
while ( checkImplies ) {
|
||||
checkImplies = false;
|
||||
|
||||
for ( app in apps ) {
|
||||
confidence = apps[app].confidence;
|
||||
|
||||
if ( w.apps[app] && w.apps[app].implies ) {
|
||||
// Cast strings to an array
|
||||
if ( typeof w.apps[app].implies === 'string' ) {
|
||||
w.apps[app].implies = [ w.apps[app].implies ];
|
||||
}
|
||||
|
||||
w.apps[app].implies.forEach(function(implied) {
|
||||
implied = parse(implied)[0];
|
||||
|
||||
if ( !w.apps[implied.string] ) {
|
||||
w.log('Implied application ' + implied.string + ' does not exist', 'warn');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !apps.hasOwnProperty(implied.string) ) {
|
||||
apps[implied.string] = w.detected[url] && w.detected[url][implied.string] ? w.detected[url][implied.string] : new Application(implied.string, true);
|
||||
|
||||
checkImplies = true;
|
||||
}
|
||||
|
||||
// Apply app confidence to implied app
|
||||
for ( id in confidence ) {
|
||||
apps[implied.string].confidence[id + ' implied by ' + app] = confidence[id] * ( implied.confidence ? implied.confidence / 100 : 1 );
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
w.log(Object.keys(apps).length + ' apps detected: ' + Object.keys(apps).join(', ') + ' on ' + url);
|
||||
|
||||
// Keep history of detected apps
|
||||
for ( app in apps ) {
|
||||
confidence = apps[app].confidence;
|
||||
version = apps[app].version;
|
||||
|
||||
// Per URL
|
||||
w.detected[url][app] = apps[app];
|
||||
|
||||
for ( id in confidence ) {
|
||||
w.detected[url][app].confidence[id] = confidence[id];
|
||||
}
|
||||
|
||||
if ( w.detected[url][app].getConfidence() >= 100 ) {
|
||||
// Per hostname
|
||||
if ( /(www.)?((.+?)\.(([a-z]{2,3}\.)?[a-z]{2,6}))$/.test(hostname) && !/((local|dev(elopment)?|stag(e|ing)?|test(ing)?|demo(shop)?|admin|google|cache)\.|\/admin|\.local)/.test(url) ) {
|
||||
if ( !w.ping.hostnames.hasOwnProperty(hostname) ) {
|
||||
w.ping.hostnames[hostname] = { applications: {}, meta: {} };
|
||||
}
|
||||
|
||||
if ( !w.ping.hostnames[hostname].applications.hasOwnProperty(app) ) {
|
||||
w.ping.hostnames[hostname].applications[app] = { hits: 0 };
|
||||
}
|
||||
|
||||
w.ping.hostnames[hostname].applications[app].hits ++;
|
||||
|
||||
if ( version ) {
|
||||
w.ping.hostnames[hostname].applications[app].version = version;
|
||||
}
|
||||
} else {
|
||||
w.log('Ignoring hostname "' + hostname + '"');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Additional information
|
||||
if ( w.ping.hostnames.hasOwnProperty(hostname) ) {
|
||||
if ( typeof data.html === 'string' && data.html ) {
|
||||
match = data.html.match(/<html[^>]*[: ]lang="([a-z]{2}((-|_)[A-Z]{2})?)"/i);
|
||||
|
||||
if ( match && match.length ) {
|
||||
w.ping.hostnames[hostname].meta['language'] = match[1];
|
||||
}
|
||||
|
||||
regexMeta = /<meta[^>]+>/ig;
|
||||
|
||||
while ( match = regexMeta.exec(data.html) ) {
|
||||
if ( !match.length ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
match = match[0].match(/name="(author|copyright|country|description|keywords)"[^>]*content="([^"]+)"/i);
|
||||
|
||||
if ( match && match.length === 3 ) {
|
||||
w.ping.hostnames[hostname].meta[match[1]] = match[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( Object.keys(w.ping.hostnames).length >= 20 ) {
|
||||
driver('ping');
|
||||
}
|
||||
|
||||
apps = null;
|
||||
data = null;
|
||||
|
||||
driver('displayApps');
|
||||
}
|
||||
};
|
||||
|
||||
return w;
|
||||
})();
|
||||
|
||||
// CommonJS package
|
||||
// See http://wiki.commonjs.org/wiki/CommonJS
|
||||
if ( typeof exports === 'object' ) {
|
||||
exports.wappalyzer = wappalyzer;
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
{
|
||||
"Date":"Fri, 17 Jul 2015 11:05:08 GMT",
|
||||
"Content-Encoding":"gzip",
|
||||
"Age":"0",
|
||||
"X-Cache":"MISS",
|
||||
"Connection":"keep-alive",
|
||||
"Content-Length":"1940",
|
||||
"Via":"1.1 varnish",
|
||||
"X-Served-By":"cache-lcy1122-LCY",
|
||||
"Last-Modified":"Thu, 16 Apr 2015 14:24:18 GMT",
|
||||
"Server":"GitHub.com",
|
||||
"X-Timer":"S1437131108.300792,VS0,VE84",
|
||||
"Vary":"Accept-Encoding",
|
||||
"Content-Type":"text/html; charset=utf-8",
|
||||
"Access-Control-Allow-Origin":"*",
|
||||
"Expires":"Fri, 17 Jul 2015 11:10:54 GMT",
|
||||
"Cache-Control":"max-age=600",
|
||||
"Accept-Ranges":"bytes",
|
||||
"X-Cache-Hits":"0"
|
||||
}
|
@ -0,0 +1,149 @@
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" ng-app="presen" >
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Preso Engines | CodeLanka</title>
|
||||
<!-- Bootstrap CSS -->
|
||||
<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet">
|
||||
<script src="//code.jquery.com/jquery.js"></script>
|
||||
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.5/angular.min.js"></script>
|
||||
<link href='//fonts.googleapis.com/css?family=Ubuntu' rel='stylesheet' type='text/css'>
|
||||
|
||||
<link href="css/style.css" rel="stylesheet">
|
||||
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
"use strict";
|
||||
var $bgobj = $(".ha-bg-parallax"); // assigning the object
|
||||
$(window).on("scroll", function () {
|
||||
var yPos = -($(window).scrollTop() / $bgobj.data('speed'));
|
||||
// Put together our final background position
|
||||
var coords = '100% ' + yPos + 'px';
|
||||
// Move the background
|
||||
$bgobj.css({ backgroundPosition: coords });
|
||||
});
|
||||
$('div.product-chooser').not('.disabled').find('div.product-chooser-item').on('click', function(){
|
||||
$(this).parent().parent().find('div.product-chooser-item').removeClass('selected');
|
||||
$(this).addClass('selected');
|
||||
$(this).find('input[type="radio"]').prop("checked", true);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div>
|
||||
<div class="ha-bg-parallax text-center block-marginb-none" data-type="background" data-speed="20">
|
||||
<div class="ha-parallax-body">
|
||||
<div class="ha-content ha-content-whitecolor">
|
||||
<h1 id="headernav">Preso Engines</h1>
|
||||
"Presentation Engines"
|
||||
</div>
|
||||
<div class="ha-parallax-divider-wrapper">
|
||||
<span class="ha-diamond-divider-md img-responsive"></span>
|
||||
</div>
|
||||
<div class="ha-heading-parallax">By | CodeLanka</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container" ng-controller="presentationController">
|
||||
<h2></h2>
|
||||
<div class="row form-group product-chooser">
|
||||
<div class="col-xs-12 col-sm-12 col-md-4 col-lg-4"
|
||||
ng-repeat="presentation in presentations">
|
||||
<div class="product-chooser-item">
|
||||
<div class="col-xs-8 col-sm-8 col-md-12 col-lg-12">
|
||||
<hr/>
|
||||
<span class="title">
|
||||
{{presentation.name}}
|
||||
</span>
|
||||
|
||||
<span class="website">
|
||||
<a href="{{presentation.website}}">{{presentation.website}}</a>
|
||||
</span>
|
||||
|
||||
<span class="description">
|
||||
{{presentation.description}}</span>
|
||||
<input type="radio" name="product" value="mobile_desktop"
|
||||
checked="checked">
|
||||
<hr/>
|
||||
<div class="col-xs-4 col-sm-4 col-md-4 col-lg-4 text-center">
|
||||
<i class="fa fa-star"></i>
|
||||
<h2>{{presentation.stargazers_count}}</h2>
|
||||
</div>
|
||||
<div class="col-xs-4 col-sm-4 col-md-4 col-lg-4 text-center">
|
||||
<i class="fa fa-users"></i>
|
||||
<h2>{{presentation.watchers_count}}</h2>
|
||||
</div>
|
||||
<div class="col-xs-4 col-sm-4 col-md-4 col-lg-4 text-center">
|
||||
<i class="fa fa-bug"></i>
|
||||
<h2>{{presentation.open_issues_count}}</h2>
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
<hr>
|
||||
<p>Github -
|
||||
<a href="http://github.com/{{presentation.github}}">{{presentation.github}}</a>
|
||||
</p>
|
||||
<p>Demo -
|
||||
<a href="{{presentation.demo}}">{{presentation.demo}}</a>
|
||||
</p>
|
||||
|
||||
<p>License - {{presentation.license}} </p>
|
||||
|
||||
<p>Language - {{presentation.language}} </p>
|
||||
<hr/>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- jQuery -->
|
||||
<!-- Bootstrap JavaScript -->
|
||||
<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
|
||||
|
||||
<script>
|
||||
var phonecatApp = angular.module('presen', []);
|
||||
phonecatApp.controller('presentationController', function ($scope,$http) {
|
||||
|
||||
var github = "https://api.github.com/repos/";
|
||||
|
||||
$http.get('data.json').
|
||||
success(function(data, status, headers, config) {
|
||||
$scope.presentations=data.engines;
|
||||
|
||||
for (var i = data.engines.length - 1; i >= 0; i--) {
|
||||
$scope.presentations[i].stargazers_count=0;
|
||||
$scope.presentations[i].watchers_count=0;
|
||||
$scope.presentations[i].open_issues_count=0;
|
||||
|
||||
(function(no){
|
||||
var githuburl = github+data.engines[no].github;
|
||||
|
||||
$http.get(githuburl)
|
||||
.success(function(data, status, headers, config) {
|
||||
$scope.presentations[no].stargazers_count=data.stargazers_count;
|
||||
$scope.presentations[no].watchers_count=data.watchers_count;
|
||||
$scope.presentations[no].open_issues_count=data.open_issues_count;
|
||||
|
||||
})
|
||||
.error(function(data, status, headers, config) {});
|
||||
}(i));
|
||||
|
||||
|
||||
|
||||
};
|
||||
}).
|
||||
error(function(data, status, headers, config) {});
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 469 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 648 B |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 691 B |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1006 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 837 B |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 971 B |
Before Width: | Height: | Size: 440 B |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 754 B |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 724 B After Width: | Height: | Size: 661 B |
After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 533 B |
After Width: | Height: | Size: 862 B |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 553 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 718 B |
After Width: | Height: | Size: 718 B |
After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 935 B |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.8 KiB |