- // ==UserScript==
- // @name [satology] Auto Claim Multiple Faucets with Monitor UI
- // @description Automatic rolls and claims for 50+ crypto faucets/PTC/miners (Freebitco.in BTC, auto promo code for 16 CryptosFaucet, FaucetPay, StormGain, etc)
- // @description Claim free ADA, BNB, BCH, BTC, DASH, DGB, DOGE, ETH, FEY, LINK, LTC, NEO, SHIB, STEAM, TRX, USDC, USDT, XEM, XRP, ZEC, ETC
- // @version 3.0.57
- // @author satology
- // @namespace satology.onrender.com
- // @homepage https://criptologico.com/tools/cc
- // @noframes
-
- // @grant GM_info
- // @grant GM_setValue
- // @grant GM_getValue
- // @grant GM_deleteValue
- // @grant GM_xmlhttpRequest
- // @grant window.close
- // @grant GM_openInTab
- // @grant window.onurlchange
- // @connect criptologico.com
-
-
- // @note IMPORTANT
- // @note - To start the script you need to navigate to https://criptologico.com/tools/cc
- // @note - Each schedule will open it's own tab to allow multiclaiming
-
- // @icon https://www.google.com/s2/favicons?domain=criptologico.com
- // @require https://cdnjs.cloudflare.com/ajax/libs/nearest-color/0.4.4/nearestColor.js
- // @match https://app.stormgain.com/crypto-miner/
- // @match https://app.freecardano.com/*
- // @match https://app.freebinancecoin.com/*
- // @match https://app.freebitcoin.io/*
- // @match https://app.freedash.io/*
- // @match https://app.free-doge.com/*
- // @match https://app.freeethereum.com/*
- // @match https://app.freecryptom.com/*
- // @match https://app.free-ltc.com/*
- // @match https://app.freeneo.io/*
- // @match https://app.freesteam.io/*
- // @match https://app.free-tron.com/*
- // @match https://app.freeusdcoin.com/*
- // @match https://app.freetether.com/*
- // @match https://app.freenem.com/*
- // @match https://app.freeshibainu.com/*
- // @match https://app.coinfaucet.io/*
- // @match https://app.freepancake.com/*
- // @match https://app.freematic.com/*
- // @match https://app.freebittorrent.com/*
- // @match https://app.freebfg.com/*
- // @match https://freebitco.in/*
- // @match https://faucetpay.io/*
- // @match https://bigbtc.win/*
- // @match https://www.bestchange.com/*
- // @match https://faucetok.net/*
- // @match https://betfury.io/boxes/all*
- // @match https://www.free-doge.io/
- // @match https://www.free-doge.io/free/
- // @match https://autofaucet.dutchycorp.space/login.php*
- // @match https://autofaucet.dutchycorp.space/roll.php*
- // @match https://autofaucet.dutchycorp.space/coin_roll.php*
- // @match https://express.dutchycorp.space/index.php*
- // @match https://express.dutchycorp.space/roll.php*
- // @match https://express.dutchycorp.space/coin_roll.php*
- // @match https://faucetcrypto.com/dashboard
- // @match https://faucetcrypto.com/task/faucet-claim
- // @match https://faucetcrypto.com/ptc/*
- // @match https://faucetcrypto.com/task/ptc-advertisement/*
- // @match https://faupig-bit.online/page/dashboard*
- // @match https://faupig-bit.online/account/login/not-logged-in
- // @match https://freegridco.in/*
- // @match https://james-trussy.com/*
- // @match https://www.only1024.com/f*
- // @match https://criptologico.com/tools/cc*
- // @match https://yescoiner.com/*
- // @match https://coindiversity.io/*
- // @match https://ltcfaucet.top/*
- // @match https://bnbfaucet.top/*
- // @match https://dogecoinfaucet.top/*
- // @match https://tronfaucet.top/*
- // @match https://ethfaucet.top/*
- // @match https://freebch.club/*
- // @match https://zecfaucet.net/*
- // @match https://faucet.monster/*
- // @match https://auto-crypto.ml/*
- // @match https://claimclicks.com/*
- // @match https://cryptoclicks.net/*
- // @match https://freeshiba.cf/*
- // @match https://auto-crypto.click/*
- // ==/UserScript==
-
- (function() {
- 'use strict';
- const localeConfig = {
- setToEnglish: true, // will set the faucets to English
- stringSearches: {
- promoCodeAccepted: 'roll',
- promoCodeUsed: 'already used',
- promoCodeInvalid: ['not found', 'only alphanumeric'],
- promoCodeExpired: ['ended']
- }
- };
-
- const STATUS = {
- INITIALIZING: 0,
- IDLE: 1,
- CLAIMING: 2
- };
-
- const K = Object.freeze({
- WebType: {
- UNDEFINED: 0,
- CRYPTOSFAUCETS: 1,
- STORMGAIN: 2,
- FREEBITCOIN: 3,
- FAUCETPAY: 4,
- FREELITECOIN: 5,
- FREEETHEREUMIO: 6,
- BAGIKERAN: 7,
- OKFAUCET: 8,
- BIGBTC: 9,
- BESTCHANGE: 10,
- KINGBIZ: 11,
- BFBOX: 13,
- FREEDOGEIO: 14,
- DUTCHYROLL: 15,
- FCRYPTO: 16,
- CPU: 17,
- CBG: 18,
- FPB: 19,
- G8: 20,
- FREEGRC: 21,
- HELI: 22,
- VIE: 23,
- O24: 24,
- YCOIN: 25,
- CDIVERSITY: 26,
- BSCADS: 27,
- CTOP: 28,
- AUTOCML: 29,
- CCLICKS: 30
- },
- CF: {
- UrlType: {
- HOME: 0,
- FREE: 1,
- CONTACTTWITTER: 2,
- PROMOTION: 3,
- STATS: 4,
- SETTINGS: 5,
- FREEROLLS: 6,
- LOGIN: 7,
- GAMES: 8,
- IGNORE: 99
- },
- PromoStatus: {
- NOCODE: 0,
- PENDING: 1,
- ACCEPTED: 2,
- USEDBEFORE: 3,
- INVALID: 4,
- UNKNOWNERROR: 5,
- EXPIRED: 6
- },
- },
- RandomInteractionLevel: {
- NONE: 0,
- LOW: 1,
- MEDIUM: 2,
- HIGH: 3
- },
- Integers: {
- HS_26_IN_MILLISECONDS: 93600000, //Using 26 hs instead of 24hs
- HS_2_IN_MILLISECONDS: 7200000 //and 2hs gap retry when code is flagged as USEDBEFORE
- },
- WalletType: {
- FP_USERNAME: 99,
- FP_MAIL: 100,
- FP_BTC: 101,
- FP_BNB: 102,
- FP_BCH: 103,
- FP_DASH: 104,
- FP_DGB: 105,
- FP_DOGE: 106,
- FP_ETH: 107,
- FP_FEY: 108,
- FP_LTC: 109,
- FP_TRX: 110,
- FP_USDT: 111,
- FP_ZEC: 112,
- FP_SOL: 113,
- FP_MATIC: 114,
- FP_XRP: 115,
- FP_ADA: 116,
- EC: 200,
- BTC: 1,
- LTC: 2
- },
- ErrorType: {
- ERROR: 0,
- TIMEOUT: 1,
- NEED_TO_LOGIN: 2,
- ROLL_ERROR: 3,
- CLICK_ROLL_ERROR: 4,
- LOGIN_ERROR: 5,
- CLAIM_ERROR: 6,
- ADDRESS_ERROR: 7,
- MIN_WITHDRAW_ERROR: 8,
- IP_BAN: 9,
- IP_RESTRICTED: 10,
- IP_ERROR: 11,
- FORCE_CLOSED: 12,
- NO_FUNDS: 13,
- VERIFY_EMAIL: 14,
- NO_ADDRESS: 15,
- FAUCET_EMPTY: 16
- },
- CMC: {
- MULT: '-1',
- BTC: '1',
- LTC: '2',
- XRP: '52',
- DOGE: '74',
- DGB: '109',
- DASH: '131',
- USDT: '825',
- XEM: '873',
- ETH: '1027',
- STEEM: '1230',
- NEO: '1376',
- ZEC: '1437',
- BCH: '1831',
- BNB: '1839',
- TRX: '1958',
- LINK: '1975',
- ADA: '2010',
- USDC: '3408',
- SOL: '5426',
- SHIB: '5994',
- FEY: '10361',
- BFG: '11038',
- CAKE: '7186',
- GRC: '833',
- MATIC: '3890',
- BABY: '10334',
- BTT: '16086',
- BSW: '10746',
- },
- LOCATION: {
- UNKNOWN: 0,
- MANAGER: 1,
- SITE: 2
- }
- });
-
- let persistence, shared, manager, ui, CFPromotions, interactions, CFHistory, SiteProcessor, eventer;
- let uiRenderer;
-
- Element.prototype.isVisible = function() {
- return !!(this.offsetWidth||this.offsetHeight||this.getClientRects().length);
- };
- Element.prototype.isUserFriendly = function(selector) {
- let e = selector ? this.querySelector(selector) : this;
- return e && e.isVisible() ? e : null;
- };
- Document.prototype.isUserFriendly = Element.prototype.isUserFriendly;
-
- Number.prototype.toDate = function() {
- return new Date(this);
- };
- Number.prototype.msToCountdown = function() {
- const remainingSeconds = Math.ceil(this / 1000);
- const hours = Math.floor(remainingSeconds / 3600).toString().padStart(2, '0');
- const minutes = Math.floor((remainingSeconds % 3600) / 60).toString().padStart(2, '0');
- const seconds = (remainingSeconds % 60).toString().padStart(2, '0');
- return `${hours}:${minutes}:${seconds}`;
- };
-
- String.prototype.clean = function() {
- let output = "";
- for (let i = 0; i < this.length; i++) {
- if (this.charCodeAt(i) <= 127) {
- output += this.charAt(i);
- }
- }
- return output;
- };
- String.prototype.formatUnicorn = function () {
- "use strict";
- var str = this.toString();
- if (arguments.length) {
- var t = typeof arguments[0];
- var key;
- var args = ("string" === t || "number" === t) ?
- Array.prototype.slice.call(arguments)
- : arguments[0];
-
- for (key in args) {
- str = str.replace(new RegExp("\\{" + key + "\\}", "gi"), args[key]);
- }
- }
-
- return str;
- };
-
- Array.prototype.shuffle = function () {
- let currentIndex = this.length, temporaryValue, randomIndex;
-
- while (0 !== currentIndex) {
- randomIndex = Math.floor(Math.random() * currentIndex);
- currentIndex -= 1;
- temporaryValue = this[currentIndex];
- this[currentIndex] = this[randomIndex];
- this[randomIndex] = temporaryValue;
- }
-
- return this;
- };
-
- let helpers = {
- typer: function(inputElm, value) {
- let lastValue = inputElm.value;
- inputElm.value = value;
- let event = new Event('input', { bubbles: true });
- event.simulated = true;
- let tracker = inputElm._valueTracker;
- if (tracker) {
- tracker.setValue(lastValue);
- }
- inputElm.dispatchEvent(event);
- },
-
- hasValue: function (val) {
- return val !== null && val !== undefined;
- },
- getTdPrintableTime: function (date = new Date()) {
- if (date != null) {
- return ('0' + date.getHours()).slice(-2) + ':' + ('0' + date.getMinutes()).slice(-2);
- }
- return '';
- },
- getPrintableTime: function (date = new Date()) {
- if (date == null) {
- return '';
- }
- return ('0' + date.getHours()).slice(-2) + ':' + ('0' + date.getMinutes()).slice(-2) + ':' + ('0' + date.getSeconds()).slice(-2);
- },
- getPrintableDateTime: function (date) {
- if (date != null) {
- return ('0' + date.getDate()).slice(-2) + '/' + ('0' + (date.getMonth() + 1)).slice(-2) + ' ' + ('0' + date.getHours()).slice(-2) + ':' + ('0' + date.getMinutes()).slice(-2);
- } else {
- return '';
- }
- },
- getEnumText: function (enm, value) {
- return Object.keys(enm).find(key => enm[key] === value) || '_ERR';
- },
- randomMs: function (a, b){
- return a + (b - a) * Math.random();
- },
- addMinutes: function(mins, date = new Date()) {
- return date.setMinutes(date.getMinutes() + +mins);
- },
- addSeconds: function(secs, date = new Date()) {
- return date.setSeconds(date.getSeconds() + +secs);
- },
- randomHexColor: function() {
- const hexChars = '0123456789abcdef';
- let color = '';
- for (let i = 0; i < 6; i++) {
- color += hexChars[Math.floor(Math.random() * hexChars.length)];
- }
- return color;
- },
- randomString: function(length) {
- let str = '';
- const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
- const charactersLength = characters.length;
-
- for (let i = 0; i < length; i++) {
- str += characters.charAt(Math.floor(Math.random() * charactersLength));
- }
-
- return str;
- },
- randomInt: function(min, max) {
- min = Math.ceil(min);
- max = Math.floor(max);
- return Math.floor(Math.random() * (max - min + 1)) + min;
- },
- addMs: function(ms, date = new Date()) {
- return date.setMilliseconds(date.getMilliseconds() + ms);
- },
- getRandomMs: function(minute, rangeDiffInPercentage) { // Now will be a random value between minute and minute + rangeDiffPercentage%; Example if minute = 30 and rangeDiffPercentage = 5 => random in the range [30, 31.5]
- let msMin = minute * 60 * 1000;
- let msMax = msMin + rangeDiffInPercentage/100 * msMin;
- return helpers.randomMs(msMin, msMax);
- },
- hsToMs: function(hours) {
- return hours * 60 * 60 * 1000;
- },
- minToMs: function(min) {
- return min * 60 * 1000;
- },
- getEmojiForPromoStatus: function(promoStatus) {
- switch (promoStatus) {
- case K.CF.PromoStatus.NOCODE:
- return '⚪';
- case K.CF.PromoStatus.PENDING:
- return '⏳';
- case K.CF.PromoStatus.ACCEPTED:
- return '✔️';
- case K.CF.PromoStatus.USEDBEFORE:
- return '🕙';
- case K.CF.PromoStatus.INVALID:
- return '❌';
- case K.CF.PromoStatus.EXPIRED:
- return '📅';
- case K.CF.PromoStatus.UNKNOWNERROR:
- return '❗';
- }
- },
- getHost: function(url, withHttps = false) {
- if (url.includes('//')) {
- url = url.split('//')[1];
- }
- url = url.split('/')[0];
- return withHttps ? ('https://' + url) : url;
- },
- cf: {
- getUrlType: function(url) {
- if (url.endsWith('/free-rolls')) {
- return K.CF.UrlType.FREEROLLS;
- }
- if (url.split('?')[0].endsWith('/free')) {
- return K.CF.UrlType.FREE;
- }
- if (url.includes('/promotion/')) {
- return K.CF.UrlType.PROMOTION;
- }
- if (url.endsWith('/contact-twitter')) {
- return K.CF.UrlType.CONTACTTWITTER;
- }
- if (url.endsWith('/settings')) {
- return K.CF.UrlType.SETTINGS;
- }
- if (url.endsWith('/stats')) {
- return K.CF.UrlType.STATS;
- }
- if (url.endsWith('/games')) {
- return K.CF.UrlType.GAMES;
- }
- if (url.endsWith('/')) {
- url = url.slice(0, -1);
- if (url == helpers.getHost(url, true)) {
- return K.CF.UrlType.HOME;
- }
- }
- if (url.endsWith('/login')) {
- return K.CF.UrlType.LOGIN;
- }
-
- return K.CF.UrlType.IGNORE;
- }
- },
- triggerMouseEvent: function (elm, eventType) {
- let clickEvent = document.createEvent('MouseEvents');
- clickEvent.initEvent (eventType, true, true);
- elm.dispatchEvent (clickEvent);
- },
- alternativeClick: function (elm) {
- helpers.triggerMouseEvent (elm, "mouseover");
- helpers.triggerMouseEvent (elm, "mousedown");
- helpers.triggerMouseEvent (elm, "mouseup");
- helpers.triggerMouseEvent (elm, "click");
- },
- textQuerySelector: function (selector, text) {
- let all = [...document.querySelectorAll(selector)].filter(x => x.innerText.toLowerCase() == text.toLowerCase())
- if (all.length == 1) {
- return all[0];
- }
- return undefined;
- }
- }
-
- class Persistence {
- constructor(prefix = 'autoWeb_') {
- this.prefix = prefix;
- }
- save(key, value, parseIt = false) {
- GM_setValue(this.prefix + key, parseIt ? JSON.stringify(value) : value);
- }
- load(key, parseIt = false) {
- let value = GM_getValue(this.prefix + key);
- if(value && parseIt) {
- value = JSON.parse(value);
- }
- return value;
-
- }
- }
-
- let objectGenerator = {
- createShared: function() {
- let config = {};
- function initializeConfig() {
- config = {
- 'devlog.enabled': false,
- 'devlog.maxLines': 200,
- 'defaults.extraInterval': true,
- 'defaults.timeout': 4,
- 'defaults.postponeMinutes': 65,
- 'defaults.postponeMinutes.min': 65,
- 'defaults.postponeMinutes.max': 65,
- 'defaults.workInBackground': true,
- 'defaults.nextRun.useCountdown': true,
- 'defaults.nextRun': 60,
- 'defaults.nextRun.min': 60,
- 'defaults.nextRun.max': 60,
- 'defaults.sleepMode': false,
- 'defaults.sleepMode.min': "00:00",
- 'defaults.sleepMode.max': "01:00",
- 'cf.tryGetCodes': false,
- 'cf.usePromoCodes': true,
- 'cf.rollOnce': false,
- 'cf.autologin': false,
- 'cf.credentials.mode': 1,
- 'cf.credentials.email': 'YOUR@EMAIL.com',
- 'cf.credentials.password': 'YOURPASSWORD',
- 'cf.sleepHoursIfIpBan': 8,
- 'fp.maxTimeInMinutes': 15,
- 'fp.randomPtcOrder': true,
- 'dutchy.useBoosted': false,
- 'bk.withdrawMode': "0",
- 'bk.hoursBetweenWithdraws': 4,
- 'bk.sleepMinutesIfIpBan': 75,
- 'bestchange.address': '101',
- 'ui.runtime': 0,
- 'bigbtc.postponeMinutes': '0',
- 'jtfey.credentials.mode': 2,
- 'jtfey.credentials.username': 'YOUR_USERNAME',
- 'jtfey.credentials.password': 'YOURPASSWORD',
- 'ycoin.credentials.mode': 2,
- 'ycoin.credentials.username': 'YOUR_ACCOUNT_NUMBER',
- 'ycoin.credentials.password': 'YOURPASSWORD',
- 'bkclass.coin': 'LTC',
- 'bkclass.bcoin': 'LTC',
- 'migrations': [
- {version: '00200799', applied: false} // migration to change pcodes status from error to usable due to ui changes
- ]
- };
-
- let storedData = persistence.load('config', true);
- if(storedData) {
- for (const prop in config) {
- if(storedData.hasOwnProperty(prop)) {
- config[prop] = storedData[prop];
- }
- }
- }
-
- config.version = GM_info.script.version;
- };
- function getConfig() {
- return config;
- };
- function updateConfig(items) {
- items.forEach( function (item) {
- config[item.prop] = item.value;
- });
- persistence.save('config', config, true);
- };
- function migrationApplied(migrationVersion) {
- try {
- let mig = config.migrations.find(x => x.version == migrationVersion);
- mig.applied = true;
- persistence.save('config', config, true);
- } catch (err) {
- console.warn('Error saving migration as applied');
- console.error(err);
- }
- };
- function devlog(msg, elapsed = false, reset = false) {
- if(!config['devlog.enabled']) {
- return;
- }
-
- let log;
- if(reset) {
- log = [`${helpers.getPrintableTime()}|Log cleared`];
- } else {
- log = persistence.load('devlog', true);
- log = log ?? [];
- }
-
- if(msg) {
- msg = scheduleUuid ? `[${scheduleUuid}] ${msg}` : msg;
- let previous;
- try {
- previous = log[log.length - 1].split('|')[1];
- } catch {}
- if(elapsed && (previous == msg)) {
- log[log.length - 1] = `${helpers.getPrintableTime()}|${msg}|[Elapsed time: ${elapsed} seconds]`;
- } else {
- log.push(`${helpers.getPrintableTime()}|${msg}`);
- }
- }
-
- if(log.length > 200) {
- log.splice(0, log.length - 200);
- }
-
- persistence.save('devlog', log, true);
- };
- function getDevLog() {
- let log;
- log = persistence.load('devlog', true);
- if(log) {
- return log;
- }
- };
-
- function getRunningSites() {
- let ret = [];
- loadFlowControl();
- if(!runningSites || runningSites == {}) {
- return ret;
- }
- for (const sch in runningSites) {
- if (runningSites[sch].host) {
- ret.push(runningSites[sch].host);
- }
- }
- return ret;
- }
-
- let runningSites = {}
- let scheduleUuid = null;
- function isOpenedByManager() {
- loadFlowControl();
- if(!runningSites || runningSites == {}) {
- return false;
- }
- let uuid = null;
- for (const sch in runningSites) {
- if ( (runningSites[sch].host && runningSites[sch].host == window.location.host) ||
- (runningSites[sch].params && runningSites[sch].params.trackUrl && window.location.href.includes(runningSites[sch].params.trackUrl))
- ) {
- uuid = sch;
- break;
- }
- }
- if (!uuid) {
- return false;
- }
-
- if (runningSites[uuid].runStatus == 'COMPLETED') {
- return false;
- } else {
- scheduleUuid = uuid;
- return true;
- }
- };
- function loadFlowControl() {
- runningSites = persistence.load('runningSites', true) || {};
- };
- function setFlowControl(schedule, id, url, webType, params = null) {
- runningSites[schedule] = {
- id: id,
- changedAt: Date.now(),
- url: url,
- host: url.host,
- type: webType,
- opened: false,
- error: false,
- result: {}
- };
-
- if(params) {
- runningSites[schedule].params = params;
- } else {
- runningSites[schedule].params = {};
- }
- saveFlowControl(schedule);
- };
- function isCompleted(expectedId) {
- loadFlowControl();
- for(const sch in runningSites) {
- if (runningSites[sch].id == expectedId) {
- if (runningSites[sch].runStatus == 'COMPLETED') {
- return true;
- } else {
- return false;
- }
- }
- }
- return false;
- };
- function isIncompleted(expectedId) {
- loadFlowControl();
- for(const sch in runningSites) {
- if (runningSites[sch].id == expectedId) {
- if (runningSites[sch].runStatus == 'WORKING') {
- return true;
- } else {
- return false;
- }
- }
- }
- return false;
- };
- function hasErrors(expectedId) {
- for(const sch in runningSites) {
- if (runningSites[sch].id == expectedId && runningSites[sch].error) {
- return true;
- }
- }
- return false;
- };
- function getResult(schedule) {
- if (schedule) {
- return runningSites.hasOwnProperty(schedule) ? runningSites[schedule].result : {};
- }
- return runningSites.hasOwnProperty(scheduleUuid) ? runningSites[scheduleUuid].result : {};
- };
- function getCurrent(schedule) {
- if (schedule) {
- return runningSites.hasOwnProperty(schedule) ? runningSites[schedule] : {};
- }
- return runningSites.hasOwnProperty(scheduleUuid) ? runningSites[scheduleUuid] : {};
- };
- function saveAndclose(runDetails, delay = 0) {
- markAsVisited(runDetails);
- if(delay) {
- setTimeout(window.close, delay);
- } else {
- setTimeout(window.close, 1000);
- }
- };
- function purgeFlowControlSchedules(validSchedules) {
- loadFlowControl();
- let deletables = [];
- for (var sch in runningSites) {
- if (!validSchedules.includes(sch)) {
- deletables.push(sch);
- }
- }
- deletables.forEach(x => {
- delete runningSites[sch];
- });
- persistence.save('runningSites', runningSites, true);
- };
- function saveFlowControl(schedule) {
- schedule = schedule ? schedule : scheduleUuid;
- if (!schedule) {
- persistence.save('runningSites', runningSites, true);
- return;
- }
- let tempFlow = persistence.load('runningSites', true);
- tempFlow[schedule] = runningSites[schedule];
- persistence.save('runningSites', tempFlow, true);
- };
- function markAsVisited(runDetails, runStatus = 'COMPLETED') {
- if (!scheduleUuid) {
- return;
- }
- runningSites[scheduleUuid].opened = true;
- runningSites[scheduleUuid].runStatus = runStatus;
- runningSites[scheduleUuid].result = runDetails ? runDetails : runningSites[scheduleUuid].result;
-
- saveFlowControl(scheduleUuid);
- };
- function addError(errorType, errorMessage, schedule) {
- if (schedule) {
- runningSites[schedule].error = true;
- runningSites[schedule].result.errorType = errorType;
- runningSites[schedule].result.errorMessage = errorMessage;
- } else {
- runningSites[scheduleUuid].error = true;
- runningSites[scheduleUuid].result.errorType = errorType;
- runningSites[scheduleUuid].result.errorMessage = errorMessage;
- }
-
- saveFlowControl(schedule ? schedule : scheduleUuid);
- };
- function closeWithError(errorType, errorMessage) {
- addError(errorType, errorMessage);
- window.close();
- setInterval(() => {
- window.close();
- }, 15000);
- };
- function clearFlowControl(schedule) {
- if (schedule && schedule != 'all') {
- runningSites[schedule] = {};
- saveFlowControl(schedule);
- } else if (schedule == 'all') {
- runningSites = {};
- persistence.save('runningSites', {}, true);
- }
- };
- function clearRetries() {
- loadFlowControl();
- runningSites[scheduleUuid].retrying = false;
- saveFlowControl(scheduleUuid);
- return false;
- };
- function isRetrying() {
- if(runningSites[scheduleUuid].retrying) {
- return true;
- }
- runningSites[scheduleUuid].retrying = true;
- saveFlowControl(scheduleUuid);
- return false;
- };
- function setProp(key, val) {
- runningSites[scheduleUuid][key] = val;
- saveFlowControl(scheduleUuid);
- };
- function getProp(key) {
- return runningSites[scheduleUuid][key];
- };
- function getParam(key) {
- try {
- } catch {}
- return runningSites[scheduleUuid].params[key];
- };
- initializeConfig();
- return {
- devlog: devlog,
- getDevLog: getDevLog,
- setFlowControl: setFlowControl,
- isCompleted: isCompleted,
- isIncompleted: isIncompleted,
- isOpenedByManager: isOpenedByManager,
- saveFlowControl: saveFlowControl,
- getCurrent: getCurrent,
- getResult: getResult,
- addError: addError,
- closeWindow: saveAndclose,
- closeWithError: closeWithError,
- updateWithoutClosing: markAsVisited,
- hasErrors: hasErrors,
- clearFlowControl: clearFlowControl,
- getConfig: getConfig,
- updateConfig: updateConfig,
- clearRetries: clearRetries,
- isRetrying: isRetrying,
- setProp: setProp,
- getProp: getProp,
- getParam: getParam,
- migrationApplied: migrationApplied,
- purgeFlowControlSchedules: purgeFlowControlSchedules,
- getRunningSites: getRunningSites
- };
- },
- createCFPromotions: function() {
- let codes = [];
-
- function PromotionCode(id, code, repeatDaily = false, expiration = null, isRemoved = false) {
- this.id = id;
- this.code = code;
- this.added = new Date();
- this.statusPerFaucet = [];
- this.repeatDaily = repeatDaily;
- this.lastExecTimeStamp = null;
- this['expiration' + 'Date'] = expiration;
- this.isRemoved = isRemoved;
- };
-
- function getFaucetStatusInPromo(promo, faucetId) {
- let faucet = promo.statusPerFaucet.find(x => x.id == faucetId);
- if (faucet.status && promo.repeatDaily) {
- if((faucet.status == K.CF.PromoStatus.ACCEPTED && (Date.now() - faucet.execTimeStamp.getTime()) > K.Integers.HS_26_IN_MILLISECONDS)
- || (faucet.status == K.CF.PromoStatus.USEDBEFORE && (Date.now() - faucet.execTimeStamp.getTime()) > K.Integers.HS_2_IN_MILLISECONDS)) {
- faucet.status = K.CF.PromoStatus.PENDING;
- }
- }
- return faucet.status ?? K.CF.PromoStatus.NOCODE;
- };
-
- function addNew(code, repeatDaily = false, expiration = null) {
- let found = codes.find(x => x.code == code);
- if (found) {
- found.repeatDaily = repeatDaily;
- found['expiration' + 'Date'] = expiration;
- found.isRemoved = false;
- } else {
- found = new PromotionCode(codes.length, code, repeatDaily, expiration);
- codes.push(found);
- }
-
- found.statusPerFaucet = manager.getFaucetsForPromotion().map(x => {
- return {
- id: x.id,
- };});
- found.statusPerFaucet.forEach(function (element, idx, arr) {
- arr[idx].status = K.CF.PromoStatus.PENDING;
- arr[idx].execTimeStamp = null;
- });
-
- save();
- };
-
- function includeNewCodes(newCodes) {
- for(let i=0; i<newCodes.length; i++) {
- let item = newCodes[i];
- let exists = codes.find(x => x.code.toLowerCase() == item.code.toLowerCase());
- if (!exists) {
- addNew(item.code, !item.oneTimeOnly, item['expiration' + 'Date']);
- } else {
- }
- }
- };
-
- function getAll() {
- return codes.filter(x => !x.isRemoved);
- };
-
- function updateFaucetForCode(code, faucetId, newStatus) {
- let promo = codes.find(x => x.code == code);
- let faucet = promo.statusPerFaucet.find(x => x.id == faucetId);
- if(faucet) {
- faucet.status = newStatus;
- faucet.execTimeStamp = new Date();
- promo.lastExecTimeStamp = faucet.execTimeStamp;
- }
- save();
- };
-
- function hasPromoAvailable(faucetId) {
- let resp = [];
- codes.forEach(function (promotion, idx, arr) {
- let status = getFaucetStatusInPromo(promotion, faucetId);
- if (status == K.CF.PromoStatus.PENDING && !promotion.isRemoved) {
- resp.push(promotion.code);
- }
- });
- if (resp.length > 0) {
- return resp;
- } else {
- return false;
- }
- };
-
- function save() {
- persistence.save('CFPromotions', codes, true);
- };
-
- function load(data) {
- codes = data;
- save();
- };
-
- function removeAll() {
- codes.forEach(x => x.isRemoved = true);
- codes = codes.filter(x => x['expiration' + 'Date'] && Date.parse(x['expiration' + 'Date']) > Date.now());
- save();
- };
-
- function remove(id, code) {
- let idx = codes.findIndex(x => x.id == id && x.code == code);
- if(idx != -1) {
- codes[idx].isRemoved = true;
- save();
- }
-
- return idx;
- };
-
- return {
- addNew: addNew,
- removeAll: removeAll,
- remove: remove,
- getAll: getAll,
- load: load,
- updateFaucetForCode: updateFaucetForCode,
- hasPromoAvailable: hasPromoAvailable,
- includeNewCodes: includeNewCodes
- }
- },
- createInteractions: function(){
- let randomInteractionLevel = K.RandomInteractionLevel.MEDIUM;
- let maxActions = 0;
- let performedActions = -1;
- let selectableElements;
- let actions = {
- available: [
- function() {
- let element = interactions.selectableElements[helpers.randomInt(0, interactions.selectableElements.length - 1)];
-
- try {
- if (document.body.createTextRange) {
- const range = document.body.createTextRange();
- range.moveToElementText(element);
- range.select();
- } else if (window.getSelection) {
- const selection = window.getSelection();
- const range = document.createRange();
- range.selectNodeContents(element);
- selection.removeAllRanges();
- selection.addRange(range);
- }
- } catch (err) { }
-
- interactions.addPerformed();
- }
- ]
- };
-
- function start(selectableElements) {
- performedActions = 0;
- switch(randomInteractionLevel) {
- case K.RandomInteractionLevel.NONE:
- maxActions = 0;
- break;
- case K.RandomInteractionLevel.LOW:
- maxActions = helpers.randomInt(2, 4);
- break;
- case K.RandomInteractionLevel.MEDIUM:
- maxActions = helpers.randomInt(5, 8);
- break;
- case K.RandomInteractionLevel.HIGH:
- maxActions = helpers.randomInt(12, 16);
- break;
- }
- interactions.selectableElements = selectableElements;
- performActions();
- }
-
- function performActions() {
- if(performedActions >= maxActions) {
- return;
- }
- let delay = 0;
- for(let i = 0; i < maxActions; i++) {
- delay += helpers.randomMs(350, 1500);
- setTimeout(actions.available[helpers.randomInt(0, actions.available.length - 1)], delay);
- }
- }
-
- function addPerformed() {
- performedActions++;
- }
- function completed() {
- return (performedActions >= maxActions);
- }
-
- return {
- start: start,
- completed: completed,
- addPerformed: addPerformed,
- selectableElements: selectableElements
- };
- },
- createCFProcessor: function() {
- const NavigationProcess = {
- ROLLING: 1,
- PROCESSING_PROMOTION: 2,
- LOGIN: 3
- };
- let navigationProcess;
- let countdown;
- let rollButton;
- let promotionTag;
- let timeWaiting= 0;
- let loopingForErrors = false;
- let tempRollNumber = null;
- let firstRollCompleted = false;
-
- function init() {
- let urlType = helpers.cf.getUrlType(window.location.href);
- console.log('URL TYPE:', urlType)
- switch(urlType) {
- case K.CF.UrlType.FREE:
- if(localeConfig.setToEnglish) {
- document.querySelector('.locale-changer .p-dropdown-trigger')?.click();
- setTimeout(() => {
- document.querySelector("#pv_id_3_3")?.click();
- }, 1000);
- }
- addJS_Node (null, null, overrideSelectNativeJS_Functions);
- interactions = objectGenerator.createInteractions();
- run();
- break;
-
- case K.CF.UrlType.PROMOTION:
- interactions = objectGenerator.createInteractions();
- runPromotion();
- break;
- case K.CF.UrlType.GAMES:
- location.replace('/free');
- break;
- case K.CF.UrlType.HOME:
- case K.CF.UrlType.LOGIN:
- if (shared.getConfig()['cf.autologin']) {
- addJS_Node (null, null, overrideSelectNativeJS_Functions);
- doLogin();
- } else {
- shared.closeWithError(K.ErrorType.NEED_TO_LOGIN, '');
- }
- break;
-
- case K.CF.UrlType.CONTACTTWITTER:
- shared.closeWithError(K.ErrorType.IP_BAN, '');
- break;
- default:
- break;
- }
- return;
- }
-
- function run() {
- navigationProcess = NavigationProcess.ROLLING;
- setInterval(tryClosePopup, helpers.randomMs(3000, 6000));
- setTimeout(findCountdownOrRollButton, helpers.randomMs(2000, 5000));
- };
-
- function doLogin() {
- navigationProcess = NavigationProcess.LOGIN;
-
- setTimeout(findLoginForm, helpers.randomMs(2000, 5000));
- };
-
- function isFullyLoaded() { //Waits 55 seconds max
- if(document.readyState == 'complete' || timeWaiting == -1) {
- timeWaiting = 0;
- if (firstRollCompleted) {
- roll();
- } else {
- interact();
- }
- } else {
- timeWaiting = -1;
- setTimeout(isFullyLoaded, helpers.randomMs(15000, 25000));
- }
- };
- function runPromotion() {
- navigationProcess = NavigationProcess.PROCESSING_PROMOTION
- setTimeout(findPromotionTag, helpers.randomMs(1000, 3000));
- };
- function tryClosePopup() {
- let popupBtn = document.querySelector('.p-dialog .p-dialog-header-close');
- if (popupBtn && popupBtn.isVisible()) {
- popupBtn.click();
- }
- };
- function isRollResultVisible() {
- let rollDiv = document.querySelector('.result');
- if (rollDiv && rollDiv.isVisible() && rollDiv.innerText != '') {
- }
- };
- let waitRollNumberCount = 0;
- function closeToast() {
- document.querySelector('.p-toast-icon-close')?.click();
- }
- async function waitForRollNumber() {
- let newNumber = -1;
- try { // intento leer el rolled number
- newNumber = [...document.querySelectorAll('.lucky-number-wrapper img')].map(x => x.src.split('/').slice(-1)[0].split('.').slice(-3)[0]).join('');
- newNumber = parseInt(newNumber)
- } catch(err) {
- newNumber = null;
- }
- if (newNumber === null) { // si no logro leerlo, bajo 1 en tempRollNumber
- if (tempRollNumber < 0) {
- tempRollNumber -= 1;
- } else {
- tempRollNumber = -1;
- }
- if (tempRollNumber < -5) {
- processRunDetails();
- return;
- } else {
- await wait(3000);
- return waitForRollNumber();
- }
- }
-
- if (newNumber == tempRollNumber) {
- timeWaiting = 0;
- if (shared.getConfig()['cf.rollOnce']) {
- processRunDetails();
- return;
- } else {
- firstRollCompleted = true;
- closeToast();
- setTimeout(findCountdownOrRollButton, helpers.randomMs(1000, 2000));
- return;
- }
- } else {
- waitRollNumberCount++;
- if (waitRollNumberCount > 15) {
- setTimeout(() => { location.reload(); }, 5000);
- return;
- }
-
- tempRollNumber = newNumber;
- await wait(3000);
- return waitForRollNumber();
- }
-
- };
- function isLoggedIn() {
- return !!document.querySelector('[data-icon="user"]');
- }
-
- function findCountdownOrRollButton() {
- if (!isLoggedIn()) {
- location.reload();
- }
- if( isCountdownVisible() && !isRollButtonVisible() ) {
- timeWaiting = 0;
- processRunDetails();
- } else if ( !isCountdownVisible() && isRollButtonVisible() ) {
- timeWaiting = 0;
- setTimeout(isFullyLoaded, helpers.randomMs(1000, 5000));
- } else if ( isCountdownVisible() && isRollButtonVisible() ) {
- try {
- let minLeft = document.querySelector('.minutes .digits').innerText;
- if (minLeft < 1) {
- timeWaiting = 0;
- setTimeout(isFullyLoaded, helpers.randomMs(1000, 5000));
- }
- } catch (err) { console.log(`Error on alt logic of CF roll: ${err}`); }
- } else {
- if (timeWaiting/1000 > shared.getConfig()['defaults.timeout'] * 60) {
- shared.closeWithError(K.ErrorType.TIMEOUT, '');
- return;
- }
-
- timeWaiting += 3000;
- setTimeout(findCountdownOrRollButton, helpers.randomMs(2000, 5000));
- }
- };
- function addUrlChangeListener() {
- if (window.onurlchange === null) {
- window.addEventListener('urlchange', (data) => {
- if (navigationProcess == NavigationProcess.LOGIN && !window.location.href.includes('/login')) {
- loopingForErrors = false;
- init();
- }
- });
- }
- };
- function findLoginForm() {
- if ( document.querySelector('#email')?.isVisible() && document.querySelector('#password')?.isVisible() ) {
- addUrlChangeListener();
- let errElement = document.querySelector('.login-wrapper .error');
- if( errElement && errElement.innerHTML != '') {
- let errorMessage = errElement.innerText;
- shared.closeWithError(K.ErrorType.LOGIN_ERROR, errorMessage);
- return;
- }
- if(!loopingForErrors) {
- if(shared.getConfig()['cf.credentials.mode'] == 1) {
- timeWaiting = 0;
- helpers.typer(document.querySelector('.login-wrapper input[name="email"],#email'), shared.getConfig()['cf.credentials.email']);
- helpers.typer(document.querySelector('.login-wrapper input[name="password"],#password'), shared.getConfig()['cf.credentials.password']);
- document.querySelector('#password')?.closest('div')?.querySelector('button')?.click();
- loopingForErrors = true;
- } else {
- if(document.querySelector('.login-wrapper input[name="email"],#email').value != '' && document.querySelector('.login-wrapper input[name="password"],#password').value != '') {
- document.querySelector('#password')?.closest('div')?.querySelector('button')?.click();
- loopingForErrors = true;
- } else {
- if (timeWaiting/1000 > (shared.getConfig()['defaults.timeout'] / 1.5) * 60) {
- shared.closeWithError(K.ErrorType.LOGIN_ERROR, 'No credentials were provided');
- return;
- }
- }
- }
- }
- }
-
- if (timeWaiting/1000 > shared.getConfig()['defaults.timeout'] * 60) {
- shared.closeWithError(K.ErrorType.TIMEOUT, '');
- return;
- }
-
- timeWaiting += 3000;
- setTimeout(findLoginForm, helpers.randomMs(2000, 5000));
- };
- function interact() {
- let selectables = [].concat([...document.querySelectorAll('td')], [...document.querySelectorAll('p')], [...document.querySelectorAll('th')]);
-
- interactions.start(selectables);
- setTimeout(waitInteractions, helpers.randomMs(2000, 4000));
- }
- function waitInteractions() {
- if(interactions.completed()) {
- roll();
- } else {
- setTimeout(waitInteractions, helpers.randomMs(2000, 4000));
- }
- }
- function isCountdownVisible() {
- countdown = document.querySelectorAll('.minutes .digits');
- return (countdown.length > 0 && countdown[0].isVisible());
- };
- function isRollButtonVisible() {
- let rollButtonIcon = document.querySelector('.p-button [data-icon="gift"]');
- if (!rollButtonIcon) {
- return false;
- }
- rollButton = rollButtonIcon.closest('button');
- return rollButton && !rollButton.disabled && rollButton.isVisible();
- };
- function roll() {
- rollButton.scrollIntoView({ behavior: "smooth", block: "nearest", inline: "nearest" });
- rollButton.click();
- tempRollNumber = -1;
- setTimeout(waitForRollNumber, helpers.randomMs(4000, 7000));
- }
- function isPromotionTagVisible() {
- let pTag;
- try {
- pTag = document.querySelectorAll('.p-message-text.p-message-text')[0];
- } catch(err) {
- return false;
- }
- if (pTag) {
- promotionTag = pTag;
- return true;
- }
- return false;
- };
- function findPromotionTag() {
- if( isPromotionTagVisible() ) {
- processRunDetails();
- } else {
- setTimeout(findPromotionTag, helpers.randomMs(2000, 5000));
- }
- };
- function processRunDetails() {
- let result = {};
- if(navigationProcess == NavigationProcess.ROLLING) {
- result.claimed = readClaimed();
- result.balance = readBalance();
- if(result.claimed != 0) {
- result.rolledNumber = readRolledNumber();
- }
- let minOneHour = result.rolledNumber && result.rolledNumber != 0;
- result.nextRoll = readCountdown(minOneHour);
- result.balance = readBalance();
- } else if (navigationProcess == NavigationProcess.PROCESSING_PROMOTION) {
- result = shared.getResult() || {};
- if (!result.promoCodeResults) {
- result.promoCodeResults = [];
- }
- let pc = {
- promoCode: readPromoCode(),
- promoStatus: readPromoStatus()
- };
-
- result.promoCodeResults.push(pc);
- shared.updateWithoutClosing(result, 'WORKING');
- setTimeout(gotoNextPromoCode, helpers.randomMs(1000, 2500));
- return;
- }
- shared.closeWindow(result);
- };
- function gotoNextPromoCode() {
- let codes = shared.getCurrent().params.promoCodes;
- if (!codes) {
- shared.closeWindow();
- return;
- }
- let pc = readPromoCode();
- let pcIdx = codes.findIndex(x => x == pc);
- if (pcIdx == -1 || pcIdx == codes.length - 1) {
- shared.closeWindow();
- return;
- }
- window.location.href = '/promotion/' + codes[pcIdx + 1];
- };
- function readCountdown(minOneHour = false) {
- let minsElement = document.querySelector('.minutes .digits');
- let mins = "0";
- if (minsElement) {
- mins = minsElement.innerHTML;
- }
- if (mins) {
- let estimated = helpers.addMinutes(+mins + 1);
- let oneHour = Date.now() + (60*60*1000);
- if (minOneHour && (oneHour > estimated) ) {
- return oneHour;
- }
- return estimated;
- } else {
- return null;
- }
- };
- function readClaimed() {
- let claimed = 0;
- try {
- claimed = document.querySelector('.p-toast-message-text .p-toast-detail').innerHTML;
- claimed = claimed.trim();
- claimed = claimed.split(' ').slice(-2)[0]
- } catch(err) { }
- return claimed;
- };
- function readRolledNumber() {
- let number = 0;
- try {
- number = [...document.querySelectorAll('.lucky-number-wrapper img')].map(x => x.src.split('/').slice(-1)[0].split('.').slice(-3)[0]).join('');
- number = parseInt(number);
- } catch(err) { }
- return number;
- };
- function readBalance() {
- let balance = "";
- try {
- balance = document.querySelectorAll('header div div div > span span')[1].innerText.trim().split(' ')[0];
- } catch(err) { }
- return balance;
- };
- function readPromoStatus() {
- let promoStatus = K.CF.PromoStatus.UNKNOWNERROR;
- try {
- if(promotionTag.innerHTML.indexOf(localeConfig.stringSearches.promoCodeAccepted) > 0) {
- return K.CF.PromoStatus.ACCEPTED;
- } else if(promotionTag.innerHTML.indexOf(localeConfig.stringSearches.promoCodeUsed) > 0) {
- return K.CF.PromoStatus.USEDBEFORE;
- } else if(promotionTag.innerHTML.indexOf(localeConfig.stringSearches.promoCodeExpired) > 0) {
- return K.CF.PromoStatus.EXPIRED;
- } else if(localeConfig.stringSearches.promoCodeInvalid.findIndex(x => promotionTag.innerHTML.indexOf(x) > -1) == -1) {
- return K.CF.PromoStatus.INVALID;
- }
- } catch ( err ) { }
- return promoStatus;
- };
- function validatePromoString() {
-
- };
- function readPromoCode() {
- var urlSplit = window.location.href.split('/');
- return urlSplit[urlSplit.length - 1];
- };
- function displayStatusUi() {
- let wrapper = document.createElement('div');
- wrapper.innerHTML = '<div class="withdraw-button bg-2" style="top:30%; z-index:1500;" href="#">⚙️ <span id="process-status">Processing</span></div>';
- document.querySelector( 'body' ).prepend( wrapper.firstChild );
- };
- return {
- init: init
- };
- },
- createCFHistory: function() {
- let rollsMeta = [
- { id: 0, range: '0000-9885', count: 0 },
- { id: 1, range: '9886-9985', count: 0 },
- { id: 2, range: '9986-9993', count: 0 },
- { id: 3, range: '9994-9997', count: 0 },
- { id: 4, range: '9998-9999', count: 0 },
- { id: 5, range: '10000', count: 0 }
- ];
-
- function initOrLoad() {
- let storedData = persistence.load('CFHistory', true);
- if(storedData) {
- rollsMeta = storedData;
- }
- };
-
- function addRoll(number) {
- switch(true) {
- case (number <= 9885):
- rollsMeta[0].count++;
- break;
- case (number <= 9985):
- rollsMeta[1].count++;
- break;
- case (number <= 9993):
- rollsMeta[2].count++;
- break;
- case (number <= 9997):
- rollsMeta[3].count++;
- break;
- case (number <= 9999):
- rollsMeta[4].count++;
- break;
- case (number == 10000):
- rollsMeta[5].count++;
- break;
- default:
- break;
- }
- save();
- };
-
- function getRollsMeta() {
- return rollsMeta.map(x => x.count);
- };
-
- function save() {
- persistence.save('CFHistory', rollsMeta, true);
- };
-
- return {
- initOrLoad: initOrLoad,
- addRoll: addRoll,
- getRollsMeta: getRollsMeta
- }
- },
- };
-
- function overrideSelectNativeJS_Functions () {
- window.alert = function alert (message) {
- }
- }
- function addJS_Node (text, s_URL, funcToRun) {
- var scriptNode= document.createElement ('script');
- scriptNode.type= "text/javascript";
- if (text)scriptNode.textContent= text;
- if (s_URL)scriptNode.src= s_URL;
- if (funcToRun)scriptNode.textContent = '(' + funcToRun.toString() + ')()';
- var element = document.getElementsByTagName ('head')[0] || document.body || document.documentElement;
- element.appendChild (scriptNode);
- }
- function addHtml(data) { // data = { target: '', where: '', content: '' }
- document.querySelector(data.target).insertAdjacentHTML(data.where, data.content);
- }
- function addTemplateTag(data) {
- let templateTag = document.createElement('template');
- templateTag.id = data.id;
- templateTag.innerHTML = data.content;
- let container = document.body || document.documentElement;
- container.appendChild(templateTag);
- }
- function useTemplate(data) { // data = { templateId: '', target: '', where: '', replacements: {} }
- let template = document.querySelector(`#${data.templateId}`).innerHTML;
- let content = template.formatUnicorn(data.replacements);
- addHtml({
- target: data.target,
- where: data.where,
- content: content
- });
- }
-
- function isExpectedPtc() {
- let runningList = shared.getRunningSites();
- let ptcHosts = ['faucetpay.io'];
-
- for (let i = 0; i < ptcHosts.length; i++) {
- if (document.referrer.includes(`//${ptcHosts[i]}`) && runningList.includes(ptcHosts[i])) {
- waitForCloseSignal(ptcHosts[i]);
- return true;
- }
- }
- return false;
- }
-
- async function waitForCloseSignal(host) {
- await wait(3000);
- const signal = GM_getValue(`ptc-close-signal-${host}`) || null;
- if (signal) {
- window.close();
- }
- return waitForCloseSignal(host);
- }
-
- function detectWeb() {
- if (isExpectedPtc()) {
- return;
- }
- if(!shared.isOpenedByManager()) {
- return;
- }
- instance = K.LOCATION.SITE;
-
- let typeFromManager = shared.getCurrent().type;
-
- siteTimer = new Timer({ isManager: false, delaySeconds: 20, uuid: shared.getProp('schedule'), webType: typeFromManager });
- switch( typeFromManager ) {
- case K.WebType.STORMGAIN:
- SiteProcessor = createSGProcessor();
- setTimeout(SiteProcessor.run, helpers.randomMs(10000, 20000));
- break;
- case K.WebType.CRYPTOSFAUCETS:
- SiteProcessor = objectGenerator.createCFProcessor();
- setTimeout(SiteProcessor.init, helpers.randomMs(1000, 3000));
- break;
- case K.WebType.FREEBITCOIN:
- SiteProcessor = createFBProcessor();
- setTimeout(SiteProcessor.run, helpers.randomMs(2000, 5000));
- break;
- case K.WebType.FAUCETPAY:
- SiteProcessor = new FPPtc();
- setTimeout(() => { SiteProcessor.init() }, helpers.randomMs(2000, 5000));
- break;
- case K.WebType.BIGBTC:
- SiteProcessor = createBigBtcProcessor();
- setTimeout(SiteProcessor.init, helpers.randomMs(2000, 4000));
- break;
- case K.WebType.BESTCHANGE:
- SiteProcessor = createBestChangeProcessor();
- setTimeout(SiteProcessor.init, helpers.randomMs(4000, 6000));
- break;
- case K.WebType.BFBOX:
- SiteProcessor = new BFRoll(helpers.getEnumText(K.CMC, shared.getCurrent().params.cmc).toLowerCase());
- setTimeout(() => { SiteProcessor.init() }, helpers.randomMs(2000, 5000));
- break;
- case K.WebType.DUTCHYROLL:
- SiteProcessor = new DutchyRoll();
- setTimeout(() => { SiteProcessor.init() }, helpers.randomMs(2000, 5000));
- break;
- case K.WebType.FCRYPTO:
- SiteProcessor = new FCryptoRoll();
- setTimeout(() => { SiteProcessor.init() }, helpers.randomMs(2000, 5000));
- break;
- case K.WebType.FPB:
- SiteProcessor = new FPB(shared.getCurrent().params.sitePrefix);
- setTimeout(() => { SiteProcessor.init() }, helpers.randomMs(3000, 5000));
- break;
- case K.WebType.FREEGRC:
- SiteProcessor = new GRCRoll();
- setTimeout(() => { SiteProcessor.init() }, helpers.randomMs(3000, 5000));
- break;
- case K.WebType.VIE:
- SiteProcessor = new VieRoll();
- setTimeout(() => { SiteProcessor.init() }, helpers.randomMs(3000, 5000));
- break;
- case K.WebType.O24:
- SiteProcessor = new O24Roll();
- setTimeout(() => { SiteProcessor.init() }, helpers.randomMs(3000, 5000));
- break;
- case K.WebType.YCOIN:
- SiteProcessor = new YCoin();
- setTimeout(() => { SiteProcessor.init() }, helpers.randomMs(3000, 5000));
- break;
- case K.WebType.CDIVERSITY:
- SiteProcessor = new CDiversity();
- setTimeout(() => { SiteProcessor.init() }, helpers.randomMs(3000, 5000));
- break;
- case K.WebType.CTOP:
- SiteProcessor = new CTop();
- setTimeout(() => { SiteProcessor.init() }, helpers.randomMs(3000, 5000));
- break;
- case K.WebType.AUTOCML:
- SiteProcessor = new AutoCMl();
- setTimeout(() => { SiteProcessor.init() }, helpers.randomMs(3000, 5000));
- break;
- case K.WebType.CCLICKS:
- SiteProcessor = new CClicks();
- setTimeout(() => { SiteProcessor.init() }, helpers.randomMs(3000, 5000));
- break;
- default:
- break;
- }
- }
-
- class UiBaseRenderer {
- constructor(uiRenderer) { this.uiRenderer = uiRenderer; }
- }
- class UiSitesRenderer extends UiBaseRenderer {
- appendEventListeners() {
-
- document.querySelector('#modal-assign-schedule').addEventListener('click', this.onClickOnModalAssignSchedule.bind(this));
- eventer.on('siteChangedSchedule', (e) => {
- this.uiRenderer.toast(`Site moved to schedule ${e.scheduleId}`);
- manager.resyncAll({withUpdate: true}); // should act based on data only
- });
-
- document.querySelector('#schedule-table-body').addEventListener('click', this.onClickOnSitesTableBody.bind(this));
-
- document.querySelector('.action-edit-all-sites').addEventListener('click', this.onClickOnEditAllSites.bind(this));
- document.querySelector('.action-edit-all-sites-cancel').addEventListener('click', this.onClickOnCancelEditAllSites.bind(this));
- document.querySelector('.action-edit-all-sites-save').addEventListener('click', this.onClickOnSaveEditAllSites.bind(this));
-
- document.querySelector('.action-add-external-site').addEventListener('click', this.onClickOnAddSiteButton.bind(this));
- document.querySelector('#modal-add-site').addEventListener('click', this.onClickOnModalAddSite.bind(this));
- eventer.on('siteAdded', (e) => {
- this.uiRenderer.toast(`Site ${e.siteName} added`);
- manager.resyncAll({withUpdate: true}); // should act based on data only
- });
- eventer.on('siteRemoved', (e) => {
- this.uiRenderer.toast(`Site ${e.siteName} removed`);
- manager.resyncAll({withUpdate: true}); // should act based on data only
- });
- }
-
- _legacyAddBadges(stats) {
- let consecutiveTimeout = stats.countTimeouts;
- let otherErrors = stats.errors;
- let html = ' ';
-
- if (consecutiveTimeout) {
- html += `<span class="badge badge-pill badge-warning" title="${consecutiveTimeout} consecutive timeouts">${consecutiveTimeout}</span>`;
- }
-
- if (otherErrors) {
- html += `<span class="badge badge-pill badge-warning" title="${otherErrors.errorMessage}">${helpers.getEnumText(K.ErrorType, otherErrors.errorType)}</span>`;
- }
- return html;
- }
-
- removeDeletedSitesRows(validSiteIds) {
- let removableRows = [...document.querySelectorAll('#schedule-table-body tr')].filter(r => !validSiteIds.includes(r.dataset.id));
- removableRows.forEach(r => {
- r.remove();
- });
- }
-
- renderSiteRow(site) {
-
- let row = [...document.querySelectorAll('#schedule-table-body tr')]
- .filter(r => r.dataset.id == site.id);
-
- if (row.length == 0) {
- row = document.createElement('tr');
- document.querySelector('#schedule-table-body').appendChild(row);
- row.setAttribute('aria-expanded', false);
- row.classList.add('align-middle');
- row.dataset.id = site.id;
- row.dataset.cmc = site.cmc;
- } else {
- row = row[0];
- }
-
- row.dataset.json = `${JSON.stringify(site)}`;
- row.dataset.schedule = site.schedule;
- row.dataset.nextRollTimestamp = site.nextRoll ? site.nextRoll.getTime() : 'null';
- row.dataset.enabled = site.enabled ? '1' : '0';
- if (site.balance) {
- if (typeof site.balance == 'string') {
- row.dataset.balance = site.balance.split(' ')[0];
- } else {
- row.dataset.balance = site.balance.toFixed(8);
- }
- } else {
- row.dataset.balance = '';
- }
-
- let tds = '';
-
- tds += '<td class="align-middle edit-status d-none em-only"><label class="switch"><input type="checkbox" data-original="' + (site.enabled ? '1' : '0') + '" ' + (site.enabled ? 'checked' : ' ') + '><span class="slider round"></span></label></td>';
- tds += '<td class="align-middle" title="' + helpers.getPrintableDateTime(site.nextRoll) + '"><span><i class="fas fa-square pr-1" style="color: #' + site.schedule + ';"></i></span>' + helpers.getTdPrintableTime(site.nextRoll) + '</td>';
- if (site.isExternal && site.clId == -1) {
- tds += '<td class="align-middle text-left"><a class="" title="Visit site" target="_blank" rel="noreferrer" href="' + site.url + '"><i class="fa fa-external-link-alt"></i></a></td>';
- } else {
- tds += '<td class="align-middle text-left"><a class="" title="Visit site" target="_blank" rel="noreferrer" href="' + (new URL(site.clId, 'https://criptologico.com/goto/')).href + '"><i class="fa fa-external-link-alt"></i></a></td>';
- }
-
- tds += '<td class="align-middle em-input text-left" data-field="displayName">';
- if (site.cmc) {
- tds +='<div class="input-group input-group-sm">';
- tds += '<div class="input-group-prepend"><span class="input-group-text">';
- if (site.cmc > 0) {
- let cmcLower = helpers.getEnumText(K.CMC, site.cmc).toLowerCase();
- tds += '<img loading="lazy" src="/static/c-icons/' + cmcLower + '.svg" height="20" alt="' + cmcLower + '">';
- } else {
- tds += '<i class="fa fa-question-circle"></i>';
- }
- tds += '</span></div>';
- }
- tds += ' <span class="site-name-container px-1">' + site.name + '</span></div></td>';
-
- tds +='<td class="align-middle text-right">' + site.lastClaim.toFixed(Number.isInteger(site.lastClaim) ? 0 : 8) + '</td>';
- tds +='<td class="align-middle text-right">' + site.aggregate.toFixed(Number.isInteger(site.aggregate) ? 0 : 8) + '</td>';
-
- tds += '<td class="align-middle text-right">' + (+row.dataset.balance > 100 ? (+row.dataset.balance).toFixed(2) : row.dataset.balance) + '</td>';
- tds +='<td class="align-middle text-right fiat-conversion em-hide"></td>';
- tds +='<td class="align-middle">' + this._legacyAddBadges(site.stats) + '</td>';
- tds +='<td class="align-middle justify-content-center em-hide">';
-
- tds +=
- `<div class="btn-group btn-group-sm">
- <button type="button" title="Run ASAP" class="btn btn-default action-run-asap">
- <i class="fa fa-bolt"></i>
- </button>
- <button type="button" title="Schedule parameters..."
- class="btn btn-default action-edit-site ${Object.keys(site.params).some( k => k.endsWith('.override') && site.params[k] == true ) ? 'text-warning' : ''}">
- <i class="fa fa-clock"></i>
- </button>
- <div class="btn-group btn-group-sm">
- <button type="button" class="btn btn-default dropdown-toggle dropdown-icon" data-toggle="dropdown" aria-expanded="false">
- </button>
- <div class="dropdown-menu dropdown-menu-right text-sm" style="">
- <a class="dropdown-item action-site-edit-parameters"><i class="fa fa-edit"></i> Site arguments...</a>
- <a class="dropdown-item action-site-assign-schedule"><i class="fa fa-exchange-alt"></i> Move to...</a>`;
- if (site.isExternal) {
- tds += `<a class="dropdown-item action-site-remove-external"><i class="fa fa-trash"></i> Remove site</a>`;
- }
- tds += `</div></div></div>`;
-
- tds +='</td></tr>';
-
- row.innerHTML = tds;
- }
-
- legacyRenderSiteData(site, config) {
- document.querySelector('#faucet-name').innerHTML = site.name;
- document.querySelector('#faucet-name').dataset.id = site.id;
- let data = site.params || {};
-
- for (const prop in config) {
- let overrideElement = document.querySelector('[data-site-prop="' + prop + '.override"]');
- if (overrideElement) {
- overrideElement.dataset.original = (data[prop + '.override'] ? "1" : "0");
- overrideElement.checked = data[prop + '.override'];
- }
-
- let element = document.querySelector('[data-site-prop="' + prop + '"]');
- if(element) {
- if(element.type == 'select-one' || element.type == 'text' || element.type == 'password' || element.type == 'number' || element.type == 'time') {
- element.dataset.original = data[prop] ?? config[prop];
- element.value = data[prop] ?? config[prop];
- } else if (element.type == 'checkbox') {
- element.dataset.original = ((data[prop] ?? config[prop]) ? "1" : "0");
- element.checked = data[prop] ?? config[prop];
- }
- element.disabled = true;
- }
- }
-
- let elWorkInBackgroundOverride = document.querySelector('[data-site-prop="defaults.workInBackground.override"]');
- let elWorkInBackground = document.querySelector('[data-site-prop="defaults.workInBackground"]');
- elWorkInBackground.disabled = !elWorkInBackgroundOverride.checked;
- elWorkInBackgroundOverride.onchange = function (e) {
- document.querySelector('[data-site-prop="defaults.workInBackground"]').disabled = !e.target.checked;
- }
-
- let elTimeoutOverride = document.querySelector('[data-site-prop="defaults.timeout.override"]');
- let elTimeout = document.querySelector('[data-site-prop="defaults.timeout"]');
- elTimeout.disabled = !elTimeoutOverride.checked;
- elTimeoutOverride.onchange = function (e) {
- document.querySelector('[data-site-prop="defaults.timeout"]').disabled = !e.target.checked;
- }
-
- let elPostponeOverride = document.querySelector('[data-site-prop="defaults.postponeMinutes.override"]');
- let elPostpone = document.querySelector('[data-site-prop="defaults.postponeMinutes"]');
- let elPostponeMin = document.querySelector('[data-site-prop="defaults.postponeMinutes.min"]');
- let elPostponeMax = document.querySelector('[data-site-prop="defaults.postponeMinutes.max"]');
- elPostpone.disabled = !elPostponeOverride.checked;
- elPostponeMin.disabled = !elPostponeOverride.checked || (elPostpone.value > "0");
- elPostponeMax.disabled = !elPostponeOverride.checked || (elPostpone.value > "0");
- elPostponeOverride.onchange = function (e) {
- let mode = document.querySelector('[data-site-prop="defaults.postponeMinutes"]');
- mode.disabled = !e.target.checked;
- document.querySelector('[data-site-prop="defaults.postponeMinutes.min"]').disabled = !e.target.checked || mode.value > 0;
- document.querySelector('[data-site-prop="defaults.postponeMinutes.max"]').disabled = !e.target.checked || mode.value > 0;
- }
- elPostpone.onchange = function (e) {
- document.querySelector('[data-site-prop="defaults.postponeMinutes.min"]').disabled = e.target.value > 0;
- document.querySelector('[data-site-prop="defaults.postponeMinutes.max"]').disabled = e.target.value > 0;
- if (e.target.value > 0) {
- document.querySelector('[data-site-prop="defaults.postponeMinutes.min"]').value = e.target.value;
- document.querySelector('[data-site-prop="defaults.postponeMinutes.max"]').value = e.target.value;
- }
- }
-
- let elNextRunOverride = document.querySelector('[data-site-prop="defaults.nextRun.override"]');
- let elNextRun = document.querySelector('[data-site-prop="defaults.nextRun"]');
- let elNextRunMin = document.querySelector('[data-site-prop="defaults.nextRun.min"]');
- let elNextRunMax = document.querySelector('[data-site-prop="defaults.nextRun.max"]');
- let elNextRunUseCountdown = document.querySelector('[data-site-prop="defaults.nextRun.useCountdown"]');
- elNextRun.disabled = !elNextRunOverride.checked;
- elNextRunMin.disabled = !elNextRunOverride.checked || (elNextRun.value > "0");
- elNextRunMax.disabled = !elNextRunOverride.checked || (elNextRun.value > "0");
- elNextRunUseCountdown.disabled = !elNextRunOverride.checked;
- elNextRunOverride.onchange = function (e) {
- let mode = document.querySelector('[data-site-prop="defaults.nextRun"]');
- mode.disabled = !e.target.checked;
- document.querySelector('[data-site-prop="defaults.nextRun.min"]').disabled = !e.target.checked || mode.value > 0;
- document.querySelector('[data-site-prop="defaults.nextRun.max"]').disabled = !e.target.checked || mode.value > 0;
- document.querySelector('[data-site-prop="defaults.nextRun.useCountdown"]').disabled = !e.target.checked;
- }
- elNextRun.onchange = function (e) {
- document.querySelector('[data-site-prop="defaults.nextRun.min"]').disabled = e.target.value > 0;
- document.querySelector('[data-site-prop="defaults.nextRun.max"]').disabled = e.target.value > 0;
- if (e.target.value > 0) {
- document.querySelector('[data-site-prop="defaults.nextRun.min"]').value = e.target.value;
- document.querySelector('[data-site-prop="defaults.nextRun.max"]').value = e.target.value;
- }
- }
-
- let elSleepOverride = document.querySelector('[data-site-prop="defaults.sleepMode.override"]');
- let elSleep = document.querySelector('[data-site-prop="defaults.sleepMode"]');
- let elSleepMin = document.querySelector('[data-site-prop="defaults.sleepMode.min"]');
- let elSleepMax = document.querySelector('[data-site-prop="defaults.sleepMode.max"]');
- elSleep.disabled = !elSleepOverride.checked;
- elSleepMin.disabled = !elSleepOverride.checked || !elSleep.checked;
- elSleepMax.disabled = !elSleepOverride.checked || !elSleep.checked;
- elSleepOverride.onchange = function (e) {
- let mode = document.querySelector('[data-site-prop="defaults.sleepMode"]');
- mode.disabled = !e.target.checked;
- document.querySelector('[data-site-prop="defaults.sleepMode.min"]').disabled = !e.target.checked || !mode.checked;
- document.querySelector('[data-site-prop="defaults.sleepMode.max"]').disabled = !e.target.checked || !mode.checked;
- }
- elSleep.onchange = function (e) {
- document.querySelector('[data-site-prop="defaults.sleepMode.min"]').disabled = !e.target.checked;
- document.querySelector('[data-site-prop="defaults.sleepMode.max"]').disabled = !e.target.checked;
- }
-
- return;
- }
-
- sortSitesTable() {
- const tbody = document.querySelector('#schedule-table-body');
-
- let rows, switching, i, shouldSwitch;
- switching = true;
- while (switching) {
- switching = false;
- rows = tbody.rows;
-
- for (i = 0; i < (rows.length - 1); i++) {
- shouldSwitch = false;
-
- let aNextRoll, bNextRoll, aHasLoginError, bHasLoginError, aName, bName;
- aNextRoll = rows[i].dataset.nextRollTimestamp;
- bNextRoll = rows[i + 1].dataset.nextRollTimestamp;
- if (aNextRoll == 'null' && bNextRoll == 'null') {
- aName = rows[i].querySelector('.site-name-container').innerText;
- bName = rows[i + 1].querySelector('.site-name-container').innerText;
- if (aName.toLowerCase() > bName.toLowerCase()) {
- shouldSwitch = true;
- break;
- }
- } else if (aNextRoll == 'null' || (aNextRoll > bNextRoll)) {
- shouldSwitch = true;
- break;
- }
- }
- if (shouldSwitch) {
- rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
- switching = true;
- }
- }
- }
-
- onClickOnSitesTableBody(e) {
- let actionElement = e.target;
- if (actionElement.tagName === 'I') {
- actionElement = actionElement.parentElement;
- }
- const row = actionElement.closest('tr');
- if (actionElement.classList.contains('action-edit-site')) {
- e.stopPropagation();
- this.uiRenderer.openModal('modal-site', row.dataset.id);
- } else if (actionElement.classList.contains('action-run-asap')) {
- e.stopPropagation();
- Site.setAsRunAsap(row.dataset.id);
- } else if (actionElement.classList.contains('action-site-assign-schedule')) {
- this.uiRenderer.openModal('modal-assign-schedule', { site_id: row.dataset.id, schedule_id: row.dataset.schedule });
- } else if (actionElement.classList.contains('action-site-edit-parameters')) {
- this.uiRenderer.openModal('modal-site-parameters', { site_id: row.dataset.id });
- } else if (actionElement.classList.contains('action-site-remove-external')) {
- Site.remove(row.dataset.id);
- console.info('TODO: remove site and all the related configuration', row.dataset.id);
- }
- }
-
- onClickOnModalAssignSchedule(e) {
- const modalAssignScheduleToSite = document.querySelector('#modal-assign-schedule');
- let actionElement = e.target.tagName === 'I' ? e.target.parentElement : e.target;
- if (actionElement.classList.contains('modal-save')) {
- let data = this.uiRenderer.parseContainer(modalAssignScheduleToSite.querySelector('.form-container'));
- if (data.original_schedule_id == data.schedule) {
- } else {
- Site.getById(data.site_id).changeSchedule(data.schedule);
- }
- }
- }
-
- onClickOnModalAddSite(e) {
- const modal = document.querySelector('#modal-add-site');
- let actionElement = e.target.tagName === 'I' ? e.target.parentElement : e.target;
- if (actionElement.classList.contains('modal-save')) {
- let formData = this.uiRenderer.parseContainer(modal.querySelector('.form-container'));
- let data = {};
- data.name = formData.site_name;
- data.url = new URL(formData.site_url);
- data.schedule = formData.schedule;
- data.clId = -1;
- data.id = 'ext_rnd_id_' + helpers.randomString(8);
- data.type = K.WebType.UNDEFINED;
- data.cmc = -1;
- data.rf = '';
- data.isExternal = true;
-
- console.warn('Savable new site');
- Site.add(data);
- return;
- if (data.original_schedule_id == data.schedule) {
- } else {
- Site.getById(data.site_id).changeSchedule(data.schedule);
- }
- }
- }
-
- onClickOnEditAllSites(e) {
- document.querySelectorAll("#schedule-table-body td.em-input .site-name-container").forEach(function (x) {
- let val = x.innerHTML;
- x.innerHTML = "<input type=\'text\' class=\'form-control form-control-sm\' data-original=\'" + val.trim() + "\' value=\'" + val.trim() + "\' />";
- });
- document.querySelectorAll("#schedule-table-body td.edit-status").forEach(function (x) {
- x.classList.remove("d-none");
- });
- document.querySelectorAll(".em-only").forEach(x => x.classList.remove("d-none"));
- document.querySelectorAll(".em-hide").forEach(x => x.classList.add("d-none"));
- }
-
- onClickOnCancelEditAllSites(e) {
- document.querySelectorAll("#schedule-table-body td.em-input .site-name-container input").forEach(function(x) {
- x.parentNode.innerHTML = x.dataset.original;
- });
- document.querySelectorAll(".em-only").forEach(x => x.classList.add("d-none"));
- document.querySelectorAll(".em-hide").forEach(x => x.classList.remove("d-none"));
- }
-
- onClickOnSaveEditAllSites(e) {
- let updateObject;
- var updateData = document.getElementById("update-data");
- if (updateData.innerHTML != "") {
- updateObject = JSON.parse(updateData.innerHTML);
- } else {
- updateObject = {
- runAsap: { ids: [], changed: false },
- editSingle: { changed: false, items: [] },
- wallet: { changed: false, items: [] },
- config: { changed: false, items: [] },
- site: { changed: false, list: [] }
- };
- }
-
- document.querySelectorAll("#schedule-table-body tr").forEach(function (row) {
- let textInputCell = row.querySelector(".em-input .site-name-container");
- let textInput = textInputCell.querySelector("input");
- let activeSwitch = row.querySelector("td.edit-status input");
- let single = { id: row.dataset.id, displayName: textInput.dataset.original, enabled: activeSwitch.dataset.original };
- textInputCell.innerHTML = textInput.value;
- if(textInput.dataset.original != textInput.value) {
- single.displayName = textInput.value;
- }
- if(activeSwitch.dataset.original != Boolean(activeSwitch.checked)) {
- single.enabled = Boolean(activeSwitch.checked);
- }
- if(textInput.dataset.original != textInput.value || activeSwitch.dataset.original != Boolean(activeSwitch.checked)) {
- updateObject.editSingle.items.push(single);
- updateObject.editSingle.changed = true;
- }
- });
- if(updateObject.editSingle.changed) {
- document.getElementById("update-data").innerHTML = JSON.stringify(updateObject);
- this.uiRenderer.toast("Data will be updated as soon as possible");
- }
-
- document.querySelectorAll(".em-only").forEach(x => x.classList.add("d-none"));
- document.querySelectorAll(".em-hide").forEach(x => x.classList.remove("d-none"));
- }
-
- onClickOnAddSiteButton(e) {
- e.stopPropagation();
- this.uiRenderer.openModal('modal-add-site');
- }
-
- renderAddExternalSite() {
- const modalAssignSchedule = document.getElementById('modal-add-site');
- let selectElm = modalAssignSchedule.querySelector('select');
- let options = [];
- let firstSchedule = '';
- Schedule.getAllForCrud().forEach(sch => {
- if (firstSchedule == '') {
- firstSchedule = sch.uuid;
- }
- options.push(`<option value="${sch.uuid}"><i class="fas fa-square" style="color: #${sch.uuid}"></i>${sch.name}</option>`)
- });
- selectElm.innerHTML = options.join('');
- selectElm.value = firstSchedule;
- return;
- }
-
- renderAssignScheduleToSite(values) {
- const modalAssignSchedule = document.getElementById('modal-assign-schedule');
- modalAssignSchedule.querySelector('input[name="site_id"]').value = values.site_id;
- modalAssignSchedule.querySelector('input[name="original_schedule_id"]').value = values.schedule_id;
- let selectElm = modalAssignSchedule.querySelector('select');
- let options = [];
- Schedule.getAllForCrud().forEach(sch => {
- options.push(`<option value="${sch.uuid}"><i class="fas fa-square" style="color: #${sch.uuid}"></i>${sch.name}</option>`)
- });
- selectElm.innerHTML = options.join('');
- selectElm.value = values.schedule_id || "";
- return;
- }
- }
- class UiPromosRenderer extends UiBaseRenderer {
- appendEventListeners() {
- document.querySelector('#promo-button').addEventListener('click', this.onClickSavePromoCode.bind(this));
- document.querySelector('#button-try-get-codes').addEventListener('click', this.onClickTryGetCodes.bind(this));
- document.querySelector('#promo-table-body').addEventListener('click', this.onClickOnPromoTableBody.bind(this));
- }
-
- onClickSavePromoCode(e) {
- var promoText = document.getElementById("promo-text-input");
- var promoCode = document.getElementById("promo-code-new");
- var promoDaily = document.getElementById("promo-daily");
- var promoObject = { action: "ADD", code: promoText.value.trim(), repeatDaily: promoDaily.checked };
- promoCode.innerHTML =JSON.stringify(promoObject);
- this.uiRenderer.toast("Adding promo code: " + promoObject.code + "...");
- promoText.value = '';
- }
-
- onClickTryGetCodes(e) {
- var promoCode = document.getElementById("promo-code-new");
- var promoObject = { action: "TRYGETCODES" };
- promoCode.innerHTML =JSON.stringify(promoObject);
- this.uiRenderer.toast("Fetching codes...");
- }
-
- _legacyRemoveUsedDailyCodes(codes) {
- if(codes && codes.length) {
- codes.forEach(code => {
- if(!code.repeatDaily) {
- let counter = 0;
- for(let i = 0; i < code.statusPerFaucet.length; i++) {
- if(code.statusPerFaucet[i].execTimeStamp) {
- counter++;
- }
- }
- if(counter == code.statusPerFaucet.length) {
- setTimeout(() => removePromoCode(code.id, code.code), 20000);
- }
- }
- });
- }
- }
-
- legacyRenderPromotionTable(codes) {
- let tableBody = '';
- this._legacyRemoveUsedDailyCodes(codes);
-
- for(let c=0; c < codes.length; c++) {
- let data = codes[c];
- tableBody += '<tr data-promotion-code="' + data.code + '" data-promotion-id="' + data.id + '">';
- tableBody += '<td class="align-middle text-left ' + (data.repeatDaily ? 'text-warning' : '') + '">';
- tableBody += `<a class="action-remove-promo-code" data-toggle="tooltip" data-placement="left" title="Remove" onclick=""><i class="fa fa-times-circle"></i></a>`;
- tableBody += '<span title="' + (data.repeatDaily ? 'Reusable Code' : 'One-time-only Code') + '">' + data.code + '</span></td>';
- tableBody +='<td class="align-middle" title="' + (data.repeatDaily ? 'Reusable Code' : 'One-time-only Code') + '">' + helpers.getPrintableDateTime(data.added) + '</td>';
-
- for(let i=0, all = data.statusPerFaucet.length; i < all; i++) {
- tableBody +='<td class="align-middle" title="Runned @' + helpers.getPrintableDateTime(data.statusPerFaucet[i].execTimeStamp) + '">' + helpers.getEmojiForPromoStatus(data.statusPerFaucet[i].status ?? 0) + '</td>';
- }
- tableBody +='</tr>';
- }
-
- document.getElementById('promo-table-body').innerHTML = tableBody;
- }
-
- onClickOnPromoTableBody(e) {
- let actionElement = e.target;
- if (actionElement.tagName === 'I') {
- actionElement = actionElement.parentElement;
- }
- const row = actionElement.closest('tr');
- if (actionElement.classList.contains('action-remove-promo-code')) {
- e.stopPropagation();
- var promoCode = document.getElementById("promo-code-new");
- var promoObject = { action: "REMOVE", id: row.dataset.promotionId, code: row.dataset.promotionCode };
- promoCode.innerHTML =JSON.stringify(promoObject);
- }
- }
- }
- class UiConfigRenderer extends UiBaseRenderer {
- legacyRenderConfigData(data) {
- for (const prop in data) {
- let element = document.querySelector('[data-prop="' + prop + '"]');
- if(element) {
- if(element.type == 'select-one' || element.type == 'text' || element.type == 'password' || element.type == 'number' || element.type == 'time') {
- element.dataset.original = data[prop];
- element.value = data[prop];
- } else if (element.type == 'checkbox') {
- element.dataset.original = (data[prop] ? "1" : "0");
- element.checked = data[prop];
- }
- }
- }
-
- let elCfTryGetCodes = document.querySelector('[data-prop="cf.tryGetCodes"]')
- let elCredentialsAutologin = document.querySelector('[data-prop="cf.autologin"]');
- let elCredentialsMode = document.querySelector('[data-prop="cf.credentials.mode"]');
- let elCredentialsEmail = document.querySelector('[data-prop="cf.credentials.email"]');
- let elCredentialsPassword = document.querySelector('[data-prop="cf.credentials.password"]');
- let elDevlogEnabled = document.querySelector('[data-prop="devlog.enabled"]');
- let elDevlogMaxLines = document.querySelector('[data-prop="devlog.maxLines"]');
- let elJtfeyCredentialsMode = document.querySelector('[data-prop="jtfey.credentials.mode"]');
- let elJtfeyCredentialsUsername = document.querySelector('[data-prop="jtfey.credentials.username"]');
- let elJtfeyCredentialsPassword = document.querySelector('[data-prop="jtfey.credentials.password"]');
- let elYCoinCredentialsMode = document.querySelector('[data-prop="ycoin.credentials.mode"]');
- let elYCoinCredentialsUsername = document.querySelector('[data-prop="ycoin.credentials.username"]');
- let elYCoinCredentialsPassword = document.querySelector('[data-prop="ycoin.credentials.password"]');
-
- let elPostpone = document.querySelector('[data-prop="defaults.postponeMinutes"]');
- let elPostponeMin = document.querySelector('[data-prop="defaults.postponeMinutes.min"]');
- let elPostponeMax = document.querySelector('[data-prop="defaults.postponeMinutes.max"]');
- elPostponeMin.disabled = (elPostpone.value > "0");
- elPostponeMax.disabled = (elPostpone.value > "0");
- if (elPostponeMin.disabled && elPostponeMax.disabled) {
- elPostponeMin.value = elPostpone.value;
- elPostponeMax.value = elPostpone.value;
- }
- elPostpone.onchange = function (e) {
- document.querySelector('[data-prop="defaults.postponeMinutes.min"]').disabled = e.target.value > 0;
- document.querySelector('[data-prop="defaults.postponeMinutes.max"]').disabled = e.target.value > 0;
- if (e.target.value > 0) {
- document.querySelector('[data-prop="defaults.postponeMinutes.min"]').value = e.target.value;
- document.querySelector('[data-prop="defaults.postponeMinutes.max"]').value = e.target.value;
- }
- }
-
- let elNextRun = document.querySelector('[data-prop="defaults.nextRun"]');
- let elNextRunMin = document.querySelector('[data-prop="defaults.nextRun.min"]');
- let elNextRunMax = document.querySelector('[data-prop="defaults.nextRun.max"]');
- let elNextRunUseCountdown = document.querySelector('[data-prop="defaults.nextRun.useCountdown"]');
- elNextRunMin.disabled = (elNextRun.value > "0");
- elNextRunMax.disabled = (elNextRun.value > "0");
- if (elNextRunMin.disabled && elNextRunMax.disabled) {
- elNextRunMin.value = elNextRun.value;
- elNextRunMax.value = elNextRun.value;
- }
- elNextRun.onchange = function (e) {
- document.querySelector('[data-prop="defaults.nextRun.min"]').disabled = e.target.value > 0;
- document.querySelector('[data-prop="defaults.nextRun.max"]').disabled = e.target.value > 0;
- if (e.target.value > 0) {
- document.querySelector('[data-prop="defaults.nextRun.min"]').value = e.target.value;
- document.querySelector('[data-prop="defaults.nextRun.max"]').value = e.target.value;
- }
- }
-
- let elSleepMode = document.querySelector('[data-prop="defaults.sleepMode"]');
- let elSleepModeMin = document.querySelector('[data-prop="defaults.sleepMode.min"]');
- let elSleepModeMax = document.querySelector('[data-prop="defaults.sleepMode.max"]');
- elSleepModeMin.disabled = !elSleepMode.checked;
- elSleepModeMax.disabled = !elSleepMode.checked;
- elSleepMode.onchange = function (e) {
- document.querySelector('[data-prop="defaults.sleepMode.min"]').disabled = !e.target.checked;
- document.querySelector('[data-prop="defaults.sleepMode.max"]').disabled = !e.target.checked;
- }
-
- elCredentialsMode.disabled = !elCredentialsAutologin.checked;
-
- elCredentialsEmail.disabled = ( (!elCredentialsAutologin.checked || elCredentialsMode.value == "2") ? true : false);
- elCredentialsPassword.disabled = ( (!elCredentialsAutologin.checked || elCredentialsMode.value == "2") ? true : false);
-
- elCredentialsAutologin.onchange = function (e) {
- document.querySelector('[data-prop="cf.credentials.mode"]').disabled = !e.target.checked;
- if (elCredentialsMode.value == "2") {
- document.querySelector('[data-prop="cf.credentials.email"]').disabled = true;
- document.querySelector('[data-prop="cf.credentials.password"]').disabled = true;
- } else {
- document.querySelector('[data-prop="cf.credentials.email"]').disabled = false;
- document.querySelector('[data-prop="cf.credentials.password"]').disabled = false;
- }
- }
-
- elCredentialsMode.onchange = function (e) {
- if (e.target.value == "2") {
- document.querySelector('[data-prop="cf.credentials.email"]').disabled = true;
- document.querySelector('[data-prop="cf.credentials.password"]').disabled = true;
- } else {
- document.querySelector('[data-prop="cf.credentials.email"]').disabled = false;
- document.querySelector('[data-prop="cf.credentials.password"]').disabled = false;
- }
- }
-
- elYCoinCredentialsUsername.disabled = ( (elYCoinCredentialsMode.value == "2") ? true : false);
- elYCoinCredentialsPassword.disabled = ( (elYCoinCredentialsMode.value == "2") ? true : false);
- elYCoinCredentialsMode.onchange = function (e) {
- if (e.target.value == "2") {
- document.querySelector('[data-prop="ycoin.credentials.username"]').disabled = true;
- document.querySelector('[data-prop="ycoin.credentials.password"]').disabled = true;
- } else {
- document.querySelector('[data-prop="ycoin.credentials.username"]').disabled = false;
- document.querySelector('[data-prop="ycoin.credentials.password"]').disabled = false;
- }
- }
-
- elJtfeyCredentialsUsername.disabled = ( (elJtfeyCredentialsMode.value == "2") ? true : false);
- elJtfeyCredentialsPassword.disabled = ( (elJtfeyCredentialsMode.value == "2") ? true : false);
- elJtfeyCredentialsMode.onchange = function (e) {
- if (e.target.value == "2") {
- document.querySelector('[data-prop="jtfey.credentials.username"]').disabled = true;
- document.querySelector('[data-prop="jtfey.credentials.password"]').disabled = true;
- } else {
- document.querySelector('[data-prop="jtfey.credentials.username"]').disabled = false;
- document.querySelector('[data-prop="jtfey.credentials.password"]').disabled = false;
- }
- }
-
- elDevlogMaxLines.disabled = !elDevlogEnabled.checked;
- elDevlogEnabled.onchange = function (e) {
- document.querySelector('[data-prop="devlog.maxLines"]').disabled = !e.target.checked;
- }
- }
- }
- class UiWalletRenderer extends UiBaseRenderer {
- legacyRenderWalletTable(data) {
- let tableBody = '';
-
- for(let i=0, all = data.length; i < all; i++) {
- tableBody += '<tr class="align-middle" data-id="'+ data[i].id + '">';
- tableBody += '<td class="align-middle">' + data[i].name + '</td>';
- tableBody += '<td class="align-middle em-input"><input type="text" class="w-100" onfocus="this.select();" data-field="address" data-original="' + data[i].address + '" value="' + data[i].address + '"></td>';
- tableBody += '</tr>';
- }
-
- document.getElementById('wallet-table-body').innerHTML = tableBody;
- }
- }
- class UiSchedulesRenderer extends UiBaseRenderer {
- appendEventListeners() {
- document.querySelector('#schedules-toggler').addEventListener('change', this.onScheduleToggled.bind(this));
- }
-
- onScheduleToggled(e) {
- e.stopPropagation();
- let actionElement = e.target.tagName !== 'LABEL' ? e.target.closest('label') : e.target;
- let otherActiveLabels = [...actionElement.parentElement.querySelectorAll('label.active')].filter(l => l.dataset.schedule != actionElement.dataset.schedule);
- if (otherActiveLabels.length > 0) {
- otherActiveLabels.forEach(l => l.classList.remove('active'));
- }
- this.toggleSchedule(actionElement.dataset.schedule);
- }
-
- toggleSchedule(uuid) {
-
- if (uuid) {
- this.selectedSchedule = uuid;
- } else {
- if (!this.selectedSchedule) {
- this.selectedSchedule = 'all';
- }
- }
-
- [...document.querySelectorAll('#schedule-table-body tr')].forEach((row) => {
- if (this.selectedSchedule == 'all') {
- row.classList.remove('d-none');
- } else if (row.getAttribute('data-schedule') == this.selectedSchedule) {
- row.classList.remove('d-none');
- } else {
- row.classList.add('d-none');
- }
- });
-
- if (this.selectedSchedule == 'all') {
- [...document.querySelectorAll('#console-log tr')].forEach(x => {
- x.classList.remove('d-none');
- })
- } else {
- [...document.querySelectorAll('#console-log tr')].forEach(x => {
- if (x.getAttribute('data-schedule') == 'false' || x.getAttribute('data-schedule') == this.selectedSchedule) {
- x.classList.remove('d-none');
- } else {
- x.classList.add('d-none');
- }
- })
- }
- };
-
- renderTBody() {
- let rows = [];
- Schedule.getAllForCrud().forEach(sch => {
- rows.push(this.renderRow(sch));
- });
- return rows.join('');
- }
-
- renderRow(sch) {
- let row =
- `<tr data-uuid="${sch.uuid}"
- data-order="${sch.order}"
- data-added="${sch.added ? 'true' : 'false'}"
- data-removed="false"
- data-updated="false"
- data-originals='${!sch.added ? JSON.stringify(sch) : ""}'>
- <td class="row-handle"><i class="fas fa-grip-vertical"></i></td>
- <td><div class="input-group input-group-sm color-picker colorpicker-element" style="max-width: 125px;">
- <div class="input-group-prepend"><span class="input-group-text"><i class="fas fa-square" style="color: #${sch.uuid}"></i></span></div>
- <input type="text" name="uuid" class="form-control" data-original-title="" value="${sch.uuid}">
- </div></td>
- <td><input type="text" name="name" class="form-control form-control-sm" value="${sch.name}"></td>
- <td>
- <button type="button" title="Remove" class="btn btn-default btn-sm action-schedule-remove"><i class="fa fa-trash"></i></button>
- </td>
- </tr>`;
- return row;
- }
- }
- class UiSiteParameterRenderer extends UiBaseRenderer {
- static handlers = new Map();
-
- static registerHandler(name, handler) {
- UiSiteParameterRenderer.handlers.set(name, handler);
- }
-
- static getHandler(name) {
- const handlerClass = UiSiteParameterRenderer.handlers.get(name);
- return handlerClass || false;
- }
-
- appendEventListeners() {
- document.querySelector('#modal-site-parameters').addEventListener('click', this.onClickOnModalSiteParameter.bind(this));
- }
-
- onClickOnModalSiteParameter(e) {
- const modal = document.querySelector('#modal-site-parameters');
- let actionElement = e.target.tagName === 'I' ? e.target.parentElement : e.target;
- if (actionElement.classList.contains('modal-save')) {
- e.preventDefault();
- let form = modal.querySelector('.form-container form');
- if (!form.checkValidity()) {
- form.reportValidity();
- return;
- }
- let data = this.uiRenderer.parseContainer(form);
- $(modal).modal('hide');
- }
- }
-
- renderFields(values) {
- let fieldsHtml = '';
- values.forEach( field => {
- field.text = field.text || field.name.charAt(0).toUpperCase() + field.name.slice(1).toLowerCase().replaceAll('_', ' ');
-
- switch (field.type) {
- case 'credentials_or_autofilled': // TODO: will need to condition username/email/password!
- break;
- case 'email':
- fieldsHtml += uiRenderer.addInputEmailHtml(field);
- break;
- case 'password':
- fieldsHtml += uiRenderer.addInputPasswordHtml(field);
- break;
- case 'checkbox':
- field.value = (field.value === true || field.value === 'true' || field.value === 1 || field.value === "1") ? true : false;
- fieldsHtml += uiRenderer.addSliderHtml(field);
- break;
- case 'numberInput':
- fieldsHtml += uiRenderer.addInputNumberHtml(field);
- break;
- case 'textInput':
- case 'username':
- field.required = 'true';
- default:
- fieldsHtml += uiRenderer.addInputTextHtml(field);
- break;
- }
- });
- const modalSiteParameters = document.getElementById('modal-site-parameters');
- modalSiteParameters.querySelector('.form-container form').innerHTML = fieldsHtml;
- }
-
- renderEditSiteParameters(args) { // { site_id: 'x' }
- const site = Site.getById(args.site_id);
-
- const siteParameters = site.getSiteParameters(); // async? for external site parameters that need to be loaded from other stg...
-
- if (!siteParameters) {
- console.warn(`Site ${site.id} ${site.name} does not require parameters setup.`);
- return;
- }
-
- if (!siteParameters.handler) {
- console.warn(`Handler name is missing`);
- return;
- }
-
- const handlerClass = UiSiteParameterRenderer.getHandler(siteParameters.handler);
- if (!handlerClass) {
- console.warn(`Invalid handler class name: ${siteParameters.handler}`);
- return;
- }
-
- const handler = new handlerClass(siteParameters.values);
- handler.preRender();
-
- let fields = [
- { name: 'AUTO_UPDATE_PROMO_CODES', type: 'checkbox', value: 'false' },
- { name: 'MAX_ROLLS_PER_VISIT', type: 'numberInput', value: 1, min: 0 },
- { name: 'AUTO_LOGIN', type: 'checkbox', value: 'true' },
- { name: 'EMAIL', type: 'email', value: '' },
- { name: 'PASSWORD', type: 'password', value: '' }
- ];
-
- fields.forEach( (f, idx) => {
- if (f.order == null || f.order == undefined) {
- f.order = idx;
- }
- });
-
- let values = persistence.load(`site_parameters_${args.site_id}`, true) || [];
- for(const field of fields) {
- let vIdx = values.findIndex(v => v.name == field.name);
- if (vIdx > -1) {
- field.value = values[vIdx].value;
- }
- }
- values = fields;
-
- this.renderFields(values);
-
- handler.postRender();
- return;
- }
-
- }
-
- class UiRenderer {
- constructor () {
- this.sites = new UiSitesRenderer(this);
- this.siteParameters = new UiSiteParameterRenderer(this);
- this.promos = new UiPromosRenderer(this);
- this.config = new UiConfigRenderer(this);
- this.wallet = new UiWalletRenderer(this);
- this.schedules = new UiSchedulesRenderer(this);
- this.selectedSchedule = null;
- }
-
- initialize() {
- this.appendCSS();
- }
-
- toast(msg, msgType = "info") {
- toastr[msgType](msg);
- }
-
- openModal(id, values = null) {
- const dlg = document.querySelector('#modal-dlg');
- dlg.querySelectorAll(".modal-content").forEach(x => x.classList.add('d-none'));
- switch (id) {
- case 'modal-backup':
- console.info('TODO: GM_listValues => loop keys => save json as blob');
- break;
-
- case 'modal-ereport':
- case 'modal-config':
- case 'modal-site':
- document.getElementById("target-spinner").innerHTML = JSON.stringify({id: id, siteId: values});
- document.getElementById("modal-spinner").classList.remove("d-none");
- dlg.querySelector('div').classList.add('modal-lg');
- break;
- case 'modal-add-site':
- this.sites.renderAddExternalSite();
- document.getElementById(id).classList.remove("d-none");
- dlg.querySelector('div').classList.remove('modal-lg');
- break;
- case 'modal-slAlert':
- shortlinkAlert.load(id);
- dlg.querySelector('div').classList.add('modal-lg');
- break;
- case 'modal-schedules':
- document.getElementById(id).querySelector('table tbody').innerHTML = this.schedules.renderTBody();
- this.appendColorPickers('.color-picker');
- dlg.querySelector('div').classList.remove('modal-lg');
- document.getElementById(id).classList.remove("d-none");
- break;
- case 'modal-assign-schedule':
- this.sites.renderAssignScheduleToSite(values);
- document.getElementById(id).classList.remove("d-none");
- dlg.querySelector('div').classList.remove('modal-lg');
- break;
- case 'modal-site-parameters':
- this.siteParameters.renderEditSiteParameters(values);
- document.getElementById(id).classList.remove("d-none");
- dlg.querySelector('div').classList.remove('modal-lg');
- break;
- default:
- dlg.querySelector('div').classList.add('modal-lg');
- document.getElementById(id).classList.remove("d-none");
- break;
- }
-
- $(dlg).modal('show');
- }
-
- appendEventListeners() {
- for (const renderer in this) {
- if (this[renderer] && typeof this[renderer].appendEventListeners === 'function') {
- this[renderer].appendEventListeners();
- }
- }
- $('[data-toggle="tooltip"]').tooltip({
- trigger: 'hover'
- });
- }
-
- appendCSS() {
- let css = document.createElement('style');
- css.innerHTML = `
- td.em-input {
- padding-top: 0;
- padding-bottom: 0;
- }
- pre {
- height: 145px;
- width:100%;
- white-space: pre-wrap;
- padding-left: 1em;
- }
- pre span {
- display: block;
- }
- .row-schedule-handle {
-
- }
- .grabbable:not(.d-none):not(.in-use) {
- cursor: move;
- cursor: grab;
- cursor: -moz-grab;
- cursor: -webkit-grab;
- }
-
- .grabbable:not(.d-none):not(.in-use):active {
- cursor: grabbing;
- cursor: -moz-grabbing;
- cursor: -webkit-grabbing;
- }
-
- .row-handle {
- cursor: grab;
- }
-
- .dropdown-item {
- cursor: pointer;
- }
-
- #schedule-table th,td {
- vertical-align: middle;
- padding-top: .25rem!important;
- padding-bottom: .25rem!important;
- }
-
- #schedule-table-body td.em-input input[readonly] {
- background-color:transparent;
- border: 0;
- font-size: 1em;
- }
-
- td[data-field="displayName"] .input-group-prepend .input-group-text {
- background-color: transparent;
- border-color: transparent;
- font-size: 1em;
- }
-
- .custom-switch input,label {
- cursor: pointer;
- }
- `;
- document.head.appendChild(css);
- }
-
- addLegacySliderHtml(propName, propValue, text) {
- return `<label class="switch"><input type="checkbox" ${propName}="${propValue}" data-original="1"><span class="slider round"></span></label> ${text}`;
- }
-
- addSliderHtml(field) {
- const rndStr = helpers.randomString(8);
- return `<div class="form-group"><div class="custom-control custom-switch custom-switch-off-danger custom-switch-on-success">
- <input type="checkbox" class="custom-control-input" name="${field.name}" id="${rndStr}" ${field.value ? 'checked' : ''}>
- <label class="custom-control-label" for="${rndStr}">${field.text}</label>
- </div></div>`;
- }
-
- addInputEmailHtml(field) {
- const rndStr = helpers.randomString(8);
- const pattern = "[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,3}$";
- return `<div class="form-group row"><label for="${rndStr}" class="col-sm-4 col-form-label">${field.text}</label>
- <div class="col-sm-8">
- <input type="email" class="form-control" required id="${rndStr}" placeholder="${field.placeholder || ' '}" name="${field.name}" pattern="${pattern}" value="${field.value || ''}">
- </div></div>`;
-
- }
-
- addInputPasswordHtml(field) {
- const rndStr = helpers.randomString(8);
- return `<div class="form-group row"><label for="${rndStr}" class="col-sm-4 col-form-label">${field.text}</label>
- <div class="col-sm-8">
- <input type="password" min="${field.min !== undefined ? field.min : ''}" min="${field.max !== undefined ? field.max : ''}" class="form-control" required id="${rndStr}" placeholder="${field.placeholder || ' '}" name="${field.name}" value="${field.value || ''}">
- </div></div>`;
- }
-
- addInputTextHtml(field) {
- const rndStr = helpers.randomString(8);
- return `<div class="form-group row"><label for="${rndStr}" class="col-sm-4 col-form-label">${field.text}</label>
- <div class="col-sm-8">
- <input type="text" class="form-control" required="${field.required || 'false'}" id="${rndStr}" placeholder="${field.placeholder || ' '}" name="${field.name}" value="${field.value || ''}">
- </div></div>`;
- }
-
- addInputNumberHtml(field) {
- const rndStr = helpers.randomString(8);
- return `<div class="form-group row"><label for="${rndStr}" class="col-sm-4 col-form-label">${field.text}</label>
- <div class="col-sm-8">
- <input type="number" step="${field.step || 1}" class="form-control" required id="${rndStr}" placeholder="${field.placeholder || ' '}" name="${field.name}" value="${field.value || ''}">
- </div></div>`;
- }
-
- parseContainer(container) {
- let obj = {};
- Object.assign(obj, container.dataset);
- let inputs = container.querySelectorAll('input, select');
- inputs.forEach(function (input) {
- if (input.type == 'checkbox') {
- obj[input.name] = input.checked ? 'true' : 'false';
- } else if (input.type == 'number') {
- obj[input.name] = +input.value;
- } else {
- obj[input.name] = input.value;
- }
- });
-
- for (const p in obj) { // type converter. TODO: add int, float, etc.
- if (obj[p] === 'true') { obj[p] = true }
- if (obj[p] === 'false') { obj[p] = false }
-
- if (p == 'uuid') {
- obj[p] = obj[p].toLowerCase().replace('#', '');
- }
- if (p == 'originals') {
- try {
- obj[p] = JSON.parse(obj[p]);
- } catch (err) { delete obj[p]; }
- }
- }
- return obj;
- }
-
- parseTable(table) {
- let rows = table.querySelectorAll('tbody tr');
- let data = [];
- rows.forEach( (r, idx) => {
- let obj = this.parseContainer(r);
- obj.order = '' + idx; // fix order
- if (!(obj.added && obj.removed)) { // skip if it was just added and removed
- data.push(obj);
- }
- });
-
- return data;
- }
-
- appendColorPickers(selector) {
- $(selector).each(function () {
- $(this).colorpicker();
- $(this).on('colorpickerChange', function(event) {
- $(event.target.querySelector('.fa-square')).css('color', event.color.toString());
- });
- });
- }
- }
-
- class EventEmitter {
- constructor() {
- this.events = {};
- }
-
- on(eventName, callback) {
- if (!this.events[eventName]) {
- this.events[eventName] = [];
- }
- this.events[eventName].push(callback);
- }
-
- emit(eventName, data) {
- const eventCallbacks = this.events[eventName];
- if (eventCallbacks) {
- eventCallbacks.forEach(callback => {
- callback(data);
- });
- }
- }
- }
-
- class Timeout {
- constructor() {
- this.startedAt;
- this.interval;
- this.cb = (() => { shared.closeWithError(K.ErrorType.TIMEOUT, '') });
- let paramTimeout = shared.getParam('timeout');
- if (paramTimeout) {
- this.wait = paramTimeout * 60;
- } else {
- this.wait = shared.getConfig()['defaults.timeout'] * 60
- }
- this.wait += 30; // add a threshold
- this.restart();
- }
-
- get elapsed() {
- return Date.now() - this.startedAt;
- }
-
- restart(addSeconds = false) {
- if(this.interval) {
- clearTimeout(this.interval);
- }
- this.startedAt = Date.now();
- if(addSeconds) {
- this.wait = this.wait + addSeconds;
- }
- this.interval = setTimeout( () => { this.cb() }, this.wait * 1000);
- }
- }
-
- class Timer {
- constructor(params) {
- Object.assign(this, params);
- if(!useTimer || (this.webType && !Timer.webTypes().includes(this.webType))) {
- return;
- }
- this.delay = this.delaySeconds * 1000;
-
- }
-
- static webTypes() {
- return [K.WebType.FREELITECOIN, K.WebType.FREEETHEREUMIO, K.WebType.BIGBTC, K.WebType.FCRYPTO, K.WebType.FPB] // , K.WebType.BSCADS]
- };
-
- startCheck(webType) {
- this.webType = webType;
- if(!useTimer || (helpers.hasValue(webType) && !Timer.webTypes().includes(webType))) {
- return;
- }
- persistence.save(this.uuid + '_lastAccess', Date.now());
- this.interval = setInterval(() => {
- this.isAlive();
- }, this.delay);
- }
-
- stopCheck() {
- if(!useTimer) {
- return;
- }
- clearInterval(this.interval);
- }
-
- tick() {
- if(!useTimer) {
- return;
- }
- persistence.save(this.uuid + '_lastAccess', Date.now());
- }
-
- isAlive() {
- return;
- }
- }
-
- const wait = ms => new Promise(resolve => setTimeout(resolve, ms || 3000));
-
- class CrawlerWidget {
- constructor(params) {
- if (!params || (!params.selector && !params.fnSelector)) {
- throw new Error('CrawlerWidget requires a selector or a function selector parameter');
- }
- this.context = this.context || document;
- Object.assign(this, params);
- }
-
- get isUserFriendly() {
- if (this.selector) {
- this.element = this.context.isUserFriendly(this.selector);
- return this.element;
- } else {
- this.element = this.fnSelector();
- return this.element;
- }
- }
- }
-
- class ReadableWidget extends CrawlerWidget {
- constructor(params) {
- if (params && !params.parser) {
- params.parser = Parsers.innerText; //default parser
- }
- super(params);
- }
-
- get value() {
- if (this.isUserFriendly) {
- return this.parser(this.element, this.options);
- } else {
- return '';
- }
- }
- }
-
- class TextboxWidget extends CrawlerWidget {
- get value() {
- if (!this.isUserFriendly) {
- return '';
- }
- return this.element.value;
- }
-
- set value(newValue) {
- if (!this.isUserFriendly) {
- return '';
- }
- this.element.value = newValue;
- return '';
- }
- }
-
- class ButtonWidget extends CrawlerWidget {
-
- click() {
- if (this.isUserFriendly) {
- this.element.click();
- return Promise.resolve(true);
- } else {
- }
- }
- }
-
- class SubmitWidget extends CrawlerWidget {
- click() {
- if (this.isUserFriendly) {
- let frm = this.element;
- while(frm.nodeName != 'FORM' && frm.nodeName != null) {
- frm = frm.parentElement;
- }
- if (frm.nodeName == 'FORM') {
- frm.submit();
- } else {
- return;
- }
- return Promise.resolve(true);
- } else {
- }
- }
- }
-
- class CountdownWidget extends CrawlerWidget {
- constructor(params) {
- if (params && !params.parser) {
- params.parser = Parsers.innerText; //default parser
- }
- super(params);
- }
-
- get timeLeft() {
- if (this.isUserFriendly) {
- return this.parser(this.element, this.options);
- } else {
- throw new Error(`CountdownWidget (selector: '${this.selector}') cannot be read`);
- }
- }
- }
-
- class Parsers {
- static innerText(elm) { // '0.12341234' => '0.12341234'
- try {
- return elm.innerText;
- } catch (err) { }
- }
- static trimNaNs(elm) { // 'You won 0.12341234 TRX' => '0.12341234'
- try {
- return elm.innerText.replace(/[^\d.-]/g, '');
- } catch (err) { }
- }
- static splitAndIdxTrimNaNs(elm, options) { // '17.96 Coins (17.50 + 0.46)' => 17.96
- try {
- return elm.innerText.split(options.splitter)[options.idx].replace(/[^\d.-]/g, '');
- } catch (err) { }
- }
- static innerTextIntToFloat(elm) { // 'You won 1234 satoshis' => 0.00001234
- try {
- let sats = elm.innerText.replace(/\D/g, '');
- return sats / 100000000;
- } catch (err) { }
- }
- static innerTextJoinedToInt(elm) { // '7|2|9|6' => 7296
- try {
- return parseInt([... elm].map( x => x.innerText).join(''));
- } catch (err) { }
- }
- static stormGainCountdown(elm) { // '3:01:01' => 120000
- try {
- let timeLeft = elm.innerText.split(':');
- if (timeLeft[0] == 'Synchronizing') {
- }
-
- if(timeLeft.length === 3) {
- return parseInt(timeLeft[0]) * 60 + parseInt(timeLeft[1]);
- }
- } catch (err) {
- return null;
- }
- }
- static kingBizCountdown(elm) { // '4|2' => 42
- try {
- let itms = elm.querySelectorAll('.flip-clock-active .up');
- if (itms.length > 1 && itms[0].isVisible() && itms[1].isVisible()) {
- return parseInt([itms[0].innerText, itms[1].innerText].join(''));
- }
- } catch (err) {
- return null;
- }
- }
- static freeGrcCountdown(elm) { // 'Wait for 53:31 before next roll' => 53
- try {
- let val = elm.innerText.split(':')[0];
- val = val.replace(/[^\d.-]/g, '');
- return parseInt(val);
- } catch (err) {
- return null;
- }
- }
- static bestChangeCountdown(elm) { // '00:58:35' => 58
- try {
- if (elm.value) {
- let timeLeft = elm.value.split(':');
- if (timeLeft.length > 1) {
- return parseInt(timeLeft[1]);
- }
- }
- } catch (err) {
- return null;
- }
- }
- static freeEthereumIoClaimed(elm) { // 'You won 0.12341234 TRX and rolled number 7623' => 0.12341234
- try {
- let line = elm.innerHTML;
- let idx = line.search(/0\./);
- return parseFloat(line.slice(idx, idx + 10));
- } catch (err) { }
- }
- static bfBoxClaimed(elm) {
- try {
- let currency = elm.querySelector('.free-box__withdraw-currency').innerText;
- let val = elm.querySelector('.free-box__need-sum').innerText.replace(/ /g,'').split('/')[1];
-
- if (currency == 'Satoshi') {
- val = val/100000000;
- }
- return val;
- } catch (err) {
- return null;
- }
- }
- static g8ClaimsLeft(elm) {
- try {
- if (elm.innerText.includes('\nYou have ')) { // 'Claim 183848 satoshi (0.00012 USD) every 20 Seconds\nYou have 70 claims left today.'
- let val = elm.innerText.split('\nYou have ')[1].split(' ')[0];
- return val;
- } else {
- return null;
- }
- } catch (err) {
- return null;
- }
- }
- static cbgClaimed(elm) {
- try {
- if (elm.innerText.includes('was sent to')) { //?? was sent to you on...
- let val = elm.innerText.trim().split(' ')[0];
- if (elm.innerText.includes('oshi') || elm.innerText.includes('gwei')) {
- val = val/100000000;
- }
- return val;
- } else {
- return null;
- }
- } catch (err) {
- return null;
- }
- }
- static dutchysClaimed(elm) { // 'You Won :101 DUTCHY + 20 XP' => 101
- try {
- let splitted = elm.innerText.split('DUTCHY');
- return splitted[0].replace(/[^\d.-]/g, '');
- } catch (err) { shared.devlog(`@Parsers.dutchysClaimed, with element [${elm}] Error: ${err}`); }
- }
- static dutchysClaimedToFloat(elm) { // 'You Won :22437 ADA + 100 XP' => 0.00022437
- try {
- let sats = elm.innerText.split('+');
- sats = sats[0].replace(/\D/g, '');
- return sats / 100000000;
- } catch (err) { shared.devlog(`@Parsers.dutchysClaimedToFloat, with element [${elm}] Error: ${err}`); }
- }
- static splitAndIdxToInt(elm, options) { // options: { splitter: ':', idx: 1} // '26 Minutes 23' w/spliiter='Minutes' => 26
- try {
- return parseInt(elm.innerText.split(options.splitter)[options.idx].trim());
- } catch (err) { shared.devlog(`Error @Parsers.splitAndIdxToInt: ${err}`); }
- }
- static fromTextTimer(elm) { // '0 hours 11 minutes 1 seconds' => 12 minutes
- try {
- let hours, minutes;
- hours = +elm.innerText.split(' hours')[0].trim();
- minutes = +elm.innerText.split('hours ')[1].split('minutes')[0].trim();
- return hours * 60 + minutes + 1;
- } catch (err) { shared.devlog(`Error @Parsers.splitAndIdxToInt: ${err}`); }
- }
- }
- class ImageProcessor {
- constructor(img) {
- this._img = img;
- }
-
- isImageComplete() {
- return this._img && this._img.complete;
- }
-
- createDrawer(width, height) {
- let canvas = document.createElement('canvas');
- canvas.setAttribute('width', width);
- canvas.setAttribute('height', height);
- let ctx = canvas.getContext('2d');
- return {
- canvas: canvas,
- ctx: ctx
- };
- }
-
- getDrawer() {
- return this._drawer;
- }
-
- toCanvas() {
- this._drawer = this.createDrawer(this._img.width, this._img.height);
- this._drawer.ctx.drawImage(this._img, 0, 0);
- }
-
- foreach(filter) {
- let imgData = this._drawer.ctx.getImageData(0, 0, this._drawer.canvas.width, this._drawer.canvas.height);
- for (var x = 0; x < imgData.width; x++) {
- for (var y = 0; y < imgData.height; y++) {
- var i = x * 4 + y * 4 * imgData.width;
- var pixel = { r: imgData.data[i + 0], g: imgData.data[i + 1], b: imgData.data[i + 2] };
-
- pixel = filter(pixel);
-
- imgData.data[i + 0] = pixel.r;
- imgData.data[i + 1] = pixel.g;
- imgData.data[i + 2] = pixel.b;
- imgData.data[i + 3] = 255;
- }
- }
- this._drawer.ctx.putImageData(imgData, 0, 0);
- }
-
- binarize (threshold) {
- var image = this._drawer.canvas.getContext('2d').getImageData(0, 0, this._drawer.canvas.width, this._drawer.canvas.height);
- for (var x = 0; x < image.width; x++) {
- for (var y = 0; y < image.height; y++) {
- var i = x * 4 + y * 4 * image.width;
- var brightness = 0.34 * image.data[i] + 0.5 * image.data[i + 1] + 0.16 * image.data[i + 2];
- image.data[i] = brightness >= threshold ? 255 : 0;
- image.data[i + 1] = brightness >= threshold ? 255 : 0;
- image.data[i + 2] = brightness >= threshold ? 255 : 0;
- image.data[i + 3] = 255;
- }
- }
- this._drawer.canvas.getContext('2d').putImageData(image, 0, 0);
- }
-
- invert(filter) {
- this.foreach(function (p) {
- p.r = 255 - p.r;
- p.g = 255 - p.g;
- p.b = 255 - p.b;
- return p;
- });
- }
-
- imgDataToBool(imgData) {
- let character = [];
- const data = imgData.data;
- for (let i = 0; i < imgData.data.length; i += 4) {
- let val = data[i] + data[i+1] + data[i+2];
- character.push(val == 0 ? true : false);
- }
- return character;
- }
- }
-
- class CaptchaWidget extends CrawlerWidget {
- constructor(params) {
- super(params);
- }
-
- solve() { return true; }
-
- async isSolved() { return false; }
- }
-
- class RecaptchaWidget extends CaptchaWidget {
- constructor(params) {
- let defaultParams = {
- selector: function() { return grecaptcha },
- waitMs: [1000, 5000],
- timeoutMs: 4 * 60 * 1000
- };
- for (let p in params) {
- defaultParams[p] = params[p];
- }
- super(defaultParams);
- }
-
- get isUserFriendly() {
- this.element = grecaptcha;
- return this.element;
- }
-
- async isSolved() {
- return wait().then( () => {
- try {
- if (this.isUserFriendly && this.element.hasOwnProperty('getPageId') && this.element.getPageId() && this.element.hasOwnProperty('getResponse') && (typeof(this.element.getResponse) == 'function')
- && this.element.getResponse().length > 0) {
- return Promise.resolve(true);
- }
- } catch (err) {}
- return this.isSolved();
- });
- }
- }
-
- class HCaptchaWidget extends CaptchaWidget {
- constructor(params) {
- let defaultParams = {
- selector: '.h-captcha > iframe',
- waitMs: [1000, 5000],
- timeoutMs: 4 * 60 * 1000
- };
- for (let p in params) {
- defaultParams[p] = params[p];
- }
- super(defaultParams);
- }
-
- async isSolved() {
- return wait().then( () => {
- if (this.isUserFriendly && this.element.hasAttribute('data-hcaptcha-response') && this.element.getAttribute('data-hcaptcha-response').length > 0) {
- return Promise.resolve(true);
- }
- return this.isSolved();
- });
- }
- }
-
- class BKCaptchaWidget extends CaptchaWidget {
- constructor() {
- let defaultParams = {
- selector: 'img[src="antibot.php"]',
- waitMs: [1000, 5000],
- timeoutMs: 4 * 60 * 1000
- };
- super(defaultParams);
- this._imgProcessor;
- this._characters = [];
- }
-
- charList() {
- return [{"answer":"g","width":8,"height":9,"bools":[false,true,true,true,true,true,false,true,true,true,false,false,false,true,true,true,true,true,false,false,false,true,true,false,true,true,false,false,false,true,true,false,false,true,true,true,true,true,false,false,true,true,false,false,false,false,false,false,false,true,true,true,true,true,true,false,true,true,false,false,false,false,true,true,false,true,true,true,true,true,true,false]},
- {"answer":"5","width":8,"height":10,"bools":[true,true,true,true,true,true,true,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,true,true,true,false,false,true,true,true,false,false,true,true,false,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,true,true,false,false,false,false,true,true,false,true,true,false,false,true,true,false,false,false,true,true,true,true,false,false]},
- {"answer":"W","width":8,"height":10,"bools":[true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,true,true,false,true,true,true,true,false,true,true,false,true,true,true,true,false,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false,true,true,true,true,true,false,false,false,false,true,true]},
- {"answer":"O","width":8,"height":10,"bools":[false,false,true,true,true,true,false,false,false,true,true,false,false,true,true,false,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,false,true,true,false,false,true,true,false,false,false,true,true,true,true,false,false]},
- {"answer":"N","width":8,"height":10,"bools":[true,true,false,false,false,false,true,true,true,true,true,false,false,false,true,true,true,true,true,true,false,false,true,true,true,true,true,true,false,false,true,true,true,true,false,true,true,false,true,true,true,true,false,true,true,false,true,true,true,true,false,false,true,true,true,true,true,true,false,false,false,true,true,true,true,true,false,false,false,true,true,true,true,true,false,false,false,false,true,true]},
- {"answer":"T","width":8,"height":10,"bools":[true,true,true,true,true,true,true,true,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false]},
- {"answer":"q","width":8,"height":9,"bools":[false,false,true,true,true,false,true,true,false,true,true,false,false,true,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,false,true,true,false,false,true,true,true,false,false,true,true,true,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true]},
- {"answer":"l","width":4,"height":10,"bools":[true,true,true,false,false,true,true,false,false,true,true,false,false,true,true,false,false,true,true,false,false,true,true,false,false,true,true,false,false,true,true,false,false,true,true,false,true,true,true,true]},
- {"answer":"B","width":8,"height":10,"bools":[true,true,true,true,true,true,false,false,true,true,false,false,false,true,true,false,true,true,false,false,false,false,true,true,true,true,false,false,false,true,true,false,true,true,true,true,true,true,false,false,true,true,false,false,false,true,true,false,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,true,true,false,true,true,true,true,true,true,false,false]},
- {"answer":"3","width":8,"height":10,"bools":[false,false,true,true,true,true,false,false,true,true,false,false,false,true,true,false,false,false,false,false,false,false,true,true,false,false,false,false,false,true,true,false,false,false,false,true,true,true,false,false,false,false,false,false,false,true,true,false,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,true,true,false,false,false,true,true,false,false,true,true,true,true,true,false,false]},
- {"answer":"s","width":8,"height":7,"bools":[false,true,true,true,true,true,true,false,true,true,false,false,false,false,true,true,true,true,false,false,false,false,false,false,false,true,true,true,true,true,true,false,false,false,false,false,false,false,true,true,true,true,false,false,false,false,true,true,false,true,true,true,true,true,true,false]},
- {"answer":"p","width":8,"height":9,"bools":[true,true,false,true,true,true,false,false,true,true,true,false,false,true,true,false,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,true,false,false,true,true,false,true,true,false,true,true,true,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false]},
- {"answer":"L","width":7,"height":10,"bools":[true,true,false,false,false,false,false,true,true,false,false,false,false,false,true,true,false,false,false,false,false,true,true,false,false,false,false,false,true,true,false,false,false,false,false,true,true,false,false,false,false,false,true,true,false,false,false,false,false,true,true,false,false,false,false,false,true,true,false,false,false,false,false,true,true,true,true,true,true,true]},
- {"answer":"Z","width":7,"height":10,"bools":[false,true,true,true,true,true,true,false,false,false,false,false,true,true,false,false,false,false,false,true,true,false,false,false,false,true,true,false,false,false,false,true,true,false,false,false,false,true,true,false,false,false,false,true,true,false,false,false,false,true,true,false,false,false,false,false,true,true,false,false,false,false,false,true,true,true,true,true,true,true]},
- {"answer":"F","width":8,"height":10,"bools":[true,true,true,true,true,true,true,true,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,true,true,true,true,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false]},
- {"answer":"p","width":8,"height":9,"bools":[true,true,false,true,true,true,false,false,true,true,true,false,false,true,true,false,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,true,false,false,true,true,false,true,true,false,true,true,true,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false]},
- {"answer":"T","width":8,"height":10,"bools":[true,true,true,true,true,true,true,true,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false]},
- {"answer":"8","width":8,"height":10,"bools":[false,false,true,true,true,true,false,false,false,true,true,false,false,true,true,false,true,true,false,false,false,false,true,true,false,true,true,false,false,true,true,false,false,false,true,true,true,true,false,false,false,true,true,false,false,true,true,false,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,false,true,true,false,false,true,true,false,false,false,true,true,true,true,false,false]},
- {"answer":"P","width":8,"height":10,"bools":[true,true,true,true,true,true,true,false,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,true,true,true,true,true,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false]},
- {"answer":"J","width":6,"height":10,"bools":[false,false,true,true,true,true,false,false,false,false,true,true,false,false,false,false,true,true,false,false,false,false,true,true,false,false,false,false,true,true,false,false,false,false,true,true,false,false,false,false,true,true,true,false,false,false,true,true,true,true,false,true,true,false,false,true,true,true,false,false]},
- {"answer":"y","width":8,"height":9,"bools":[true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,false,true,true,false,false,true,true,true,false,false,true,true,true,false,true,true,true,false,false,false,false,false,true,true,false,true,true,true,true,true,true,false]},
- {"answer":"r","width":8,"height":7,"bools":[false,false,true,true,true,true,false,false,false,true,true,false,false,true,true,false,true,true,false,false,false,false,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,false,false,false,false,true,true,false,false,false,true,true,false,false,true,true,true,true,true,false]},
- {"answer":"R","width":8,"height":10,"bools":[true,true,true,true,true,true,true,false,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,false,false,false,true,true,false,false,true,true,false,false,true,true,false,false,false,true,true,false,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true]},
- {"answer":"M","width":8,"height":10,"bools":[true,true,false,false,false,false,true,true,true,true,true,false,false,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,false,true,true,true,true,false,true,true,false,true,true,true,true,false,true,true,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true]},
- {"answer":"d","width":8,"height":10,"bools":[false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,true,true,true,false,true,true,false,true,true,false,false,true,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,false,true,true,false,false,true,true,true,false,false,true,true,true,false,true,true]},
- {"answer":"E","width":7,"height":10,"bools":[true,true,true,true,true,true,true,true,true,false,false,false,false,false,true,true,false,false,false,false,false,true,true,false,false,false,false,false,true,true,true,true,true,true,false,true,true,false,false,false,false,false,true,true,false,false,false,false,false,true,true,false,false,false,false,false,true,true,false,false,false,false,false,true,true,true,true,true,true,true]},
- {"answer":"7","width":8,"height":10,"bools":[true,true,true,true,true,true,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,true,true,false,false,false,false,false,true,true,false,false,false,false,false,true,true,false,false,false,false,false,true,true,false,false,false,false,false,true,true,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false]},
- {"answer":"Z","width":7,"height":10,"bools":[true,true,true,true,true,true,true,false,false,false,false,false,true,true,false,false,false,false,false,true,true,false,false,false,false,true,true,false,false,false,false,true,true,false,false,false,false,true,true,false,false,false,false,true,true,false,false,false,false,true,true,false,false,false,false,false,true,true,false,false,false,false,false,true,true,true,true,true,true,true]},
- {"answer":"l","width":4,"height":10,"bools":[true,true,true,false,false,true,true,false,false,true,true,false,false,true,true,false,false,true,true,false,false,true,true,false,false,true,true,false,false,true,true,false,false,true,true,false,true,true,true,true]},
- {"answer":"K","width":8,"height":10,"bools":[true,true,false,false,false,false,true,true,true,true,false,false,false,true,true,false,true,true,false,false,true,true,false,false,true,true,false,true,true,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,false,true,true,false,false,false,true,true,false,false,true,true,false,false,true,true,false,false,false,true,true,false,true,true,false,false,false,false,true,true]},
- {"answer":"6","width":8,"height":10,"bools":[false,false,true,true,true,true,false,false,false,true,true,false,false,true,true,false,true,true,false,false,false,false,true,false,true,true,false,false,false,false,false,false,true,true,false,true,true,true,false,false,true,true,true,false,false,true,true,false,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,false,true,true,false,false,true,false,false,false,false,true,true,true,true,false,false]},
- {"answer":"H","width":8,"height":10,"bools":[true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true]},
- {"answer":"5","width":8,"height":10,"bools":[true,true,true,true,true,true,true,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,true,true,true,false,false,true,true,true,false,false,true,true,false,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,true,true,false,false,false,false,true,true,false,true,true,false,false,true,true,false,false,false,true,true,true,true,false,false]},
- {"answer":"Y","width":8,"height":10,"bools":[true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,false,true,true,false,false,true,true,false,false,false,true,true,true,true,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false]},
- {"answer":"d","width":8,"height":10,"bools":[false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,true,true,true,false,true,true,false,true,true,false,false,true,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,false,true,true,false,false,true,true,true,false,false,true,true,true,false,true,true]},
- {"answer":"p","width":8,"height":9,"bools":[true,true,false,true,true,true,false,false,true,true,true,false,false,true,true,false,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,true,false,false,true,true,false,true,true,false,true,true,true,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false]},
- {"answer":"z","width":6,"height":7,"bools":[true,true,true,true,true,true,false,false,false,false,true,true,false,false,false,true,true,false,false,false,true,true,false,false,false,true,true,false,false,false,true,true,false,false,false,false,true,true,true,true,true,true]},
- {"answer":"n","width":8,"height":7,"bools":[true,true,false,true,true,true,false,false,true,true,true,false,false,true,true,false,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true]},
- {"answer":"a","width":8,"height":7,"bools":[false,false,true,true,true,true,true,false,false,true,true,false,false,false,true,true,false,false,false,false,false,false,true,true,false,true,true,true,true,true,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,true,true,true,false,true,true,true,true,false,true,true]},
- {"answer":"8","width":8,"height":10,"bools":[false,false,true,true,true,true,false,false,false,true,true,false,false,true,true,false,true,true,false,false,false,false,true,true,false,true,true,false,false,true,true,false,false,false,true,true,true,true,false,false,false,true,true,false,false,true,true,false,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,false,true,true,false,false,true,true,false,false,false,true,true,true,true,false,false]},
- {"answer":"t","width":8,"height":9,"bools":[false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,true,true,true,true,true,true,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,true,true,false,false,false,true,true,true,true,false]},
- {"answer":"q","width":8,"height":9,"bools":[false,false,true,true,true,false,true,true,false,true,true,false,false,true,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,false,true,true,false,false,true,true,true,false,false,true,true,true,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true]},
- {"answer":"a","width":8,"height":7,"bools":[false,false,true,true,true,true,true,false,false,true,true,false,false,false,true,true,false,false,false,false,false,false,true,true,false,true,true,true,true,true,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,true,true,true,false,true,true,true,true,false,true,true]},
- {"answer":"Z","width":7,"height":10,"bools":[true,true,true,true,true,true,true,false,false,false,false,false,true,true,false,false,false,false,false,true,true,false,false,false,false,true,true,false,false,false,false,true,true,false,false,false,false,true,true,false,false,false,false,true,true,false,false,false,false,true,true,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,true,true,true,true]},
- {"answer":"1","width":6,"height":10,"bools":[false,false,true,true,false,false,false,true,true,true,false,false,true,true,true,true,false,false,false,false,true,true,false,false,false,false,true,true,false,false,false,false,true,true,false,false,false,false,true,true,false,false,false,false,true,true,false,false,false,false,true,true,false,false,true,true,true,true,true,true]},
- {"answer":"m","width":8,"height":7,"bools":[true,false,true,true,false,true,true,false,true,true,false,true,true,false,true,true,true,true,false,true,true,false,true,true,true,true,false,true,true,false,true,true,true,true,false,true,true,false,true,true,true,true,false,true,true,false,true,true,true,true,false,true,true,false,true,true]},
- {"answer":"l","width":4,"height":10,"bools":[true,true,true,false,false,true,true,false,false,true,true,false,false,true,true,false,false,true,true,false,false,true,true,false,false,true,true,false,false,true,true,false,false,true,true,false,true,true,true,true]},
- {"answer":"q","width":8,"height":9,"bools":[false,false,true,true,true,false,true,true,false,true,true,false,false,true,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,false,true,true,false,false,true,true,true,false,false,true,true,true,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true]},
- {"answer":"C","width":8,"height":10,"bools":[false,false,true,true,true,true,false,false,false,true,true,false,false,false,true,true,true,true,false,false,false,false,false,true,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,true,false,true,true,false,false,false,true,true,false,false,true,true,true,true,true,false]},
- {"answer":"a","width":8,"height":7,"bools":[false,false,true,true,true,true,true,false,false,true,true,false,false,false,true,true,false,false,false,false,false,false,true,true,false,true,true,true,true,true,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,true,true,true,false,true,true,true,true,false,true,true]},
- {"answer":"2","width":8,"height":10,"bools":[false,false,true,true,true,true,false,false,false,true,true,false,false,true,true,false,true,true,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,true,true,false,false,false,false,false,true,true,false,false,false,false,false,true,true,false,false,false,false,false,true,true,false,false,false,false,false,true,true,false,false,false,false,false,true,true,true,true,true,true,true,true]},
- {"answer":"h","width":8,"height":10,"bools":[true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,true,true,true,false,false,true,true,true,false,false,true,true,false,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true]},
- {"answer":"F","width":7,"height":10,"bools":[true,true,true,true,true,true,true,true,true,false,false,false,false,false,true,true,false,false,false,false,false,true,true,false,false,false,false,false,true,true,true,true,true,true,false,true,true,false,false,false,false,false,true,true,false,false,false,false,false,true,true,false,false,false,false,false,true,true,false,false,false,false,false,true,true,false,false,false,false,false]},
- {"answer":"c","width":8,"height":7,"bools":[false,false,true,true,true,true,true,false,false,true,true,false,false,false,true,true,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,false,true,true,false,false,false,true,true,false,false,true,true,true,true,true,false]},
- {"answer":"P","width":8,"height":10,"bools":[true,true,true,true,true,true,true,false,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,true,true,true,true,true,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,false,false,false,false,false,false,false]},
- {"answer":"r","width":8,"height":7,"bools":[true,true,false,true,true,true,false,false,false,true,true,true,false,false,true,true,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false]},
- {"answer":"Y","width":8,"height":10,"bools":[true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,false,true,true,false,false,true,true,false,false,false,true,true,true,true,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false]},
- {"answer":"S","width":8,"height":10,"bools":[false,true,true,true,true,true,true,false,true,true,false,false,false,false,true,true,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,false,true,true,true,true,true,true,false,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,true,true,false,false,false,false,true,true,false,true,true,true,true,true,true,false]},
- {"answer":"u","width":8,"height":7,"bools":[true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,false,true,true,false,false,true,true,true,false,false,true,true,true,false,true,true]},
- {"answer":"M","width":8,"height":10,"bools":[true,true,false,false,false,false,true,true,true,true,true,false,false,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,false,true,true,true,true,false,true,true,false,true,true,true,true,false,true,true,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true]},
- {"answer":"S","width":8,"height":10,"bools":[false,true,true,true,true,true,true,false,true,true,false,false,false,false,true,true,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,false,true,true,true,true,true,true,false,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,true,true,false,false,false,false,true,true,false,true,true,true,true,true,true,false]},
- {"answer":"g","width":8,"height":9,"bools":[false,true,true,true,true,true,false,true,true,true,false,false,false,true,true,true,true,true,false,false,false,true,true,false,true,true,false,false,false,true,true,false,false,true,true,true,true,true,false,false,true,true,false,false,false,false,false,false,false,true,true,true,true,true,true,false,true,true,false,false,false,false,true,true,false,true,true,true,true,true,true,false]},
- {"answer":"U","width":8,"height":10,"bools":[true,true,false,false,false,false,true,true,true,true,false,false,false,false,false,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,false,true,true,false,false,true,true,false,false,false,true,true,true,true,false,false]},
- {"answer":"k","width":7,"height":10,"bools":[true,true,false,false,false,false,false,true,true,false,false,false,false,false,true,true,false,false,false,false,false,true,true,false,false,true,true,false,true,true,false,true,true,false,false,true,true,true,true,false,false,false,true,true,true,true,false,false,false,true,true,false,true,true,false,false,true,true,false,false,true,true,false,true,true,false,false,false,true,true]},
- {"answer":"4","width":8,"height":10,"bools":[false,false,false,false,false,true,true,false,false,false,false,false,true,true,true,false,false,false,false,true,true,true,true,false,false,false,true,true,false,true,true,false,false,true,true,false,false,true,true,false,true,true,false,false,false,true,true,false,true,true,true,true,true,true,true,true,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false]},
- {"answer":"A","width":8,"height":10,"bools":[false,false,false,true,true,false,false,false,false,false,true,true,true,true,false,false,false,true,true,false,false,true,true,false,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true]},
- {"answer":"b","width":8,"height":10,"bools":[true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,true,true,true,false,false,true,true,true,false,false,true,true,false,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,true,false,false,true,true,false,true,true,false,true,true,true,false,false]},
- {"answer":"I","width":6,"height":10,"bools":[true,true,true,true,true,true,false,false,true,true,false,false,false,false,true,true,false,false,false,false,true,true,false,false,false,false,true,true,false,false,false,false,true,true,false,false,false,false,true,true,false,false,false,false,true,true,false,false,false,false,true,true,false,false,true,true,true,true,true,true]},
- {"answer":"o","width":8,"height":7,"bools":[false,false,true,true,true,true,false,false,false,true,true,false,false,true,true,false,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,false,true,true,false,false,true,true,false,false,false,true,true,true,true,false,false]},
- {"answer":"i","width":6,"height":10,"bools":[false,false,true,true,false,false,false,false,true,true,false,false,false,false,false,false,false,false,false,true,true,true,false,false,false,false,true,true,false,false,false,false,true,true,false,false,false,false,true,true,false,false,false,false,true,true,false,false,false,false,true,true,false,false,true,true,true,true,true,true]},
- {"answer":"C","width":8,"height":10,"bools":[false,false,true,true,true,true,true,false,false,true,true,false,false,false,true,true,true,true,false,false,false,false,false,true,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,true,false,true,true,false,false,false,true,true,false,false,true,true,true,true,true,false]},
- {"answer":"e","width":8,"height":7,"bools":[false,false,true,true,true,true,false,false,false,true,true,false,false,true,true,false,true,true,false,false,false,false,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,false,false,false,false,true,true,false,false,false,true,true,false,false,true,true,true,true,true,false]},
- {"answer":"w","width":8,"height":7,"bools":[true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,true,true,false,true,true,true,true,false,true,true,false,true,true,true,true,false,true,true,false,true,true,true,true,true,true,true,true,true,true,false,true,true,false,false,true,true,false]},
- {"answer":"f","width":8,"height":10,"bools":[false,false,false,true,true,true,true,false,false,false,true,true,false,false,true,true,false,false,true,true,false,false,true,true,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,true,true,true,true,true,true,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false]},
- {"answer":"j","width":7,"height":12,"bools":[false,false,false,false,false,true,true,false,false,false,false,false,true,true,false,false,false,false,false,false,false,false,false,false,false,true,true,true,false,false,false,false,false,true,true,false,false,false,false,false,true,true,false,false,false,false,false,true,true,false,false,false,false,false,true,true,false,false,false,false,false,true,true,true,true,false,false,false,true,true,true,true,false,false,false,true,true,false,true,true,true,true,true,false]},
- {"answer":"F","width":6,"height":10,"bools":[true,true,true,true,true,true,true,true,false,false,false,false,true,true,false,false,false,false,true,true,false,false,false,false,true,true,true,true,true,true,true,true,false,false,false,false,true,true,false,false,false,false,true,true,false,false,false,false,true,true,false,false,false,false,true,true,false,false,false,false]},
- {"answer":"x","width":8,"height":7,"bools":[true,true,false,false,false,false,true,true,false,true,true,false,false,true,true,false,false,false,true,true,true,true,false,false,false,false,false,true,true,false,false,false,false,false,true,true,true,true,false,false,false,true,true,false,false,true,true,false,true,true,false,false,false,false,true,true]},
- {"answer":"e","width":8,"height":7,"bools":[false,false,true,true,true,true,false,false,false,true,true,false,false,true,true,false,true,true,false,false,false,false,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,false,false,false,false,true,true,false,false,false,true,true,false,false,true,true,true,true,true,false]},
- {"answer":"G","width":8,"height":10,"bools":[false,false,true,true,true,true,true,false,false,true,true,false,false,false,true,true,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,true,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,false,true,true,false,false,false,true,true,false,false,true,true,true,true,true,false]},
- {"answer":"0","width":8,"height":10,"bools":[false,false,false,true,true,false,false,false,false,false,true,true,true,true,false,false,false,true,true,false,false,true,true,false,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,false,true,true,false,false,true,true,false,false,false,true,true,true,true,false,false,false,false,false,true,true,false,false,false]},
- {"answer":"0","width":8,"height":10,"bools":[false,false,false,true,true,false,false,false,false,false,true,true,true,true,false,false,false,true,true,false,false,true,true,false,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,false,true,true,false,false,true,true,false,false,false,true,true,true,true,false,false,false,false,false,true,true,false,false,false]},
- {"answer":"D","width":8,"height":10,"bools":[true,true,true,true,true,true,false,false,true,true,false,false,false,true,true,false,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,true,true,false,true,true,true,true,true,true,false,false]},
- {"answer":"e","width":8,"height":7,"bools":[false,false,true,true,true,true,false,false,false,true,true,false,false,true,true,false,true,true,false,false,false,false,true,true,true,true,true,true,true,true,true,true,false,true,false,false,false,false,false,false,false,true,true,false,false,false,true,true,false,false,true,true,true,true,true,false]},
- {"answer":"X","width":8,"height":10,"bools":[true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,false,true,true,false,false,true,true,false,false,false,true,true,true,true,false,false,false,false,false,true,true,false,false,false,false,false,false,true,true,false,false,false,false,false,true,true,true,true,false,false,false,true,true,false,false,true,true,false,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true]},
- {"answer":"Q","width":8,"height":10,"bools":[false,false,true,true,true,true,false,false,false,true,true,false,false,true,true,false,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,false,false,false,true,true,true,true,false,true,true,false,true,true,true,true,false,false,true,true,true,true,false,true,true,false,false,true,true,false,false,false,true,true,true,true,false,true]}];
- }
-
- async isReady() {
- return wait().then( () => {
- let img = document.querySelector(this.selector);
- if(img && img.complete) {
- this._imgProcessor = new ImageProcessor(img);
- return Promise.resolve(true);
- }
- return this.isReady();
- });
- }
-
- async isSolved() {
- return this.isReady()
- .then( () => this.solve())
- .then( (solution) => {
- document.querySelector('input[name="kodecaptcha"]').value = solution;
- return Promise.resolve(true);
- })
- .catch(err => {
- return Promise.reject(`Error ${err}`);
- });
- }
-
- preProcessImage() {
- this._imgProcessor.toCanvas();
- this._imgProcessor.binarize(200);
- this._imgProcessor.invert();
- }
-
- cropCharacter(startFrom = 0) {
- let imgData = this._imgProcessor.getDrawer().ctx.getImageData(startFrom, 0, this._imgProcessor.getDrawer().canvas.width - startFrom, this._imgProcessor.getDrawer().canvas.height);
- let newBounds = { left: null, right:null, top: null, bottom: null };
- let readingCharacter = false;
- let endOfCharacter = null;
-
- for (var x = 0; x < imgData.width; x++) {
- if (endOfCharacter) {
- newBounds.right = endOfCharacter;
- break;
- }
-
- let isColumnEmpty = true;
- for (var y = 0; y < imgData.height; y++) {
- var i = x * 4 + y * 4 * imgData.width;
- var pixel = { r: imgData.data[i + 0], g: imgData.data[i + 1], b: imgData.data[i + 2] };
-
- if (pixel.r + pixel.g + pixel.b == 0) {
- if (newBounds.left == null || newBounds.left > x) {
- newBounds.left = x;
- }
- if (newBounds.right == null || newBounds.right < x) {
- newBounds.right = x;
- }
-
- if (newBounds.top == null || newBounds.top > y) {
- newBounds.top = y;
- }
-
- if (newBounds.bottom == null || newBounds.bottom < y) {
- newBounds.bottom = y;
- }
- readingCharacter = true;
- isColumnEmpty = false;
- }
- }
-
- if (isColumnEmpty && readingCharacter) {
- endOfCharacter = x - 1;
- break;
- }
- }
-
- return {
- x: startFrom + newBounds.left,
- y: newBounds.top,
- width: newBounds.right - newBounds.left + 1,
- height: newBounds.bottom - newBounds.top + 1,
- nextBegins: startFrom + newBounds.right + 1
- };
- }
-
- splitInCharacters() {
- let chars = [];
- let i =0;
- do {
- chars.push(this.cropCharacter( i== 0 ? 0 : chars[i-1].nextBegins ) );
- let copy = document.createElement('canvas').getContext('2d');
- copy.canvas.width = chars[i].width;
- copy.canvas.height = chars[i].height;
-
- let trimmedData = this._imgProcessor.getDrawer().ctx.getImageData(chars[i].x, chars[i].y, chars[i].width, chars[i].height);
- copy.putImageData(trimmedData, 0, 0);
-
- chars[i].bools = this._imgProcessor.imgDataToBool(trimmedData);
- chars[i].dataUrl = copy.canvas.toDataURL("image/png");
-
- i++;
- } while(i < 5);
-
- this._characters = chars;
- }
-
- guess(charElm) {
- let bestGuess = {
- answer: '',
- blacksMatched: 0,
- blacksMissed: 0,
- percentageBlacks: 0,
- exactMatch: false
- };
-
- let totalPixels = charElm.width * charElm.height;
- let totalBlacks = charElm.bools.filter(x => x === true).length;
- this.charList().filter(x => x.answer != '').forEach( function (elm) {
- if (bestGuess.exactMatch) {
- return;
- }
- if (charElm.width == elm.width && charElm.height == elm.height) {
- if (charElm.bools.join(',') == elm.bools.join(',')) {
- bestGuess = {
- answer: elm.answer,
- percentageBlacks: 100,
- exactMatch: true
- };
- return;
- }
-
- let blacksMatched = 0;
- let blacksMissed = 0;
- let percentageBlacks = 0;
- for (let p = 0; p < totalPixels; p++) {
- if (charElm.bools[p] === true || elm.bools[p] === true) {
- if (elm.bools[p] == charElm.bools[p]) {
- blacksMatched++;
- } else {
- blacksMissed++;
- }
- }
- }
-
- if (blacksMatched != 0 || blacksMissed != 0) {
- percentageBlacks = blacksMatched/(blacksMatched + blacksMissed);
- }
-
- if (percentageBlacks > bestGuess.percentageBlacks) {
- bestGuess = {
- answer: elm.answer,
- blacksMatched: blacksMatched,
- blacksMissed: blacksMissed,
- percentageBlacks: percentageBlacks
- };
- }
- }
- });
- return bestGuess;
- }
-
- async solve() {
- let solution = '';
- if(this._imgProcessor.isImageComplete()) {
- this.preProcessImage();
- this.splitInCharacters();
-
- this._characters.forEach( ch => {
- let bestGuess = this.guess(ch);
- solution += bestGuess.answer;
- });
- }
- return Promise.resolve(solution);
- }
- }
-
- class NoCaptchaWidget extends CaptchaWidget {
- constructor(params) {
- let defaultParams = {
- selector: 'svg.feather-check-circle',
- waitMs: 10000
- };
- for (let p in params) {
- defaultParams[p] = params[p];
- }
- super(defaultParams);
- }
-
- async isSolved() {
- return wait().then( () => {
- if (this.isUserFriendly) {
- return Promise.resolve(true);
- }
- return this.isSolved();
- });
- }
- }
-
- class GeeTestCaptchaWidget extends CaptchaWidget {
- constructor(params) {
- let defaultParams = {
- selector: '.geetest_captcha.geetest_lock_success,.geetest_ghost_success.geetest_success_animate',
- waitMs: 2000
- };
- for (let p in params) {
- defaultParams[p] = params[p];
- }
- super(defaultParams);
- }
-
- async isSolved() {
- return wait().then( () => {
- if (this.isUserFriendly) {
- return Promise.resolve(true);
- }
- return this.isSolved();
- });
- }
- }
-
- class CBL01CaptchaWidget extends CaptchaWidget {
- constructor(params) {
- let defaultParams = {
- selector: '',
- waitMs: 2000
- };
- for (let p in params) {
- defaultParams[p] = params[p];
- }
- super(defaultParams);
- }
-
- async isReady() {
- return wait(1).then( () => {
- if(this.isUserFriendly) {
- return Promise.resolve(true);
- }
- return wait().then( () => { this.isReady(); });
- });
- }
-
- async solve() {
- let answer = document.getElementById('captchainput').value;
- if (answer != '') {
- if (answer.startsWith('JJJ')) {
- answer = answer.slice(3);
- document.getElementById('captchainput').value = answer;
- }
-
- if (answer.length != 6) {
- document.getElementById('captchainput').value ='';
- window.location.reload();
- return wait(10000).then( () => { this.solve(); });
- } else {
- return wait().then( () => { return true; } );
- }
- } else {
- return wait().then( () => { this.solve(); });
- }
- }
-
- async isSolved() {
- return this.isReady()
- .then( () => this.solve())
- .then( (solution) => {
- return Promise.resolve(true);
- })
- .catch(err => { shared.devlog(err); })
- }
- }
-
- class D1CaptchaWidget extends CaptchaWidget {
- constructor() {
- let defaultParams = {
- selector: '#submit_captcha span',
- waitMs: [1000, 5000],
- timeoutMs: 4 * 60 * 1000
- };
- super(defaultParams);
- this.selectors = {
- submitButton: '#submit',
- answerSpan: '#submit_captcha span'
- }
- this._elements = {
- submitButton: new ButtonWidget({selector: '#submit'}),
- answerSpan: new ReadableWidget({selector: '#submit_captcha span'})
- };
- }
-
- async isReady() {
- return wait().then( () => {
- if(this._elements.submitButton.isUserFriendly) {
- return Promise.resolve(true);
- }
- return this.isReady();
- });
- }
-
- async solve() {
- if (this._elements.answerSpan.isUserFriendly) {
- let answer = this._elements.answerSpan.value;
- answer = answer ? answer.trim() : answer;
- let input = document.querySelector(`input[value="${answer}"`);
- if (input) {
- helpers.alternativeClick(input.parentElement.querySelector('i'));
- return wait().then( () => { return true; } );
- } else {
- return Promise.reject(`@D1Captcha input NOT FOUND for answer: ${answer}`);
- }
- } else {
- return Promise.reject('Answer span not found!!!');
- }
- }
-
- async isSolved() {
- return this.isReady()
- .then( () => this.solve())
- .then( (solution) => {
- return Promise.resolve(true);
- })
- .catch(err => { shared.devlog(err); })
- }
- }
-
- class Faucet {
- constructor(elements, actions = {}) {
- this._url = window.location.href;
- this._timeout = new Timeout(); // this.maxSeconds);
- this._elements = elements;
- this._actions = {
- preRun: false,
- preRoll: false,
- altValidation: false,
- readClaimed: true,
- readBalance: true,
- readTimeLeft: true,
- readRolledNumber: false,
- isMultiClaim: false,
- checkIfOutOfFunds: false,
- preSaveResult: false
- }
- this._actions = { ...this._actions, ...actions };
- this._params = shared.getCurrent().params || {};
- this._result = this._actions.isMultiClaim ? (shared.getProp('tempResults') || {}) : (shared.getResult() || {});
- }
-
- hasCloudflare() {
- let h2 = document.querySelector('h2#challenge-running');
- let stage = document.querySelector('#challenge-stage');
- if (h2 || stage) {
- return true;
- }
- return false;
- }
-
- useUrlListener() {
- if (window.onurlchange === null) {
- window.addEventListener('urlchange', (data) => {
- if (this._url != window.location.href) {
- this._url = window.location.href;
- this.resetRun();
- }
- });
- }
- }
-
- resetRun() {
- wait().then( () => { this.init(); });
- }
-
- init() {
- throw new Error('Init not implemented!');
- }
-
- login() {
- throw new Error('Login not implemented!'); //return NEED_TO_LOGIN
- }
-
- async run(action = false) {
- if (this._actions.checkIfOutOfFunds) {
- this.checkIfOutOfFunds();
- }
-
- if (this._actions.preRun) {
- await wait().then( () => { this.preRun() } );;
- }
-
- if (!action) {
- this.detectAction().then( (resolve) => {
- this.perform(resolve.action);
- });
- } else {
- this.perform(action);
- }
- }
-
- perform(action) {
- switch(action) {
- case 'doRoll':
- if(this._actions.preRoll) {
- this.preRoll();
- }
- this._elements.captcha.isSolved().then(() => { this.clickRoll() });
- break;
- case 'needToWait':
- this.updateResult();
- break;
- default:
- break;
- }
- }
-
- async detectAction() {
- return wait().then( () => {
- if ( this.isCountdownVisible() ) {
- return Promise.resolve({action: 'needToWait'});
- } else if ( this.isRollButtonVisible() ) {
- return Promise.resolve({action: 'doRoll'});
- } else {
- return this.detectAction();
- }
- });
- }
-
- preRoll() {
- throw new Error('PreRoll not implemented!');
- }
-
- preRun() {
- throw new Error('PreRun not implemented!');
- }
-
- altValidation() {
- throw new Error('AltValidation not implemented!');
- }
-
- isCountdownVisible() {
- return this._elements.countdownMinutes && this._elements.countdownMinutes.isUserFriendly;
- }
-
- isRollButtonVisible() {
- return this._elements.rollButton && this._elements.rollButton.isUserFriendly;
- }
-
- clickRoll() {
- try {
- this._elements.rollButton.element.scrollIntoView(false);
- this._elements.rollButton.click();
- this.validateRun();
- } catch (err) {
- shared.closeWithError(K.ErrorType.CLICK_ROLL_ERROR, err);
- }
- }
-
- failureValidation() {
- throw new Error('FailureValidation not implemented!');
- }
-
- async validateRun() {
- return wait(this._actions.useFailureValidation ? 6000 : null).then( () => {
- if (this._actions.useFailureValidation) {
- if (this.failureValidation()) {
- return;
- }
- }
- if (this._elements.success?.isUserFriendly) {
- return this.updateResult();
- } else if(this._actions.altValidation) {
- if(this.altValidation()) {
- return this.updateResult();
- }
- }
- return wait(2000).then( () => { this.validateRun() });
- });
- }
-
- async updateResult() {
- if(this._actions.readClaimed) {
- this._result.claimed = this.readClaimed();
- }
- if(this._actions.readBalance) {
- this._result.balance = this.readBalance();
- }
- if(this._actions.readTimeLeft) {
- this._result.nextRoll = this.readNextRoll();
- }
- if(this._actions.readRolledNumber) {
- this._result.rolledNumber = this.readRolledNumber();
- }
- if (this._actions.isMultiClaim) {
- shared.setProp('tempResults', this._result);
- return this._actions.postRun ? this.postRun() : true;
- }
- if (this._actions.preSaveResult) {
- this.preSaveResult();
- }
- if (this._actions.updateWithoutClosing) {
- shared.updateWithoutClosing(this._result);
- return this._actions.postRun ? this.postRun() : true;
- } else {
- shared.closeWindow(this._result);
- }
- }
-
- readNextRoll() {
- try {
- if (this._elements.countdownMinutes && this._elements.countdownMinutes.isUserFriendly) {
- return helpers.addMinutes(this._elements.countdownMinutes.timeLeft);
- }
- } catch (err) { shared.devlog(`@readNextRoll: ${err}`); }
- return null;
- }
-
- readRolledNumber() {
- let rolled = 0;
- try {
- if(this._elements.rolledNumber.isUserFriendly) {
- rolled = this._elements.rolledNumber.value;
- }
- } catch (err) { shared.devlog(`@readRolledNumber: ${err}`); }
- return rolled;
- }
-
- readBalance() {
- let balance = 0;
- try {
- if(this._elements.balance.isUserFriendly) {
- balance = this._elements.balance.value;
- }
- } catch (err) { shared.devlog(`@readBalance: ${err}`); }
- return balance;
- }
-
- readClaimed() { //TODO: review if previous claimed should be received as arg
- let claimed = this._result.claimed ?? 0;
- if (this._actions.isMultiClaim) {
- this._oldClaimed = claimed;
- } else {
- }
-
- try {
- if(this._elements.claimed.isUserFriendly) {
- claimed = +claimed + +this._elements.claimed.value;
- } else {
- }
- } catch (err) { shared.devlog(`@readClaimed: ${err}`); }
- return claimed;
- }
-
- checkIfOutOfFunds() {
- let divAlerts = [...document.querySelectorAll(this._elements.outOfFundsDivSelector)];
- divAlerts.forEach( function (d) {
- if (d.innerText.toLowerCase().includes('not have sufficient funds')) {
- shared.closeWithError(K.ErrorType.FAUCET_EMPTY, d.innerText);
- return;
- }
- });
- }
-
- setCurrentCaptcha() {
- if ([...document.querySelectorAll('iframe')].map(x => x.src || '').filter(x => x.includes('hcaptcha.com')).length > 0) {
- return;
- }
- this._elements.captcha = new RecaptchaWidget();
- }
- }
-
- class BFRoll extends Faucet {
- constructor(coinPrefix, trySpin = false) {
- let elements = {
- preRunButton: new ButtonWidget({selector: '.free-box.free-box__' + coinPrefix + ' button'}), //'#' + coinPrefix + '_free_box_withdraw_page'}),
- captcha: new NoCaptchaWidget({ selector: '.free-box-withdraw__footer button' }), // .button_red.button_center.button_fullwidth' }),
- rollButton: new ButtonWidget({selector: '.free-box-withdraw__footer button' }), // .button_red.button_center.button_fullwidth'}),
- success: new ReadableWidget({selector: '.modal:not(.free-box-withdraw,fury-wheel-modal), .vue-notification-template.my-notify.success'}),
- claimed: new ReadableWidget({selector: '.free-box.free-box__' + coinPrefix, parser: Parsers.bfBoxClaimed}),
- progressBar: new ReadableWidget({selector: '.free-box.free-box__' + coinPrefix + ' .free-box__progress-bar progress'}),
- };
-
- let actions = {
- preRun: true,
- readClaimed: true,
- readBalance: false,
- readRolledNumber: false
- };
- super(elements, actions);
- this.coinPrefix = coinPrefix;
- this.trySpin = trySpin;
- }
-
- init() {
- if (this._url.includes('https://betfury.io/boxes/all')) {
- this.run();
- return;
- } else {
- return;
- }
- }
-
- async spin() {
- let clickables = document.querySelectorAll('.fury-wheel__wheel-btn, .fury-wheel__btn-wrap, .fury-wheel__btn-content, .fury-wheel__btn-img');
- if (clickables.length > 0) {
- clickables[Math.floor(Math.random()*clickables.length)].click();
- wait(15000).then ( () => { shared.closeWindow(this._result); } );
- }
- return;
- }
-
- async preRun() {
- return wait().then( () => {
- try {
- let popup = document.querySelector('.modal-wrapper .modal:not(.free-box-withdraw,fury-wheel-modal) .modal__btn-close');
- if (popup) {
- popup.click();
- popup.click(); // twice
- }
- } catch (err) {}
-
- if (this.trySpin) {
- let spinUnavailable = document.querySelector('.bonus.bonus_furywheel.wait');
- if (spinUnavailable) {
- } else {
- let spinBtn = document.querySelector('.wheel-amin'); //bonus bonus_furywheel wait
- if (spinBtn) {
- spinBtn.click();
- wait(10000).then ( () => { this.spin() } );
- return wait(60000).then ( () => { this.preRun(); } );
- }
- }
- }
-
- if (!this._elements.progressBar || !this._elements.progressBar.isUserFriendly) {
- return this.preRun();
- }
-
- if (this._elements.preRunButton.isUserFriendly) {
- if (!this._elements.preRunButton.isUserFriendly.disabled) {
- return this._elements.preRunButton.click();
- } else {
- this._timeout.restart();
- shared.closeWindow(this._result);
- return;
- }
- } else if (document.querySelectorAll('.free-box').length > 1) {
- shared.closeWithError(K.ErrorType.ERROR, 'Box might not exist for your account.');
- return;
- }
- return this.preRun();
- });
- }
-
- async validateRun() {
- return wait(7000).then( () => {
- let gtHook = document.querySelector('div.geetest_slice_bg');
- if (gtHook) {
- if (gtHook.isUserFriendly()) {
- return this.validateRun();
- }
- }
- let popup = document.querySelector('.modal-wrapper .modal:not(.free-box-withdraw,fury-wheel-modal) .modal__btn-close');
- if (!popup) {
- if (this._elements.preRunButton.isUserFriendly && !this._elements.preRunButton.isUserFriendly.disabled) {
- this._elements.preRunButton.click();
- return this.validateRun();
- }
- } else {
- try {
- if (popup) {
- popup.click();
- popup.click();
- }
- } catch (err) {}
- }
-
- if (this._elements.success.isUserFriendly) {
- return this.updateResult();
- } else if(this._actions.altValidation) {
- if(this.altValidation()) {
- return this.updateResult();
- }
- }
- return this.validateRun();
- });
- }
- }
-
- class DutchyRoll extends Faucet {
- constructor() {
- let elements = {
- countdownMinutes: new CountdownWidget({selector: '#timer', parser: Parsers.splitAndIdxToInt, options: { splitter: 'Minutes', idx: 0} }), // "26 Minutes 23"
- captcha: new HCaptchaWidget(),
- rollButton: new ButtonWidget({selector: '#claim'}), //w/booster video: '#unlockbutton' & then #claim_boosted
- success: new ReadableWidget({selector: '.card.green.pulse p,.card.blue.pulse,.card.green.animated,.card.green.pulse'}),
- claimed: new ReadableWidget({selector: '.card.green.pulse p,.card.blue.pulse,.card.green.animated,.card.green.pulse', parser: Parsers.freeEthereumIoClaimed}) //"You Won 0.00409070 TRX + 20 XP"
- };
- let actions = {
- preRun: true,
- readClaimed: true,
- readBalance: false,
- readRolledNumber: false
- };
- super(elements, actions);
- }
-
- init() {
- switch(window.location.host) {
- case 'autofaucet.dutchycorp.space':
- if (this._url.includes('/roll.php')) {
- this._elements.claimed = new ReadableWidget({selector: '.card.green.pulse p,.card.blue.pulse,.card.green.animated,.card.green.pulse', parser: Parsers.dutchysClaimed})
- } else if (this._url.includes('/login.php')) {
- shared.closeWithError(K.ErrorType.NEED_TO_LOGIN, '');
- return;
- }
- break;
- case 'express.dutchycorp.space':
- if (this._url.includes('/roll.php')) {
- this._elements.claimed = new ReadableWidget({selector: '.card.green.pulse p,.card.blue.pulse,.card.green.animated,.card.green.pulse', parser: Parsers.dutchysClaimed})
- } else if (this._url.includes('/coin_roll.php')) {
- this._elements.claimed = new ReadableWidget({selector: '.card.green.pulse p,.card.blue.pulse,.card.green.animated,.card.green.pulse', parser: Parsers.dutchysClaimedToFloat})
- } else if (this._url.includes('/index.php')) {
- shared.closeWithError(K.ErrorType.NEED_TO_LOGIN, 'You need to login using ExpressCrypto (EC-UserId-XXXXXX).');
- return;
- }
- break;
- }
- this.run();
- return;
- }
-
- async preRun() {
- if (this._elements.captcha.isUserFriendly) {
- if (shared.getConfig()['dutchy.useBoosted']) {
- this._elements.rollButton = new ButtonWidget({selector: '#unlockbutton'});
- this._elements.confirmBoost = new ButtonWidget({selector: '#claim_boosted'});
- setInterval(() => {
- try {
- if (this._elements.confirmBoost.isUserFriendly) {
- this._elements.confirmBoost.click();
- }
- } catch (err) {}
- }, 8000);
- }
- return true;
- } else {
- this.setCurrentCaptcha();
- await wait();
- return this.preRun();
- }
- }
- }
-
- class YCoin extends Faucet {
- constructor() {
- let elements = {
- rollButton: new ButtonWidget({selector: 'input[type="submit"][value="Get Free Crypto!"]'}),
- claimed: new ReadableWidget({selector: 'div.alert.alert-info', parser: Parsers.freeEthereumIoClaimed}),
- captcha: new HCaptchaWidget(),
- balance: new ReadableWidget({selector: 'a.wha[href="/account?page=history"]', parser: Parsers.trimNaNs}),
- success: new ReadableWidget({selector: 'div.alert.alert-info'}),
- login: {
- inputUser: new TextboxWidget({ selector: 'input[name="number"]' }),
- inputPass: new TextboxWidget({ selector: 'input[name="pass"]' }),
- inputSubmit: new SubmitWidget({ selector: 'input[type="submit"][value="Login!"]' }),
- setCredentials: false
- },
- };
-
- if(shared.getConfig()['ycoin.credentials.mode'] == 1) {
- elements.login.setCredentials = {
- username: shared.getConfig()['ycoin.credentials.username'],
- password: shared.getConfig()['ycoin.credentials.password']
- };
- }
-
- let actions = {
- preRun: true,
- readClaimed: true,
- readBalance: true,
- readRolledNumber: false,
- checkIfOutOfFunds: false
- };
- super(elements, actions);
- }
-
- async preRun() {
- let msgDiv;
- msgDiv = document.querySelector('p.info.success');
- if (msgDiv && msgDiv.innerText.includes('has been transferred')) {
- let result = {};
- if (msgDiv.innerText.includes('0 claims')) {
- result.nextRoll = helpers.addMinutes(60 * 24 + helpers.randomInt(10, 50));
- } else {
- result.nextRoll = helpers.addMinutes('60');
- }
- result.claimed = +msgDiv.innerText.split(' ')[0];
- result.balance = this.readBalance();
- shared.closeWindow(result);
- return;
- }
-
- msgDiv = document.querySelector('p.info.warn');
- if (msgDiv) {
- if (msgDiv.innerText.includes('can claim only')) {
- let result = {};
- result.nextRoll = helpers.addMinutes(60 * 24 + helpers.randomInt(10, 160));
- shared.closeWindow(result);
- return;
- } else if (msgDiv.innerText.includes('Please wait')) {
- let result = {};
- try {
- let unit = msgDiv.innerText.includes(' seconds') ? ' seconds' : ' minutes';
- let val = msgDiv.innerText.split('Please wait ')[1].replace(/\D/g, '');
- if (unit == ' seconds') {
- result.nextRoll = helpers.addSeconds(val);
- } else {
- result.nextRoll = helpers.addMinutes(val);
- }
- } catch {
- result.nextRoll = helpers.addMinutes(60);
- }
- shared.closeWindow(result);
- return;
- }
- }
- msgDiv = document.querySelector('p.info.fail');
- if (msgDiv) {
- if (msgDiv.innerText.toLowerCase().includes('run out of bitcoin')) {
- shared.closeWithError(K.ErrorType.FAUCET_EMPTY, 'Out of Funds');
- return;
- }
- }
-
- if (this._elements.captcha.isUserFriendly) {
- } else {
- if (this._elements.rollButton) {
- this._elements.rollButton.click();
- return;
- }
- }
- }
-
- async init() {
- if (this._url.includes('/faucet')) {
- let needToLoginButton = document.querySelector('input[type="submit"][value="Login / Signup"]');
- if (needToLoginButton) {
- needToLoginButton.click();
- return;
- }
-
- this.run();
- this.solveColorCaptcha();
- return;
- } else if (this._url.includes('/account')) {
- this.doLogin();
- return;
- }
- }
-
- async doLogin() {
- return wait().then( () => {
- let container = document.querySelector('#cc');
- if (container.innerText.includes('You are now logged in as account')) {
- let toFaucetButton = document.querySelector('#mmenu a[href="/faucet"]');
- if (toFaucetButton) {
- toFaucetButton.click();
- return;
- }
- return this.doLogin();
- }
- if (!this._elements.login.inputUser.isUserFriendly || !this._elements.login.inputPass.isUserFriendly || !this._elements.login.inputSubmit.isUserFriendly) {
- return this.doLogin();
- }
-
- let loginErrorDiv = document.querySelector('#cc .info.fail');
- if (loginErrorDiv && loginErrorDiv.innerText.includes('Invalid')) {
- shared.closeWithError(K.ErrorType.LOGIN_ERROR, loginErrorDiv.innerText);
- return;
- }
-
- if (this._elements.login.setCredentials != false) {
- this._elements.login.inputUser.value = this._elements.login.setCredentials.username;
- this._elements.login.inputPass.value = this._elements.login.setCredentials.password;
- }
-
- try {
- this._elements.login.rememberMe.isUserFriendly.checked = true;
- } catch (err) {}
-
- if (this._elements.login.inputUser.value != '' && this._elements.login.inputPass.value != '' ) {
- this._elements.login.inputSubmit.click();
- } else {
- shared.closeWithError(K.ErrorType.LOGIN_ERROR, 'No credentials were provided');
- return;
- }
- });
- }
-
- async solveColorCaptcha() {
- await wait(2000);
- let optionInputs = [...document.querySelectorAll('#newch input[type="submit"]')];
- let options = optionInputs.map(x => x.style.background);
- let wantedColor = document.querySelector('#newch p b');
- if (options.length > 0 && wantedColor) {
- try {
- let knownColors = Object.keys(nearestColor.STANDARD_COLORS);
- let toColorName = nearestColor.from(nearestColor.STANDARD_COLORS);
-
- options = options.map(x => toColorName(x).name);
- wantedColor = wantedColor.innerText.toLowerCase();
- if (wantedColor == 'grey') { wantedColor = 'gray'; }
- let solutionIdx = options.findIndex(x => x.includes(wantedColor));
- if (solutionIdx > -1) {
- optionInputs[solutionIdx].click();
- return;
- }
- if (wantedColor == 'green') {
- wantedColor = 'lime';
- solutionIdx = options.findIndex(x => x.includes(wantedColor));
- if (solutionIdx > -1) {
- optionInputs[solutionIdx].click();
- return;
- }
- }
- await wait(5000);
- location.reload();
- } catch (err) {
- await wait(15000);
- location.reload();
- }
- } else {
- return this.solveColorCaptcha();
- }
- }
-
- }
-
- class CDiversity extends Faucet {
- constructor() {
- let elements = {
- claimed: new ReadableWidget({selector: 'p.success', parser: Parsers.trimNaNs}),
- captcha: new HCaptchaWidget(),
- rollButton: new ButtonWidget({selector: 'input[type="submit"][value="Get Free Crypto!"]'}),
- };
- let actions = {
- readTimeLeft: true,
- readRolledNumber: false,
- readBalance: false
- };
- super(elements, actions);
- }
-
- init() {
- if(this.hasErrorMessage()) {
- shared.closeWithError(K.ErrorType.ERROR, 'Suspicious Activity Message Displayed');
- return;
- }
-
- let claimed = this.readClaimed();
- if (claimed != 0) {
- let result = {
- claimed: claimed,
- nextRoll: this.readNextRoll()
- };
- shared.closeWindow(result);
- return;
- }
-
- let nextRoll = this.readNextRoll();
- if(nextRoll) {
- let result = {
- nextRoll: nextRoll
- };
- shared.closeWindow(result);
- return;
- }
-
- this.solve();
- }
-
- hasErrorMessage() {
- return document.body.innerText.toLowerCase().includes('suspicious activity');
- }
-
- isFirstStep() {
- return document.querySelector('form select[name="coin"]') ? true : false;
- }
-
- async doFirstStep() {
- let form = document.querySelector('form');
- if (!form) {
- this.updateResult();
- return;
- }
- let coinSelect = form.querySelector('select[name="coin"]');
- if (!coinSelect) {
- this.updateResult();
- return;
- }
- let userInput = form.querySelector('input[name="ado"]');
- if (!userInput) {
- this.updateResult();
- return;
- }
- let submitButton = form.querySelector('input[type="submit"]');
- if (!submitButton) {
- this.updateResult();
- return;
- }
- coinSelect.value = this.getCoin();
- userInput.value = this._params.address;
-
- submitButton.parentElement.submit();
- return;
- }
-
- getCoin() {
- try {
- let tds = document.querySelectorAll('table tr td:nth-child(2)');
- return tds[helpers.randomInt(0, 5)].innerText.split(' ')[1]
- } catch (err) {
- return 'BTC';
- }
- }
-
- isSecondStep() {
- let ps = [...document.querySelectorAll('p')];
- return ps.findIndex(x => x.innerText.toLowerCase().includes('one more step...')) >= 0;
- }
-
- async solve() {
- if (this.isSecondStep()) {
- return this.run();
- }
- if (this.isFirstStep()) {
- return this.doFirstStep();
- }
- }
-
- isCountdownVisible() {
- let successDiv = document.querySelector('p.success');
- if (!successDiv) {
- return false;
- }
- if (successDiv.innerText.includes('0 claims')) {
- return true;
- }
-
- return false;
- }
-
- readClaimed() {
- let successDiv = document.querySelector('p.success');
- if (successDiv) {
- return successDiv.innerText.split(' ')[0];
- } else {
- return 0;
- }
- }
-
- readNextRoll() {
- try {
- let successDiv = document.querySelector('p.success');
- if (successDiv && successDiv.innerText.includes('You have')) {
- let claimsLeft;
- try {
- claimsLeft = successDiv.innerText.split(' claims')[0].split('have ')[1];
- } catch (err) {}
- if (claimsLeft) {
- return helpers.addMinutes(helpers.randomInt(6, 22));
- } else if (claimsLeft === '0') {
- return helpers.addMinutes(60 * 24 + helpers.randomInt(10, 160));
- }
- }
- } catch (err) { }
-
- try {
- let warnDiv = document.querySelector('p.warn');
- if (warnDiv) {
- if (warnDiv.innerText.includes('You can claim only')) {
- return helpers.addMinutes(60 * 24 + helpers.randomInt(10, 160));
- }
-
- if (warnDiv.innerText.includes('Please wait ')) {
- try {
- let unit = warnDiv.innerText.includes(' seconds') ? ' seconds' : ' minutes';
- let val = warnDiv.innerText.split('Please wait ')[1].split(unit)[0].replace(/\D/g, '');
- if (unit == ' seconds') {
- return helpers.addSeconds(val);
- } else {
- return helpers.addMinutes(val);
- }
- } catch { }
- let claimsLeft;
- try {
- claimsLeft = warnDiv.innerText.split(' seconds')[0].split('wait ')[1];
- } catch (err) {}
- if (claimsLeft) {
- return helpers.addMinutes(helpers.randomInt(6, 22));
- }
- }
- }
-
- } catch (err) { }
- return null;
- }
- }
-
- class CTop extends Faucet {
- constructor() {
- let elements = {
- claimed: new ReadableWidget({selector: 'p.success', parser: Parsers.trimNaNs}),
- captcha: new HCaptchaWidget(),
- rollButton: new ButtonWidget({selector: 'input[type="submit"]'}),
- addressInput: new TextboxWidget({ selector: 'form input[name="adr"], form input[name="a"]'})
- };
- let actions = {
- readTimeLeft: true,
- readRolledNumber: false,
- readBalance: false
- };
- super(elements, actions);
- }
-
- init() {
- if(this.hasErrorMessage('suspicious activity')) {
- shared.closeWithError(K.ErrorType.ERROR, 'Suspicious Activity Message Displayed');
- return;
- }
- if(this.hasErrorMessage('no funds left')) {
- shared.closeWithError(K.ErrorType.FAUCET_EMPTY, 'Out of Funds');
- return;
- }
- if(this.hasErrorMessage('faucet is currently disabled')) {
- shared.closeWithError(K.ErrorType.FAUCET_EMPTY, 'Faucet is disabled');
- return;
- }
-
- let claimed = this.readClaimed();
- if (claimed != 0) {
- let result = {
- claimed: claimed,
- nextRoll: this.readNextRoll()
- };
- shared.closeWindow(result);
- return;
- }
-
- let nextRoll = this.readNextRoll();
- if(nextRoll) {
- let result = {
- nextRoll: nextRoll
- };
- shared.closeWindow(result);
- return;
- }
-
- this.solve();
- }
-
- hasErrorMessage(searchTerm) {
- return document.body.innerText.toLowerCase().includes(searchTerm);
- }
-
- isFirstStep() {
- return this._elements.addressInput.isUserFriendly;
- }
-
- async doFirstStep() {
- let form = document.querySelector('form');
- if (!form) {
- this.updateResult();
- return;
- }
- if (!this._elements.addressInput.isUserFriendly) {
- this.updateResult();
- return;
- }
- let submitButton = form.querySelector('input[type="submit"]');
- if (!submitButton) {
- this.updateResult();
- return;
- }
- this._elements.addressInput.value = this._params.address;
-
- submitButton.closest('form').submit();
- return;
- }
-
- isSecondStep() {
- let ps = [...document.querySelectorAll('p')];
- return ps.findIndex(x => x.innerText.toLowerCase().includes('one more step...')) >= 0;
- }
-
- async solve() {
- if (this.isSecondStep()) {
- return this.run();
- }
- if (this.isFirstStep()) {
- return this.doFirstStep();
- }
- }
-
- isCountdownVisible() {
- let successDiv = document.querySelector('p.success');
- if (!successDiv) {
- return false;
- }
- if (successDiv.innerText.includes('0 claims')) {
- return true;
- }
-
- return false;
- }
-
- readClaimed() {
- let successDiv = document.querySelector('p.success');
- if (successDiv) {
- return successDiv.innerText.split(' ')[0];
- } else {
- return 0;
- }
- }
-
- readNextRoll() {
- try {
- let successDiv = document.querySelector('p.success');
- if (successDiv && successDiv.innerText.includes('You have')) {
- let claimsLeft;
- try {
- claimsLeft = successDiv.innerText.split(' claims')[0].split('have ')[1];
- } catch (err) {}
- if (claimsLeft) {
- return helpers.addMinutes(helpers.randomInt(12, 22));
- } else if (claimsLeft === '0') {
- return helpers.addMinutes(60 * 24 + helpers.randomInt(10, 160));
- }
- }
- } catch (err) { }
-
- try {
- let warnDiv = document.querySelector('p.warn');
- if (warnDiv) {
- if (warnDiv.innerText.includes('You can claim only')) {
- return helpers.addMinutes(60 * 24 + helpers.randomInt(10, 160));
- }
-
- if (warnDiv.innerText.includes('Please wait ')) {
- try {
- let unit = warnDiv.innerText.includes(' seconds') ? ' seconds ' : ' minutes ';
- let val = warnDiv.innerText.split('Please wait ')[1].split(unit)[0].replace(/\D/g, '');
- if (unit == ' seconds ') {
- return helpers.addSeconds(val + helpers.randomInt(90, 180));
- } else {
- return helpers.addMinutes(val + helpers.randomInt(1, 5));
- }
- } catch { }
- let claimsLeft;
- try {
- claimsLeft = warnDiv.innerText.split(' seconds')[0].split('wait ')[1];
- } catch (err) {}
- if (claimsLeft) {
- return helpers.addMinutes(helpers.randomInt(12, 22));
- }
- }
- }
-
- } catch (err) { }
- return null;
- }
- }
-
- class FPB extends Faucet {
- constructor(sitePrefix = null) {
- let elements = {
- rollButton: new ButtonWidget({selector: 'input[type="submit"][value="Claim From Faucet"],input[type="submit"][name="claim"]'}),
- claimed: new ReadableWidget({selector: 'div.alert.alert-info', parser: Parsers.freeEthereumIoClaimed}),
- captcha: new HCaptchaWidget(),
- success: new ReadableWidget({selector: 'div.alert.alert-info'}),
- login: {
- inputUser: new TextboxWidget({ selector: 'input[name="user_name"]' }),
- inputPass: new TextboxWidget({ selector: 'input[name="password"]' }),
- rememberMe: new TextboxWidget({ selector: 'input[name="remember_me"]' }),
- inputSubmit: new ButtonWidget({ selector: 'input[type="submit"][name="login"]' }),
- setCredentials: false
- },
- outOfFundsDivSelector: '.alert.alert-info'
- };
-
- if(shared.getConfig()[sitePrefix + '.credentials.mode'] == 1) {
- elements.login.setCredentials = {
- username: shared.getConfig()[sitePrefix + '.credentials.username'],
- password: shared.getConfig()[sitePrefix + '.credentials.password']
- };
- }
-
- let actions = {
- readClaimed: true,
- readBalance: false,
- readRolledNumber: false,
- checkIfOutOfFunds: true
- };
- super(elements, actions);
- }
-
- init() {
- if (this._url.includes('/dashboard')) {
- this.run();
- return;
- } else if (this._url.includes('/login')) {
- this.doLogin();
- return;
- }
- }
-
- async doLogin() {
- return wait().then( () => {
- if (!this._elements.login.inputUser.isUserFriendly || !this._elements.login.inputPass.isUserFriendly || !this._elements.login.inputSubmit.isUserFriendly) {
- return this.doLogin();
- }
-
- let loginErrorDiv = document.querySelector('div.alert.alert-info');
- if (loginErrorDiv && loginErrorDiv.innerText.includes('not valid')) {
- shared.closeWithError(K.ErrorType.LOGIN_ERROR, loginErrorDiv.innerText);
- return;
- }
-
- if (this._elements.login.setCredentials != false) {
- this._elements.login.inputUser.value = this._elements.login.setCredentials.username;
- this._elements.login.inputPass.value = this._elements.login.setCredentials.password;
- }
-
- try {
- this._elements.login.rememberMe.isUserFriendly.checked = true;
- } catch (err) {}
-
- if (this._elements.login.inputUser.value != '' && this._elements.login.inputPass.value != '' ) {
- this._elements.captcha.isSolved().then(() => {
- this._elements.login.inputSubmit.click();
- return;
- });
- } else {
- shared.closeWithError(K.ErrorType.LOGIN_ERROR, 'No credentials were provided');
- return;
- }
- });
- }
-
- async detectAction() {
- return wait().then( () => {
- if ( this.isCountdownVisible() ) {
- return Promise.resolve({action: 'needToWait'});
- } else if ( this._elements.success.isUserFriendly ) {
- return this.updateResult();
- } else if ( this.isRollButtonVisible() ) {
- return Promise.resolve({action: 'doRoll'});
- } else {
- return this.detectAction();
- }
- });
- }
-
- clickRoll() {
- try {
- try {
- window.scrollTo(0, document.body.scrollHeight);
- } catch (err) { }
- this._elements.rollButton.click();
- setTimeout( () => { this._elements.rollButton.click(); }, 5000);
- } catch (err) {
- shared.closeWithError(K.ErrorType.CLICK_ROLL_ERROR, err);
- }
- }
- }
-
- class VieRoll extends Faucet {
- constructor() {
- let elements = {
- rollButton: new SubmitWidget({selector: '.main-content button[type="submit"]'}),
- claimed: new ReadableWidget({selector: '.swal2-html-container', parser: Parsers.trimNaNs}),
- captcha: new HCaptchaWidget(),
- success: new ReadableWidget({selector: '.swal2-success-ring'}),
- login: {
- inputUser: new TextboxWidget({ selector: '#email' }),
- inputPass: new TextboxWidget({ selector: '#password' }),
- inputSubmit: new SubmitWidget({ selector: 'button[type="submit"]' })
- }
- };
-
- let actions = {
- readClaimed: true,
- readBalance: false,
- readTimeLeft: false,
- readRolledNumber: false,
- preSaveResult: false,
- preRun: true
- };
- super(elements, actions);
- }
-
- getClaimsQty() {
- let statWidgets = document.querySelectorAll('.card.mini-stats-wid');
- if (statWidgets.length < 4) return false;
-
- let claimCounts = statWidgets[3].querySelector('p');
- if (!claimCounts) return false;
-
- claimCounts = claimCounts.innerText.split('/');
- if (claimCounts.length != 2) return false;
-
- return claimCounts[0];
- }
-
- async evalClaimsQty() {
- let current = this.getClaimsQty();
-
- if (current) {
- current = +current;
- } else {
- return;
- }
-
- let previous = await shared.getProp('tempClaimsQty') || 0;
- if (!isNaN(previous)) previous = +previous;
-
- if (current == previous) {
- return;
- } else if (current < previous) {
- return this.updateResult();
- } else {
- await shared.setProp('tempClaimsQty', current);
- }
- }
-
- readClaimed() {
- let claimed = 0.12;
- try {
- claimed = +document.querySelectorAll('.card.mini-stats-wid')[2].querySelector('p').innerText.split(' ')[0];
- } catch (err) { }
- return claimed;
- }
-
- async init() {
- await this.evalClaimsQty();
-
- if (window.location.pathname.includes('/faucet')) {
- this.run();
- return;
- } else if (window.location.pathname.includes('/firewall')) {
- this.solveFirewall();
- return;
- } else if (window.location.pathname.includes('/dashboard')) {
- window.location.href = (new URL('faucet', window.location)).href;
- return;
- } else if (window.location.pathname == '/') {
- let loginBtn = document.querySelector('.btn.btn-success');
- if (loginBtn) {
- loginBtn.click();
- return;
- } else {
- window.location.href = (new URL('login', window.location)).href;
- }
- return;
- } else if (this._url.includes('/login')) {
-
- let credentialsMode = this._params.credentials.mode;
- switch(credentialsMode) {
- case -1:
- shared.closeWithError(K.ErrorType.NEED_TO_LOGIN, 'Manual login required.');
- break;
- case 0:
- shared.closeWithError(K.ErrorType.NEED_TO_LOGIN, 'Login required and autologin is not configured.');
- break;
- default:
- this.doLogin();
- break;
- }
- return;
- }
- }
-
- async preRun() {
- return;
- }
-
- async solveFirewall() {
- this.closeSwal();
-
- this._elements.captcha.isSolved().then(() => {
- let btn = new SubmitWidget({selector: 'form:not(.p-3) button[type="submit"]'});
- btn.click();
- });
- }
-
- async doLogin() {
- return wait().then( () => {
- if (!this._elements.login.inputUser.isUserFriendly || !this._elements.login.inputPass.isUserFriendly || !this._elements.login.inputSubmit.isUserFriendly) {
- return this.doLogin();
- }
-
- let loginErrorDiv = document.querySelector('div.alert.alert-danger');
- if (loginErrorDiv) {
- shared.closeWithError(K.ErrorType.LOGIN_ERROR, loginErrorDiv.innerText);
- return;
- }
-
- if (this._params.credentials.mode == 1) {
- this._elements.login.inputUser.value = this._params.credentials.username;
- this._elements.login.inputPass.value = this._params.credentials.password;
- }
-
- if (this._elements.login.inputUser.value != '' && this._elements.login.inputPass.value != '' ) {
- this._elements.captcha.isSolved().then(() => {
- this._elements.login.inputSubmit.click();
- return;
- });
- } else {
- shared.closeWithError(K.ErrorType.LOGIN_ERROR, 'No credentials were provided');
- return;
- }
- });
- }
-
- preSaveResult() {
- this.closeSwal();
- }
-
- closeSwal() {
- let okButton = document.querySelector('button.swal2-confirm');
- if (okButton) {
- okButton.click();
- }
- }
- }
-
- class GRCRoll extends Faucet {
- constructor() {
- let elements = {
- countdownMinutes: new CountdownWidget({selector: '#roll_wait_text', parser: Parsers.freeGrcCountdown}),
- rollButton: new ButtonWidget({selector: 'input[id="roll_button"]'}),
- balance: new ReadableWidget({selector: '#balance', parser: Parsers.trimNaNs}),
- claimed: new ReadableWidget({selector: '#roll_comment .won', parser: Parsers.trimNaNs}),
- rolledNumber: new ReadableWidget({selector: '#roll_result', parser: Parsers.trimNaNs}),
- captcha: new NoCaptchaWidget({selector: '#roll_button'}),
- success: new ReadableWidget({selector: '#roll_result'})
- };
- let actions = {
- readTimeLeft: true,
- readRolledNumber: true
- };
- super(elements, actions);
- }
-
- init() {
- if (this._url.includes('#free_roll')) {
- if (document.querySelectorAll('a[href="#login"]').length > 0) {
- shared.closeWithError(K.ErrorType.NEED_TO_LOGIN, '');
- return;
- } else {
- this.run();
- return;
- }
- } else {
- return;
- }
- }
-
- isCountdownVisible() {
- return this._elements.countdownMinutes && this._elements.countdownMinutes.isUserFriendly && this._elements.countdownMinutes.isUserFriendly.innerText != '';
- }
- }
-
- class O24Roll extends Faucet {
- constructor() {
- let elements = {
- claimed: new ReadableWidget({selector: '#roll_comment .won', parser: Parsers.trimNaNs})
- };
- let actions = {
- readTimeLeft: true,
- readRolledNumber: false,
- readBalance: false
- };
- super(elements, actions);
- this._isFMonster = location.host === 'faucet.monster';
- }
-
- init() {
- if(this.hasErrorMessage('no funds left')) {
- shared.closeWithError(K.ErrorType.FAUCET_EMPTY, 'Out of Funds');
- return;
- }
-
- if (this.isCountdownVisible() || this.readClaimed() != 0) {
- this.updateResult();
- return;
- }
-
- this.solve();
- }
-
- hasErrorMessage(searchTerm) {
- return document.body.innerText.toLowerCase().includes(searchTerm);
- }
-
- getSpotsAvailable() {
- try {
- let soldSpots = document.querySelectorAll('.pos:not(.pfree)').length;
- let available = 1024-soldSpots;
- return {
- sold: '' + soldSpots,
- available: '' + available
- }
- } catch (err) {
- }
- }
-
- isPrime(num) {
- for(var i = 2; i < num; i++){
- if(num % i === 0){
- return false;
- }
- }
- return num > 1;
- }
-
- async solve() {
- let spots;
- spots = this.getSpotsAvailable();
- if(!this._isFMonster && !spots) {
- this.updateResult();
- return;
- }
-
- const findNotPrime = document.querySelector('select[name="pr"]').parentElement.innerText.includes('not a prime')
- let numbers = [...document.querySelectorAll('select[name="pr"] option[value]')].map(x => x.innerText)
- let prime = null;
- if (findNotPrime) {
- prime = numbers.find(x => {
- return !this.isPrime(x)
- });
- } else {
- prime = numbers.find(x => {
- return this.isPrime(x)
- });
- }
- if(!prime) {
- this.updateResult();
- return;
- }
-
- let addrInput = document.querySelector('label input[name="a"]');
- if (addrInput) {
- addrInput.value = this._params.address;
- } else {
- this.updateResult();
- return;
- }
- await wait(helpers.randomInt(1500, 3000));
-
- if (this._isFMonster) {
- let usdtQuestion = document.querySelector('form p:nth-child(2)');
- if (!usdtQuestion || !usdtQuestion.innerText.toLowerCase().includes('faucet monitor lists tether faucets')) {
- this.updateResult();
- return;
- }
- let usdtAnswersList = [...document.querySelectorAll('select[name="fm"] option')];
- if (usdtAnswersList.length == 0) {
- this.updateResult();
- return;
- }
- usdtAnswersList = usdtAnswersList.map(x => x.value);
- let idxCorrect = usdtAnswersList.findIndex(x => x.toLowerCase() == 'yes' || x.toLowerCase() == 'y');
- if (idxCorrect === -1) {
- this.updateResult();
- return;
- }
- document.querySelector('select[name="fm"]').value = usdtAnswersList[idxCorrect];
- } else {
- let answersList = [...document.querySelectorAll('select[name="tt"] option')].map(x => x.value);
- if (answersList.includes(spots.sold)) {
- document.querySelector('select[name="tt"]').value=spots.sold;
- } else if (answersList.includes(spots.available)) {
- document.querySelector('select[name="tt"]').value=spots.available;
- } else {
- this.updateResult();
- return;
- }
- }
- await wait(helpers.randomInt(400, 5000));
-
- let primeSelect = document.querySelector('select[name="pr"]');
- helpers.triggerMouseEvent (primeSelect, "mouseenter");
- await wait(helpers.randomInt(5600, 29000));
- helpers.triggerMouseEvent (primeSelect, "mouseout");
- primeSelect.value=prime.toString()
- await wait(helpers.randomInt(1500, 5000));
-
- let claimForm = document.querySelector('form');
- if(claimForm) {
- claimForm.submit();
- }
- }
-
- isCountdownVisible() {
- let pars = [...document.querySelectorAll('p')];
- if (pars.find(x => x.innerText.includes('wait until next day'))) {
- return true;
- }
-
- if (pars.find(x => x.innerText.includes('PROBLEM'))) {
- return true;
- }
-
- return false;
- }
-
- readClaimed() {
- let pars = [...document.querySelectorAll('p')];
- let claimedElm = pars.find(x => x.innerText.includes('been transferred to your account'));
- if (claimedElm) {
- return claimedElm.innerText.split(' ')[0];
- } else {
- return 0;
- }
- }
-
- readNextRoll() {
- try {
- let pars = [...document.querySelectorAll('p')];
- if (pars.find(x => x.innerText.includes('until next day') || x.innerText.includes('ALL DAILY CLAIMS') || x.innerText.includes('You have 0 claims left'))) {
- return helpers.addMinutes(60 * 24 + helpers.randomInt(10, 160));
- }
-
- if (pars.find(x => x.innerText.includes('PROBLEM'))) {
- return helpers.addMinutes(helpers.randomInt(6, 22));
- }
-
- if (pars.find(x => x.innerText.includes('You have'))) {
- return helpers.addMinutes(helpers.randomInt(6, 22));
- }
- } catch (err) { shared.devlog(`@readNextRoll: ${err}`); }
- return helpers.addMinutes(60 * 24 + helpers.randomInt(10, 160));
- }
- }
-
- class FCryptoRoll extends Faucet {
- constructor() {
- let elements = {
- countdownMinutes: new CountdownWidget({selector: '.sidebar-links .cursor-not-allowed span.notranslate', parser: Parsers.splitAndIdxToInt, options: { splitter: ':', idx: 1} }), // '00:21:28'
- rollButton: new ButtonWidget({selector: '.flex.justify-center button.inline-flex.items-center:not(.hidden)'}),
- balance: new ReadableWidget({selector: 'div.flex.badge.text-bg-yellow', parser: Parsers.trimNaNs}), // '405.81 Coins'
- claimed: new ReadableWidget({selector: 'div.ml-3.w-0 p span.text-yellow-500.font-medium', parser: Parsers.splitAndIdxTrimNaNs, options: { splitter: '(', idx: 0} }), // '25.05 Coins (12 + 13.05)'
- captcha: new HCaptchaWidget({selector: '#hcap-script > iframe'}),
- success: new ReadableWidget({selector: 'div.ml-3.w-0 p span.text-yellow-500.font-medium'})
- };
- let actions = {
- isMultiClaim: true,
- preRoll: true,
- postRun: true,
- readRolledNumber: false,
- };
- super(elements, actions);
- this._paths = {
- faucet: '/task/faucet-claim',
- dashboard: '/dashboard'
- };
- this._linkSelectors = {
- Faucet: 'a[href="https://faucetcrypto.com/task/faucet-claim"]'
- }
- this.useUrlListener();
- }
-
- init() {
- this._elements.captcha = new HCaptchaWidget({selector: '#hcap-script > iframe'});
- this._elements.rollButton = new ButtonWidget({selector: '.flex.justify-center button.inline-flex.items-center:not(.hidden)'});
- if (this._url.endsWith(this._paths.dashboard)) {
- return this.runDashboard();
- } else if (this._url.includes(this._paths.faucet)) {
- return wait().then( () => { this.run(); });
- }
-
- return;
- }
-
- readSections() {
- let sections = {};
- try {
- for (var l in this._linkSelectors) {
- sections[l] = {};
- sections[l].elm = document.querySelector(this._linkSelectors[l]);
- if (sections[l].elm) {
- let qty = sections[l].elm.querySelector('span.ml-auto');
- sections[l].qty = (qty && !isNaN(qty.innerText)) ? qty.innerText : 0;
- }
- }
- } catch {}
-
- this.sections = sections;
- }
-
- runDashboard() {
- this.readSections();
-
- if (this.sections['Faucet'].elm) {
- this.sections['Faucet'].elm.click();
- return;
- } else {
- return wait().then( () => { this.run(); });
- }
- }
-
- scrollTo() {
- let mainContainer = document.querySelector('main');
- if (mainContainer) {
- mainContainer.scrollTo(0, mainContainer.scrollHeight - mainContainer.offsetHeight);
- }
- }
-
- preRoll() { // search for 'You don't need to solve any captcha! The system is telling me that you are a good person :)'
- this.scrollTo();
- let checkCircleSpan = document.querySelector('p.font-medium.flex.justify-center.leading-0 span.text-green-500.mr-3 svg');
- if(checkCircleSpan) {
- if (checkCircleSpan.parentElement.parentElement.innerText.toLowerCase().includes('the system is telling me that you are a good person')) {
- this._elements.captcha = new NoCaptchaWidget({selector: '.flex.justify-center button.inline-flex.items-center:not(.hidden)'});
- return;
- }
- }
- }
-
- postRun() {
-
- if (this._url.endsWith(this._paths.dashboard) || this._oldClaimed != this._result.claimed) {
- try {
- this._elements.claimed.isUserFriendly.parentElement.parentElement.parentElement.querySelector('button');
- } catch (err) {
- }
- this._oldClaimed = null;
- this.readSections();
- if (this.sections != {}) {
- if (this.sections['Faucet'].elm) {
- this.sections['Faucet'].elm.click();
- return;
- } else {
- }
- } else {
- }
- } else {
- }
-
- this._result = shared.getProp('tempResults');
- shared.closeWindow(this._result);
- return;
- }
-
- async runPtcList() {
- let listItems = [...document.querySelectorAll('.grid.grid-responsive-3 .feather.feather-eye')].map(x => x.parentElement.parentElement).filter(x => x.isUserFriendly());
- if (listItems.length > 0) {
- listItems[0].click();
- return;
- } else {
- return wait().then( () => { this.runPtcList() } );
- }
- }
-
- runPtcSingleStart() {
- return this.run('doRoll');
- }
-
- runPtcSingleWait() {
- this._elements.captcha = new NoCaptchaWidget({selector: 'a.notranslate:not(.cursor-not-allowed)' });
- this._elements.rollButton = new ButtonWidget({selector: 'a.notranslate:not(.cursor-not-allowed)' });
- return this.run('doRoll');
- }
- }
-
- class FPPtc extends Faucet {
- constructor() {
- let elements = {
- claimButton: new ButtonWidget({selector: '#pop-up button.purpleButton:not([disabled])'}),
- claimButtonDisabled: new ButtonWidget({selector: '#pop-up button.purpleButton'}),
- openPtcButton: new ButtonWidget({fnSelector: function() {
- let blacklistTitles = ['JOIN US ON WINTOMATO.COM'];
- let btn = [...document.querySelectorAll('button')].filter(x => x.innerText.toLowerCase().includes('view'));
- try {
- btn = btn.filter(x => !blacklistTitles.includes(x.parentElement.parentElement.querySelector('h2').innerText.toUpperCase()));
- } catch (err) {}
- return (btn.length > 0) ? btn[0] : null;
- }}),
- claimed: new ReadableWidget({fnSelector: function() {
- let divSpanSuccessClaim = [...document.querySelectorAll('div span')].filter(x => x.innerText.toLowerCase().includes('successfully credited with'));
- return (divSpanSuccessClaim.length > 0) ? divSpanSuccessClaim[0] : null;
- }, parser: Parsers.trimNaNs}),
- captcha: new GeeTestCaptchaWidget(),
- success: new ReadableWidget({selector: 'div.ml-3.w-0 p span.text-yellow-500.font-medium'})
- };
- let actions = {
- isMultiClaim: true,
- preRoll: true,
- postRun: true,
- readRolledNumber: false,
- };
- super(elements, actions);
- this._paths = {
- ptcList: '/ptc',
- ptcSingleView: '/ptc/view',
- login: '/account/login',
- dashboard: '/user-admin'
- };
- this.useUrlListener();
- }
-
- init() {
- if (this._url.includes(this._paths.ptcSingleView)) {
- this.doPtcList(true);
- return;
- } else if (this._url.includes(this._paths.ptcList)) {
- this.doPtcList();
- return;
- } else if (this._url.includes(this._paths.login)) {
- this.doLogin();
- return;
- } else if (this._url.includes(this._paths.dashboard)) {
- return;
- }
-
- return;
- }
-
- hasExpired() {
- return document.body.innerText.includes('The session has expired');
- }
-
- hasError() {
- return document.body.innerText.includes('must finish watching') || document.title.includes('Tab Closed Error');
- }
-
- getETAWaitSeconds(btn) {
- try {
- let seconds = btn.nextSibling.firstChild.innerText.split('s')[0];
- return +seconds;
- } catch (err) {
- }
- return 15;
- }
-
- getPayout(btn) {
- this.lastClaimed = 0;
- try {
- let payout = btn.nextSibling.lastChild.innerText.split(' ')[0];
- this.lastClaimed = +payout;
- } catch (err) {
- }
- }
-
- async validateClaim() {
- await wait(1000);
- if (this.hasExpired()) {
- console.info('CLAIM => expired');
- await wait(2000);
- return false;
- }
- if (this._elements.claimed.isUserFriendly) {
- let claimed = this._elements.claimed.value;
- if (claimed) {
- console.info('CLAIM => Returning claimed:', claimed);
- await this.storeClaim();
- await wait(2000);
- return claimed;
- }
- }
- console.info('@validateClaim => Still waiting...');
- return this.validateClaim();
- }
-
- async storeClaim() {
- let result = shared.getResult();
- result.ptcsDone = (result.ptcsDone ?? 0) + 1;
- result.claimed = +(result.claimed ?? 0) + +this.lastClaimed;
- this.lastClaimed = 0;
- shared.updateWithoutClosing(result, 'WORKING');
- }
-
- async confirmClaim() {
- GM_setValue(`ptc-close-signal-faucetpay.io`, Date.now());
- await wait(5000);
- GM_deleteValue(`ptc-close-signal-faucetpay.io`);
- let captcha = new GeeTestCaptchaWidget();
-
- await captcha.isSolved();
- if (!this._elements.claimButton.isUserFriendly) {
- return;
- }
- this._elements.claimButton.click();
- let validation = await this.validateClaim();
- return this.doPtcList();
- }
-
- async startPtc() {
- await wait(1000);
- let minSeconds = this.getETAWaitSeconds(this._elements.openPtcButton.isUserFriendly);
- this.getPayout(this._elements.openPtcButton.isUserFriendly);
- this._elements.openPtcButton.click();
- await wait(4000);
- return this.waitPtcSeconds();
- }
-
- async waitPtcSeconds() {
- if (this._elements.claimButtonDisabled.isUserFriendly) {
- return this.confirmClaim();
- }
- if (!document.title.includes('PTC Ads') && document.title.includes('s |')) {
- await wait(5000);
- return this.waitPtcSeconds();
- }
- let iframe = document.querySelector('iframe[title="ptc-view"]');
- if (document.title.includes('PTC Ads') && iframe) {
- await wait(5000);
- return this.waitPtcSeconds();
- }
- return this.confirmClaim();
- }
-
- async doPtcList(isSingle = false) {
- if (document.title.includes('PTC Ads') || document.title.includes('Complete Visit')) {
- if (this._elements.claimButtonDisabled.isUserFriendly) {
- return this.confirmClaim();
- } else {
- if(isSingle) {
- await wait(4000);
- return this.doPtcList(true);
- }
- if (this._elements.openPtcButton.isUserFriendly) {
- return this.startPtc();
- } else {
- shared.closeWindow();
- return;
- }
- }
- }
- }
-
- async doLogin() {
- let username = document.querySelector('input');
- let password = document.querySelector('input[type="password"]');
- let captcha = new GeeTestCaptchaWidget();
- let btn = document.querySelector('button[type="submit"');
- if (username && password && btn && username.value != '' && password.value != '') {
- await captcha.isSolved();
- btn.click();
- return;
- } else {
- shared.closeWithError(K.ErrorType.NEED_TO_LOGIN, '');
- }
- }
- }
-
- function createFBProcessor() {
- let countdownMinutes;
- let timeout = new Timeout(); // this.maxSeconds);
- let captcha = new HCaptchaWidget();
-
- function run() {
- setTimeout(findCountdownOrRollButton, helpers.randomMs(2000, 5000));
- };
- function findCountdownOrRollButton() {
- if ( isCountdownVisible() ) {
- timeout.restart();
- countdownMinutes = +document.querySelectorAll('.free_play_time_remaining.hasCountdown .countdown_amount')[0].innerHTML + 1;
- let result = {};
- result.balance = readBalance();
- result.nextRoll = helpers.addMinutes(countdownMinutes.toString());
-
- shared.closeWindow(result);
- return;
- }
-
- if ( isRollButtonVisible() ) {
-
- try {
- let doBonus = false; // true;
- if (doBonus) {
- if (!document.getElementById('bonus_span_free_wof')) {
- RedeemRPProduct('free_wof_5');
- setTimeout(findCountdownOrRollButton, helpers.randomMs(2000, 5000));
- return;
- }
- }
- } catch { }
-
- /* For 'Play without captcha accounts' */
- if (!captcha.isUserFriendly) {
- clickRoll()
- } else {
- captcha.isSolved().then(() => { clickRoll(); });
- }
- } else {
- setTimeout(findCountdownOrRollButton, helpers.randomMs(2000, 5000));
- }
- };
- function isCountdownVisible() {
- return document.querySelectorAll('.free_play_time_remaining.hasCountdown .countdown_amount').length > 0;
- };
- function isHCaptchaVisible() {
- let hCaptchaFrame = document.querySelector('.h-captcha > iframe');
- if (hCaptchaFrame && hCaptchaFrame.isVisible()) {
- return true;
- }
- return false;
- };
- function isRollButtonVisible() {
- return document.getElementById('free_play_form_button').isVisible();
- };
- function clickRoll() {
- try {
- document.getElementById('free_play_form_button').click();
- setTimeout(processRunDetails, helpers.randomMs(3000, 10000));
- } catch (err) {
- shared.closeWithError(K.ErrorType.CLICK_ROLL_ERROR, err);
- }
- };
- function processRunDetails() {
- if (document.getElementById('winnings').isVisible()) {
- closePopup();
-
- let result = {};
- result.claimed = readClaimed();
- result.balance = readBalance();
- if(result.claimed != 0) {
- result.rolledNumber = readRolledNumber();
- }
- shared.closeWindow(result);
- return;
- }
-
- if (document.querySelector('.free_play_result_error').isVisible()) {
- shared.closeWithError(K.ErrorType.ROLL_ERROR, document.querySelector('.free_play_result_error').innerHTML);
- return;
- }
-
- if(document.getElementById('free_play_error').isVisible()) {
- shared.closeWithError(K.ErrorType.ROLL_ERROR, document.querySelector('.free_play_error').innerHTML);
- return;
- }
-
- if (document.getElementById('same_ip_error').isVisible()) {
- shared.closeWithError(K.ErrorType.ROLL_ERROR, document.getElementById('same_ip_error').innerHTML);
- return;
- }
-
- setTimeout(processRunDetails, helpers.randomMs(5000, 6000));
- };
- function closePopup() {
- let closePopupBtn = document.querySelector('.reveal-modal.open .close-reveal-modal');
- if (closePopupBtn) {
- closePopupBtn.click();
- }
- };
- function readRolledNumber() {
- let rolled = 0;
- try {
- rolled = parseInt([... document.querySelectorAll('#free_play_digits span')].map( x => x.innerHTML).join(''));
- } catch { }
- return rolled;
- };
- function readBalance() {
- let balance = 0;
- try {
- balance = document.getElementById('balance').innerHTML;
- } catch { }
- return balance;
- };
- function readClaimed() {
- let claimed = 0;
- try {
- claimed = document.getElementById('winnings').innerHTML;
- } catch { }
- return claimed;
- };
-
- return {
- run: run
- };
- }
-
- function createBigBtcProcessor() {
- let timeout = new Timeout(); // this.maxSeconds);
- let countdownMinutes;
- let captcha = new HCaptchaWidget();
- let selectElement = {
- loadingDiv: function() {
- let loading = document.querySelector('#loading');
- if (loading && loading.isVisible()) {
- return true;
- } else {
- return false;
- }
- },
- addressInput: function() {
- return document.querySelector('#login input[name="address"]');
- },
- loginButton: function() {
- return document.querySelector('#login input[type="submit"]');
- },
- claimButton: function() {
- return document.getElementById('claimbutn');
- },
- countdown: function() { // "You have to wait\n60 minutes"
- let cd = document.getElementById('countdown');
- if(cd && cd.isVisible()) {
- return parseInt(cd.innerText);
- }
- return null;
- },
- claimedAmount: function() {
- let elm = document.querySelector('.alert.alert-success.pulse'); //"Yuppie! You won 2 satoshi!"
- if(elm && elm.isVisible()) {
- let val = parseInt(elm.innerText.replace(/\D/g, ''));
- if (Number.isInteger(val)) {
- val = val / 100000000;
- }
-
- return val;
- } else {
- return null;
- }
- },
- balance: function() {
- let elm = document.querySelector('a b');
- if (elm && elm.isVisible()) {
- let val = parseInt(elm.innerText.replace(',', ''));
- if (Number.isInteger(val)) {
- val = val / 100000000;
- }
-
- return val;
- } else {
- return null;
- }
- },
- error: function () {
- return null;
- }
- };
-
- function init() {
- window.scrollTo(0, document.body.scrollHeight);
- let m = document.getElementById('main'); if (m) { m.style.display='block'; }
- m = document.getElementById('block-adb-enabled'); if (m) { m.style.display='none'; }
- m = document.getElementById('ielement'); if (m) { m.style.display='block'; }
- setInterval(() => {
- let frames = [...document.querySelectorAll('iframe')];
- frames.forEach(x => {
- if (!x.src.includes('hcaptcha')) {
- x.remove()
- }
- });
- }, 5000);
-
- if (window.location.href.includes('/faucet')) {
- setTimeout(runFaucet, helpers.randomMs(12000, 14000));
- return;
- } else {
- setTimeout(run, helpers.randomMs(3000, 5000));
- return;
- }
- }
-
- function run() {
- try {
- setTimeout(waitIfLoading, helpers.randomMs(12000, 15000));
- } catch (err) {
- shared.closeWithErrors(K.ErrorType.ERROR, err);
- }
- };
- function doLogin() {
- let address = selectElement.addressInput();
- if(address && address.value != shared.getCurrent().params.address) {
- address.value = shared.getCurrent().params.address;
- } else {
- selectElement.loginButton().click();
- return;
- }
- setTimeout( doLogin , helpers.randomMs(1000, 2000));
- };
- function waitIfLoading() {
- if ( !selectElement.loadingDiv() ) {
- doLogin();
- return;
- } else {
- }
-
- setTimeout(waitIfLoading, helpers.randomMs(5000, 7000));
- };
- function runFaucet() {
- let claimedAmount = selectElement.claimedAmount();
- if(claimedAmount) {
- processRunDetails();
- return;
- } else if (selectElement.countdown()) {
- let result = {};
-
- shared.closeWindow(result);
- } else {
- captcha.isSolved().then(() => { clickClaim(); });
- }
- }
- function clickClaim() {
- try {
- selectElement.claimButton().click();
- return;
- } catch (err) {
- shared.closeWithError(K.ErrorType.CLICK_ROLL_ERROR, err);
- }
- };
- function processRunDetails() {
- let claimedAmount = selectElement.claimedAmount();
- let balance = selectElement.balance();
- let countdown = selectElement.countdown();
-
- if (claimedAmount && balance) {
- let result = {};
- result.claimed = claimedAmount;
- result.balance = balance;
-
- shared.closeWindow(result);
- return;
- }
-
- setTimeout(processRunDetails, helpers.randomMs(5000, 6000));
- };
-
- return {
- init: init
- };
- }
-
- function createBestChangeProcessor() {
- let timeout = new Timeout(); // this.maxSeconds);
- let countdownMinutes;
- let captcha = new HCaptchaWidget({selector: '.hcaptcha > iframe'});
- let elements = {
- captcha: function() {
- return document.querySelector('.hcaptcha > iframe');
- },
- container: function() {
- return document.querySelector('#info_bonus');
- },
- containerOpener: function() {
- return document.querySelector('#tab_bonus a');
- },
- addressInput: function() {
- return document.querySelector('#bonus_purse');
- },
- claimButton: function() {
- return document.querySelector('#bonus_button');
- },
- countdown: function() { // Time left: mm:ss
- let elm = document.querySelector('#bonus_button');
- try {
- if (elm.value) {
- let timeLeft = elm.value.split(':');
- if (timeLeft.length > 1) {
- return parseInt(timeLeft[1]);
- }
- }
- } catch (err) {
- return null;
- }
- },
- claimedAmount: function() {
- let elm = document.querySelector("#bonus_status b");
- try {
- let sats = elm.innerText.replace(/\D/g, '');
- return sats / 100000000;
- } catch (err) {
- return null;
- }
- },
- balance: function() {
- let elm = document.querySelector("#faucet_unpaid_balance b");
- try {
- let sats = elm.innerText.replace(/\D/g, '');
- return sats / 100000000;
- } catch (err) {
- return null;
- }
- }
- };
-
- function init() {
- run();
- }
-
- function run() {
- try {
- if (!elements.container().isUserFriendly()) {
- let co = elements.containerOpener();
- if(co.isUserFriendly()) {
- co.onclick = co.onmousedown;
- co.click();
- }
- }
- setTimeout(findCountdownOrRoll, helpers.randomMs(4000, 5000));
- } catch (err) {
- shared.closeWithErrors(K.ErrorType.ERROR, err);
- }
- };
- function findCountdownOrRoll() {
- let countdown = elements.countdown();
- if(countdown) {
- let result = { };
- result.nextRoll = helpers.addMinutes(countdown.toString());
-
- shared.closeWindow(result);
- return;
- }
-
- let ai = elements.addressInput();
-
- if (ai.isUserFriendly()) {
- if (ai.value != shared.getCurrent().params.address) {
- ai.value = shared.getCurrent().params.address;
- }
- captcha.isSolved().then(() => { clickClaim(); });
- return;
- }
-
- setTimeout(findCountdownOrRoll, helpers.randomMs(10000, 12000));
- };
-
- function clickClaim() {
- try {
- let btn = elements.claimButton();
- if(btn.isUserFriendly()) {
- btn.click();
- setTimeout(processRunDetails, helpers.randomMs(4000, 8000));
- } else {
- setTimeout(clickClaim, helpers.randomMs(4000, 8000));
- }
- return;
- } catch (err) {
- shared.closeWithError(K.ErrorType.CLICK_ROLL_ERROR, err);
- }
- };
-
- function processRunDetails() {
- let claimedAmount = elements.claimedAmount();
- let balance = elements.balance();
-
- if (claimedAmount && balance) {
- let result = {};
- result.claimed = claimedAmount;
- result.balance = balance;
-
- shared.closeWindow(result);
- return;
- }
-
- setTimeout(processRunDetails, helpers.randomMs(5000, 6000));
- };
-
- return {
- init: init
- };
- }
-
- function createSGProcessor() {
- let timerSpans;
- function run() {
- if(isLoading()) {
- setTimeout(run, helpers.randomMs(5000, 10000));
- return;
- } else if (hasPopup()) {
- closePopup();
- setTimeout(run, helpers.randomMs(5000, 10000));
- } else {
- if(isMinerActive()) {
- processRunDetails();
- } else {
- setTimeout(run, helpers.randomMs(5000, 10000));
- activateMiner();
- }
- }
- };
- function hasPopup() {
- if (document.querySelector('div.absolute.flex.top-0.right-0.cursor-pointer.p-4.text-white.md-text-gray-1')) {
- return true;
- }
- return false;
- };
- function closePopup() {
- try {
- document.querySelector("div.absolute.flex.top-0.right-0.cursor-pointer.p-4.text-white.md-text-gray-1").click();
- document.querySelector('svg.flex.w-8.h-8.fill-current').parentElement.click();
- } catch { shared.devlog(`@SG: error closing popup`); }
- };
- function isLoading() {
- return document.getElementById('loader-logo') ? true : false;
- };
- function isMinerActive() {
- timerSpans = document.querySelector('.font-bold.text-center.text-accent.w-11-12.text-18 span');
-
- if(timerSpans) {
- return true;
- } else {
- return false;
- }
- return (!!timerSpans);
- };
- function activateMiner() {
- let activateButton = document.querySelector("#region-main button.activate.block.w-full.h-full.mx-auto.p-0.rounded-full.select-none.cursor-pointer.focus-outline-none.border-0.bg-transparent");
- if (activateButton) {
- activateButton.click();
- setTimeout(run, helpers.randomMs(10000, 20000));
- } else {
- processRunDetails()
- }
- };
-
- function processRunDetails() {
- let result = {};
- result.nextRoll = helpers.addMinutes(readCountdown().toString());
- result.balance = readBalance();
- shared.closeWindow(result);
- };
-
- function readCountdown() {
- let synchronizing = document.querySelector('.text-15.font-bold.text-center.text-accent'); // use
- let mins = 15;
- try {
- let timeLeft = timerSpans.innerText.split(':');
- if (timeLeft[0] == 'Synchronizing') {
- }
-
- if(timeLeft.length === 3) {
- mins = parseInt(timeLeft[0]) * 60 + parseInt(timeLeft[1]);
- }
- } catch (err) { shared.devlog(`SG Error reading countdown: ${err}`); }
- return mins;
- };
- function readBalance() {
- let balance = "";
- try {
- balance = document.querySelector('span.text-accent').innerText + " BTC";
- } catch (err) { }
- return balance;
- };
- return {
- run: run,
- processRunDetails: processRunDetails
- };
- }
-
- class AutoCMl extends Faucet {
- constructor() {
- let elements = {
- claimed: new ReadableWidget({selector: 'div.alert.alert-success', parser: Parsers.splitAndIdxTrimNaNs, options: { splitter: ' ', idx: 0} }),
- captcha: new HCaptchaWidget(),
- rollButton: new ButtonWidget({selector: 'input[type="submit"].claim-button'}),
- addressInput: new TextboxWidget({ selector: 'form[role="form"] input[type="text"]'})
- };
- let actions = {
- readTimeLeft: false,
- readRolledNumber: false,
- readBalance: false
- };
- super(elements, actions);
- }
-
- init() {
- this.hideAdBlocker();
- if(this.hasErrorMessage('suspicious activity')) {
- shared.closeWithError(K.ErrorType.ERROR, 'Suspicious Activity Message Displayed');
- return;
- }
- if(this.hasErrorMessage('no funds left') || this.hasErrorMessage('not have sufficient funds')) {
- shared.closeWithError(K.ErrorType.FAUCET_EMPTY, 'Out of Funds');
- return;
- }
-
- if(this.hasErrorMessage('reached the daily claim limit')) {
- let result = {
- nextRoll: this.readNextRoll()
- };
- shared.closeWindow(result);
- return;
- }
-
- let claimed = this.readClaimed();
- if (claimed != 0) {
- if (!location.href.includes('doge')) {
- claimed = claimed/100000000;
- }
- let result = {
- claimed: claimed,
- nextRoll: this.readNextRoll()
- };
- shared.closeWindow(result);
- return;
- }
-
- let waitTime = this.hasWaitTime();
- if (waitTime) {
- let result = {
- nextRoll: helpers.addMinutes(waitTime + 1)
- };
- shared.closeWindow(result);
- return;
- }
-
- if (this.changeCaptcha()) {
- return;
- }
-
- this.setCurrentCaptcha();
-
- if (this._elements.addressInput.isUserFriendly) {
- if (this._elements.addressInput.value != this._params.address) {
- this._elements.addressInput.value = this._params.address;
- }
- }
- this.run();
- }
-
- hideAdBlocker() {
- try {
- document.getElementById("page-body").style.display = "block";
- document.getElementById("blocker-enabled").style.display = "none";
- } catch (err) {}
- setInterval(() => {
- try {
- document.getElementById("page-body").style.display = "block";
- document.getElementById("blocker-enabled").style.display = "none";
- } catch (err) {}
- }, 3000);
- }
-
- changeCaptcha() {
- let selections = [...document.querySelectorAll('div.text-center b')];
- if (selections.length == 0) {
- return false;
- }
- if (selections.filter(x => x.innerText.toLowerCase().includes('hcaptcha')).length != 1) {
- location.href = location.href.includes('?') ? (location.href + '&cc=hCaptcha') : (location.href + '?cc=hCaptcha');
- return true;
- }
- return false;
- }
-
- hasErrorMessage(searchTerm) {
- return document.body.innerText.toLowerCase().includes(searchTerm);
- }
-
- hasWaitTime() {
- try {
- let pInfos = [...document.querySelectorAll('p.alert.alert-info')].filter(x => x.innerText.toLowerCase().includes('you have to wait'));
- if (pInfos.length == 1) {
- let time = +pInfos[0].innerText.toLowerCase().replace('you have to wait ', '').split(' ')[0];
- return time;
- }
- } catch (err) {}
- return false;
- }
-
- readNextRoll() {
- try {
- let spans = [...document.querySelectorAll('div.row div.col-md-5ths span:not(.glyphicon)')];
- let idxClaimsLeft = spans.findIndex(x => x.innerText.includes('daily claims left'));
- if (idxClaimsLeft > -1) {
- if (spans[idxClaimsLeft].innerText.includes('0')) {
- return helpers.addMinutes(60 * 24 + helpers.randomInt(10, 160));
- } else {
- return helpers.addMinutes(helpers.randomInt(5, 12));
- }
- }
- } catch (err) { shared.devlog(`@readNextRoll: ${err}`); }
- return helpers.addMinutes(60 * 24 + helpers.randomInt(10, 160));
- }
- }
-
- class CClicks extends Faucet {
- constructor() {
- let elements = {
- claimed: new ReadableWidget({selector: 'div.alert.alert-success', parser: Parsers.cbgClaimed}),
- captcha: new HCaptchaWidget(),
- rollButton: new ButtonWidget({selector: '#myModal input[type="submit"].btnclaim'}),
- addressInput: new TextboxWidget({ selector: '#myModal input[type="text"]'}),
- openModalButton: new ButtonWidget({selector: 'button[data-target="#myModal"]'})
- };
- let actions = {
- readTimeLeft: false,
- readRolledNumber: false,
- readBalance: false
- };
- super(elements, actions);
- }
-
- async init() {
- if (this.hasCloudflare()) {
- return;
- }
-
- if(this.hasErrorMessage('suspicious activity')) {
- shared.closeWithError(K.ErrorType.ERROR, 'Suspicious Activity Message Displayed');
- return;
- }
- if(this.hasErrorMessage('no funds left') || this.hasErrorMessage('not have sufficient funds')) {
- shared.closeWithError(K.ErrorType.FAUCET_EMPTY, 'Out of Funds');
- return;
- }
- if(this.hasErrorMessage('reached the daily claim limit') || this.hasErrorMessage('reached the daily limit')) {
- let result = {
- nextRoll: helpers.addMinutes(60 * 8 + helpers.randomInt(15, 40))
- };
- shared.closeWindow(result);
- return;
- }
-
- let claimed = this.readClaimed();
- if (claimed != 0) {
- let result = {
- claimed: claimed,
- nextRoll: this.readNextRoll()
- };
- shared.closeWindow(result);
- return;
- }
-
- if (this.changeCaptcha()) {
- return;
- }
-
- if (this._elements.openModalButton.isUserFriendly) {
- this._elements.openModalButton.click();
- await wait(helpers.randomInt(1000, 2000));
- }
-
- if (this._elements.addressInput.isUserFriendly) {
- if (this._elements.addressInput.value != this._params.address) {
- this._elements.addressInput.value = this._params.address;
- }
- }
- this.run();
- }
-
- changeCaptcha() {
- let selections = [...document.querySelectorAll('div.text-center b')];
- if (selections.length == 0) {
- return false;
- }
- if (selections.filter(x => x.innerText.toLowerCase().includes('hcaptcha')).length != 1) {
- location.href = location.href.includes('?') ? (location.href + '&cc=hCaptcha') : (location.href + '?cc=hCaptcha');
- return true;
- }
- return false;
- }
-
- hasErrorMessage(searchTerm) {
- return document.body.innerText.toLowerCase().includes(searchTerm);
- }
-
- readNextRoll() {
- try {
- let p = document.querySelector('p.alert.alert-success');
- if (p && p.innerText.toLowerCase().includes('daily')) {
- p = p.innerText.split('\n')[1];
- p = +p.split(' daily')[0];
-
- if (p > 0) {
- return helpers.addMinutes(helpers.randomInt(3, 9));
- } else {
- return helpers.addMinutes(60 * 8 + helpers.randomInt(15, 40));
- }
- }
- return helpers.addMinutes(helpers.randomInt(3, 9));
- } catch (err) { shared.devlog(`@readNextRoll: ${err}`); }
- return helpers.addMinutes(60 * 8 + helpers.randomInt(15, 40));
- }
- }
-
- let landing, instance, siteTimer;
- let useTimer;
-
- class Site {
- constructor(params) {
- Object.assign(this, {
- schedule: '4a70e0', // Owner!
- id: null,
- name: null,
- cmc: null, // REVIEW LOCATION
- coinRef: null, // REVIEW LOCATION. Only for CFs?
- url: null, // REVIEW FORMAT. Only one/'start' url? What about complex scripts/rotators/SLs?
- rf: null, // ...
- type: null, // REVIEW DEFAULT. It should be something like 'Crawler' or 'Handler' and the site params should depend on this value
- clId: null,
- wallet: null, // should be part of site parameters/crawler based?
- enabled: false,
- lastClaim: 0,
- aggregate: 0,
- balance: 0,
- stats: {},
- nextRoll: null,
- params: {}, // should have schedule overrides and be called customExecution, scheduleParamaters or something like that
- firstRun: true,
- isExternal: false,
- }, params);
-
- this.setLegacyConditionalDefaults();
-
- }
-
- setLegacyConditionalDefaults() {
- if (this.type == K.WebType.CRYPTOSFAUCETS) {
- this.schedule = '65329c';
- }
-
- if (this.type == K.WebType.FREEBITCOIN) {
- this.params['custom.useWofRp'] = 0;
- this.params['custom.useFunRp'] = 0;
- }
-
- if (this.type == K.WebType.STORMGAIN) {
- this.params['defaults.nextRun.override'] = true;
- this.params['defaults.nextRun.useCountdown'] = true;
- this.params['defaults.nextRun'] = 0;
- this.params['defaults.nextRun.min'] = 15;
- this.params['defaults.nextRun.max'] = 20;
- }
- if (this.type == K.WebType.FAUCETPAY) {
- this.params['defaults.workInBackground.override'] = true;
- this.params['defaults.workInBackground'] = false;
- this.params['defaults.nextRun.override'] = true;
- this.params['defaults.nextRun.useCountdown'] = false;
- this.params['defaults.nextRun'] = 0;
- this.params['defaults.nextRun.min'] = 300;
- this.params['defaults.nextRun.max'] = 360;
- }
- if (this.type == K.WebType.BIGBTC) {
- this.params['defaults.nextRun.override'] = true;
- this.params['defaults.nextRun.useCountdown'] = false;
- this.params['defaults.nextRun'] = 0;
- this.params['defaults.nextRun.min'] = 15;
- this.params['defaults.nextRun.max'] = 40;
- }
- if (this.type == K.WebType.DUTCHYROLL) {
- this.params['defaults.nextRun.override'] = true;
- this.params['defaults.nextRun.useCountdown'] = true;
- this.params['defaults.nextRun'] = 0;
- this.params['defaults.nextRun.min'] = 30;
- this.params['defaults.nextRun.max'] = 35;
- }
- if (this.type == K.WebType.FCRYPTO) {
- this.params['defaults.workInBackground.override'] = true;
- this.params['defaults.workInBackground'] = false;
- this.params['defaults.nextRun.override'] = true;
- this.params['defaults.nextRun.useCountdown'] = false;
- this.params['defaults.nextRun'] = 0;
- this.params['defaults.nextRun.min'] = 26;
- this.params['defaults.nextRun.max'] = 35;
- this.params['defaults.timeout.override'] = true;
- this.params['defaults.timeout'] = 3;
- this.params['defaults.postponeMinutes.override'] = true;
- this.params['defaults.postponeMinutes'] = 0;
- this.params['defaults.postponeMinutes.min'] = 12;
- this.params['defaults.postponeMinutes.max'] = 18;
- }
- if (this.type == K.WebType.FPB) {
- this.params['defaults.nextRun.override'] = true;
- this.params['defaults.nextRun.useCountdown'] = false;
- this.params['defaults.nextRun'] = 0;
- this.params['defaults.nextRun.min'] = 22;
- this.params['defaults.nextRun.max'] = 45;
- }
- }
-
- static _sites = [];
- static getAll() {
- return Site._sites;
- }
-
- static getById(siteId) {
- return Site.getAll().find(x => x.id == siteId) || false;
- }
-
- static createFromDataArray(newSites) {
- if (!Array.isArray(newSites)) {
- newSites = [...newSites];
- }
- newSites.forEach(s => Site.getAll().push(new Site(s)));
- }
-
- static add(data) {
- let newSite = new Site(data);
- Site.getAll().push(newSite);
-
- let schedule = Schedule.getById(newSite.schedule);
-
- if (!schedule) {
- try {
- schedule = Schedule.getAll()[0];
- } catch (err) {
- console.warn('No schedules found! Reseting to default schedules');
- let defaultSchedule = new Schedule({ uuid: '4a70e0', name: 'Default' });
- let sampleSchedule = new Schedule({ uuid: '65329c', name: 'CF' });
- if (Schedule.getAll().length == 0) {
- Schedule.add(defaultSchedule);
- Schedule.add(sampleSchedule);
- }
- schedule = Schedule.getAll()[0];
- }
- }
-
- if (!schedule) {
- console.warn('Schedule NOT found');
- console.warn(data);
- return;
- }
- schedule.addSite(newSite);
-
- eventer.emit('siteAdded', {
- siteId: newSite.id,
- siteName: newSite.name,
- scheduleId: newSite.schedule
- });
- }
-
- static remove(siteId) {
- let idx = this._sites.findIndex(x => x.id === siteId);
- if (idx > -1 && this._sites[idx].isExternal) {
- let siteName = this._sites[idx].name;
- this._sites = Site.getAll().filter(x => x.id !== siteId);
- Schedule.getAll().forEach(sch => {
- sch.removeSite(siteId);
- });
- eventer.emit('siteRemoved', {
- siteId: siteId,
- siteName: siteName
- });
- }
-
- }
-
- static sortAll() {
- Site.getAll().sort( function(a,b) {
- if (a === b) {
- return 0;
- } else if (a.nextRoll === null && b.nextRoll === null) {
- let aHasLoginError = a.stats?.errors?.errorType == 2;
- let bHasLoginError = b.stats?.errors?.errorType == 2;
- if (aHasLoginError) {
- return -1;
- } else if (bHasLoginError) {
- return 1;
- }
- return a.id > b.id ? -1 : 1
- } else if (a.nextRoll === null) {
- return 1;
- } else if (b.nextRoll === null) {
- return -1;
- } else {
- return a.nextRoll.getTime() < b.nextRoll.getTime() ? -1 : 1;
- }
- });
- }
-
- static setAsRunAsap(siteId) {
- let site = Site.getById(siteId);
- if (!site) return false;
-
- try {
- let schedule = Schedule.getById(site.schedule);
- if (schedule.status == STATUS.CLAIMING) {
- console.warn(`Setting ASAP as 1st in schedule time + 1`);
- site.nextRoll = new Date(schedule.currentSite.nextRoll.getTime() + 1);
- } else {
- let now = new Date();
- if (!schedule.currentSite?.nextRoll) {
- console.warn(`Setting ASAP as now()`);
- site.nextRoll = now;
- } else if (now < schedule.currentSite.nextRoll) {
- console.warn(`Setting ASAP as now()`);
- site.nextRoll = now;
- } else {
- console.warn(`Setting ASAP as 1st in schedule time - 1`);
- site.nextRoll = new Date(schedule.currentSite.nextRoll.getTime() - 1);
- }
- }
- site.enabled = true;
-
- console.warn(`[${site.schedule}] ${site.name} updated to run ASAP from Site`);
- eventer.emit('siteUpdated', site);
- return;
- } catch (err) {
- console.error(err);
- ui.log({msg: `Error setting faucet to run ASAP from Site: ${err}`});
- }
- }
-
- changeSchedule(newScheduleId) {
- let oldScheduleId = null;
- if (this.schedule) {
- oldScheduleId = this.schedule;
- Schedule.getById(this.schedule)?.removeSite(this.id);
- }
- this.schedule = newScheduleId;
- let newSchedule = Schedule.getById(this.schedule);
- newSchedule.addSite(this); // maybe use just the ids...
- eventer.emit('siteChangedSchedule', {
- siteId: this.id,
- scheduleId: this.schedule,
- oldScheduleId: oldScheduleId
- });
- }
-
- static saveAll() {
- persistence.save('webList', Site._sites.map(x => x.toStorage()), true);
- }
-
- toStorage() { // Single site
- if (!this.isExternal) {
- return {
- id: this.id,
- isExternal: this.isExternal || false,
- name: this.name,
- schedule:this.schedule,
- lastClaim: this.lastClaim,
- aggregate: this.aggregate,
- balance: this.balance,
- stats: this.stats,
- nextRoll: this.nextRoll,
- enabled: this.enabled,
- params: this.params
- };
- } else {
- return {
- id: this.id,
- url: this.url.href,
- clId: this.clId,
- type: this.type,
- cmc: this.cmc,
- rf: this.rf,
- name: this.name,
- isExternal: this.isExternal || false,
- schedule:this.schedule,
- lastClaim: this.lastClaim,
- aggregate: this.aggregate,
- balance: this.balance,
- stats: this.stats,
- nextRoll: this.nextRoll,
- enabled: this.enabled,
- params: this.params
- };
- }
- }
-
- update(items) { // this should be for Parameters or Execution (custom)
- this.params = this.params || {};
- items.forEach( item => {
- this.params[item.prop] = item.value;
- });
- ui.log({schedule: this.schedule, siteName: this.name, msg: `Site ${this.name} updated`});
- }
-
- getSiteParameters() {
- if (this.type == K.WebType.CRYPTOSFAUCETS) {
- this.siteParameters = {
- handler: 'CF',
- fields: [
- { name: 'try_get_codes', type: 'checkbox', value: 'false', text: 'Auto update promo codes' },
- { name: 'max_rolls_per_visit', type: 'numberInput', value: 1, min: 0 },
- { name: 'autologin', type: 'checkbox', value: 'true', text: 'Autologin when necessary' },
- { name: 'credentials_mode', type: 'credentials_or_autofilled', value: '2' },
- { name: 'email', type: 'email', value: '' },
- { name: 'password', type: 'password', value: '' }
- ]
- };
- }
- return this.siteParameters || false;
- }
- }
- class Schedule {
- constructor(params) {
- Object.assign(this, {
- uuid: '4a70e0',
- name: 'default_schedule',
- status: STATUS.INITIALIZING,
- currentSite: null,
- sites: [],
- tab: null,
- timer: null, // TBD
- timeWaiting: 0,
- timeUntilNext: null,
- worker: null
- }, params)
- this.timer = new Timer({ isManager: true, delaySeconds: 30, uuid: this.uuid, webType: null });
- }
-
- static schedules = [];
-
- static getAll() {
- return Schedule.schedules;
- }
-
- static getById(scheduleId) {
- return Schedule.getAll().find(x => x.uuid == scheduleId) || false;
- }
-
- static add(newSchedule) {
- Schedule.getAll().push(newSchedule);
- }
-
- static getAllForCrud() {
- return Schedule.getAll().map(x => {
- return {
- uuid: x.uuid,
- name: x.name,
- hasSites: x.sites && x.sites.length > 0
- };
- });
- }
-
- static async initialize() {
-
- Schedule.loadAll();
-
- let defaultSchedule = new Schedule({ uuid: '4a70e0', name: 'Default' });
- let sampleSchedule = new Schedule({ uuid: '65329c', name: 'CF' });
- if (Schedule.getAll().length == 0) {
- Schedule.add(defaultSchedule);
- Schedule.add(sampleSchedule);
- return;
- }
-
- let idxDefault = Schedule.getAll().findIndex(x => x.uuid == '4a70e0');
- if (idxDefault == -1) {
- Schedule.add(defaultSchedule);
- }
- };
-
- static saveAll() {
- persistence.save('schedules', Schedule.schedules.map(x => {
- return {
- uuid: x.uuid,
- name: x.name
- };
- }), true);
- }
-
- static loadAll() {
- Schedule.schedules = [];
- let schedulesJson = persistence.load('schedules', true) || [];
- schedulesJson.forEach(function(element) {
- Schedule.getAll().push(new Schedule({
- uuid: element.uuid,
- name: element.name,
- }));
- });
- }
-
- sortSites() {
- this.sites.sort( function(a,b) {
- if (a === b) {
- return 0;
- } else if (a.nextRoll === null && b.nextRoll === null) {
- let aHasLoginError = a.stats?.errors?.errorType == 2;
- let bHasLoginError = b.stats?.errors?.errorType == 2;
- if (aHasLoginError) {
- return -1;
- } else if (bHasLoginError) {
- return 1;
- }
- return a.id > b.id ? -1 : 1
- } else if (a.nextRoll === null) {
- return 1;
- } else if (b.nextRoll === null) {
- return -1;
- } else {
- return a.nextRoll.getTime() < b.nextRoll.getTime() ? -1 : 1;
- }
- });
- }
-
- static crud(data) {
- let isInvalid = false;
- try {
- const orphanSites = [];
- data.forEach(x => {
- if (x.added) {
- if (Schedule.getById(x.uuid)) {
- isInvalid = true;
- } else {
- let newSchedule = new Schedule({
- uuid: x.uuid,
- name: x.name,
- order: x.order
- })
- Schedule.getAll().push(newSchedule);
- newSchedule.start();
- }
- } else if (x.removed) {
- let pos = Schedule.getAll().findIndex(s => s.uuid == x.originals.uuid);
- orphanSites.push(...Schedule.getAll()[pos].sites);
- Schedule.getAll().splice(pos, 1);
- } else {
- let sch = Schedule.getAll().find(s => s.uuid == x.originals.uuid);
- if (Schedule.getById(x.uuid) && (Schedule.getById(x.uuid) != sch)) {
- isInvalid = true;
- } else {
- sch.uuid = x.uuid;
- }
- sch.name = x.name;
- sch.order = x.order;
- }
- });
-
- Schedule.getAll().sort((a, b) => a.order - b.order);
-
- if (orphanSites.length > 0) {
- orphanSites.forEach(x => {
- x.schedule = Schedule.getAll()[0].uuid;
- });
-
- Schedule.getAll()[0].sites.push(...orphanSites);
- }
- Schedule.saveAll();
- } catch (err) {
- console.error(err);
- return false;
- }
- if (isInvalid) {
- return false;
- }
- return true;
- }
-
- addSite(site) { this.sites.push(site) }
- removeSite(siteId) {
- if (this.sites.findIndex(x => x.id === siteId) > -1) {
- this.sites = this.sites.filter(x => x.id !== siteId);
- this.setCurrentSite();
- }
- }
-
- setCurrentSite() {
- this.currentSite = this.sites[0];
- }
-
- start() {
- this.status = STATUS.IDLE;
- this.worker = setTimeout(() => {
- this.checkNextRoll();
- }, 2000);
- }
-
- checkNextRoll() {
- if (this.status != STATUS.IDLE) {
- return;
- }
- this.timer.stopCheck();
- clearTimeout(this.worker);
- if(!this.currentSite || this.currentSite.nextRoll == null) {
- document.querySelector(`#wait-times span[data-schedule="${this.uuid}"]`).setAttribute('data-nextroll', 'UNDEFINED');
- this.status = STATUS.IDLE;
- return;
- }
-
- if(this.currentSite.nextRoll.getTime() < Date.now()) {
- ui.log({ schedule: this.uuid, siteName: this.currentSite.name, msg: `Opening ${this.currentSite.name}`});
- document.querySelector(`#wait-times span[data-schedule="${this.uuid}"]`).setAttribute('data-nextroll', 'RUNNING');
- this.open();
- this.timeUntilNext = null;
- return;
- } else {
- this.timeUntilNext = this.currentSite.nextRoll.getTime() - Date.now() + helpers.randomMs(1000, 2000);
-
- document.querySelector(`#wait-times span[data-schedule="${this.uuid}"]`).setAttribute('data-nextroll', this.currentSite.nextRoll.getTime());
- this.worker = setTimeout(() => {
- this.checkNextRoll();
- }, this.timeUntilNext);
- this.status = STATUS.IDLE;
- }
- }
-
- getCustomOrDefaultVal(param, useOverride = false) {
- let val;
-
- if (useOverride) {
- if (this.currentSite.params && this.currentSite.params.hasOwnProperty(param)) {
- val = this.currentSite.params[param];
- if (val != -1) {
- return val;
- }
- }
- }
-
- return shared.getConfig()[param];
- }
-
- useOverride(param) {
- let overrideFlag = param + '.override';
- return this.currentSite.params && this.currentSite.params[overrideFlag];
- }
-
- closeTab() {
- try {
- this.tab.close();
- } catch (err) {
- console.warn('Error while trying to close tab', err);
- }
- };
-
- reopenTab() {
- this.tab = GM_openInTab(this.currentSite.url, { active: !this.getCustomOrDefaultVal('defaults.workInBackground', this.useOverride('defaults.workInBackground')) });
- };
-
- open(promoCodes) {
- this.status = STATUS.CLAIMING;
- let navUrl = this.currentSite.url;
- try {
- let params = this.currentSite.params || {};
- params.siteParams = this.currentSite.siteParams || { "test": "test_value" };
-
- if(promoCodes) {
- navUrl = new URL('promotion/' + promoCodes[0], this.currentSite.url.origin);
- ui.log({ schedule: this.uuid, siteName: this.currentSite.name, msg: `Opening ${this.currentSite.name} with ${promoCodes.length} Promo Codes [${promoCodes.join(',')}]`});
- params.promoCodes = promoCodes;
- }
-
- if (this.currentSite.firstRun) {
- if(Array.isArray(this.currentSite.rf) && this.currentSite.rf.length > 0) {
- navUrl = new URL(navUrl.href + this.currentSite.rf[helpers.randomInt(0, this.currentSite.rf.length - 1)]);
- }
- }
-
- if (this.currentSite.wallet) {
- try {
- params.address = manager.userWallet.find(x => x.type == this.currentSite.wallet)?.address;
- if (!params.address) {
- throw new Error('Address is not defined.');
- }
- } catch {
- ui.log({ schedule: this.uuid, siteName: this.currentSite.name, msg: `Unable to launch ${this.currentSite.name}: Address not detected > add it to the wallet.`});
- this.moveNextAfterTimeoutOrError();
- return;
- }
- }
- if(this.currentSite.type == K.WebType.BESTCHANGE) {
- params.address = shared.getConfig()['bestchange.address'] == '1' ? manager.userWallet.find(x => x.type == 1).address : params.address;
- }
- params.timeout = this.getCustomOrDefaultVal('defaults.timeout', this.useOverride('defaults.timeout'));
- params.cmc = this.currentSite.cmc;
-
- if(this.currentSite.type == K.WebType.FPB) {
- switch(this.currentSite.id) {
- case '77':
- params.sitePrefix = 'fpb';
- break;
- case '83':
- params.sitePrefix = 'fbch';
- break;
- case '92':
- params.sitePrefix = 'shost';
- break;
- }
- }
-
- if(this.currentSite.type == K.WebType.VIE) {
- params.credentials = {
- mode: shared.getConfig()['jtfey.credentials.mode'],
- username: shared.getConfig()['jtfey.credentials.username'],
- password: shared.getConfig()['jtfey.credentials.password']
- };
- }
-
- shared.setFlowControl(this.uuid, this.currentSite.id, navUrl, this.currentSite.type, params);
- setTimeout(() => {
- this.waitForResult();
- }, 15000);
-
- if (this.tab && !this.tab.closed) {
- this.closeTab(); // this.tab.close();
- } else {
- }
-
- this.timer.startCheck(this.currentSite.type);
- let noSignUpList = [ K.WebType.BESTCHANGE, K.WebType.CBG, K.WebType.G8, K.WebType.O24, K.WebType.CDIVERSITY, K.WebType.CTOP, K.WebType.AUTOCML, K.WebType.CCLICKS ];
- let hrefOpener = navUrl.href;
- if (noSignUpList.includes(this.currentSite.type)) {
- hrefOpener = (new URL(this.currentSite.clId, 'https://criptologico.com/goto/')).href;
- }
-
- this.tab = GM_openInTab(hrefOpener, { active: !this.getCustomOrDefaultVal('defaults.workInBackground', this.useOverride('defaults.workInBackground')) });
- } catch(err) {
- ui.log({ schedule: this.uuid, msg: `Error opening tab: ${err}`});
- }
- };
-
- waitForResult() {
- if(manager.isObsolete()) {
- return;
- }
-
- if(shared.isCompleted(this.currentSite.id)) {
- this.analyzeResult(); // rename to something else...
- return;
- }
-
- this.timeWaiting += 15;
- if(shared.isIncompleted(this.currentSite.id) && this.hasTimedOut()) {
- this.analyzeResult(); // rename to something else...
- return;
- }
-
- this.waitOrMoveNext(); // this should just be the error and timeout check
- return;
-
- };
-
- analyzeResult() {
-
- let currentSchedule = shared.getCurrent(this.uuid);
- currentSchedule.result = currentSchedule.result || {};
- currentSchedule.runStatus = currentSchedule.runStatus || false;
-
- if (currentSchedule.result) {
- this.updateWebListItem(currentSchedule);
-
- if (currentSchedule.result.closeParentWindow) {
- ui.log({ schedule: this.uuid, msg: `Closing working tab per process request` });
- this.closeTab();
- }
-
- if (shared.getConfig()['cf.usePromoCodes'] && this.currentSite.type == K.WebType.CRYPTOSFAUCETS) {
- let promoCode = CFPromotions.hasPromoAvailable(this.currentSite.id);
- if (promoCode) {
- this.timeWaiting = 0;
-
- this.currentSite.nextRoll = new Date(754000 + +this.currentSite.id);
- manager.update(false);
- this.open(promoCode);
- return;
- }
- }
- } else {
- ui.log({ schedule: this.uuid, siteName: this.currentSite.name, msg: `Unable to read last run result, for ID: ${this.currentSite.id} > ${this.currentSite.name}`});
- }
-
- this.timeWaiting = 0;
- this.status = STATUS.IDLE;
- shared.clearFlowControl(this.uuid);
- manager.update(true);
- manager.readUpdateValues(true);
- return;
- }
-
- waitOrMoveNext() {
- if (this.currentSite.isExternal) {
- if (!this.tab || (this.tab && this.tab.closed)) {
- this.timeWaiting = this.getCustomOrDefaultVal('defaults.timeout', this.useOverride('defaults.timeout')) * 60 + 9999;
- }
- }
- if (!shared.hasErrors(this.currentSite.id) && !this.hasTimedOut()) {
- ui.log({ schedule: this.uuid,
- siteName: this.currentSite.name,
- elapsed: this.timeWaiting,
- msg: `Waiting for ${this.currentSite.name} results...`});
- setTimeout(() => {
- this.waitForResult();
- }, 15000);
- return;
- }
-
- if (shared.hasErrors(this.currentSite.id)) {
- this.currentSite.stats.errors = shared.getResult(this.uuid); // shared.getResult(this.uuid);
-
- ui.log({ schedule: this.uuid, siteName: this.currentSite.name,
- msg: `${this.currentSite.name} closed with error: ${helpers.getEnumText(K.ErrorType,this.currentSite.stats.errors.errorType)} ${this.currentSite.stats.errors.errorMessage}`});
-
- if(this.sleepIfBan()) {
- return;
- }
- }
-
- if (this.hasTimedOut()) {
- if (this.currentSite.isExternal) {
- this.currentSite.stats.countTimeouts = 0;
- this.currentSite.stats.errors = null;
- ui.log({ schedule: this.uuid, siteName: this.currentSite.name,
- msg: `Closing ${this.currentSite.name}` });
- try {
- this.closeTab();
- } catch (err) { console.error('Unable to close working tab', err); }
- this.moveAfterNormalRun();
- return;
- } else {
- if(this.currentSite.stats.countTimeouts) {
- this.currentSite.stats.countTimeouts += 1;
- } else {
- this.currentSite.stats.countTimeouts = 1;
- }
-
- ui.log({ schedule: this.uuid, siteName: this.currentSite.name,
- msg: `Waited too much time for ${this.currentSite.name} results: triggering timeout` });
- }
- }
-
- this.moveNextAfterTimeoutOrError();
- return;
- }
-
- hasTimedOut() { // here or on a site level???
- let val = this.getCustomOrDefaultVal('defaults.timeout', this.useOverride('defaults.timeout')) * 60;
- return (this.timeWaiting > val);
- };
-
- sleepIfBan() { // This should be a SiteType hook
- if( (this.currentSite.stats.errors.errorType == K.ErrorType.IP_BAN && shared.getConfig()['cf.sleepHoursIfIpBan'] > 0)
- || ( (this.currentSite.stats.errors.errorType == K.ErrorType.IP_RESTRICTED || this.currentSite.stats.errors.errorType == K.ErrorType.IP_BAN) && shared.getConfig()['bk.sleepMinutesIfIpBan'] > 0) ) {
- if(this.currentSite.type == K.WebType.CRYPTOSFAUCETS) {
- Site.getAll().filter(x => x.enabled && x.type == K.WebType.CRYPTOSFAUCETS)
- .forEach( function(el) {
- el.nextRoll = this.sleepCheck(helpers.addMs(helpers.getRandomMs(shared.getConfig()['cf.sleepHoursIfIpBan'] * 60, 2)).toDate());
- });
- }
-
- shared.clearFlowControl(this.uuid);
- manager.update(true);
- this.timeWaiting = 0;
- this.status = STATUS.IDLE;
- shared.clearFlowControl(this.uuid);
- manager.readUpdateValues(true);
- return true;
- }
- return false;
- }
-
- updateWebListItem(currentSchedule) {
- let result = currentSchedule.result;
-
- ui.log({ schedule: this.uuid,
- msg: `Updating data: ${JSON.stringify(result)}` });
- this.currentSite.stats.countTimeouts = 0;
- this.currentSite.stats.errors = null;
-
- if (result.claimed) {
- try {
- result.claimed = parseFloat(result.claimed);
- } catch { }
- if(!isNaN(result.claimed)) {
- this.currentSite.lastClaim = result.claimed;
- this.currentSite.aggregate += result.claimed;
- }
- }
- if(result.balance) {
- this.currentSite.balance = result.balance;
- }
- this.currentSite.nextRoll = this.getNextRun(result.nextRoll ? result.nextRoll.toDate() : null);
- if(result.promoCodeResults) { // TODO: move to a processResult hook
- for(let i = 0; i < result.promoCodeResults.length; i++) {
- let item = result.promoCodeResults[i];
- CFPromotions.updateFaucetForCode(item.promoCode, this.currentSite.id, item.promoStatus);
- }
- }
- if(result.rolledNumber) {
- CFHistory.addRoll(result.rolledNumber);
- }
- }
-
- getNextRun(nextRollFromCountdown) {
- let useCustom = this.useOverride('defaults.nextRun');
- let useCountdown = this.getCustomOrDefaultVal('defaults.nextRun.useCountdown', useCustom);
- let nextRunMode = this.getCustomOrDefaultVal('defaults.nextRun', useCustom);
- let min = this.getCustomOrDefaultVal('defaults.nextRun.min', useCustom);
- let max = this.getCustomOrDefaultVal('defaults.nextRun.max', useCustom);
- let nextRun;
-
- if (useCountdown && nextRollFromCountdown) {
- nextRun = nextRollFromCountdown;
- } else {
- let minutes = (nextRunMode == 0) ? helpers.randomInt(min, max) : nextRunMode;
- let msDelay = helpers.getRandomMs(minutes, 1);
-
- nextRun = helpers.addMs(msDelay).toDate();
- }
- nextRun = this.sleepCheck(nextRun)
-
- return nextRun;
- }
-
- errorTreatment() { // Move to group custom getNextRoll
- try {
- switch(this.currentSite.stats.errors.errorType) {
- case K.ErrorType.NEED_TO_LOGIN:
- this.currentSite.enabled = false;
- this.currentSite.nextRoll = null;
- return true;
- case K.ErrorType.FAUCET_EMPTY: // retry in 8 hours
- this.currentSite.enabled = true;
- this.currentSite.nextRoll = new Date(new Date().setHours(new Date().getHours() + 8));
- return true;
- }
- } catch {}
- return false;
- }
-
- sleepCheck(nextRun) {
- let useCustom = this.useOverride('defaults.sleepMode');
- let sleepMode = this.getCustomOrDefaultVal('defaults.sleepMode', useCustom);
-
- if (sleepMode) {
- let intNextRunTime = nextRun.getHours() * 100 + nextRun.getMinutes();
- let min = this.getCustomOrDefaultVal('defaults.sleepMode.min', useCustom).replace(':', '');
- let max = this.getCustomOrDefaultVal('defaults.sleepMode.max', useCustom).replace(':', '');
-
- if (+min < +max) {
- if (+min < intNextRunTime && intNextRunTime < +max) {
- nextRun.setHours(max.slice(0, 2), max.slice(-2), 10, 10);
- ui.log({ schedule: this.uuid,
- msg: `Next run adjusted by Sleep Mode: ${helpers.getPrintableDateTime(nextRun)}` });
- }
- } else if (+min > +max) {
- if (intNextRunTime > +min || intNextRunTime < +max) {
- nextRun.setHours(max.slice(0, 2), max.slice(-2), 10, 10);
- if (nextRun.getTime() < Date.now()) {
- nextRun.setDate(nextRun.getDate() + 1);
- }
- ui.log({ schedule: this.uuid,
- msg: `Next run adjusted by Sleep Mode: ${helpers.getPrintableDateTime(nextRun)}` });
- }
- }
- }
- return nextRun;
- }
-
- moveAfterNormalRun() {
- this.currentSite.nextRoll = this.getNextRun(null);
-
- shared.clearFlowControl(this.uuid);
- manager.update(true);
- this.timeWaiting = 0;
- this.status = STATUS.IDLE;
- shared.clearFlowControl(this.uuid);
- manager.readUpdateValues(true);
- }
-
- moveNextAfterTimeoutOrError() {
- let useCustom = this.useOverride('defaults.postponeMinutes');
-
- let mode = this.getCustomOrDefaultVal('defaults.postponeMinutes', useCustom);
- let min = this.getCustomOrDefaultVal('defaults.postponeMinutes.min', useCustom);
- let max = this.getCustomOrDefaultVal('defaults.postponeMinutes.max', useCustom);
-
- let minutes = (mode == 0) ? helpers.randomInt(min, max) : mode;
- let msDelay = helpers.getRandomMs(minutes, 5);
-
- this.currentSite.nextRoll = this.sleepCheck(helpers.addMs(msDelay).toDate());
- if(this.errorTreatment()) {
- }
-
- shared.clearFlowControl(this.uuid);
- manager.update(true);
- this.timeWaiting = 0;
- this.status = STATUS.IDLE;
- shared.clearFlowControl(this.uuid);
- manager.readUpdateValues(true);
- }
- }
-
- function createManager() {
- let timestamp = null;
- let intervalUiUpdate;
- let getFeedInterval;
-
- let userWallet = [];
-
- const sites = [
- { id: '1', name: 'CF ADA', cmc: '2010', coinRef: 'ADA', url: new URL('https://app.freecardano.com/free'), rf: '?ref=335463', type: K.WebType.CRYPTOSFAUCETS, clId: 45 },
- { id: '2', name: 'CF BNB', cmc: '1839', coinRef: 'BNB', url: new URL('https://app.freebinancecoin.com/free'), rf: '?ref=161127', type: K.WebType.CRYPTOSFAUCETS, clId: 42 },
- { id: '3', name: 'CF BTC', cmc: '1', coinRef: 'BTC', url: new URL('https://app.freebitcoin.io/free'), rf: '?ref=490252', type: K.WebType.CRYPTOSFAUCETS, clId: 40 },
- { id: '4', name: 'CF DASH', cmc: '131', coinRef: 'DASH', url: new URL('https://app.freedash.io/free'), rf: '?ref=124083', type: K.WebType.CRYPTOSFAUCETS, clId: 156 },
- { id: '5', name: 'CF ETH', cmc: '1027', coinRef: 'ETH', url: new URL('https://app.freeethereum.com/free'), rf: '?ref=204076', type: K.WebType.CRYPTOSFAUCETS, clId: 44 },
- { id: '6', name: 'CF LINK', cmc: '1975', coinRef: 'LINK', url: new URL('https://app.freecryptom.com/free'), rf: '?ref=78652', type: K.WebType.CRYPTOSFAUCETS, clId: 157 },
- { id: '7', name: 'CF LTC', cmc: '2', coinRef: 'LTC', url: new URL('https://app.free-ltc.com/free'), rf: '?ref=117042', type: K.WebType.CRYPTOSFAUCETS, clId: 47 },
- { id: '8', name: 'CF NEO', cmc: '1376', coinRef: 'NEO', url: new URL('https://app.freeneo.io/free'), rf: '?ref=100529', type: K.WebType.CRYPTOSFAUCETS, clId: 158 },
- { id: '9', name: 'CF STEAM', cmc: '825', coinRef: 'STEEM', url: new URL('https://app.freesteam.io/free'), rf: '?ref=117686', type: K.WebType.CRYPTOSFAUCETS, clId: 49 },
- { id: '10', name: 'CF TRX', cmc: '1958', coinRef: 'TRX', url: new URL('https://app.free-tron.com/free'), rf: '?ref=145047', type: K.WebType.CRYPTOSFAUCETS, clId: 41 },
- { id: '11', name: 'CF USDC', cmc: '3408', coinRef: 'USDC', url: new URL('https://app.freeusdcoin.com/free'), rf: '?ref=100434', type: K.WebType.CRYPTOSFAUCETS, clId: 51 },
- { id: '12', name: 'CF USDT', cmc: '825', coinRef: 'USDT', url: new URL('https://app.freetether.com/free'), rf: '?ref=181230', type: K.WebType.CRYPTOSFAUCETS, clId: 43 },
- { id: '13', name: 'CF XEM', cmc: '873', coinRef: 'XEM', url: new URL('https://app.freenem.com/free'), rf: '?ref=295274', type: K.WebType.CRYPTOSFAUCETS, clId: 46 },
- { id: '14', name: 'CF XRP', cmc: '52', coinRef: 'XRP', url: new URL('https://app.coinfaucet.io/free'), rf: '?ref=808298', type: K.WebType.CRYPTOSFAUCETS, clId: 48 },
- { id: '15', name: 'StormGain', cmc: '1', url: new URL('https://app.stormgain.com/crypto-miner/'), rf: 'friend/BNS27140552', type: K.WebType.STORMGAIN, clId: 35 },
- { id: '16', name: 'CF DOGE', cmc: '74', coinRef: 'DOGE', url: new URL('https://app.free-doge.com/free'), rf: '?ref=97166', type: K.WebType.CRYPTOSFAUCETS, clId: 50 },
- { id: '17', name: 'FreeBitco.in', cmc: '1', url: new URL('https://freebitco.in/'), rf: '?r=41092365', type: K.WebType.FREEBITCOIN, clId: 36 },
- { id: '18', name: 'FaucetPay PTC', cmc: '825', url: new URL('https://faucetpay.io/ptc'), rf: '?r=41092365', type: K.WebType.FAUCETPAY, clId: 159 },
- { id: '52', name: 'BigBtc', cmc: '1', wallet: K.WalletType.FP_BTC, url: new URL('https://bigbtc.win/'), rf: '?id=39255652', type: K.WebType.BIGBTC, clId: 200 },
- { id: '53', name: 'BestChange', cmc: '1', url: new URL('https://www.bestchange.com/'), rf: ['index.php?nt=bonus&p=1QCD6cWJNVH4Cdnz85SQ2qtTkAwGr9fvUk'], type: K.WebType.BESTCHANGE, clId: 163 },
- { id: '58', name: 'BF BTC', cmc: '1', url: new URL('https://betfury.io/boxes/all'), rf: ['?r=608c5cfcd91e762043540fd9'], type: K.WebType.BFBOX, clId: 1 },
- { id: '61', name: 'Dutchy', cmc: '-1', url: new URL('https://autofaucet.dutchycorp.space/roll.php'), rf: '?r=corecrafting', type: K.WebType.DUTCHYROLL, clId: 141 },
- { id: '62', name: 'Dutchy Monthly Coin', cmc: '-1', url: new URL('https://autofaucet.dutchycorp.space/coin_roll.php'), rf: '?r=corecrafting', type: K.WebType.DUTCHYROLL, clId: 141 },
- { id: '68', name: 'CF SHIBA', cmc: '5994', coinRef: 'SHIBA', url: new URL('https://app.freeshibainu.com/free'), rf: '?ref=18226', type: K.WebType.CRYPTOSFAUCETS, clId: 167 },
- { id: '78', name: 'CF Cake', cmc: '7186', coinRef: 'CAKE', url: new URL('https://app.freepancake.com/free'), rf: '?ref=699', type: K.WebType.CRYPTOSFAUCETS, clId: 197 },
- { id: '80', name: 'FreeGRC', cmc: '833', url: new URL('https://freegridco.in/#free_roll'), rf: '', type: K.WebType.FREEGRC, clId: 207 },
- { id: '81', name: 'CF Matic', cmc: '3890', coinRef: 'MATIC', url: new URL('https://app.freematic.com/free'), rf: '?ref=6435', type: K.WebType.CRYPTOSFAUCETS, clId: 210 },
- { id: '84', name: 'JTFey', cmc: '-1', url: new URL('https://james-trussy.com/faucet'), rf: ['?r=corecrafting'], type: K.WebType.VIE, clId: 213 },
- { id: '85', name: 'O24', cmc: '1', wallet: K.WalletType.FP_BTC, url: new URL('https://www.only1024.com/f'), rf: ['?r=1QCD6cWJNVH4Cdnz85SQ2qtTkAwGr9fvUk'], type: K.WebType.O24, clId: 97 },
- { id: '87', name: 'CF BTT', cmc: '16086', coinRef: 'BTT', url: new URL('https://app.freebittorrent.com/free'), rf: '?ref=2050', type: K.WebType.CRYPTOSFAUCETS, clId: 218 },
- { id: '89', name: 'CF BFG', cmc: '11038', coinRef: 'BFG', url: new URL('https://app.freebfg.com/free'), rf: '?ref=117', type: K.WebType.CRYPTOSFAUCETS, clId: 219 },
- { id: '93', name: 'YCoin', cmc: '1', url: new URL('https://yescoiner.com/faucet'), rf: ['?ref=4729452'], type: K.WebType.YCOIN, clId: 234 },
- { id: '94', name: 'CDiversity', cmc: '-1', wallet: K.WalletType.FP_MAIL, url: new URL('http://coindiversity.io/free-coins'), rf: ['?r=1J3sLBZAvY5Vk9x4RY2qSFyL7UHUszJ4DJ'], type: K.WebType.CDIVERSITY, clId: 235 },
- { id: '96', name: 'Top Ltc', cmc: '2', wallet: K.WalletType.FP_LTC, url: new URL('https://ltcfaucet.top/'), rf: ['?r=MWSsGAQTYD7GH5o4oAehC8Et5PyMBfhnKK'], type: K.WebType.CTOP, clId: 239 },
- { id: '97', name: 'Top Bnb', cmc: '1839', wallet: K.WalletType.FP_BNB, url: new URL('https://bnbfaucet.top/'), rf: ['?r=0x1e8CB8A79E347C54aaF21C0502892B58F97CC07A'], type: K.WebType.CTOP, clId: 240 },
- { id: '98', name: 'Top Doge', cmc: '74', wallet: K.WalletType.FP_DOGE, url: new URL('https://dogecoinfaucet.top/'), rf: ['?r=D8Xgghu5gCryukwmxidFpSmw8aAKon2mEQ'], type: K.WebType.CTOP, clId: 241 },
- { id: '99', name: 'Top Trx', cmc: '1958', wallet: K.WalletType.FP_TRX, url: new URL('https://tronfaucet.top/'), rf: ['?r=TK3ofbD3AyXotN2111UvnwCzr2YaW8Qmx7'], type: K.WebType.CTOP, clId: 242 },
- { id: '100', name: 'Top Eth', cmc: '1027', wallet: K.WalletType.FP_ETH, url: new URL('https://ethfaucet.top/'), rf: ['?r=0xC21FD989118b8C0Db6Ac2eC944B53C09F7293CC8'], type: K.WebType.CTOP, clId: 243 },
- { id: '101', name: 'Top Bch', cmc: '1831', wallet: K.WalletType.FP_BCH, url: new URL('https://freebch.club/'), rf: ['?r=qq2qlpzs4rsn30utrumezpkzezpteqj92ykdgfeq5u'], type: K.WebType.CTOP, clId: 244 },
- { id: '102', name: 'Top Zec', cmc: '1437', wallet: K.WalletType.FP_ZEC, url: new URL('https://zecfaucet.net/'), rf: ['?r=t1erPs9qw3SgnX7kJPmR4uKFnLaoVww2jCy'], type: K.WebType.CTOP, clId: 245 },
- { id: '103', name: 'FMonster', cmc: '825', wallet: K.WalletType.FP_USDT, url: new URL('https://faucet.monster/'), rf: '', type: K.WebType.O24, clId: 246 },
- { id: '104', name: 'Auto-C BNB', cmc: '1839', wallet: K.WalletType.FP_BNB, url: new URL('https://auto-crypto.click/'), rf: ['?r=0x1e8CB8A79E347C54aaF21C0502892B58F97CC07A'], type: K.WebType.AUTOCML, clId: 247 },
- { id: '105', name: 'Auto-C DOGE', cmc: '74', wallet: K.WalletType.FP_DOGE, url: new URL('https://freeshiba.cf/'), rf: ['?r=D8Xgghu5gCryukwmxidFpSmw8aAKon2mEQ'], type: K.WebType.AUTOCML, clId: 248 },
- { id: '106', name: 'ClClicks DOGE', cmc: '74', wallet: K.WalletType.FP_USERNAME, url: new URL('https://claimclicks.com/doge/'), rf: ['?r=corecrafting'], type: K.WebType.CCLICKS, clId: 61 },
- { id: '107', name: 'ClClicks LTC', cmc: '2', wallet: K.WalletType.FP_USERNAME, url: new URL('https://claimclicks.com/ltc/'), rf: ['?r=corecrafting'], type: K.WebType.CCLICKS, clId: 62 },
- { id: '108', name: 'ClClicks TRX', cmc: '1958', wallet: K.WalletType.FP_USERNAME, url: new URL('https://claimclicks.com/trx/'), rf: ['?r=corecrafting'], type: K.WebType.CCLICKS, clId: 63 },
- { id: '109', name: 'ClClicks BTC', cmc: '1', wallet: K.WalletType.FP_USERNAME, url: new URL('https://claimclicks.com/btc/'), rf: ['?r=corecrafting'], type: K.WebType.CCLICKS, clId: 252 },
- { id: '110', name: 'ClClicks SOL', cmc: '5426', wallet: K.WalletType.FP_USERNAME, url: new URL('https://claimclicks.com/sol/'), rf: ['?r=corecrafting'], type: K.WebType.CCLICKS, clId: 253 },
- { id: '111', name: 'ClClicks BNB', cmc: '1839', wallet: K.WalletType.FP_USERNAME, url: new URL('https://claimclicks.com/bnb/'), rf: ['?r=corecrafting'], type: K.WebType.CCLICKS, clId: 254 },
- { id: '112', name: 'CrClicks DOGE', cmc: '74', wallet: K.WalletType.FP_USERNAME, url: new URL('https://cryptoclicks.net/doge/'), rf: ['?r=corecrafting'], type: K.WebType.CCLICKS, clId: 257 },
- { id: '113', name: 'CrClicks LTC', cmc: '2', wallet: K.WalletType.FP_USERNAME, url: new URL('https://cryptoclicks.net/ltc/'), rf: ['?r=corecrafting'], type: K.WebType.CCLICKS, clId: 258 },
- { id: '114', name: 'CrClicks TRX', cmc: '1958', wallet: K.WalletType.FP_USERNAME, url: new URL('https://cryptoclicks.net/trx/'), rf: ['?r=corecrafting'], type: K.WebType.CCLICKS, clId: 259 },
- { id: '115', name: 'CrClicks BTC', cmc: '1', wallet: K.WalletType.FP_USERNAME, url: new URL('https://cryptoclicks.net/btc/'), rf: ['?r=corecrafting'], type: K.WebType.CCLICKS, clId: 256 },
- { id: '116', name: 'CrClicks SOL', cmc: '5426', wallet: K.WalletType.FP_USERNAME, url: new URL('https://cryptoclicks.net/sol/'), rf: ['?r=corecrafting'], type: K.WebType.CCLICKS, clId: 261 },
- { id: '117', name: 'CrClicks BNB', cmc: '1839', wallet: K.WalletType.FP_USERNAME, url: new URL('https://cryptoclicks.net/bnb/'), rf: ['?r=corecrafting'], type: K.WebType.CCLICKS, clId: 260 },
- ];
-
- const wallet = [
- { id: '99', name: 'FaucetPay Username', type: K.WalletType.FP_USERNAME },
- { id: '100', name: 'FaucetPay Email', type: K.WalletType.FP_MAIL },
- { id: '101', name: 'FaucetPay BTC (Bitcoin)', type: K.WalletType.FP_BTC },
- { id: '102', name: 'FaucetPay BNB (Binance Coin)', type: K.WalletType.FP_BNB },
- { id: '103', name: 'FaucetPay BCH (Bitcoin Cash)', type: K.WalletType.FP_BCH },
- { id: '104', name: 'FaucetPay DASH (Dash)', type: K.WalletType.FP_DASH },
- { id: '105', name: 'FaucetPay DGB (DigiByte)', type: K.WalletType.FP_DGB },
- { id: '106', name: 'FaucetPay DOGE (Dogecoin)', type: K.WalletType.FP_DOGE },
- { id: '107', name: 'FaucetPay ETH (Ethereum)', type: K.WalletType.FP_ETH },
- { id: '108', name: 'FaucetPay FEY (Feyorra)', type: K.WalletType.FP_FEY },
- { id: '109', name: 'FaucetPay LTC (Litecoin)', type: K.WalletType.FP_LTC },
- { id: '110', name: 'FaucetPay TRX (Tron)', type: K.WalletType.FP_TRX },
- { id: '111', name: 'FaucetPay USDT (Tether TRC20)', type: K.WalletType.FP_USDT },
- { id: '112', name: 'FaucetPay ZEC (Zcash)', type: K.WalletType.FP_ZEC },
- { id: '113', name: 'FaucetPay SOL (Solana)', type: K.WalletType.FP_SOL },
- { id: '114', name: 'FaucetPay MATIC (Polygon)', type: K.WalletType.FP_MATIC },
- { id: '116', name: 'FaucetPay ADA (Cardano)', type: K.WalletType.FP_ADA },
- { id: '200', name: 'ExpressCrypto (EC-UserId-XXXXXX)', type: K.WalletType.EC },
- { id: '1', name: 'BTC Alternative Address', type: K.WalletType.BTC }
- ];
-
- async function start() {
- await loader.initialize();
- ui.init(getCFlist(), Schedule.getAll());
- uiRenderer.appendEventListeners();
- shared.purgeFlowControlSchedules(Schedule.getAll().map(x => x.uuid));
- update();
- uiRenderer.wallet.legacyRenderWalletTable(userWallet);
- intervalUiUpdate = setInterval(readUpdateValues, 10000);
- Schedule.getAll().forEach(x => {
- x.start();
- });
- if (document.querySelector('#console-log').innerText == 'Loading...') {
- document.querySelector('#console-log').innerHTML = '<table><tr><td><b>Running...</b></td></tr></table>';
- }
- getFeedInterval = setInterval(getCodesFeed, 25000);
- };
-
- let loader = function() {
- async function initialize() {
- setTimestamp();
- await Schedule.initialize();
- await initializeSites();
- initializeUserWallet();
- initializePromotions();
- initializeHistory();
- };
- async function initializeSites() {
- Site.createFromDataArray(sites);
- await updateSitesWithStoredData();
- await addSitesToSchedules();
- };
- async function updateSitesWithStoredData() {
- let storedData = persistence.load('webList', true);
- if (storedData) {
- storedData.forEach( function (stored) {
- if (stored.isExternal) {
- stored.url = new URL(stored.url);
- Site.add(stored);
- }
- let site = Site.getById(stored.id);
- if (!site) {
- return;
- }
- for (const prop in stored) {
- site[prop] = stored[prop];
- }
- if (!site.enabled) {
- site.nextRoll = null;
- } else {
- site.nextRoll = site.nextRoll ? new Date(site.nextRoll) : new Date();
- }
- if (site.aggregate || site.balance) {
- site.firstRun = false;
- }
- })
- }
- };
- async function addSitesToSchedules() {
- Site.getAll().forEach(site => {
- let scheduleOfSite = Schedule.getById(site.schedule);
- if (!scheduleOfSite) {
- console.warn(`Attention! Site ${site.name} has a reference to a schedule that does not exist: (${site.schedule})`);
- scheduleOfSite = Schedule.getAll()[0];
- console.warn(`Assigning it to first schedule (${scheduleOfSite.uuid}) instead.`);
- site.schedule = scheduleOfSite.uuid; // use .changeSchedule to save the change???
- }
- scheduleOfSite.addSite(site);
- });
- };
- function initializeUserWallet() {
- addWallets();
- addStoredWalletData();
- };
- function addWallets() {
- wallet.forEach(x => userWallet.push(x));
- userWallet.forEach(function (element, idx, arr) {
- arr[idx].address = '';
- });
- };
- function addStoredWalletData() {
- let storedData = persistence.load('userWallet', true);
- if(storedData) {
- storedData.forEach( function (element) {
- let idx = userWallet.findIndex(x => x.id == element.id);
- if(idx != -1) {
- userWallet[idx].address = element.address ?? userWallet[idx].address;
- }
- });
- }
- };
- function initializePromotions() {
- let storedData = persistence.load('CFPromotions', true);
- if (storedData) {
- let mig00200799 = false;
- try {
- mig00200799 = shared.getConfig().migrations.find(x => x.version == '00200799' && !x.applied);
- } catch (err) {}
-
- let allCFs = manager.getFaucetsForPromotion().map( cf => cf.id );
- storedData.forEach( function (element, idx, arr) {
- arr[idx].added = new Date(element.added);
- arr[idx].statusPerFaucet.forEach( function (el, i, a) {
- a[i].execTimeStamp = (el.execTimeStamp != null) ? new Date(el.execTimeStamp) : null;
- if (mig00200799 && el.status == 4) {
- a[i].status = 1;
- }
- });
- allCFs.forEach( function (cf) {
- if (!arr[idx].statusPerFaucet.find( x => x.id == cf )) {
- let newCf = { id: cf, status: 1, execTimeStamp: null };
- arr[idx].statusPerFaucet.push(newCf);
- }
- });
- });
- if (mig00200799) {
- shared.migrationApplied('00200799');
- }
- CFPromotions.load(storedData);
- }
- };
- function initializeHistory() {
- CFHistory.initOrLoad();
- };
- function setTimestamp() {
- timestamp = Date.now();
- persistence.save('timestamp', timestamp);
- };
- return {
- initialize: initialize
- };
- }();
- function getCodesFeed(force = false) {
- clearInterval(getFeedInterval);
- if (!force) {
- let tryGet = shared.getConfig()['cf.tryGetCodes'] || false;
- if (!tryGet) {
- return;
- }
- }
-
- let nextFeed = helpers.randomMs(2 * 60 * 60 * 1000, 4 * 60 * 60 * 1000);
- getFeedInterval = setInterval(getCodesFeed, nextFeed)
-
- GM_xmlhttpRequest({
- method: "GET",
- url: "https://criptologico.com/api/?key=XI2HV-1P9PQ-W637F-68B9B-A248&requests[cf_codes]",
- timeout: 10000,
- onload: function(response) {
- try {
- let txt = response.responseText;
- let parsed = JSON.parse(txt);
- if (parsed.success) {
- let newCodes = [];
- for(let i = 0; i < parsed.cf_codes.length; i++) {
- let item = parsed.cf_codes[i];
- let newCode = {};
- newCode.code = item.code;
- newCode.oneTimeOnly = item.is_one_time == '1';
- newCode['expiration' + 'Date'] = item.expiration_date.replace(' ', 'T') + 'Z';
- newCode['expiration' + 'Date'] = new Date(newCode['expiration' + 'Date']);
- newCodes.push(newCode);
- }
- CFPromotions.includeNewCodes(newCodes);
- uiRenderer.promos.legacyRenderPromotionTable(CFPromotions.getAll());
- }
- } catch(err) {
- console.error('unexpected error parsing codes list');
- console.error(err);
- }
- },
- onerror: function(e) {
- console.error('error getting codes');
- console.error(e);
- },
- ontimeout: function() {
- console.error('timeout getting codes');
- },
- });
- }
- function readUpdateValues(forceCheck = false) {
- readPromoCodeValues();
- readModalData();
-
- if(true) {
- let updateDataElement = document.getElementById('update-data');
- let updateValues = updateDataElement.innerText.clean();
-
- if (updateValues != '') {
- updateDataElement.innerText = '';
- let updateObj = JSON.parse(updateValues);
- if(updateObj.editSingle.changed) {
- updateObj.editSingle.items.forEach(function (element, idx, arr) {
- try {
- let site = Site.getById(element.id);
-
- site.name = element.displayName;
-
- if (site.enabled != element.enabled) {
- site.enabled = element.enabled;
- if(site.enabled) {
- site.nextRoll = new Date(idx);
- } else {
- site.nextRoll = null;
- }
- }
- ui.log({ schedule: site.schedule,
- msg: `Faucet updated. New name: ${element.displayName}. Active: ${element.enabled}` });
- } catch (err) {
- ui.log({ schedule: this.uuid,
- msg: `Error updating faucet data: ${err}` });
- }
- });
- }
-
- if(updateObj.wallet.changed) {
- updateObj.wallet.items.forEach(function (element) {
- try {
- let itemIndex = userWallet.findIndex(x => x.id == element.id);
- userWallet[itemIndex].address = element.address;
-
- ui.log({ msg: `Wallet Address updated [${userWallet[itemIndex].name}]: ${userWallet[itemIndex].address}` });
- } catch (err) {
- ui.log({ msg: `Error updating wallet/address: ${err}` });
- }
- });
-
- uiRenderer.wallet.legacyRenderWalletTable(userWallet);
- saveUserWallet();
- }
-
- if(updateObj.config.changed) {
- try {
- shared.updateConfig(updateObj.config.items);
- ui.log({ msg: `Config updated. Reloading in a few seconds...` });
- window.location.reload();
- return;
- } catch (err) {
- ui.log({ msg: `Error updating config: ${err}` });
- }
-
- }
-
- if(updateObj.site.changed) {
- updateObj.site.list.forEach( (x) => {
- try {
- updateSite(x.id, x.items);
- } catch (err) {
- ui.log({ msg: `Error updating site: ${err}` });
- }
- });
- }
-
- if(updateObj.runAsap.changed || updateObj.editSingle.changed || updateObj.site.changed) {
- resyncAll({ withUpdate: true });
- return;
- }
- }
- }
- if(forceCheck) {
- resyncAll({ withUpdate: false });
- }
- };
- function resyncAll(options = { withUpdate: false} ) {
- if (options.withUpdate) {
- update(true);
- }
- Schedule.getAll().forEach(x => {
- x.checkNextRoll();
- });
- }
- function updateSite(id, items) {
- let site = Site.getById(id);
- if (site) {
- site.params = site.params || {};
- items.forEach( (item) => {
- site.params[item.prop] = item.value;
- });
-
- ui.log({ schedule: site.schedule, siteName: site.name,
- msg: `Site ${site.name} updated` });
- }
- }
- function readModalData() { // This should be migrated and dissapear!
- if(document.getElementById('modal-spinner').isVisible()) {
- let targetObject = JSON.parse(document.getElementById('target-spinner').innerHTML);
- let target = targetObject.id;
- if (target == 'modal-ereport') {
- let temp = shared.getDevLog();
- document.getElementById('log-textarea').value = temp.join('\n');
- } else if (target == 'modal-config') {
- uiRenderer.config.legacyRenderConfigData(shared.getConfig());
- } else if (target == 'modal-site') {
- let site = Site.getById(targetObject.siteId);
- uiRenderer.sites.legacyRenderSiteData(site, shared.getConfig());
- }
- document.getElementById('modal-spinner').classList.toggle('d-none');
- document.getElementById(target).classList.toggle('d-none');
- document.getElementById('target-spinner').innerHTML = '';
- }
- }
- function sortSites () { // Temporary, just to decouple it...
- Site.sortAll();
- Schedule.getAll().forEach( schedule => schedule.sortSites() );
- };
- function update(sortIt = true) {
- if(sortIt) {
- sortSites();
- Schedule.getAll().forEach( schedule => schedule.setCurrentSite() );
- }
-
- Site.saveAll();
- Site.getAll().forEach(site => {
- uiRenderer.sites.renderSiteRow(site);
- });
- uiRenderer.sites.removeDeletedSitesRows(Site.getAll().map(x => x.id));
- convertToFiat();
- uiRenderer.sites.sortSitesTable(); // y reordenar
- uiRenderer.promos.legacyRenderPromotionTable(CFPromotions.getAll());
- updateRollStatsSpan();
- };
-
- function saveUserWallet() {
- const data = userWallet.map(x => {
- return {
- id: x.id,
- address: x.address
- };});
-
- persistence.save('userWallet', data, true);
- }
-
- function isObsolete() {
- let savedTimestamp = persistence.load('timestamp');
- if (savedTimestamp && savedTimestamp > timestamp) {
- ui.log({ msg: '<b>STOPING EXECUTION!<b> A new Manager UI window was opened. Process should continue there' });
- clearInterval(intervalUiUpdate);
- return true;
- }
- return false;
- };
-
- function readPromoCodeValues() {
- let promoCodeElement = document.getElementById('promo-code-new');
- let promoDataStr = promoCodeElement.innerText.clean();
-
- if (promoDataStr == '') {
- return;
- }
-
- let promoData = JSON.parse(promoDataStr);
-
- if(promoData.action) {
- switch (promoData.action) {
- case 'FORCESTOPFAUCET':
- Schedule.getAll().forEach(s => {
- if (s.status != STATUS.IDLE) {
- s.currentSite.enabled = false;
- s.closeTab();
- }
- });
-
- update(true);
- shared.clearFlowControl('all');
- setTimeout(() => {
- window.location.reload();
- }, 3000);
-
- promoCodeElement.innerText = '';
- break;
- case 'ADD':
- CFPromotions.addNew(promoData.code, promoData.repeatDaily);
- promoCodeElement.innerText = '';
- document.getElementById('promo-text-input').value = '';
- uiRenderer.toast("Code " + promoData.code + " added!");
- ui.log({ msg: `Promo code ${promoData.code} added` });
- uiRenderer.promos.legacyRenderPromotionTable(CFPromotions.getAll());
- break;
- case 'REMOVEALLPROMOS':
- CFPromotions.removeAll();
- promoCodeElement.innerText = '';
- uiRenderer.toast("Promo codes removed!");
- ui.log({ msg: `Promo codes removed` });
- uiRenderer.promos.legacyRenderPromotionTable(CFPromotions.getAll());
- break;
- case 'REMOVE':
- if(CFPromotions.remove(promoData.id, promoData.code) != -1) {
- ui.log({ msg: `Promo code ${promoData.code} removed` });
- } else {
- ui.log({ msg: `Unable to remove code ${promoData.code}` });
- }
- promoCodeElement.innerText = '';
- uiRenderer.promos.legacyRenderPromotionTable(CFPromotions.getAll());
- break;
- case 'TRYGETCODES':
- getCodesFeed(true);
- promoCodeElement.innerText = '';
- uiRenderer.toast("Looking for new codes!");
- break;
- }
- }
- };
-
- function updateRollStatsSpan() {
- let rollsSpanElement = document.getElementById('rolls-span');
- rollsSpanElement.innerText = CFHistory.getRollsMeta().join(',');
- };
-
- function getCFlist() {
- let items;
- items = Site.getAll().filter(f => f.type === K.WebType.CRYPTOSFAUCETS);
- items = items.map(x => {
- return {
- id: x.id,
- name: x.coinRef
- };});
- items.sort((a, b) => (a.name > b.name) ? 1 : -1);
-
- return items;
- };
-
- function closeWorkingTab(schedule) {
- let sc = Schedule.getAll().find(x => x.uuid == schedule);
- if (sc) sc.closeTab()
- };
- function reloadWorkingTab(schedule) {
- let sc = Schedule.getAll().find(x => x.uuid == schedule);
- if (sc) {
- sc.closeTab();
- sc.reopenTab();
- }
- };
- function getAllSites() {
- return Site.getAll();
- }
- return{
- start: start,
- getFaucetsForPromotion: getCFlist,
- closeWorkingTab: closeWorkingTab,
- reloadWorkingTab: reloadWorkingTab,
- getAllSites: getAllSites,
- resyncAll: resyncAll,
- isObsolete: isObsolete,
- update: update,
- userWallet: userWallet,
- readUpdateValues: readUpdateValues
- };
- }
- function createUi() {
-
- let injectables = {
- managerJs: function () {
-
- window.myBarChart = null;
- window.landing = window.location.host;
-
- window.sendErrorReport = function sendErrorReport() {
- try {
- let header = new Headers();
- header.append("Content-Type", "application/json");
- let description = document.getElementById("log-message").value;
- let log = document.getElementById("log-textarea").value.split('\n');
- let content = {"description":description, "log":log};
- let opt = { method: "POST", header, mode: "cors", body: JSON.stringify(content) };
- fetch("https://1d0103ec5a621b87ea27ffed3c072796.m.pipedream.net", opt).then(response => {
- }).catch(err => {
- console.error("[error] " + err.message);
- });
- } catch { }
- };
-
- window.getUpdateObject = function getUpdateObject() {
- let updateObject;
- var updateData = document.getElementById("update-data");
- if (updateData.innerHTML != "") {
- updateObject = JSON.parse(updateData.innerHTML);
- } else {
- updateObject = { runAsap: { ids: [], changed: false}, editSingle: { changed: false, items: [] }, wallet: { changed: false, items: []}, config: { changed: false, items: []}, site: { changed: false, list: []} };
- }
- return updateObject;
- };
-
- window.removePromoCode = function removePromoCode(id, code) {
- var promoCode = document.getElementById("promo-code-new");
- var promoObject = { action: "REMOVE", id: id, code: code };
- promoCode.innerHTML =JSON.stringify(promoObject);
- };
-
- window.editWallet = {
- save: function() {
- let updateObject = getUpdateObject();
- document.querySelectorAll("#wallet-table-body tr").forEach( function(row) {
- let textInput = row.querySelector(".em-input input");
- if(textInput.dataset.original != textInput.value) {
- let single = { id: row.dataset.id, address: textInput.value.trim() };
- updateObject.wallet.items.push(single);
- updateObject.wallet.changed = true;
- }
- });
- if(updateObject.wallet.changed) {
- document.getElementById("update-data").innerHTML = JSON.stringify(updateObject);
- toastr["info"]("Wallet will be updated as soon as possible");
- }
- },
- toggleJson: function(val) {
- if (document.querySelector('#wallet-json').isVisible()) {
- if(val != 'cancel') {
- editWallet.fromJson();
- }
- } else {
- editWallet.toJson();
- }
- document.querySelector('.footer-json').classList.toggle('d-none');
- document.querySelector('.footer-table').classList.toggle('d-none');
- document.querySelector('#wallet-table').classList.toggle('d-none');
- document.querySelector('#wallet-json').classList.toggle('d-none');
- },
- toJson: function() {
- let j = [];
- document.querySelectorAll('#wallet-table-body tr').forEach(function (row) {
- j.push({ id: row.dataset.id, address: row.querySelector('.em-input input').value });
- });
- document.querySelector('#wallet-json').value = JSON.stringify(j);
- },
- fromJson: function() {
- let j = JSON.parse(document.querySelector('#wallet-json').value);
- document.querySelectorAll('#wallet-table-body tr').forEach(function (row) {
- let element = j.find(x => x.id == row.dataset.id);
- if (element) {
- row.querySelector('.em-input input').value = element.address;
- }
- });
- },
- cancel: function() {
- document.querySelectorAll("#wallet-table-body .em-input input").forEach( function(x) {
- x.value = x.dataset.original;
- });
- }
- };
-
- window.editConfig = {
- save: function() {
- let updateObject = getUpdateObject();
- document.querySelectorAll("#modal-config [data-original][data-prop]").forEach(function(elm) {
- let single = { prop: elm.dataset.prop, value: elm.dataset.value };
- if(elm.dataset.original != elm.value && (elm.type == "select-one" || elm.type == "text" || elm.type == "password" || elm.type == "number" || elm.type == "time") ) {
- single.value = elm.value;
- updateObject.config.items.push(single);
- updateObject.config.changed = true;
- } else if (elm.type == "checkbox" && ((elm.dataset.original == "0" && elm.checked) || (elm.dataset.original == "1" && !elm.checked)) ) {
- single.value = elm.checked;
- updateObject.config.items.push(single);
- updateObject.config.changed = true;
- }
- });
- if(updateObject.config.changed) {
- document.getElementById("update-data").innerHTML = JSON.stringify(updateObject);
- toastr["info"]("Config will be updated as soon as possible");
- }
- },
- cancel: function() {
- document.querySelectorAll("#modal-config [data-original][data-prop]").forEach(function(elm) {
- if(elm.type == "select-one" || elm.type == "text" || elm.type == "password" || elm.type == "number" || elm.type == "time") {
- elm.value = elm.dataset.original;
- } else if (elm.type == "checkbox") {
- elm.checked = (elm.dataset.original == "1" ? true : false)
- }
- });
- }
- };
-
- window.editSite = {
- save: function() {
- let updateObject = getUpdateObject();
- let faucet = { id: document.querySelector("#faucet-name").dataset.id, items: [] };
- document.querySelectorAll("#modal-site [data-original][data-site-prop]").forEach(function(elm) {
- let single = { prop: elm.dataset.siteProp, value: elm.dataset.original };
- if(elm.dataset.original != elm.value && (elm.type == "select-one" || elm.type == "text" || elm.type == "password" || elm.type == "number" || elm.type == "time") ) {
- single.value = elm.value;
- faucet.items.push(single);
- updateObject.site.changed = true;
- } else if (elm.type == "checkbox" && ((elm.dataset.original == "0" && elm.checked) || (elm.dataset.original == "1" && !elm.checked)) ) {
- single.value = elm.checked;
- faucet.items.push(single);
- updateObject.site.changed = true;
- }
- });
- if(updateObject.site.changed) {
- updateObject.site.list.push(faucet);
- document.getElementById("update-data").innerHTML = JSON.stringify(updateObject);
- toastr["info"]("Site will be updated as soon as possible");
- }
-
- },
- cancel: function() {
- document.querySelectorAll("#modal-site [data-original][data-site-prop]").forEach(function(elm) {
- if(elm.type == "select-one" || elm.type == "text" || elm.type == "password" || elm.type == "number" || elm.type == "time") {
- elm.value = elm.dataset.original;
- } else if (elm.type == "checkbox") {
- elm.checked = (elm.dataset.original == "1" ? true : false)
- }
- });
- }
- };
-
- window.editEreport = {
- save: function() {
- sendErrorReport();
- },
- cancel: function() {
- }
- };
-
- window.modalSave = function modalSave(content) {
- switch(content) {
- case "wallet":
- editWallet.save();
- break;
- case "ereport":
- editEreport.save();
- break;
- case "config":
- editConfig.save();
- break;
- case "site":
- editSite.save();
- break;
- case "slAlert":
- shortlinkAlert.save();
- break;
- }
- };
-
- window.modalCancel = function modalCancel(content) {
- if(content == "wallet") {
- editWallet.cancel();
- } else if ("ereport") {
- editEreport.cancel();
- }
- document.querySelectorAll("modal-content").forEach(x => x.classList.add("d-none"));
- };
-
- window.updateValues = function updateValues(type, values) {
- let updateObject = getUpdateObject();
- if (type == "runAsap") {
- updateObject.runAsap.ids.push(values.id);
- updateObject.runAsap.changed = true;
- document.getElementById("update-data").innerHTML = JSON.stringify(updateObject);
- uiRenderer.toast("Faucet will be updated to run as soon as possible");
- }
- };
-
- window.schedulesInterval = null;
- window.startSchedulesInterval = function startSchedulesInterval(uuids) {
- if (window.schedulesInterval) {
- clearInterval(window.schedulesInterval);
- }
-
- let innerWaitTimes = '';
- uuids.forEach(x => {
- innerWaitTimes += `<span data-schedule="${x}" data-nextroll="UNDEFINED" class="mx-1"><i class="fas fa-square pr-1" style="color: #${x};"></i><span></span></span>`;
- });
-
- let container = document.querySelector('#wait-times');
- container.innerHTML = innerWaitTimes;
- window.schedulesInterval = setInterval(() => {
- [...document.querySelectorAll('#wait-times > span')].forEach(sp => {
- let nroll = sp.getAttribute('data-nextroll');
- let spanScheduleId = sp.getAttribute('data-schedule');
- if (nroll == 'UNDEFINED') {
- sp.querySelector('span').innerText = '-';
- } else if (nroll == 'RUNNING') {
- sp.querySelector('span').innerText = 'Running';
- let inUseElm = document.querySelector(`#schedule-table tr[data-schedule="${spanScheduleId}"]`);
- if (inUseElm) {
- inUseElm.classList.add('in-use');
- }
- } else {
- let timeVal = +nroll - Date.now();
- sp.querySelector('span').innerText = timeVal.msToCountdown();
- if (timeVal < -60000) {
- console.info(`Resync required: ${timeVal}`);
- }
- }
- })
- }, 1000);
- }
- window.confirmable = {
- open: function (req, details = null, params = null) {
- let btn = document.getElementById("confirm-req-btn");
- btn.setAttribute('data-request', req);
- btn.setAttribute('data-params', params ? JSON.stringify(params) : '{}');
-
- if(details) {
- document.querySelector("#confirmable-modal p").innerText = details;
- }
- return;
- },
- accept: function () {
- let btn = document.getElementById("confirm-req-btn");
- let req = { type: '', params: {}};
- req.type = btn.getAttribute('data-request');
- req.params = JSON.parse(btn.getAttribute('data-params'));
- switch(req.type) {
- case 'removeAllPromos':
- window.removeAllPromos();
- break;
- case 'forceStopFaucet':
- window.forceStopFaucet();
- break;
- default:
- break;
- }
- }
- }
-
- window.removeAllPromos = function removeAllPromos() {
- var promoCode = document.getElementById("promo-code-new");
- var promoObject = { action: "REMOVEALLPROMOS" };
- promoCode.innerHTML =JSON.stringify(promoObject);
- toastr["info"]("Removing all promo codes... please wait");
- };
-
- window.forceStopFaucet = function forceStopFaucet() {
- var promoCode = document.getElementById("promo-code-new");
- var promoObject = { action: "FORCESTOPFAUCET" };
- promoCode.innerHTML =JSON.stringify(promoObject);
- toastr["info"]("Trying to stop... Please wait for reload");
- };
-
- window.openStatsChart = function openStatsChart() {
- if(myBarChart) { myBarChart.destroy(); }
- let statsFragment = document.getElementById("stats-fragment");
- if (statsFragment.style.display === "block") { statsFragment.style.display = "none"; document.getElementById("stats-button").innerText = "Lucky Number Stats"; } else {
- statsFragment.style.display = "block"; document.getElementById("stats-button").innerText = "Close Stats";
- var canvas = document.getElementById("barChart");
- var ctx = canvas.getContext("2d");
- var dataSpan = document.getElementById("rolls-span");
- var data = {
- labels: ["0000-9885", "9886-9985", "9986-9993", "9994-9997", "9998-9999", "10000"],
- datasets: [ { fill: false, backgroundColor: [ "#990000", "#660066", "#000099", "#ff8000", "#ffff00", "#00ff00"],
- data: dataSpan.innerText.split(",") } ] };
- var options = { plugins: { legend: { display: false } }, title: { display: true, text: "Rolled Numbers", position: "top" }, rotation: -0.3 * Math.PI };
- myBarChart = new Chart(ctx, { type: "doughnut", data: data, options: options });
- }
- };
-
- window.shortlinkAlert = {
- load: function(id, destination) {
- let hideShortlinkAlerts = localStorage.getItem("hideShortlinkAlerts");
- hideShortlinkAlerts = hideShortlinkAlerts ? JSON.parse(hideShortlinkAlerts) : false;
-
- if (hideShortlinkAlerts) {
- } else {
- document.getElementById(id).classList.remove("d-none");
- }
- },
- save: function () {
- localStorage.setItem("hideShortlinkAlerts", JSON.stringify(document.getElementById("hideShortlinkAlerts").checked));
- window.open("https://example.com", "_blank");
- }
- }
- }
- };
-
- let logLines = [];
- function init(cfFaucets, schedules) {
- appendJavaScript();
- appendHtml(schedules);
- updateSchedulesToggler();
- appendEventListeners();
- appendWidgets();
- setupEventerListeners();
-
- createPromoTable(cfFaucets);
- try {
- document.querySelector('.page-title h1').innerHTML = 'Auto Claim';
- } catch (err) {}
- };
- function setupEventerListeners() {
- eventer.on('siteUpdated', (site) => {
- Site.sortAll(); // en todos los sites...
- let schedule = Schedule.getById(site.schedule);
- schedule.sortSites(); // solo en el schedule de este site
- schedule.setCurrentSite(); // solo en el schedule de este site
- Site.saveAll();
- uiRenderer.sites.renderSiteRow(site); // solo la row de este site
- uiRenderer.sites.sortSitesTable(); // y reordenar
-
- schedule.checkNextRoll(); // solo en el schedule de este site
- convertToFiat();
- });
- }
- function appendWidgets() {
- $('.tableSortable').sortable({
- placeholder:'sort-highlight',
- handle:'.row-handle',
- cursor: 'grabbing',
- axis: 'y',
- stop: function(event, ui) {
- $("tbody.ui-sortable tr").each(function(index) {
- $(this).attr("data-order", index);
- });
- }
- });
- $('#promo-daily').bootstrapSwitch();
- $('#bss-log').bootstrapSwitch({
- onSwitchChange(event, state) {
- $('#console-log').collapse('toggle');
- },
- onInit: function(event, state) {
- this.$element.closest('.bootstrap-switch-container').find('.bootstrap-switch-handle-on').first().addClass('fa fa-eye').text('');
- this.$element.closest('.bootstrap-switch-container').find('.bootstrap-switch-handle-off').first().addClass('fa fa-eye-slash').text('');
- }
- });
- };
- function updateSchedulesToggler() {
- let container = document.querySelector('#schedules-toggler');
- let html = '<label class="btn btn-outline-primary active" data-schedule="all"><input type="radio" name="options" autocomplete="off" checked="true"> All</label>';
- Schedule.getAll().forEach(x => {
- html += `<label class="btn btn-outline-primary" data-schedule="${x.uuid}">
- <i class="fas fa-square pr-1" style="color: #${x.uuid};"></i>${x.name}
- <input type="radio" name="options" autocomplete="off">
- </label>`;
- });
- container.innerHTML = html;
- startSchedulesInterval(Schedule.getAllForCrud().map(x => x.uuid));
- uiRenderer.schedules.toggleSchedule('all');
- };
- function appendEventListeners() {
- document.querySelector('.dropdown-settings-menu').addEventListener('click', function(e) {
- let actionElement = e.target.tagName === 'I' ? e.target.parentElement : e.target;
- if (actionElement.dataset.target) {
- e.stopPropagation();
- uiRenderer.openModal(actionElement.dataset.target);
- }
- });
-
- const modalSchedules = document.querySelector('#modal-schedules');
- modalSchedules.addEventListener('click', function(e) {
- let actionElement = e.target.tagName === 'I' ? e.target.parentElement : e.target;
- if (actionElement.classList.contains('action-schedule-add')) {
- e.stopPropagation();
- let rows = modalSchedules.querySelectorAll('table tbody tr');
- let rndColor = helpers.randomHexColor();
- let rowTemplate = uiRenderer.schedules.renderRow({
- uuid: rndColor,
- name: rndColor,
- order: rows.length,
- added: true
- });
- $(modalSchedules.querySelector('table tbody tr:last-child')).after(rowTemplate);
- uiRenderer.appendColorPickers('table tbody tr:last-child .color-picker');
- } else if (actionElement.classList.contains('action-schedule-remove')) {
- let rows = modalSchedules.querySelectorAll('table tbody tr:not(.d-none)');
- if (rows.length <= 1) {
- alert('You need to keep at least 1 schedule');
- } else {
- let current = actionElement.closest('tr');
- if (current.dataset.added === 'true') {
- current.remove();
- } else {
- current.dataset.removed = 'true';
- current.classList.add('d-none');
- }
- }
- } else if (actionElement.classList.contains('modal-save')) {
- let data = uiRenderer.parseTable(modalSchedules.querySelector('table'));
- let isValid = Schedule.crud(data);
- updateSchedulesToggler();
- manager.resyncAll({withUpdate: true});
- if (!isValid) {
- uiRenderer.toast('Some schedules might have errors/invalid colors', 'warning');
- }
- }
- });
- };
- function appendJavaScript() {
- addJS_Node (null, null, injectables.managerJs);
- };
- function addCardHtml(obj) {
- return `<div class="card m-1"><div class="card-header">${obj.header}</div><div class="card-body px-4">${obj.body}</div></div>`;
- };
- function addRandomBetween(propSelect, propMin, propMax) {
- return `<table><tr><td>
- <select class="form-control" ${propSelect.name}="${propSelect.value}">
- <option value="0">Random between...</option><option value="15">15 minutes</option><option value="30">30 minutes</option><option value="35">35 minutes</option><option value="45">45 minutes</option><option value="65">65 minutes</option><option value="90">90 minutes</option><option value="120">120 minutes</option>
- </select></td>
- <td><input type="number" data-original="" ${propMin.name}="${propMin.value}" min="1" value="15" step="5" class="form-control"></td><td>and</td><td><input type="number" data-original="" ${propMax.name}="${propMax.value}" value="65" step="5" class="form-control"></td><td>minutes</td></tr></table>`;
- }
- function appendHtml(schedules) {
- let html ='';
- let tgt = document.querySelector('div.row.py-3');
- if (tgt) {
- let rowDiv = document.createElement('div');
- rowDiv.innerHTML = '<div class="row py-3 ac-log"><div class="col-12 justify-content-center"><div class="card"><div class="card-body" id="referral-table"></div></div></div></div>';
- tgt.after(rowDiv);
- }
-
- html += '<div class="modal fade" id="confirmable-modal" tabindex="-1" role="dialog" aria-hidden="true">';
- html += '<div class="modal-dialog modal-sm modal-dialog-centered"><div class="modal-content">';
- html += '<div class="modal-header"><h4 class="modal-title">Are you sure?</h4><button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button></div>';
- html += '<div class="modal-body"><p></p></div>';
- html += '<div class="modal-footer justify-content-between"><button type="button" class="btn btn-default" data-dismiss="modal">No</button>';
- html += '<button type="button" class="btn btn-primary" data-dismiss="modal" id="confirm-req-btn" onclick="confirmable.accept()">Yes</button></div>';
- html += '</div></div>';
- html += '</div>';
-
- html += '<div class="modal fade" id="modal-dlg" tabindex="-1" role="dialog" data-backdrop="static" aria-hidden="true">';
- html += ' <div class="modal-dialog modal-lg modal-dialog-centered modal-dialog-scrollable" role="document">';
-
- html += '<div class="modal-content bg-beige" id="modal-spinner"><div class="modal-body"><div class="d-flex justify-content-center"><span id="target-spinner" class="d-none"></span><span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>Loading data</div></div></div>';
-
- html += ' <div class="modal-content bg-beige d-none" id="modal-ereport">';
- html += ' <div class="modal-header"><h5 class="modal-title"><i class="fa fa-history"></i> Submit an Error</h5></div>';
- html += ' <div class="modal-body">';
- html += ' <div class="alert alert-danger">Don\'t send private information as data might be publicly access.</div>';
- html += ' <textarea rows="4" id="log-message" class="form-control" placeholder="PLEASE do not send logs without describing here the issue you are facing..."></textarea>';
- html += ' <label for="log-textarea">Log</label>';
- html += ' <textarea rows="10" id="log-textarea" class="form-control"></textarea>';
- html += ' </div>';
- html += ' <div class="modal-footer"><a class="btn m-2 anchor btn-outline-danger align-middle" onclick="modalCancel(\'ereport\')" data-dismiss="modal"><i class="fa fa-times-circle"></i> Cancel</a>';
- html += ' <a class="btn m-2 anchor btn-outline-success align-middle" onclick="modalSave(\'ereport\')" data-dismiss="modal"><i class="fa fa-paper-plane"></i> Send</a></div>';
- html += ' </div>';
-
- html += ' <div class="modal-content bg-beige d-none" id="modal-wallet">';
- html += ' <div class="modal-header"><h5 class="modal-title"><i class="fa fa-wallet"></i> Your Addresses</h5></div>';
- html += ' <div class="modal-body">';
- html += ' <div><table class="table custom-table-striped" id="wallet-table">';
- html += ' <thead><tr><th class="">Name</th><th class="">Address</th></tr></thead>';
- html += ' <tbody class="overflow-auto" id="wallet-table-body"></tbody></table><textarea rows="14" id="wallet-json" class="d-none w-100"></textarea>';
- html += ' </div>';
- html += ' </div>';
- html += '<div class="modal-footer">';
- html += '<div class="footer-json d-none">';
- html += '<a class="btn m-2 anchor btn-outline-danger align-middle" onclick="editWallet.toggleJson(\'cancel\')"><i class="fa fa-times-circle"></i> Cancel</a>';
- html += '<a class="btn m-2 anchor btn-outline-primary align-middle" onclick="editWallet.toggleJson()"><i class="fa fa-edit"></i> Confirm</a></div>';
- html += '<div class="footer-table"><a class="btn m-2 anchor btn-outline-primary align-middle" onclick="editWallet.toggleJson()"><i class="fa fa-edit"></i> Edit as JSON</a>';
- html += '<a class="btn m-2 anchor btn-outline-danger align-middle" onclick="modalCancel(\'wallet\')" data-dismiss="modal"><i class="fa fa-times-circle"></i> Cancel</a>';
- html += '<a class="btn m-2 anchor btn-outline-success align-middle" onclick="modalSave(\'wallet\')" data-dismiss="modal"><i class="fa fa-check-circle"></i> Save</a></div></div>';
- html += ' </div>';
-
- html += ' <div class="modal-content bg-beige d-none" id="modal-info">';
- html += ' <div class="modal-header"><h5 class="modal-title"><i class="fa fa-info"></i> Info</h5></div>';
- html += ' <div class="modal-body">';
- html += '<ul>';
- html += '<li>First of all, make sure you visit our <a href="https://discord.gg/gaYYBjJUhP" target="_blank">discord</a> server for specific issues with the script. Unfortunately, our original server and user account was disabled after +2 years. We are trying to bring the community together in a new one now.</li>';
- html += `<li>The script comes with <b>2 schedules</b> (Default and CF). You can add more from <i>Settings > Schedules...</i><br>About the <i>Schedules</i>:`;
- html += `<ul><li>Each schedule will open a new tab, so:<br>N schedules = N simultaneous tabs.</li>`;
- html += `<li>Each schedule has it's own list of sites.<br>You can have N sites per schedule, but each site can be in just 1 schedule to avoid overlapping.</li>`;
- html += `<li>We suggest you to test how many tabs you can run simultaneously before creating too many schedules.<br>Usually, with 4 or 5 it will run smoothly.</li></ul>`;
- html += `</li>`;
- html += '<li>Almost all sites in the list require an external hCaptcha solver or similar scripts/extensions. You can find our free suggestions in Settings > Other requirements...</li>';
- html += '<li>Stormgain requires a GeeTest solver. You can use <a href="https://greasyfork.org/en/scripts/444560" target="_blank">this script</a> to solve the captchas through 2Captcha API service.</li>';
- html += `<li>Some sites pay directly to <a href="https://faucetpay.io/?r=freebtc" target="_blank"><i class="fa fa-external-link-alt"></i> FaucetPay</a>. You need to add your FP addresses at <i>Settings > Wallet...</i> to claim from those sites.</li>`;
- html += `<li>You can set default configurations at <i>Settings > Defaults...</i></li>`;
- html += `<li>At <i>Settings > Defaults</i>, you will also find <i>Site Specific</i> settings like credentials for auto login.</li>`;
- html += '<li>You can override configurations for a specific site using the edit (<i class="fa fa-clock"></i>) buttons</li>';
- html += '<li>When enabling a new site, try it first with the tab on focus, to detect potential issues</li>';
- html += '</ul>';
- html += ' </div>';
- html += '<div class="modal-footer">';
- html += '<a class="btn m-2 anchor btn-outline-warning align-middle" data-dismiss="modal"><i class="fa fa-edit"></i> Close</a></div>';
- html += ' </div>';
-
- html += '<div class="modal-content bg-beige" id="modal-schedules">';
- html += ' <div class="modal-header py-2"><h5 class="modal-title"><i class="fa fa-stopwatch"></i> Schedules</h5>';
- html += ' <div class="ml-auto"><button type="button" class="btn btn-default btn-sm action-schedule-add">';
- html += ' <i class="fa fa-plus"></i> Add Schedule';
- html += ' </button></div>';
- html += ' </div>';
- html += ' <div class="modal-body">';
- html += '<div class="callout callout-warning m-0"><p class="text-justify">Each schedule opens sites in a new/different tab.<br>Colors must be unique.</p></div>';
- html += ' <table class="table">';
- html += ' <thead>';
- html += ' <tr><th></th><th class="text-center" width="35%">Color</th><th class="text-center">Name</th><th></th></tr>';
- html += ' </thead>';
- html += ' <tbody class="tableSortable">';
- html += ' </tbody>';
- html += ' </table>';
- html += ' </div>';
- html += ' <div class="modal-footer">';
- html += ' <a class="btn m-2 anchor btn-outline-danger align-middle" data-dismiss="modal"><i class="fa fa-times-circle"></i> Cancel</a>';
- html += ' <a class="btn m-2 anchor btn-outline-success align-middle modal-save" data-dismiss="modal"><i class="fa fa-check-circle"></i> Save</a>';
- html += ' </div>';
- html += '</div>';
-
- html += '<div class="modal-content bg-beige" id="modal-assign-schedule">';
- html += ' <div class="modal-header py-2"><h5 class="modal-title"><i class="fa fa-exchange-alt"></i> Move to...</h5>';
- html += ' </div>';
- html += ' <div class="modal-body">';
- html += ' <div class="form-container">';
- html += ' <input type="hidden" name="site_id" value="not_set">';
- html += ' <input type="hidden" name="original_schedule_id" value="not_set">';
- html += ' <label class="control-label">Schedule</label>';
- html += ' <select class="form-control" name="schedule">';
- html += ' </select>';
- html += ' </div>';
- html += ' </div>';
- html += ' <div class="modal-footer">';
- html += ' <a class="btn m-2 anchor btn-outline-danger align-middle" data-dismiss="modal"><i class="fa fa-times-circle"></i> Cancel</a>';
- html += ' <a class="btn m-2 anchor btn-outline-success align-middle modal-save" data-dismiss="modal"><i class="fa fa-check-circle"></i> Save</a>';
- html += ' </div>';
- html += '</div>';
-
- html += '<div class="modal-content bg-beige" id="modal-add-site">';
- html += ' <div class="modal-header py-2"><h5 class="modal-title"><i class="fa fa-code"></i> Add Site...</h5>';
- html += ' </div>';
- html += ' <div class="modal-body">';
- html += ' <div class="form-container">';
- html += uiRenderer.addInputTextHtml({ required: true, name: 'site_name', value: '', text: 'Display name'});
- html += uiRenderer.addInputTextHtml({ required: true, name: 'site_url', value: '', text: 'Url to open', placeholder: 'Example: https://freebitcoin.io/free' });
- html += ' <label class="control-label">Schedule</label>';
- html += ' <select class="form-control" name="schedule">';
- html += ' </select>';
- html += ' </div>';
- html += ' </div>';
- html += ' <div class="modal-footer">';
- html += ' <a class="btn m-2 anchor btn-outline-danger align-middle" data-dismiss="modal"><i class="fa fa-times-circle"></i> Cancel</a>';
- html += ' <a class="btn m-2 anchor btn-outline-success align-middle modal-save" data-dismiss="modal"><i class="fa fa-check-circle"></i> Save</a>';
- html += ' </div>';
- html += '</div>';
-
- html += '<div class="modal-content bg-beige" id="modal-site-parameters">';
- html += ' <div class="modal-header py-2"><h5 class="modal-title"><i class="fa fa-edit"></i> Edit Site Arguments...</h5>';
- html += ' </div>';
- html += ' <div class="modal-body">';
- html += ' <div class="form-container"><form action="">';
- html += ` <div>Soon you'll be able to edit the site's specific settings here (credentials, withdrawal configuration, etc.)<br>`;
- html += `You'll also see the site specific requirements, like required captcha solvers.<br>Meanwhile, go to Settings > Defaults > Site Specifics.<br>If there's something to configurate for this site, it'll be listed there.`;
- html += `<br>You can find a general requirements list in Settings > Other requirements...</div>`;
- html += ' </form></div>';
- html += ' </div>';
- html += ' <div class="modal-footer">';
- html += ' <a class="btn m-2 anchor btn-outline-danger align-middle" data-dismiss="modal"><i class="fa fa-times-circle"></i> Close</a>';
- html += ' </div>';
- html += '</div>';
-
- html += ' <div class="modal-content bg-beige d-none" id="modal-slAlert">';
- html += ' <div class="modal-header"><h5 class="modal-title">Attention</h5></div>';
- html += ' <div class="modal-body">';
- html += ' <div class="alert alert-warning">You will be redirected to a shortlink, and after completing it the new Twitter Daily Promo Code will be added to your table.<br>';
- html += 'This is an optional contribution. You can still get the code the old fashion way.</div>';
- html += uiRenderer.addLegacySliderHtml('id', 'hideShortlinkAlerts', `Stop warning me before a shortlink`);
- html += ' </div>';
- html += '<div class="modal-footer"><a class="btn m-2 anchor btn-outline-danger align-middle" onclick="modalCancel(\'slAlert\')" data-dismiss="modal"><i class="fa fa-times-circle"></i> Cancel</a>';
- html += '<a class="btn m-2 anchor btn-outline-success align-middle" onclick="modalSave(\'slAlert\')" data-dismiss="modal"><i class="fa fa-external-link-alt"></i> Lets Go!</a></div>';
- html += ' </div>';
-
- html += ' <div class="modal-content bg-beige d-none" id="modal-site">';
- html += ' <div class="modal-header"><h5 class="modal-title"><i class="fa fa-clock"></i> <span id="faucet-name" data-id=""></span> Schedule Parameters</h5></div>';
- html += ' <div class="modal-body">';
- html += ' <div class="alert alert-warning">Override Settings for the selected faucet.<br>Faucet-specific configurations will be moved here soon.</div>';
- html += ' <div class="row">';
-
- html += ' <div class="col-md-12 col-sm-12">';
- html += addCardHtml({
- header: uiRenderer.addLegacySliderHtml('data-site-prop', 'defaults.workInBackground.override', 'Override Work Mode'),
- body: uiRenderer.addLegacySliderHtml('data-site-prop', 'defaults.workInBackground', 'Open tab in background')
- });
- html += addCardHtml({
- header: uiRenderer.addLegacySliderHtml('data-site-prop', 'defaults.nextRun.override', 'Override Next Run'),
- body: `<div>${uiRenderer.addLegacySliderHtml('data-site-prop', 'defaults.nextRun.useCountdown', 'Use faucet countdown when possible')}</div>` +
- `<label class="control-label">Otherwise wait:</label>` +
- addRandomBetween({ name: 'data-site-prop', value: 'defaults.nextRun' }, { name: 'data-site-prop', value: 'defaults.nextRun.min' }, { name: 'data-site-prop', value: 'defaults.nextRun.max' })
- });
- html += addCardHtml({
- header: uiRenderer.addLegacySliderHtml('data-site-prop', 'defaults.sleepMode.override', 'Override Sleep Mode'),
- body: uiRenderer.addLegacySliderHtml('data-site-prop', 'defaults.sleepMode', 'Sleep mode') +
- `<table><tr><td>Don't claim between </td><td><input type="time" data-original="" data-site-prop="defaults.sleepMode.min" class="form-control"></td><td>and</td>
- <td><input type="time" data-original="" data-site-prop="defaults.sleepMode.max" class="form-control"></td></tr></table>`
- });
- html += ' <div class="card m-1"><div class="card-header">Timeout</div>';
- html += ' <div class="card-body px-4">';
- html += addCardHtml({
- header: uiRenderer.addLegacySliderHtml('data-site-prop', 'defaults.timeout.override', 'Override Timeout'),
- body: `<table><tr><td>After</td><td><input type="number" data-original="" data-site-prop="defaults.timeout" min="2" value="5" step="1" class="form-control"></td><td>minutes</td></tr></table>`
- });
- html += addCardHtml({
- header: uiRenderer.addLegacySliderHtml('data-site-prop', 'defaults.postponeMinutes.override', 'Override Postpone'),
- body: `<label class="control-label">After timeout/error, postpone for:</label>` +
- addRandomBetween({ name: 'data-site-prop', value: 'defaults.postponeMinutes' }, { name: 'data-site-prop', value: 'defaults.postponeMinutes.min' }, { name: 'data-site-prop', value: 'defaults.postponeMinutes.max' })
- });
- html += ' </div>';
- html += ' </div>';
- html += ' </div>';
- html += ' </div>';
- html += ' </div>';
- html += '<div class="modal-footer"><a class="btn m-2 anchor btn-outline-danger align-middle" onclick="modalCancel(\'site\')" data-dismiss="modal"><i class="fa fa-times-circle"></i> Cancel</a>';
- html += '<a class="btn m-2 anchor btn-outline-success align-middle" onclick="modalSave(\'site\')" data-dismiss="modal"><i class="fa fa-check-circle"></i> Save</a></div>';
- html += ' </div>';
-
- html += '<div class="modal-content bg-beige d-none" id="modal-config">';
- html += ' <div class="modal-header"><h5 class="modal-title"><i class="fa fa-cog"></i> Settings</h5></div>';
- html += ' <div class="modal-body">';
- html += ' <div class="row">';
-
- html += ' <div class="col-md-12 col-sm-12">';
- html += ' <div class="card card-info m-1"><div class="card-header">Defaults<div class="card-tools"><button type="button" class="btn btn-white btn-sm" data-card-widget="collapse" title="Collapse"><i class="fas fa-minus"></i></button></div></div>';
- html += ' <div class="card-body px-4">';
- html += `<div>${uiRenderer.addLegacySliderHtml('data-prop', 'defaults.workInBackground', 'Open tabs in background')}</div>`;
- html += `<div>${uiRenderer.addLegacySliderHtml('data-prop', 'defaults.extraInterval', 'Use extra timer to detect ad redirects faster')}</div>`;
-
- html += addCardHtml({
- header: 'Next Run',
- body: `<div>${uiRenderer.addLegacySliderHtml('data-prop', 'defaults.nextRun.useCountdown', 'Use faucet countdown when possible')}</div>` +
- `<label class="control-label">Otherwise wait:</label>` +
- addRandomBetween({ name: 'data-prop', value: 'defaults.nextRun' }, { name: 'data-prop', value: 'defaults.nextRun.min' }, { name: 'data-prop', value: 'defaults.nextRun.max' })
- });
- html += addCardHtml({
- header: 'Timeout',
- body: `<table><tr><td>After</td><td><input type="number" data-original="" data-prop="defaults.timeout" min="2" value="5" step="1" class="form-control"></td><td>minutes</td></tr></table>` +
- `<label class="control-label">After timeout/error, postpone for:</label>` +
- addRandomBetween({ name: 'data-prop', value: 'defaults.postponeMinutes' }, { name: 'data-prop', value: 'defaults.postponeMinutes.min' }, { name: 'data-prop', value: 'defaults.postponeMinutes.max' })
- });
- html += addCardHtml({
- header: 'Logging',
- body: `<div>${uiRenderer.addLegacySliderHtml('data-prop', 'devlog.enabled', 'Store log (enables the \'Log\' button)')}</div>` +
- `<table><tr><td>Max log size in lines:</td><td><input type="number" data-original="" data-prop="devlog.maxLines" min="100" step="100" class="form-control"></td></tr></table>`
- });
- html += addCardHtml({
- header: uiRenderer.addLegacySliderHtml('data-prop', 'defaults.sleepMode', 'Sleep mode'),
- body: `<table><tr><td>Don't claim between </td><td><input type="time" data-original="" data-prop="defaults.sleepMode.min" class="form-control"></td><td>and</td>
- <td><input type="time" data-original="" data-prop="defaults.sleepMode.max" class="form-control"></td></tr></table>`
- });
- html += ' </div></div>';
- html += ' </div>';
-
- html += ' <div class="col-md-12 col-sm-12">';
- html += ' <div class="card card-info m-1"><div class="card-header">Site Specifics<div class="card-tools"><button type="button" class="btn btn-white btn-sm" data-card-widget="collapse" title="Collapse"><i class="fas fa-minus"></i></button></div></div>';
- html += ' <div class="card-body px-4">';
-
- html += ' <div class="card m-1 collapsed-card"><div class="card-header">CryptosFaucets<div class="card-tools"><button type="button" class="btn btn-white btn-sm" data-card-widget="collapse" title="Collapse"><i class="fas fa-plus"></i></button></div></div>';
- html += ' <div class="card-body px-4" style="display: none;">';
- html += ' <div><label class="switch"><input type="checkbox" data-prop="cf.rollOnce" ><span class="slider round"></span></label> Roll once per round </div>';
- html += ' <div><label class="switch"><input type="checkbox" data-prop="cf.usePromoCodes" ><span class="slider round"></span></label> Try to use promo codes every day (disable it if you are facing too many captcha timeouts) </div>';
- html += ' <div><label class="switch"><input type="checkbox" data-prop="cf.tryGetCodes" ><span class="slider round"></span></label> Auto update promo codes </div>';
- html += ' <div><label class="switch"><input type="checkbox" data-prop="cf.autologin" ><span class="slider round"></span></label> Autologin when necessary</div>';
- html += ' <select class="form-control" data-prop="cf.credentials.mode">';
- html += ' <option value="1">Use Email and Password</option><option value="2">Filled by 3rd party software/extension</option>';
- html += ' </select>';
- html += ' <label class="control-label">E-Mail</label>';
- html += ' <input maxlength="200" type="text" data-prop="cf.credentials.email" required="required" class="form-control" placeholder="Email address..."/>';
- html += ' <label class="control-label">Password</label>';
- html += ' <input maxlength="200" type="password" data-prop="cf.credentials.password" required="required" class="form-control" placeholder="Password..."/>';
- html += ' <label class="control-label">Hours to wait If IP is banned:</label>';
- html += ' <select class="form-control" data-prop="cf.sleepHoursIfIpBan">';
- html += ' <option value="0">Disabled</option><option value="2">2</option><option value="4">4</option><option value="8">8</option><option value="16">16</option><option value="24">24</option><option value="26">26</option>';
- html += ' </select>';
- html += ' </div></div>';
-
- html += ' <div class="card m-1 collapsed-card"><div class="card-header">JTFey<div class="card-tools"><button type="button" class="btn btn-white btn-sm" data-card-widget="collapse" title="Collapse"><i class="fas fa-plus"></i></button></div></div>';
- html += ' <div class="card-body px-4" style="display: none;">';
- html += ' <label class="control-label">Login Mode</label>';
- html += ' <select class="form-control" data-prop="jtfey.credentials.mode">';
- html += ' <option value="1">Use Username and Password</option><option value="2">Filled by 3rd party software/extension</option>';
- html += ' </select>';
- html += ' <label class="control-label">E-Mail</label>';
- html += ' <input maxlength="200" type="text" data-prop="jtfey.credentials.username" required="required" class="form-control" placeholder="Email address..."/>';
- html += ' <label class="control-label">Password</label>';
- html += ' <input maxlength="200" type="password" data-prop="jtfey.credentials.password" required="required" class="form-control" placeholder="Password..."/>';
- html += ' </div></div>';
-
- html += ' <div class="card m-1 collapsed-card"><div class="card-header">FaucetPay PTC<div class="card-tools"><button type="button" class="btn btn-white btn-sm" data-card-widget="collapse" title="Collapse"><i class="fas fa-plus"></i></button></div></div>';
- html += ' <div class="card-body px-4" style="display: none;">';
- html += ' <div><label class="switch"><input type="checkbox" data-prop="fp.randomPtcOrder" ><span class="slider round"></span></label> Random PTC order </div>';
- html += ' <label class="control-label">Max duration per run:</label>';
- html += ' <select class="form-control" data-prop="fp.maxTimeInMinutes">';
- html += ' <option value="5">5 minutes</option><option value="10">10 minutes</option><option value="15">15 minutes</option><option value="30">30 minutes</option>';
- html += ' </select>';
- html += ' </div></div>';
-
- html += ' <div class="card m-1 collapsed-card"><div class="card-header">Dutchy<div class="card-tools"><button type="button" class="btn btn-white btn-sm" data-card-widget="collapse" title="Collapse"><i class="fas fa-plus"></i></button></div></div>';
- html += ' <div class="card-body px-4" style="display: none;">';
- html += ' <div><label class="switch"><input type="checkbox" data-prop="dutchy.useBoosted" ><span class="slider round"></span></label> Try boosted roll </div>';
- html += ' </div></div>';
-
- html += ' <div class="card m-1 collapsed-card"><div class="card-header">BestChange<div class="card-tools"><button type="button" class="btn btn-white btn-sm" data-card-widget="collapse" title="Collapse"><i class="fas fa-plus"></i></button></div></div>';
- html += ' <div class="card-body px-4" style="display: none;">';
- html += ' <label class="control-label">BTC Address:</label>';
- html += ' <select class="form-control" data-prop="bestchange.address">';
- html += ' <option value="101">Faucet Pay BTC</option><option value="1">BTC Alt Address</option>';
- html += ' </select>';
- html += ' </div></div>';
-
- html += ' <div class="card m-1 collapsed-card"><div class="card-header">Yes Coiner<div class="card-tools"><button type="button" class="btn btn-white btn-sm" data-card-widget="collapse" title="Collapse"><i class="fas fa-plus"></i></button></div></div>';
- html += ' <div class="card-body px-4" style="display: none;">';
- html += ' <label class="control-label">Login Mode</label>';
- html += ' <select class="form-control" data-prop="ycoin.credentials.mode">';
- html += ' <option value="1">Use Username and Password</option><option value="2">Filled by 3rd party software/extension</option>';
- html += ' </select>';
- html += ' <label class="control-label">E-Mail</label>';
- html += ' <input maxlength="200" type="text" data-prop="ycoin.credentials.username" required="required" class="form-control" placeholder="Account number..."/>';
- html += ' <label class="control-label">Password</label>';
- html += ' <input maxlength="200" type="password" data-prop="ycoin.credentials.password" required="required" class="form-control" placeholder="Password..."/>';
- html += ' </div></div>';
-
- html += ' </div></div>';
- html += ' </div>';
- html += ' </div>';
- html += '</div>';
- html += '<div class="modal-footer"><a class="btn m-2 anchor btn-outline-danger align-middle" onclick="modalCancel(\'config\')" data-dismiss="modal"><i class="fa fa-times-circle"></i> Cancel</a>';
- html += '<a class="btn m-2 anchor btn-outline-success align-middle" onclick="modalSave(\'config\')" data-dismiss="modal"><i class="fa fa-check-circle"></i> Save</a></div>';
- html += ' </div>';
-
- html += '</div>';
- html += '</div>';
-
- html += '<section id="table-struct" class="fragment "><div class="container-fluid "><div class="py-1 "><div class="row mx-0 justify-content-center">';
- html += '<a class="btn m-2 anchor btn-outline-danger align-middle" data-toggle="modal" data-target="#confirmable-modal" onclick="confirmable.open(\'forceStopFaucet\', \'Running faucet will be disabled and the manager will reload.\')"><i class="fa fa-stop-circle"></i>Force Stop</a>';
- html += '</div>';
-
- html += '<div class="card">';
-
- html += '<div class="card-header">';
- html += '<div class="d-flex p-0">';
-
- html += '<div id="schedules-toggler" class="btn-group btn-group-toggle" data-toggle="buttons">';
-
- html += '</div>';
-
- html += '<div class="card-tools ml-auto mt-2 mr-1">';
- html += '<input type="checkbox" data-toggle="switch" data-label-text="Log" title="Show/Hide Log" id="bss-log" checked>';
-
- html += `<button type="button" class="btn btn-flat btn-sm btn-outline-primary mx-1 dropdown-toggle" data-toggle="dropdown" aria-expanded="false"><i class="fa fa-cog"></i> Settings</button>
- <div class="dropdown-menu text-sm dropdown-settings-menu" style="">
- <a class="dropdown-item btn-open-dialog" data-target="modal-config"><i class="fa fa-cog"></i> Defaults...</a>
- <div class="dropdown-divider"></div>
- <a class="dropdown-item btn-open-dialog" data-target="modal-schedules"><i class="fa fa-stopwatch"></i> Schedules...</a>
- <a class="dropdown-item btn-open-dialog" data-target="modal-wallet"><i class="fa fa-wallet"></i> Wallets...</a>
- <a class="dropdown-item btn-open-dialog" data-target="modal-requirements"><i class="fa fa-exclamation-circle"></i> Other requirements...</a>
- <!-- <a class="dropdown-item btn-open-dialog" data-target="modal-sites"><i class="fa fa-window-restore"></i> Sites...</a> -->
- <div class="dropdown-divider"></div>
- <a class="dropdown-item btn-open-dialog" data-target="modal-info"><i class="fa fa-info"></i> Help/Info...</a>
- </div>`;
-
- html += '<button type="button" class="btn btn-tool" data-card-widget="collapse"><i class="fas fa-minus"></i></button>';
- html += '<button type="button" class="btn btn-tool mx-1" data-card-widget="maximize"><i class="fas fa-expand"></i></button>';
- html += '</div></div>';
- html += '<div id="wait-times" class="row mx-0 p-0 justify-content-center"></div>';
- html += '</div>';
-
- html += '<div class="card-body table-responsive p-0" style="height: 400px;" id="schedule-container">';
- html += '<pre class="collapse show" id="console-log"><b>Loading...</b></pre>';
- html += '</div>';
-
- html += '</div>';
-
- html += '</div>';
- html += '<span id="update-data" style="display:none;"></span></section>';
- html += '<section id="table-struct-promo" class="fragment "><div class="container-fluid "><div class="py-1 ">';
-
- html += '<div class="card"><div class="card-header"><h3 class="card-title font-weight-bold">Promo Codes</h3><span id="promo-code-new" style="display:none;"></span>';
- html += '<div class="card-tools">';
-
- html += '<div class="input-group input-group-sm btn-tool">';
- html += '<input id="promo-text-input" type="text" name="table_search" class="form-control float-right" placeholder="CF Promo Code..." style="width:130px;">';
- html += '<input type="checkbox" data-toggle="switch" title="Check if the code can be reused every 24hs" id="promo-daily" data-on-text="Daily" data-off-text="1 Time">';
- html += '<div class="input-group-append"><button type="submit" class="btn btn-default" id="promo-button""><i class="fas fa-plus"></i> Add</button></div>';
- html += '<div class="input-group-append"><button type="submit" class="btn btn-default btn-outline-danger mx-1" data-toggle="modal" data-target="#confirmable-modal" onclick="confirmable.open(\'removeAllPromos\', \'All promo codes will be removed.\')"><i class="fas fa-times-circle"></i> Remove All</button></div>';
- html += '<div class="input-group-append"><button type="submit" class="btn btn-default btn-outline-primary" id="button-try-get-codes"><i class="fas fa-bolt"></i> Try to Get Codes</button></div>';
- html += '<div class="input-group-append"><button type="button" class="btn btn-tool btn-sm mx-1" data-card-widget="collapse" title="Collapse"><i class="fas fa-minus"></i></button></div>';
- html += '<div class="input-group-append"><button type="button" class="btn btn-tool btn-sm mx-1" data-card-widget="maximize" title="Maximize"><i class="fas fa-expand"></i></button></div>';
- html += '</div>';
- html += '</div>';
-
- html += '</div>';
- html += '<div class="card-body table-responsive p-0" id="promo-container">';
- html += '</div></div>';
-
- html +='</div></div></section>';
- html += '<section class="fragment"><div class="container-fluid ">';
- html += '<div class="row justify-content-center"><a class="btn m-2 anchor btn-outline-primary" id="stats-button" onclick="openStatsChart()">CF Lucky Number Stats</a></div>';
- html +='<div class="py-1" id="stats-fragment" style="display:none;"><div class="row align-items-center text-center justify-content-center">';
- html += '<div class="col-md-12 col-lg-8"><canvas id="barChart"></canvas><span id="rolls-span" style="display:none;"></span></div></div></div></div></div></section>';
-
- let wrapper = document.createElement('div');
- wrapper.innerHTML = html.trim();
-
- let target = document.getElementById('referral-table');
- target.parentNode.insertBefore(wrapper, target);
- document.getElementById('schedule-container').appendChild( createScheduleTable() );
-
- if (document.querySelector('.main-header .navbar-nav.ml-auto')) {
- let discord = document.createElement('li');
- discord.classList.add('nav-item');
- discord.innerHTML = '<a class="btn btn-primary btn-sm m-1" href="https://discord.gg/gaYYBjJUhP" target="_blank"><div class=""><span class="badge badge-pill badge-warning mr-2" title="">(new)</span>discord</div></a>';
- document.querySelector('.main-header .navbar-nav.ml-auto').prepend(discord);
- } else {
- let discord = document.createElement('div');
- discord.innerHTML = '<a class="btn m-2 btn-primary" href="https://discord.gg/gaYYBjJUhP" target="_blank"><div class=""><span class="badge badge-pill badge-warning mr-2" title="">(new)</span>discord</div></a>';
- document.querySelector('.navbar-nav').prepend(discord);
- }
- addHtml({
- target: '#modal-dlg .modal-dialog',
- where: 'afterbegin',
- content: `<div class="modal-content bg-beige d-none" id="modal-requirements">
- <div class="modal-header"><h5 class="modal-title"><i class="fa fa-exclamation-circle"></i> Other requirements</h5></div>
- <div class="modal-body">
- <div class="callout callout-warning m-3">
- <p class="text-justify">Some sites might require specific tools like captcha solvers that are not including in the script.</p>
- </div>
- <div>
- <table class="table custom-table-striped" id="requirements-table">
- <thead><tr><th class="">Name</th><th class="">Description</th><th class="">Suggestion</th></tr></thead>
- <tbody class="overflow-auto" id="requirements-table-body">
- </tbody>
- </table>
- </div>
- </div>
- <div class="modal-footer">
- <a class="btn m-2 anchor btn-outline-danger align-middle" data-dismiss="modal"><i class="fa fa-times-circle"></i> Close</a>
- </div>
- </div>`
- });
- addTemplateTag({
- id: 'tpl-requirement-row',
- content: `<tr><td>{name}</td><td>{description}</td><td>{suggestion}</td></tr>`
- });
- const tempRequirementsList = [
- { id: '1', name: 'HCaptcha Solver', description: 'A solver for HCaptcha challenges', suggestion: `Latest github version of hektCaptcha extension (free)<br><a href="https://bit.ly/3Y24vg5" target="_blank"><i class="fa fa-external-link-alt"></i> Visit</a>` },
- { id: '2', name: 'Recaptcha Solver', description: 'A solver for ReCaptcha challenges', suggestion: `Latest github version of hektCaptcha extension (free)<br><a href="https://bit.ly/3Y24vg5" target="_blank"><i class="fa fa-external-link-alt"></i> Visit</a>` },
- { id: '3', name: 'Cloudflare Challenge Bypass', description: 'A solver for Cloudflare/Turnstile challenges', suggestion: `Auto clicker user script (free)<br><a href="https://sharetext.me/knpmyolewq" target="_blank"><i class="fa fa-external-link-alt"></i> Visit</a>` },
- { id: '6', name: 'Active Tab/Window', description: 'The site requires the tab to be active. A good option is Tab Revolver Extension, which will loop the tabs opened in a specific window.', suggestion: `<a href="https://bit.ly/3Y28lpA" target="_blank"><i class="fa fa-external-link-alt"></i> User Script</a> or <a href="https://bit.ly/3q0H4Ht" target="_blank"><i class="fa fa-external-link-alt"></i> Extension</a>` },
- ];
- for(let r=0; r< tempRequirementsList.length; r++) {
- let req = tempRequirementsList[r];
- useTemplate({
- templateId: 'tpl-requirement-row',
- target: '#requirements-table-body',
- where: 'afterbegin',
- replacements: req
- });
- }
- };
- function createPromoTable(faucets) {
- let table = document.createElement('table');
- let inner = '';
- table.classList.add('table', 'custom-table-striped');
- table.setAttribute('id','promo-table');
-
- inner += '<caption style="text-align: -webkit-center;">⏳ Pending ✔️ Accepted 🕙 Used Before ❌ Invalid code ❗ Unknown error ⚪ No code</caption>';
- inner += '<thead><tr><th class="">Code</th><th class="">Added</th>';
-
- for (let i = 0, all = faucets.length; i < all; i++) {
- inner += '<th data-faucet-id="' + faucets[i].id + '">' + faucets[i].name + '</th>';
- }
-
- inner += '</tr></thead><tbody id="promo-table-body"></tbody></table>';
-
- table.innerHTML = inner
- document.getElementById('promo-container').appendChild( table );
- };
- function createScheduleTable() {
- let table = document.createElement('table');
- let inner;
- table.classList.add('table', 'custom-table-striped', 'table-head-fixed', 'text-nowrap');
- table.setAttribute('id','schedule-table');
-
- inner = '<thead><tr>';
- inner += '<th scope="col" class="edit-status d-none em-only" style="">Active</th><th class="">Next Roll</th><th class=""></th><th class="">Name</th><th class="text-center">Last Claim</th>';
- inner += '<th class="text-center">Aggregate</th><th class="text-center">Balance</th><th class="text-center em-hide" id="converted-balance-col">FIAT</th>';
- inner += '<th scope="col" class="text-center em-hide">Msgs</th>';
- inner += '<th scope="col" class="" style="">';
- inner += `<div class="btn-group btn-group-sm">
- <button type="button" data-toggle="tooltip" title="Add site..." class="btn btn-default action-add-external-site em-hide">
- <i class="fa fa-plus"></i>
- </button>
- <button type="button" title="Cancel" class="btn btn-danger action-edit-all-sites-cancel em-only d-none"><i class="fa fa-times-circle"></i> Cancel</button>
- <button type="button" title="Save" class="btn btn-success action-edit-all-sites-save em-only d-none"><i class="fa fa-check-circle"></i> Save</button>
- <button type="button" data-toggle="tooltip" title="Edit all..." class="btn btn-default action-edit-all-sites em-hide"><i class="fa fa-toggle-off"></i></button>
- </div>`;
- inner += '</th></tr></thead><tbody id="schedule-table-body"></tbody>';
- table.innerHTML = inner;
-
- return table;
- };
- function renderLogRow(data) {
- let tr = document.createElement('tr');
- tr.dataset.schedule = data.schedule;
- tr.dataset.ts = data.ts.getTime();
- tr.dataset.siteName = data.siteName || '';
- tr.dataset.elapsed = data.elapsed || '';
- let color = data.schedule ? `#${data.schedule}` : `transparent`;
- let showIt = !data.schedule || !uiRenderer.schedules.selectedSchedule
- || uiRenderer.schedules.selectedSchedule == 'all' || uiRenderer.schedules.selectedSchedule == data.schedule;
- if (!showIt) {
- tr.classList.add('d-none');
- }
-
- let tds = '';
- tds += `<td>${helpers.getPrintableTime(data.ts)}</td>`;
- tds += `<td><i class="fas fa-square pr-1" style="color: ${color};"></i></td>`;
- if (data.elapsed) {
- tds += `<td>${data.msg} [Elapsed time: ${data.elapsed} seconds]</td>`;
- } else {
- tds += `<td>${data.msg}</td>`;
- }
- tr.innerHTML = tds;
-
- document.querySelector('#console-log table').appendChild(tr);
- };
- function log(data) {
- if (!data || !data.msg) {
- console.warn(`Log attempt without data or msg!`, data);
- return;
- }
- data.ts = new Date();
- data.schedule = data.schedule || false;
- data.siteName = data.siteName || false;
- data.elapsed = data.elapsed || false;
-
- if(shared.getConfig()['devlog.enabled']) {
- if (data.schedule) {
- } else {
- }
- };
-
- if (data.elapsed) {
- let previous = logLines.find(x => x.msg == data.msg && x.schedule == data.schedule);
- if (previous) {
- previous.elapsed = data.elapsed;
- previous.ts = data.ts;
- logLines.sort( (a, b) => b.ts.getTime() - a.ts.getTime());
- } else {
- logLines.unshift(data);
- }
- } else {
- logLines.unshift(data);
- }
- while(logLines.length > 30) {
- logLines.pop();
- }
-
- document.querySelector('#console-log table').innerHTML = '';
- logLines.forEach(r => renderLogRow(r));
- };
- function legacyLog(data, elapsed = false) {
- if (!data || !data.msg) {
- return;
- }
- elapsed = data.elapsed || false;
- let msg = data.msg;
- if (data.schedule) {
- msg = `[${data.schedule}] ${data.msg}`;
- }
-
- if(shared.getConfig()['devlog.enabled']) { shared.devlog(msg, elapsed) };
- if(msg) {
- let waitingIdx = logLines.findIndex(line => {
- let waitingMsg= line.split(' ')[1];
- if (waitingMsg == msg) {
- return true;
- }
- });
-
- let previous = waitingIdx > -1 ? logLines[waitingIdx].split(' ')[1] : '';
- if (elapsed && (previous == msg)) {
- logLines[waitingIdx] = helpers.getPrintableTime() + ' ' + msg + ' [Elapsed time: ' + elapsed + ' seconds]';
- } else {
- while(logLines.length > 20) {
- logLines.pop();
- }
- logLines.unshift(helpers.getPrintableTime() + ' ' + msg);
- }
-
- document.getElementById('console-log').innerHTML = logLines.map(x => {
- const regex = /\[([0-9a-fA-F]+)\]/;
- const match = regex.exec(x);
- let colorNumber = null;
- if (match !== null) {
- colorNumber = match[1];
- }
-
- let showIt = !colorNumber || !window.selectedSchedule || window.selectedSchedule == 'all' || window.selectedSchedule == colorNumber;
-
- const formattedMsg = x.replace(/\[([0-9a-fA-F]+)\]/, '<i class="fas fa-square pr-1" style="color: #$1;"></i>');
-
- let line = `<span data-schedule="${colorNumber ? colorNumber : ''}" class="${showIt ? '' : 'd-none'}">${formattedMsg}</span>`;
- return line;
- }).join('');
- }
- };
- return {
- init: init,
- log: log
- }
- }
-
- async function init() {
- eventer = new EventEmitter();
- persistence = new Persistence();
- shared = objectGenerator.createShared();
- useTimer = shared.getConfig()['defaults.extraInterval'];
- if (location.href.startsWith('https://criptologico.com/tools/cc')) {
- landing = window.location.host;
- instance = K.LOCATION.MANAGER;
- manager = createManager();
- CFPromotions = objectGenerator.createCFPromotions();
- uiRenderer = new UiRenderer();
- uiRenderer.initialize();
- ui = createUi();
- CFHistory = objectGenerator.createCFHistory();
-
- await manager.start();
- try {
- if (!document.body.classList.contains('sidebar-collapse')) document.querySelector('a[data-widget="pushmenu"]').click()
- } catch {}
- setTimeout( () => { window.stop(); }, 10000);
- } else {
- instance = K.LOCATION.UNKNOWN;
- detectWeb();
- }
- }
- init();
- })();