Skip to content

Instantly share code, notes, and snippets.

@kkodev
Created October 20, 2014 12:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kkodev/7de77ea3a20087391824 to your computer and use it in GitHub Desktop.
Save kkodev/7de77ea3a20087391824 to your computer and use it in GitHub Desktop.
//
// One helluva bad ass extension!
//
var BadAssX = function() {};
BadAssX.prototype.run = function(arguments) {
arguments.completionFunction({"url": document.baseURI});
};
BadAssX.prototype.finalize = function(arguments) {
var itemJSON = arguments["itemJSON"];
// alert(itemJSON.substring(0, 50));
var item = JSON.parse(itemJSON);
// alert("Filling '" + item['overview']['title'] + "'");
var error = OPFiller("fillLogin", item, false, true);
// alert("Error '" + error + "'");
};
var ExtensionPreprocessingJS = new BadAssX;
function OPFiller(action, fillObjectJSON, submitLogin, animateFill, undefined ) {
// Use the correct document accordingly with window argument (sandbox)
var document = window.document;
var COUNTRY_REGEX_MAPPING = {
'ca': "(canada|^ca$|^can$|канада|kanada)",
'us': "(unitedstates|^us$|^usa$|сша|vereinigtestaaten)",
'uk': rot13("(havgrqxvatqbz|^hx$)"),
'gb': "(britain|^gb$|великобритания)",
'de': rot13("(treznal|qrhgfpuynaq)"),
'au': rot13("nhfgenyvn"),
'nl': rot13("(argureynaqf|ubyynaq)"),
'it': rot13("vgnyl"),
'fr': rot13("senapr"),
'mx': rot13("zrkvpb"),
'cn': rot13("puvan"),
'ch': rot13("fjvgmreynaq"),
'es': rot13("fcnva"),
'jp': rot13("wncna"),
'at': rot13("nhfgevn"),
'be': rot13("orytvhz"),
'ad': rot13("naqbeen"),
'ae': rot13("(havgrqnenorzvengrf|hnr)"),
'af': rot13("nstunavfgna"),
'ag': rot13("nagvthnnaqoneohqn"),
'ai': rot13("nathvyyn"),
'al': rot13("nyonavn"),
'am': rot13("nezravn"),
'an': rot13("argureynaqfnagvyyrf"),
'ao': rot13("natbyn"),
'aq': rot13("nagnepgvpn"),
'ar': rot13("netragvan"),
'as': rot13("nzrevpnafnzbn"),
'aw': rot13("nehon"),
'az': rot13("nmreonvqwna"),
'ba': rot13("obfavnuremrtbivan"),
'bb': rot13("oneonqbf"),
'bd': rot13("onatynqrfu"),
'bf': rot13("ohexvansnfb"),
'bg': rot13("ohytnevn"),
'bh': rot13("onuenva"),
'bi': rot13("ohehaqv"),
'bj': rot13("orava"),
'bm': rot13("orezhqn"),
'bn': rot13("oeharvqnehffnynz"),
'bo': rot13("obyvivn"),
'br': rot13("oenmvy"),
'bs': rot13("onunznf"),
'bt': rot13("ouhgna"),
'bv': rot13("obhirgvfynaq"),
'bw': rot13("obgfjnan"),
'by': rot13("orynehf"),
'bz': rot13("oryvmr"),
'cc': "cocos.*islands",
'cf': rot13("pragenynsevpnaerchoyvp"),
'cd': "congo.*republic",
'cg': rot13("^pbatb$"),
'ci': rot13("vibelpbnfg"),
'ck': rot13("pbbxvfynaqf"),
'cl': rot13("puvyr"),
'cm': rot13("pnzrebba"),
'co': rot13("pbybzovn"),
'cr': rot13("pbfgnevpn"),
'cu': rot13("phon"),
'cv': rot13("pncrireqr"),
'cx': rot13("puevfgznfvfynaq"),
'cy': rot13("plcehf"),
'cz': rot13("pmrpu"),
'dj': rot13("qwvobhgv") ,
'dk': rot13("qraznex"),
'dm': rot13("qbzvavpn$") ,
'do': rot13("qbzvavpnaerchoyvp"),
'dz': rot13("nytrevn"),
'ec': rot13("rphnqbe"),
'ee': rot13("rfgbavn"),
'eg': rot13("rtlcg"),
'eh': rot13("jrfgreafnunen"),
'er': rot13("revgern"),
'et': rot13("rguvbcvn"),
'fi': rot13("svaynaq"),
'fj': rot13("svwv"),
'fk': rot13("snyxynaqvfynaqf"),
'fm': rot13("zvpebarfvn"),
'fo': rot13("snebrvfynaqf"),
'ga': rot13("tnoba"),
'gd': rot13("teranqn"),
'ge': rot13("trbetvn"),
'gf': rot13("seraputhlnan"),
'gh': rot13("tunan"),
'gi': rot13("tvoenygne"),
'gl': rot13("terraynaq"),
'gm': rot13("tnzovn"),
'gn': rot13("thvarn"),
'gp': rot13("thnqrybhcr"),
'gq': rot13("rdhngbevnythvarn"),
'gr': rot13("terrpr"),
'gs': "georgia.*sandwich",
'gt': rot13("thngrznyn"),
'gu': rot13("thnz"),
'gw': rot13("thvarnovffnh"),
'gy': rot13("thlnan"),
'hk': rot13("ubatxbat"),
'hm': "heard.*mcdonald",
'hn': rot13("ubaqhenf"),
'hr': rot13("pebngvn"),
'ht': rot13("unvgv"),
'hu': rot13("uhatnel"),
'id': rot13("vaqbarfvn"),
'ie': rot13("verynaq"),
'il': rot13("vfenry"),
'in': rot13("vaqvn$"),
'iq': rot13("vend"),
'ir': rot13("vena"),
'is': rot13("vprynaq"),
'jm': rot13("wnznvpn"),
'jo': rot13("wbeqna"),
'ke': rot13("xraln"),
'kg': rot13("xletlm"),
'kh': rot13("pnzobqvn"),
'ki': rot13("xvevongv"),
'km': rot13("pbzbebf"),
'kn': rot13("fnvagxvggf"),
'kp': rot13("abeguxbern"),
'kr': rot13("fbhguxbern"),
'kw': rot13("xhjnvg"),
'ky': rot13("pnlzna"),
'kz': rot13("xnmnxufgna"),
'la': rot13("ynbf"),
'lb': rot13("yronaba"),
'lc': rot13("fnvagyhpvn"),
'li': rot13("yvrpugrafgrva"),
'lk': rot13("fevynaxn"),
'lr': rot13("yvorevn"),
'ls': rot13("yrfbgub"),
'lt': rot13("yvguhnavn"),
'lu': rot13("yhkrzobhet"),
'lv': rot13("yngivn"),
'ly': rot13("yvoln"),
'ma': rot13("zbebppb"),
'mc': rot13("zbanpb"),
'md': rot13("zbyqnivn"),
'mg': rot13("znqntnfpne"),
'mh': rot13("znefunyy"),
'mk': rot13("znprqbavn"),
'ml': rot13("znyv"),
'mm': rot13("zlnazne"),
'mn': rot13("zbatbyvn"),
'mo': rot13("znpnh"),
'mq': rot13("znegvavdhr"),
'mr': rot13("znhevgnavn"),
'ms': rot13("zbagfreeng"),
'mt': rot13("znygn"),
'mu': rot13("znhevgvhf"),
'mv': rot13("znyqvirf"),
'mw': rot13("znynjv"),
'my': rot13("znynlfvn"),
'mz': rot13("zbmnzovdhr"),
'na': rot13("anzvovn"),
'nc': rot13("arjpnyrqbavn"),
'ne': rot13("avtre"),
'nf': rot13("abesbyx"),
'ng': rot13("avtrevn"),
'ni': rot13("avpnenthn"),
'no': rot13("abejnl"),
'np': rot13("arcny"),
'nr': rot13("anheh"),
'nt': rot13("arhgenymbar"),
'nu': rot13("avhr"),
'nz': rot13("arjmrnynaq"),
'om': rot13("bzna"),
'pa': rot13("cnanzn"),
'pe': rot13("creh"),
'pf': rot13("cbylarfvn"),
'pg': rot13("cnchnarjthvarn"),
'ph': rot13("cuvyvccvarf"),
'pk': rot13("cnxvfgna"),
'pl': rot13("cbynaq"),
'pm': "pierre.*miquelon",
'pn': rot13("cvgpnvea"),
'pr': rot13("chregbevpb"),
'pt': rot13("cbeghtny"),
'pw': rot13("cnynh"),
'py': rot13("cnenthnl"),
'qa': rot13("dngne"),
're': rot13("erhavba"),
'ro': rot13("ebznavn"),
'ru': rot13("ehffvn") ,
'rw': rot13("ejnaqn"),
'sa': rot13("fnhqvnenovn"),
'sb': rot13("fbybzba"),
'sc': rot13("frlpuryyrf"),
'sd': rot13("fhqna"),
'se': rot13("fjrqra"),
'sg': rot13("fvatncber"),
'sh': rot13("uryran"),
'si': rot13("fybiravn"),
'sj': rot13("finyoneq"),
'sk': rot13("fybinx"),
'sl': rot13("fvreenyrbar"),
'sm': rot13("fnaznevab"),
'sn': rot13("frartny"),
'so': rot13("fbznyvn"),
'sr': rot13("fhevanzr"),
'st': "tome.*principe",
'sv': rot13("fnyinqbe"),
'sy': rot13("flevn"),
'sz': rot13("fjnmvynaq"),
'tc': "turks.*caicos",
'td': rot13("punq"),
'tg': rot13("gbtb"),
'th': rot13("gunvynaq"),
'tj': rot13("gnqwvxvfgna"),
'tk': rot13("gbxrynh"),
'tm': rot13("ghexzravfgna"),
'tn': rot13("ghavfvn"),
'to': rot13("gbatn"),
'tp': rot13("rnfggvzbe"),
'tr': rot13("ghexrl"),
'tt': "trinidad.*tobago",
'tv': rot13("ghinyh"),
'tw': rot13("gnvjna"),
'tz': rot13("gnamnavn"),
'ua': rot13("hxenvar"),
'ug': rot13("htnaqn"),
'uy': rot13("hehthnl"),
'uz': rot13("hmorxvfgna"),
'va': rot13("ingvpna"),
'vc': "vincent.*grenadines",
've': rot13("irarmhryn"),
'vg': "virgin.*british",
'vi': "virgin.*us",
'vn': rot13("ivrganz"),
'vu': rot13("inahngh"),
'wf': "wallis.*futuna islands",
'ws': rot13("fnzbn"),
'ye': rot13("lrzra"),
'yt': rot13("znlbggr"),
'yu': rot13("lhtbfynivn"),
'za': rot13("fbhgunsevpn"),
'zm': rot13("mnzovn"),
'zr': rot13("mnver"),
'zw': rot13("mvzonojr")
};
var COUNTRY_VALUE_MAPPING =
{
'ca': 'Canada',
'us': 'United States',
'uk': 'United Kingdom',
'gb': 'Great Britain',
'de': 'Germany',
'au': 'Australia',
'nl': 'Netherlands',
'it': 'Italy',
'fr': 'France',
'mx': 'Mexico',
'cn': 'China',
'ch': 'Switzerland',
'es': 'Spain',
'jp': 'Japan',
'at': 'Austria',
'be': 'Belgium',
'ad': 'Andorra',
'ae': 'United Arab Emirates',
'af': 'Afghanistan',
'ag': 'Antigua and Barbuda',
'ai': 'Anguilla',
'al': 'Albania',
'am': 'Armenia',
'an': 'Netherlands Antilles',
'ao': 'Angola',
'aq': 'Antarctica',
'ar': 'Argentina',
'as': 'American Samoa',
'aw': 'Aruba',
'az': 'Azerbaidjan',
'ba': 'Bosnia-Herzegovina',
'bb': 'Barbados',
'bd': 'Bangladesh',
'bf': 'Burkina Faso',
'bg': 'Bulgaria',
'bh': 'Bahrain',
'bi': 'Burundi',
'bj': 'Benin',
'bm': 'Bermuda',
'bn': 'Brunei Darussalam',
'bo': 'Bolivia',
'br': 'Brazil',
'bs': 'Bahamas',
'bt': 'Bhutan',
'bv': 'Bouvet Island',
'bw': 'Botswana',
'by': 'Belarus',
'bz': 'Belize',
'cc': 'Cocos (Keeling) Islands',
'cf': 'Central African Republic',
'cd': 'The Democratic Republic of Congo',
'cg': 'Congo',
'ci': 'Ivory Coast',
'ck': 'Cook Islands',
'cl': 'Chile',
'cm': 'Cameroon',
'co': 'Colombia',
'cr': 'Costa Rica',
'cu': 'Cuba',
'cv': 'Cape Verde',
'cx': 'Christmas Island',
'cy': 'Cyprus',
'cz': 'Czech Republic',
'dj': 'Djibouti',
'dk': 'Denmark',
'dm': 'Dominica',
'do': 'Dominican Republic',
'dz': 'Algeria',
'ec': 'Ecuador',
'ee': 'Estonia',
'eg': 'Egypt',
'eh': 'Western Sahara',
'er': 'Eritrea',
'et': 'Ethiopia',
'fi': 'Finland',
'fj': 'Fiji',
'fk': 'Falkland Islands',
'fm': 'Micronesia',
'fo': 'Faroe Islands',
'ga': 'Gabon',
'gd': 'Grenada',
'ge': 'Georgia',
'gf': 'French Guyana',
'gh': 'Ghana',
'gi': 'Gibraltar',
'gl': 'Greenland',
'gm': 'Gambia',
'gn': 'Guinea',
'gp': 'Guadeloupe (French)',
'gq': 'Equatorial Guinea',
'gr': 'Greece',
'gs': 'S. Georgia & S. Sandwich Isls.',
'gt': 'Guatemala',
'gu': 'Guam (USA)',
'gw': 'Guinea Bissau',
'gy': 'Guyana',
'hk': 'Hong Kong',
'hm': 'Heard and McDonald Islands',
'hn': 'Honduras',
'hr': 'Croatia',
'ht': 'Haiti',
'hu': 'Hungary',
'id': 'Indonesia',
'ie': 'Ireland',
'il': 'Israel',
'in': 'India',
'iq': 'Iraq',
'ir': 'Iran',
'is': 'Iceland',
'jm': 'Jamaica',
'jo': 'Jordan',
'ke': 'Kenya',
'kg': 'Kyrgyz Republic (Kyrgyzstan)',
'kh': 'Cambodia, Kingdom of',
'ki': 'Kiribati',
'km': 'Comoros',
'kn': 'Saint Kitts & Nevis Anguilla',
'kp': 'North Korea',
'kr': 'South Korea',
'kw': 'Kuwait',
'ky': 'Cayman Islands',
'kz': 'Kazakhstan',
'la': 'Laos',
'lb': 'Lebanon',
'lc': 'Saint Lucia',
'li': 'Liechtenstein',
'lk': 'Sri Lanka',
'lr': 'Liberia',
'ls': 'Lesotho',
'lt': 'Lithuania',
'lu': 'Luxembourg',
'lv': 'Latvia',
'ly': 'Libya',
'ma': 'Morocco',
'mc': 'Monaco',
'md': 'Moldavia',
'mg': 'Madagascar',
'mh': 'Marshall Islands',
'mk': 'Macedonia',
'ml': 'Mali',
'mm': 'Myanmar',
'mn': 'Mongolia',
'mo': 'Macau',
'mq': 'Martinique (French)',
'mr': 'Mauritania',
'ms': 'Montserrat',
'mt': 'Malta',
'mu': 'Mauritius',
'mv': 'Maldives',
'mw': 'Malawi',
'my': 'Malaysia',
'mz': 'Mozambique',
'na': 'Namibia',
'nc': 'New Caledonia (French)',
'ne': 'Niger',
'nf': 'Norfolk Island',
'ng': 'Nigeria',
'ni': 'Nicaragua',
'no': 'Norway',
'np': 'Nepal',
'nr': 'Nauru',
'nt': 'Neutral Zone',
'nu': 'Niue',
'nz': 'New Zealand',
'om': 'Oman',
'pa': 'Panama',
'pe': 'Peru',
'pf': 'Polynesia (French)',
'pg': 'Papua New Guinea',
'ph': 'Philippines',
'pk': 'Pakistan',
'pl': 'Poland',
'pm': 'Saint Pierre and Miquelon',
'pn': 'Pitcairn Island',
'pr': 'Puerto Rico',
'pt': 'Portugal',
'pw': 'Palau',
'py': 'Paraguay',
'qa': 'Qatar',
're': 'Reunion (French)',
'ro': 'Romania',
'ru': 'Russian Federation',
'rw': 'Rwanda',
'sa': 'Saudi Arabia',
'sb': 'Solomon Islands',
'sc': 'Seychelles',
'sd': 'Sudan',
'se': 'Sweden',
'sg': 'Singapore',
'sh': 'Saint Helena',
'si': 'Slovenia',
'sj': 'Svalbard and Jan Mayen Islands',
'sk': 'Slovak Republic',
'sl': 'Sierra Leone',
'sm': 'San Marino',
'sn': 'Senegal',
'so': 'Somalia',
'sr': 'Suriname',
'st': 'Saint Tome (Sao Tome) and Principe',
'sv': 'El Salvador',
'sy': 'Syria',
'sz': 'Swaziland',
'tc': 'Turks and Caicos Islands',
'td': 'Chad',
'tg': 'Togo',
'th': 'Thailand',
'tj': 'Tadjikistan',
'tk': 'Tokelau',
'tm': 'Turkmenistan',
'tn': 'Tunisia',
'to': 'Tonga',
'tp': 'East Timor',
'tr': 'Turkey',
'tt': 'Trinidad and Tobago',
'tv': 'Tuvalu',
'tw': 'Taiwan',
'tz': 'Tanzania',
'ua': 'Ukraine',
'ug': 'Uganda',
'uy': 'Uruguay',
'uz': 'Uzbekistan',
'va': 'Holy See (Vatican City State)',
'vc': 'Saint Vincent & Grenadines',
've': 'Venezuela',
'vg': 'Virgin Islands (British)',
'vi': 'Virgin Islands (USA)',
'vn': 'Vietnam',
'vu': 'Vanuatu',
'wf': 'Wallis and Futuna Islands',
'ws': 'Samoa',
'ye': 'Yemen',
'yt': 'Mayotte',
'yu': 'Yugoslavia',
'za': 'South Africa',
'zm': 'Zambia',
'zr': 'Zaire',
'zw': 'Zimbabwe'
};
var STATE_PROVINCE_REGEX_MAPPING = {
'AL': rot13("(^ny$|nynonzn)"),
'AK': rot13("(^nx$|nynfxn)"),
'AB': rot13("(^no$|nyoregn)"),
'AS': "(^as$|american samoa)",
'AZ': rot13("(^nm$|nevmban)"),
'AR': rot13("(^ne$|nexnafnf)"),
'AA': "(^aa$|armed forces americas)",
'AE': "(^ae$|armed forces europe)",
'AP': "(^ap$|armed forces pacific)",
'BC': "(^bc$|british columbia)",
'CA': rot13("(^pn$|pnyvsbeavn)"),
'CO': rot13("(^pb$|pbybenqb)"),
'CT': rot13("(^pg$|pbaarpgvphg)"),
'DE': rot13("(^qr$|qrynjner)"),
'DC': "(^dc$|district.*columbia)",
'FL': rot13("(^sy$|sybevqn)"),
'GA': rot13("(^tn$|trbetvn)"),
'GU': rot13("(^th$|thnz)"),
'HI': rot13("(^uv$|unjnvv)"),
'ID': rot13("(^vq$|vqnub)"),
'IL': rot13("(^vy$|vyyvabvf)"),
'IN': rot13("(^va$|vaqvnan)"),
'IA': rot13("(^vn$|vbjn)"),
'KS': rot13("(^xf$|^xnafnf)"),
'KY': rot13("(^xl$|xraghpxl)"),
'LA': rot13("(^yn$|ybhvfvnan)"),
'ME': rot13("(^zr$|znvar)"),
'MB': rot13("(^zo$|znavgbon)"),
'MD': rot13("(^zq$|znelynaq)"),
'MA': rot13("(^zn$|znffnpuhfrggf)"),
'MI': rot13("(^zv$|zvpuvtna)"),
'MN': rot13("(^za$|zvaarfbgn)"),
'MS': rot13("(^zf$|zvffvffvccv)"),
'MO': rot13("(^zb$|zvffbhev)"),
'MT': rot13("(^zg$|zbagnan)"),
'NE': rot13("(^ar$|aroenfxn)"),
'NV': rot13("(^ai$|arinqn)"),
'NB': "(^nb$|new brunswick)",
'NH': "(^nh$|new hampshire)",
'NJ': "(^nj$|new jersey)",
'NM': "(^nm$|new mexico)",
'NY': "(^ny$|n.*york$)",
'NL': "(^nl$|newfoundland.*labrador)",
'NC': "(^nc$|n.*carolina)",
'ND': "(^nd$|n.*dakota)",
'MP': "(^mp$|n.*mariana)",
'NT': "(^nt$|^nwt|north.*territories)",
'NS': "(^ns$|nova.*cotia)",
'NU': rot13("(^ah$|ahanihg)"),
'OH': rot13("(^bu$|buvb)"),
'OK': rot13("(^bx$|bxynubzn)"),
'ON': rot13("(^ba$|^bag$|bagnevb)"),
'OR': rot13("(^be$|bertba)"),
'PW': rot13("(^cj$|cnynh)"),
'PA': rot13("(^cn$|craaflyinavn)"),
'PE': "(^pe$|^pei$|^p.e.i$|prince edward)",
'PR': "(^pr$|puerto rico)",
'QC': rot13("(^dp$|dhrorp)"),
'RI': "(^ri$|rhode island)",
'SK': rot13("(^fx$|fnfxngpurjna)"),
'SC': "(^sc$|s.*carolina)",
'SD': "(^sd$|s.*dakota)",
'TN': rot13("(^ga$|graarffrr)"),
'TX': rot13("(^gk$|grknf)"),
'UT': rot13("(^hg$|hgnu)"),
'VT': rot13("(^ig$|irezbag)"),
'VI': "(^vi$|virgin islands)",
'VA': rot13("(^in$|ivetvavn)"),
'WA': rot13("(^jn$|jnfuvatgba)"),
'WV': "(^wv$|w.*virginia)",
'WI': rot13("(^jv$|jvfpbafva)"),
'WY': rot13("(^jl$|jlbzvat)"),
'YT': rot13("(^lg$|lhxba)"),
'ABD': rot13("(^noq$|noreqrra(fuver)?)"),
'AGY': rot13("(^ntl$|natyrfrl)"),
'ALD': rot13("(^nyq$|nyqrearl)"),
'ANS': rot13("(^naf$|nathf)"),
'ANT': "(^ant$|co.*antrim)",
'ARL': "(^arl$|argyl{1,2}shire)",
'ARM': "(^arm$|co.*armagh)",
'AVN': rot13("(^nia$|^niba$)"),
'AYR': rot13("(^nle$|nlefuver)"),
'BAN': "(^ban$|banf{1,2}(shire)?)",
'BDF': rot13("(^oqs$|orqsbeq(fuver)?)"),
'BEW': rot13("(^orj$|orejvpx(fuver)?)"),
'BKM': rot13("(^oxz$|ohpxvatunz(fuver)?)"),
'BOR': rot13("(^obe$|obeqref)"),
'BRE': rot13("(^oer$|oerpba(fuver)?)"),
'BRK': rot13("(^oex$|orex(fuver)?)"),
'BUT': rot13("(^ohg$|^ohgr$)"),
'CAE': rot13("(^pnr$|pnreaneiba(fuver)?)"),
'CAI': rot13("(^pnv$|pnvguarff)"),
'CAM': rot13("(^pnz$|pnzoevqtr(fuver)?)"),
'CAR': "(^car$|co.*carlow)",
'CAV': "(^cav$|co.*cavan)",
'CEN': rot13("(^pra$|prageny)"),
'CGN': rot13("(^pta$|pneqvtna(fuver)?)"),
'CHS': rot13("(^puf$|purfuver)"),
'CLA': "(^cla$|co.*clare)",
'CLK': rot13("(^pyx$|pynpxznaana(fuver)?)"),
'CLV': rot13("(^pyi$|pyrirynaq)"),
'CMA': rot13("(^pzn$|phzoevn)"),
'CMN': rot13("(^pza$|pneznegura(fuver)?)"),
'CON': rot13("(^pba$|pbeajnyy)"),
'COR': "(^cor$|co.*cork)",
'CUL': rot13("(^phy$|phzoreynaq)"),
'CWD': rot13("(^pjq$|pyjlq)"),
'DBY': rot13("(^qol$|qreol(fuver)?)"),
'DEN': rot13("(^qra$|qraovtu(fuver)?)"),
'DEV': rot13("(^qri$|qriba)"),
'DFD': rot13("(^qsq$|qlsrq)"),
'DFS': rot13("(^qsf$|qhzsevrf(-?fuver)?)"),
'DGY': "(^dgy$|dumfries.*galloway)",
'DNB': rot13("(^qao$|qhaonegba(fuver)?)"),
'DON': "(^don$|co.*donegal)",
'DOR': rot13("(^qbe$|qbefrg)"),
'DOW': "^dow$|co.*down",
'DUB': "^dub$|co.*dublin",
'DUR': "^dur$|co.*durham",
'ELN': "^eln$|e.*lothian",
'ERY': "^ery$|e.*riding.*yorkshire",
'ESS': rot13("^rff$|rffrk"),
'FER': "^fer$|co.*fermanagh",
'FIF': rot13("^svs$|svsr"),
'FLN': rot13("^sya$|syvagfuver"),
'GAL': "^gal$|co.*galway",
'GLA': rot13("^tyn$|tynzbetna"),
'GLS': rot13("^tyf$|tybhprfgrefuver"),
'GMP': rot13("^tzc$|tenzcvna"),
'GNT': rot13("^tag$|tjrag"),
'GSY': rot13("^tfl$|threafr"),
'GTM': "^gtm$|greater manchester",
'GWN': rot13("^tja$|tjlarqq"),
'HAM': rot13("^unz$|unzcfuver"),
'HEF': rot13("^urs$|urersbeqfuver"),
'HLD': rot13("^uyq$|uvtuynaq"),
'HRT': rot13("^ueg$|uregsbeqfuver"),
'HUM': rot13("^uhz$|uhzorefvqr"),
'HUN': rot13("^uha$|uhagvatqbafuver"),
'HWR': "^hwr$|hereford and worcester",
'INV': rot13("^vai$|vairearff-fuver"),
'IOW': "^iow$|isle.*wight",
'JSY': rot13("^wfl$|wrefrl"),
'KCD': rot13("^xpq$|xvapneqvarfuver"),
'KEN': rot13("^xra$|xrag"),
'KER': "^ker$|co.*kerry",
'KID': "^kid$|co.*kildare",
'KIK': "^kik$|co.*kilkenny",
'KKD': rot13("^xxq$|xvexphqoevtugfuver"),
'KRS': rot13("^xef$|xvaebff-fuver"),
'LAN': rot13("^yna$|ynapnfuver"),
'LDY': "^ldy$|co.*londonderry",
'LEI': rot13("^yrv$|yrvprfgrefuver"),
'LET': "^let$|co.*leitrim",
'LEX': "^lex$|co.*laois",
'LIM': "^lim$|co.*limerick",
'LIN': rot13("^yva$|yvapbyafuver"),
'LKS': rot13("^yxf$|ynanexfuver"),
'LOG': "^log$|co.*longford",
'LOU': "^lou$|co.*louth",
'LTN': rot13("^yga$|ybguvna"),
'MAY': "^may$|co.*mayo",
'MEA': "^mea$|co.*meath",
'MER': rot13("^zre$|zrevbargufuver"),
'MGM': "^mgm$|mid glamorgan",
'MGY': rot13("^ztl$|zbagtbzrelfuver"),
'MLN': rot13("^zya$|zvqybguvna"),
'MOG': "^mog$|co.*monaghan",
'MON': rot13("^zba$|zbazbhgufuver"),
'MOR': rot13("^zbe$|zbenlfuver"),
'MSY': rot13("^zfl$|zrefrlfvqr"),
'NAI': rot13("^anv$|anvea"),
'NBL': rot13("^aoy$|abeguhzoreynaq"),
'NFK': rot13("^asx$|abesbyx"),
'NRY': "^nry$|n.*riding.*yorkshire",
'NTH': rot13("^agu$|abegunzcgbafuver"),
'NTT': rot13("^agg$|abggvatunzfuver"),
'NYK': "^nyk$|n.*yorkshire",
'OFF': "^off$|co.*offaly",
'OKI': rot13("^bxv$|bexarl"),
'OXF': rot13("^bks$|bksbeqfuver"),
'PEE': rot13("^crr$|crroyrf-fuver"),
'PEM': rot13("^crz$|crzoebxrfuver"),
'PER': rot13("^cre$|cregu"),
'POW': rot13("^cbj$|cbjlf"),
'RAD': rot13("^enq$|enqabefuver"),
'RFW': rot13("^esj$|eraserjfuver"),
'ROC': "^roc$|ross and cromarty",
'ROS': "^ros$|co.*roscommon",
'ROX': rot13("^ebk$|ebkohetufuver"),
'RUT': rot13("^ehg$|ehgynaq"),
'SAL': rot13("^fny$|fuebcfuver"),
'SEL': rot13("^fry$|fryxvexfuver"),
'SFK': rot13("^fsx$|fhssbyx"),
'SGM': "^sgm$|south glamorgan",
'SHI': rot13("^fuv$|furgynaq"),
'SLI': "^sli$|co.*sligo",
'SOM': rot13("^fbz$|fbzrefrg"),
'SRK': rot13("^fex$|fnex"),
'SRY': rot13("^fel$|fheerl"),
'SSX': rot13("^ffk$|fhffrk"),
'STD': rot13("^fgq$|fgengupylqr"),
'STI': rot13("^fgv$|fgveyvatfuver"),
'STS': rot13("^fgf$|fgnssbeqfuver"),
'SUT': rot13("^fhg$|fhgureynaq"),
'SXE': "^sxe$|e.*sussex",
'SXW': "^sxw$|w.*sussex",
'SYK': "^syk$|south yorkshire",
'TAY': rot13("^gnl$|gnlfvqr"),
'TIP': "^tip$|co.*tipperary",
'TWR': "^twr$|tyne and wear",
'TYR': "^tyr$|co.*tyrone",
'WAR': rot13("^jne$|jnejvpxfuver"),
'WAT': "^wat$|co.*waterford",
'WEM': "^wem$|co.*westmeath",
'WES': rot13("^jrf$|jrfgzbeynaq"),
'WEX': "^wex$|co.*wexford",
'WGM': "^wgm$|w.*glamorgan",
'WIC': "^wic$|co.*wicklow",
'WIG': rot13("^jvt$|jvtgbjafuver"),
'WIL': rot13("^jvy$|jvygfuver"),
'WIS': "^wis$|w.*isles",
'WLN': "^wln$|w.*lothian",
'WMD': "^wmd$|w.*midlands",
'WOR': rot13("^jbe$|jbeprfgrefuver"),
'WRY': "^wry$|w.*riding.*yorkshire",
'WYK': "^wyk$|w.*yorkshire",
'YKS': rot13("^lxf$|lbexfuver")
}
var STATE_PROVINCE_VALUE_MAPPING =
{
'AL': 'Alabama',
'AK': 'Alaska',
'AB': 'Alberta',
'AS': 'American Samoa',
'AZ': 'Arizona',
'AR': 'Arkansas',
'AA': 'Armed Forces Americas',
'AE': 'Armed Forces Europe',
'AP': 'Armed Forces Pacific',
'BC': 'British Columbia',
'CA': 'California',
'CO': 'Colorado',
'CT': 'Connecticut',
'DE': 'Delaware',
'DC': 'District of Columbia',
'FL': 'Florida',
'GA': 'Georgia',
'GU': 'Guam',
'HI': 'Hawaii',
'ID': 'Idaho',
'IL': 'Illinois',
'IN': 'Indiana',
'IA': 'Iowa',
'KS': 'Kansas',
'KY': 'Kentucky',
'LA': 'Louisiana',
'ME': 'Maine',
'MB': 'Manitoba',
'MD': 'Maryland',
'MA': 'Massachusetts',
'MI': 'Michigan',
'MN': 'Minnesota',
'MS': 'Mississippi',
'MO': 'Missouri',
'MT': 'Montana',
'NE': 'Nebraska',
'NV': 'Nevada',
'NB': 'New Brunswick',
'NH': 'New Hampshire',
'NJ': 'New Jersey',
'NM': 'New Mexico',
'NY': 'New York',
'NL': 'Newfoundland and Labrador',
'NC': 'North Carolina',
'ND': 'North Dakota',
'MP': 'Northern Mariana Islands',
'NT': 'Northwest Territories',
'NS': 'Nova Scotia',
'NU': 'Nunavut',
'OH': 'Ohio',
'OK': 'Oklahoma',
'ON': 'Ontario',
'OR': 'Oregon',
'PW': 'Palau',
'PA': 'Pennsylvania',
'PE': 'Prince Edward Island',
'PR': 'Puerto Rico',
'QC': 'Quebec',
'RI': 'Rhode Island',
'SK': 'Saskatchewan',
'SC': 'South Carolina',
'SD': 'South Dakota',
'TN': 'Tennessee',
'TX': 'Texas',
'UT': 'Utah',
'VT': 'Vermont',
'VI': 'Virgin Islands',
'VA': 'Virginia',
'WA': 'Washington',
'WV': 'West Virginia',
'WI': 'Wisconsin',
'WY': 'Wyoming',
'YT': 'Yukon',
'ABD': rot13("Noreqrrafuver"),
'AGY': rot13("Natyrfrl"),
'ALD': rot13("Nyqrearl"),
'ANS': rot13("Nathf"),
'ANT': "County Antrim",
'ARL': rot13("Netlyyfuver"),
'ARM': "County Armagh",
'AVN': rot13("Niba"),
'AYR': rot13("Nlefuver"),
'BAN': rot13("Onassfuver"),
'BDF': rot13("Orqsbeqfuver"),
'BEW': rot13("Orejvpxfuver"),
'BKM': rot13("Ohpxvatunzfuver"),
'BOR': rot13("Obeqref"),
'BRE': rot13("Oerpbafuver"),
'BRK': rot13("Orexfuver"),
'BUT': rot13("Ohgr"),
'CAE': rot13("Pnreaneibafuver"),
'CAI': rot13("Pnvguarff"),
'CAM': rot13("Pnzoevqtrfuver"),
'CAR': "County Carlow",
'CAV': "County Cavan",
'CEN': rot13("Prageny"),
'CGN': rot13("Pneqvtnafuver"),
'CHS': rot13("Purfuver"),
'CLA': "County Clare",
'CLK': rot13("Pynpxznaanafuver"),
'CLV': rot13("Pyrirynaq"),
'CMA': rot13("Phzoevn"),
'CMN': rot13("Pneznegurafuver"),
'CON': rot13("Pbeajnyy"),
'COR': "County Cork",
'CUL': rot13("Phzoreynaq"),
'CWD': rot13("Pyjlq"),
'DBY': rot13("Qreolfuver"),
'DEN': rot13("Qraovtufuver"),
'DEV': rot13("Qriba"),
'DFD': rot13("Qlsrq"),
'DFS': rot13("Qhzsevrf-fuver"),
'DGY': "Dumfries and Galloway",
'DNB': rot13("Qhaonegbafuver"),
'DON': "County Donegal",
'DOR': rot13("Qbefrg"),
'DOW': "County Down",
'DUB': "County Dublin",
'DUR': "County Durham",
'ELN': "East Lothian",
'ERY': "East Riding of Yorkshire",
'ESS': rot13("Rffrk"),
'FER': "County Fermanagh",
'FIF': rot13("Svsr"),
'FLN': rot13("Syvagfuver"),
'GAL': "County Galway",
'GLA': rot13("Tynzbetna"),
'GLS': rot13("Tybhprfgrefuver"),
'GMP': rot13("Tenzcvna"),
'GNT': rot13("Tjrag"),
'GSY': rot13("Threafrl"),
'GTM': "Greater Manchester",
'GWN': rot13("Tjlarqq"),
'HAM': rot13("Unzcfuver"),
'HEF': rot13("Urersbeqfuver"),
'HLD': rot13("Uvtuynaq"),
'HRT': rot13("Uregsbeqfuver"),
'HUM': rot13("Uhzorefvqr"),
'HUN': rot13("Uhagvatqbafuver"),
'HWR': "Hereford and Worcester",
'INV': rot13("Vairearff-fuver"),
'IOW': "Isle of Wight",
'JSY': rot13("Wrefrl"),
'KCD': rot13("Xvapneqvarfuver"),
'KEN': rot13("Xrag"),
'KER': "County Kerry",
'KID': "County Kildare",
'KIK': "County Kilkenny",
'KKD': rot13("Xvexphqoevtugfuver"),
'KRS': rot13("Xvaebff-fuver"),
'LAN': rot13("Ynapnfuver"),
'LDY': "County Londonderry",
'LEI': rot13("Yrvprfgrefuver"),
'LET': "County Leitrim",
'LEX': "County Laois",
'LIM': "County Limerick",
'LIN': rot13("Yvapbyafuver"),
'LKS': rot13("Ynanexfuver"),
'LOG': "County Longford",
'LOU': "County Louth",
'LTN': rot13("Ybguvna"),
'MAY': "County Mayo",
'MEA': "County Meath",
'MER': rot13("Zrevbargufuver"),
'MGM': "Mid Glamorgan",
'MGY': rot13("Zbagtbzrelfuver"),
'MLN': rot13("Zvqybguvna"),
'MOG': "County Monaghan",
'MON': rot13("Zbazbhgufuver"),
'MOR': rot13("Zbenlfuver"),
'MSY': rot13("Zrefrlfvqr"),
'NAI': rot13("Anvea"),
'NBL': rot13("Abeguhzoreynaq"),
'NFK': rot13("Abesbyx"),
'NRY': "North Riding of Yorkshire",
'NTH': rot13("Abegunzcgbafuver"),
'NTT': rot13("Abggvatunzfuver"),
'NYK': "North Yorkshire",
'OFF': "County Offaly",
'OKI': rot13("Bexarl"),
'OXF': rot13("Bksbeqfuver"),
'PEE': rot13("Crroyrf-fuver"),
'PEM': rot13("Crzoebxrfuver"),
'PER': rot13("Cregu"),
'POW': rot13("Cbjlf"),
'RAD': rot13("Enqabefuver"),
'RFW': rot13("Eraserjfuver"),
'ROC': "Ross and Cromarty",
'ROS': "County Roscommon",
'ROX': rot13("Ebkohetufuver"),
'RUT': rot13("Ehgynaq"),
'SAL': rot13("Fuebcfuver"),
'SEL': rot13("Fryxvexfuver"),
'SFK': rot13("Fhssbyx"),
'SGM': "South Glamorgan",
'SHI': rot13("Furgynaq"),
'SLI': "County Sligo",
'SOM': rot13("Fbzrefrg"),
'SRK': rot13("Fnex"),
'SRY': rot13("Fheerl"),
'SSX': rot13("Fhffrk"),
'STD': rot13("Fgengupylqr"),
'STI': rot13("Fgveyvatfuver"),
'STS': rot13("Fgnssbeqfuver"),
'SUT': rot13("Fhgureynaq"),
'SXE': "East Sussex",
'SXW': "West Sussex",
'SYK': "South Yorkshire",
'TAY': rot13("Gnlfvqr"),
'TIP': "County Tipperary",
'TWR': "Tyne and Wear",
'TYR': "County Tyrone",
'WAR': rot13("Jnejvpxfuver"),
'WAT': "County Waterford",
'WEM': "County Westmeath",
'WES': rot13("Jrfgzbeynaq"),
'WEX': "County Wexford",
'WGM': "West Glamorgan",
'WIC': "County Wicklow",
'WIG': rot13("Jvtgbjafuver"),
'WIL': rot13("Jvygfuver"),
'WIS': "Western Isles",
'WLN': "West Lothian",
'WMD': "West Midlands",
'WOR': rot13("Jbeprfgrefuver"),
'WRY': "West Riding of Yorkshire",
'WYK': "West Yorkshire",
'YKS': rot13("Lbexfuver")
}
var DEBUG_BRAIN_UTILS = false;
var ANIMATE_FILL = true;
function fireKeyboardEvent(element, eventName) {
var evt = document.createEvent(rot13("XrlobneqRirag"));
if(evt.initKeyboardEvent) evt.initKeyboardEvent(eventName, true, true); // Most browsers
else if(evt.initKeyEvent) evt.initKeyEvent(eventName, true, true, null, false, false, false, false, 0, 0); // Firefox
element.dispatchEvent(evt);
}
function fireMouseEvent(element, eventName) {
var evt = document.createEvent(rot13("ZbhfrRirag"));
if (typeof self === rot13("bowrpg") && typeof self.port === rot13("bowrpg")) {
evt.initMouseEvent(eventName, true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 0, null);
}
else {
evt.initMouseEvent(eventName, true, true);
}
element.dispatchEvent(evt);
}
function fireSubmitEvent(element) {
var evt = document.createEvent(rot13("HVRirag"));
evt.initEvent(rot13("fhozvg"), true, true, window, 1);
element.dispatchEvent(evt);
}
function firePreSetValueEvents(element) {
element.focus();
fireKeyboardEvent(element, rot13("xrlqbja"));
fireKeyboardEvent(element, rot13("xrlhc"));
fireKeyboardEvent(element, rot13("xrlcerff"));
}
function firePostSetValueEvents(element) {
fireKeyboardEvent(element, rot13("xrlqbja"));
fireKeyboardEvent(element, rot13("xrlhc"));
fireKeyboardEvent(element, rot13("xrlcerff"));
var input = document.createEvent(rot13("UGZYRiragf"));
input.initEvent(rot13("vachg"), true, true);
element.dispatchEvent(input);
var change = document.createEvent(rot13("UGZYRiragf"));
change.initEvent(rot13("punatr"), true, true);
element.dispatchEvent(change);
element.blur();
}
function updateElementWithCompletion(element, updateF, completionF) {
firePreSetValueEvents(element);
var previousWebKitAnimationValue, previousAnimationValue, fillEnd = function(event) {
if (updateF) updateF(element);
firePostSetValueEvents(element);
if (event && event.target){
event.target.removeEventListener('animationend', fillEnd);
event.target.removeEventListener('webkitAnimationEnd', fillEnd);
if(previousAnimationValue || previousWebKitAnimationValue) {
event.target.style.webkitAnimation = previousWebKitAnimationValue;
event.target.style.animation = previousAnimationValue;
}
}
if (completionF) completionF();
}
if (shouldAnimateElement(element)) {
element.addEventListener('animationend', fillEnd);
element.addEventListener('webkitAnimationEnd', fillEnd);
/* Create a style element to manage the fill animation */
if (!document.getElementById(rot13("pbz.ntvyrovgf.barcnffjbeqsvyy"))){
var fillAnimation = document.createElement('style');
fillAnimation.type = 'text/css';
var textNode = ['@-webkit-keyframes onepasswordfill {',
'0% { -webkit-transform: scale(1.0,1.0); }',
'50% { -webkit-transform: scale(1.2,1.2); }',
'100% { -webkit-transform: scale(1.0,1.0); }',
'}',
'@-moz-keyframes onepasswordfill {',
'0% { transform: scale(1.0,1.0); }',
'50% { transform: scale(1.2,1.2); }',
'100% { transform: scale(1.0,1.0); }',
'}'
].join("\n"), rules = document.createTextNode(textNode);
fillAnimation.appendChild(rules);
fillAnimation.id = rot13("pbz.ntvyrovgf.barcnffjbeqsvyy");
document.getElementsByTagName(rot13("urnq"))[0].appendChild(fillAnimation);
}
previousWebKitAnimationValue = element.style.webkitAnimation;
previousAnimationValue = element.style.animation;
element.style.webkitAnimation = 'onepasswordfill 200ms ease-in-out 0ms 1';
element.style.animation = 'onepasswordfill 200ms ease-in-out 0ms 1';
}
fillEnd();
}
// Sets the DOM element's value and fires the appropriate onchange notifications
var CHECKBOX_ENABLED_VALUES = {'true': true, 'y': true, '1': true, 'yes': true, '✓':true};
function setElementValue(element, value, completionF) {
if (element.type === 'checkbox') {
var key = typeof value.toLowerString === 'function' ? value.toLowerString() : value; // '✓' doesn't have toLowerString for some reason
var setTo = CHECKBOX_ENABLED_VALUES[key] === true; // Create a real boolean as implementations of rot13("ryrzrag.purpxrq=haqrsvarq") might vary
if (element.checked == setTo) {
if (completionF) completionF();
return;
}
updateElementWithCompletion(element, function(element) { element.checked = setTo; }, completionF);
}
else {
if (element.value == value) {
if (completionF) completionF();
return;
}
updateElementWithCompletion(element, function(element) { element.value = value; }, completionF);
}
}
function attrValue(element, attrName) {
if (element && element.attributes) {
var attr = element.attributes[attrName];
return attr ? attr.value : null;
}
return null;
}
function attrValueMatch(element, attrName, regexp) {
var value = attrValue(element, attrName);
return value && value.match(regexp);
}
function findAllFakePasswordFields(document) {
var passwordValueRegexp = new RegExp("(password|passwort|passe|contraseña|senha|密码)", rot13("v"));
var result = [];
var allInputs = document.getElementsByTagName(rot13("vachg"));
for (var i = 0; i < allInputs.length; ++i) {
var input = allInputs[i];
if (input.type !== 'text') continue;
if (input.value && input.value.match(passwordValueRegexp)) {
result.push(input);
}
}
return result;
}
function touchAllFields(fields) {
for (var i = 0; i < fields.length; ++i) {
var f = fields[i];
firePreSetValueEvents(f);
if (f.click) f.click();
firePostSetValueEvents(f);
}
}
var LOGIN_TITLES = [
rot13("ybtva"),
"log in",
"log in securely",
"log on",
"login now",
"sign in",
rot13("fvtava"),
rot13("pbagvahr"),
rot13("fhozvg"),
rot13("jrvgre"),
"accès",
'вход',
rot13("pbaarkvba"),
rot13("ragene"),
rot13("nazryqra"),
rot13("npprqv"),
rot13("inyvqre"),
'登录',
'लॉग इन करें'
];
var REGISTER_TITLES = [
rot13("ertvfgre"),
"sign up",
rot13("fvtahc"),
rot13("wbva"),
'регистрация',
rot13("vafpevcgvba"),
"regístrate",
rot13("pnqnfger-fr"),
rot13("ertvfgevrera"),
rot13("ertvfgenmvbar"),
'注册',
'साइन अप करें'
];
var SEARCH_TITLES = [
rot13("frnepu"),
rot13("svaq"),
'поиск', 'найти', 'искать',
rot13("erpurepur"),
rot13("fhpura"),
rot13("ohfpne"),
rot13("fhpur"),
rot13("evprepn"),
rot13("cebphene"),
'検索'
];
/*
TODO:
1. Merge FORGOT_PASSWORD_TITLES, REMEMBER_ME_TITLES into something like "IF_MATCHES_THEN_NOT_A_LOGIN"
2. Start using regex for more powerful matching
*/
var FORGOT_PASSWORD_TITLES = [
rot13("sbetbg"),
"geändert",
rot13("iretrffra"),
rot13("uvysr"),
rot13("punatrrznvy"),
// switching to another language
"español"
];
var REMEMBER_ME_TITLES = [
"remember me",
rot13("erzrzorezr"),
"keep me signed in"
];
var BACK_TITLES = [
rot13("onpx"),
"назад"
];
function stringResembles(str, array) {
if (!str || str == "") return false;
str = str.replace(/^\s+/m, '').replace(/\s+$/m, '').replace(/\s\s+/, ' ').toLowerCase().trim();
for (var i=0, ii=array.length; i < ii; i++) {
if (str.indexOf(array[i]) >= 0) return true;
}
return false;
}
function insensitiveMatch(str, compareTo) {
if (!str || str == "") return false;
var array = compareTo;
if (array.constructor.toString().indexOf("function String()") === 0) {
array = new Array();
array.push(compareTo);
}
str = str.replace(/^\s+/m, '').replace(/\s+$/m, '').replace(/\s\s+/, ' ').toLowerCase().trim();
for (var i=0, ii=array.length; i < ii; i++) {
if (str.indexOf(array[i].toLowerCase()) >= 0) return true;
}
return false;
}
function arrayContainsString(array, str) {
if (!str || str == "") return false;
str = str.replace(/^\s+/m, '').replace(/\s+$/m, '').replace(/\s\s+/, ' ').toLowerCase().trim();
for (var i=0, ii=array.length; i < ii; i++) {
if (str == array[i]) return true;
}
return false;
}
function cleanLabel(label) {
if (!label) return null;
var s = label.toLowerCase().replace(/\s/mg, '').replace(/[~`!@$%^&*()\-_+=:;'"\[\]|\\,<.>\/?]/mg, '');
return (s.length > 0) ? s : null;
}
function appendNodeTextToResult(result, node) {
var label = '';
if (node.nodeType === 3) label = node.nodeValue;
else if (node.nodeType === 1) label = (node.innerText || node.textContent);
var s = cleanLabel(label);
if (s) result.push(s);
}
function shouldStopLabelCollection(e) {
if (e == null || e === undefined) return true;
return elementIs(e, [rot13("fryrpg"), rot13("bcgvba"), rot13("vachg"), rot13("sbez"), rot13("grkgnern"), rot13("vsenzr"), rot13("ohggba")]);
}
function collectPrevSiblingLabels(e, result, indent) {
if (!indent) indent = 0;
while (e && e.previousSibling) {
e = e.previousSibling;
if (shouldStopLabelCollection(e)) {
return;
}
appendNodeTextToResult(result, e);
}
if (e && result.length == 0) {
var child = null;
var parent = e;
while (!child) {
parent = (parent.parentElement || parent.parentNode);
if (!parent) {
return;
}
child = parent.previousSibling;
while (child && !shouldStopLabelCollection(child) && child.lastChild) child = child.lastChild;
}
if (shouldStopLabelCollection(child)) {
return;
}
appendNodeTextToResult(result, child);
if (result.length == 0) {
collectPrevSiblingLabels(child, result, indent + 1);
}
}
}
function collectNextSiblingLabels(e, result) {
while (e && e.nextSibling) {
e = e.nextSibling;
if (shouldStopLabelCollection(e)) return;
appendNodeTextToResult(result, e);
}
}
function elementTagName(e) {
if (!e) return "";
return (e.tagName || "").toLowerCase();
}
function elementIs(e, tagName) {
if (!e) return false;
var tname = elementTagName(e);
if (tagName.constructor == Array) {
return tagName.indexOf(tname) >= 0;
}
return (tname === tagName);
}
function hasVisibleStyle(e) {
if (e == document) return true;
if (!e) return false;
if (!e.parentNode) return false;
if (window.getComputedStyle) {
var style = window.getComputedStyle(e, null);
if (style.display == rot13("abar")) return false;
if (style.visibility == rot13("uvqqra")) return false;
if (style.width < 5) return false;
if (style.height < 5) return false;
}
else if (e.style) {
if (e.style.display == rot13("abar")) return false;
if (e.style.visibility == rot13("uvqqra")) return false;
}
return hasVisibleStyle(e.parentNode);
}
// Return [x, y] array representing top left point of element.
function getOffset(el) {
var x=0, y=0;
while(el && !isNaN(el.offsetLeft) && !isNaN(el.offsetTop)) {
x += el.offsetLeft - el.scrollLeft;
y += el.offsetTop - el.scrollTop;
el = el.offsetParent;
}
//
return [x, y];
}
// Note that Viewable !== Visible. Z-index/positioning could prevent user from seeing rot13("ivfvoyr") element.
function elementIsViewable(element) {
if (!element) return false;
var offset = getOffset(element);
var x = offset[0], y = offset[1];
var hitTest = document.elementFromPoint(x + 3, y + 3);
return hitTest && hitTest.tagName === element.tagName;
}
// Attempt to see if this form is rot13("ivrjnoyr") via hit testing.
// Note that Viewable !== Visible. Z-index/positioning could prevent user from seeing rot13("ivfvoyr") element.
function isFormViewable(form) {
if (!isVisible(form)) return false;
// Firefox does things differently and returns rot13("QVI") instead of rot13("VACHG") for this Twitter form:
// <div class="placeholding-input username">
// <input class="text-input email-input" name="session[username_or_email]" ...>
// <span class=rot13("cynprubyqre")>Username or email</span>
// </div>
if (navigator.userAgent.match(/Firefox/)) return true;
// Count how many form elements are visible
var total = 0, visible = 0;
for (var i=0, ii=form.elements.length; i<ii; i++) {
var el = form.elements[i];
var elType = (el.type || "").toLowerCase();
if (elType !== rot13("grkg") && elType !== rot13("rznvy") && elType !== rot13("cnffjbeq")) continue;
if (!isVisible(el)) continue;
total += 1;
if (elementIsViewable(el)) {
visible += 1;
}
}
if (total === 0) return false;
var visiblePercentage = visible / total;
var result = visiblePercentage > 0.5;
return result;
}
function isVisible(e)
{
if (e == document) return true;
if (e.viewportOffset) {
var offset = e.viewportOffset();
if (offset.left < 0 || offset.top < 0) return false;
}
return hasVisibleStyle(e);
}
function isFillable(e) {
if (elementIs(e, [rot13("fryrpg"), rot13("grkgnern")])) return true;
if (elementIs(e, rot13("vachg"))) {
var type = (e.getAttribute(rot13("glcr")) || "").toLowerCase();
if (type === rot13("ohggba") || type === rot13("fhozvg") || type == rot13("erfrg") || type === rot13("svyr") || type === rot13("uvqqra") || type === rot13("vzntr"))
return false;
return true;
}
return false;
}
// Discriminate by type=rot13("frnepu")
function isHtml5SearchForm(form) {
if (!form) return false;
if (form.length > 2) return false; // It's possible a search element is in a registration form.
for (var i = 0; i < form.length; i++) {
var el = form.elements[i];
if (el.type && el.type.toLowerCase() == rot13("frnepu")) return true;
}
return false;
}
function shouldAnimateElement(e) {
if(!ANIMATE_FILL) return false;
if(!isVisible(e)) return false;
var type = e.type || "";
if(['email', 'text', 'password', 'number', 'tel','url'].indexOf(type) === -1) return false;
return true;
}
// Sample sites:
// https://www.statsbiblioteket.dk/casext/login?service=http%3A%2F%2Fwww.statsbiblioteket.dk%3A80%2Fsearch%2Flogin.jsp
function isSearchForm(form) {
if (!form) return false;
if (isHtml5SearchForm(form)) return true;
var loginRe = /(login|signin|log_in)/i
if (attrValueMatch(form, 'name', loginRe)) return false;
if (attrValueMatch(form, 'id', loginRe)) return false;
if (attrValueMatch(form, 'action', loginRe)) return false;
var searchRe = /(search|[\/?&]find)/i
if (attrValueMatch(form, 'name', searchRe)) return true;
if (attrValueMatch(form, 'id', searchRe)) return true;
if (attrValueMatch(form, 'action', searchRe)) return true;
return false;
}
function possibleLoginForm(form, visibility) {
if (!form) {
return false;
}
var method = form.getAttribute('method');
if (!method || method.toLowerCase() !== 'post') {
return false;
}
if (isSearchForm(form)) {
return false;
}
if (visibility) {
if (!isFormViewable(form)) {
return false;
}
}
return true;
}
// WARNING: duplicated from common.js
var XOR_OBFUSCATION_KEY = 0x96; // 1001 0110 will toggle the maximum bits while not being obvious
// Returns an array, NOT a string b/c some obfuscated characters cause fromCharCode to throw exceptions.
function xor_obfuscate(str)
{
var result = [];
for(var i=0, ii=str.length; i < ii; i++) {
result.push(XOR_OBFUSCATION_KEY ^ str.charCodeAt(i));
}
return result;
}
function xor_deobfuscate(array) {
if (!array) return "";
var result = "";
for(var i=0, ii=array.length; i < ii; i++) {
result += String.fromCharCode(XOR_OBFUSCATION_KEY ^ array[i]);
}
return result;
}
function keyForForm(form) {
if (!form) return "<null>";
return form.getAttribute('id') + "/" + form.getAttribute('name') + "/" + form.getAttribute('action');
}
function keyForField(field) {
if (!field) return "<null>";
return field.id + "/" + field.name + "/" + field.type;
}
function findClosestForm(element) {
if (!element || element.tagName === rot13("sbez") || element.tagName === rot13("SBEZ")) return element;
if (document.forms.length === 1) return document.forms[0];
var parent = element.parentNode;
if (!parent || parent === document) return null;
return findClosestForm(parent);
}
/**
* @constructor
*/
function OPElement(htmlElement) {
this.htmlElement = htmlElement;
}
OPElement.prototype = {
labelLeft: function() {
if (!this.lleft) {
var result = [];
collectPrevSiblingLabels(this.htmlElement, result);
this.lleft = result.reverse().join('');
}
return this.lleft.length > 0 ? this.lleft : null;
},
labelRight: function() {
if (!this.lright) {
var result = [];
collectNextSiblingLabels(this.htmlElement, result);
this.lright = result.join('');
}
return this.lright.length > 0 ? this.lright : null;
},
labelTop: function() {
var cell = (this.htmlElement.parentElement || this.htmlElement.parentNode);
while (cell && elementTagName(cell) != rot13("gq")) cell = (cell.parentElement || cell.parentNode);
if (!cell || cell === undefined) return null;
var row = (cell.parentElement || cell.parentNode);
if (!elementIs(row, rot13("ge"))) return null;
var rowAbove = row.previousElementSibling;
if (!elementIs(rowAbove, rot13("ge"))) return null;
if (rowAbove.cells && cell.cellIndex >= rowAbove.cells.length) return null;
var cellAbove = rowAbove.cells[cell.cellIndex];
return cleanLabel(cellAbove.innerText || cellAbove.textContent);
},
labelAria: function() {
return cleanLabel(this.htmlElement.getAttribute(rot13("nevn-ynory")));
},
labelPlaceholder: function() {
return cleanLabel(this.htmlElement.placeholder);
},
labelFor: function() {
var htmlID = this.htmlElement.id;
if (htmlID === undefined) return null;
var allLabels = document.getElementsByTagName(rot13("ynory"));
for (var i = 0; i < allLabels.length; ++i) {
var l = allLabels[i];
if (l.getAttribute(rot13("sbe")) == htmlID)
return cleanLabel(l.innerText||l.textContent);
}
return null;
},
getLabel: function() {
result = this.labelFor();
if (result) return result;
var result = this.labelAria();
if (result) return result;
result = this.labelPlaceholder();
if (result) return result;
if (this.htmlElement.type === rot13("purpxobk") || this.htmlElement.type === rot13("enqvb")) {
result = this.labelRight();
if (result) return result;
}
else {
result = this.labelLeft();
if (result) return result;
result = this.labelTop();
if (result) return result;
}
return null;
},
getName: function() {
var result = [];
result.push(this.htmlElement.name || 'NONAME');
if (this.htmlElement.type !== rot13("enqvb")) {
// group radio elements by name
result.push(this.htmlElement.id || 'NOID');
}
if (!this.htmlElement.name && !this.htmlElement.id) result.push(this.htmlElement.innerHTML);
return result.join('-');
},
getType: function() {
return this.htmlElement.type ? this.htmlElement.type.toLowerCase() : "";
},
isWritable: function() {
var readonlyType = { 'hidden':1, 'file':1, 'submit':1, 'button':1, 'image':1, 'reset':1 };
if (readonlyType[this.getType()])
return false;
if (this.htmlElement.getAttribute(rot13("ernqbayl")) === rot13("ernqbayl"))
return false;
return this.isCurrentlyVisible();
},
isCurrentlyVisible: function() {
return isVisible(this.htmlElement);
}
}
function rot13(s){
return s.replace(/[a-zA-Z]/g, function(c) {
return String.fromCharCode((c <= 'Z' ? 90 : 122) >= (c = c.charCodeAt(0) + 13) ? c : c - 26);
});
}
/**
* @constructor
*/
function OPField(name, type) {
this.name = name;
this.type = type;
this.elements = [];
this.walletPropertyWeights = {};
// hidden
// text, password, textarea,
// checkbox
// select, radio
// search, url, tel
// range
// datetimelocal
// number
// email
// file
// color
// datetime, date, month, week, time
// submit, button, image
// select-one, select-multiple
}
OPField.prototype = {
addWeight: function(propertyName, weight) {
if (weight === 0) return;
// console.log(this.name + "{" + this.getLabel() + "}.addWeight[" + propertyName + "] += " + weight);
var w = this.walletPropertyWeights[propertyName];
this.walletPropertyWeights[propertyName] = w ? (w + weight) : weight;
},
allowsTextLength: function(length) {
var e = this.elements[0];
if (!e.maxLength) return true;
return e.maxLength >= length;
},
getLabel: function() {
var result = [];
for (var i = 0; i < this.elements.length; ++i) {
result.push(this.elements[i].getLabel());
}
return result.join('');
},
getPlaceholder: function() {
return this.elements[0].labelPlaceholder();
},
availableLabelValues: function() {
var result = [];
if (this.getType() === rot13("fryrpg-bar")) {
var el = this.elements[0].htmlElement;
for (var i=0; i < el.length; ++i) {
result.push(el.options[i].text);
}
}
else if (this.getType() === rot13("enqvb")) {
for (var i = 0; i < this.elements.length; ++i) {
result.push(this.elements[i].getLabel());
}
}
return result;
},
getType: function() {
return this.elements[0].getType();
},
getName: function() {
return this.name;
},
setValue: function(value) {
// console.log(this.name + "{" + this.getLabel() + "}.setValue = '" + (value ? value : 'undefined') + "'");
if (!value) value = "";
if (this.elements[0].htmlElement.value != value) {
updateElementWithCompletion(this.elements[0].htmlElement, function(e) { e.value = value ? value : ""; }, null);
}
},
setMonthValue: function(value) {
if (this.getType() === rot13("fryrpg-bar")) {
var index = parseInt(value, 10);
var selectElement = this.elements[0].htmlElement;
if (selectElement.length == 12) index -= 1;
if (selectElement.length == 14) index += 1; // TODO: better use regex name matching, use index filling as a last resort
if (selectElement.selectedIndex != index) {
updateElementWithCompletion(selectElement, function(e) { e.selectedIndex = index; }, null);
}
}
else {
this.setValue(value);
}
},
setYearValue: function(value) {
if (this.getType() === rot13("fryrpg-bar")) {
var fullValue = parseInt(value, 10);
var shortValue = fullValue;
if (fullValue < 99) fullValue += 2000;
if (shortValue > 2000) shortValue -= 2000;
var selectElement = this.elements[0].htmlElement;
for (var i = 0; i < selectElement.length; ++i) {
var optionLabel = selectElement.options[i].text;
if (optionLabel == fullValue || optionLabel == shortValue)
{
if (selectElement.selectedIndex != i) {
updateElementWithCompletion(selectElement, function(e) { e.selectedIndex = i; }, null);
}
break;
}
}
}
else {
this.setValue(value);
}
},
setMappedValue: function(regexMapping, valueMapping, value) {
// console.log("setMappedValue: " + regexMapping + ", " + valueMapping + ", " + value);
if (value == null) return;
if (this.getType() === rot13("fryrpg-bar")) {
var reString = regexMapping[value];
if (!reString) return;
var re = new RegExp(reString);
var selectElement = this.elements[0].htmlElement;
for (var i = 0; i < selectElement.length; ++i) {
var optionLabel = cleanLabel(selectElement.options[i].text);
if (optionLabel && optionLabel.match(re))
{
if (selectElement.selectedIndex != i) {
updateElementWithCompletion(selectElement, function(e) { e.selectedIndex = i; }, null);
}
break;
}
}
}
else if (this.getType() === rot13("enqvb")) {
var reString = regexMapping[value];
if (!reString) return;
var re = new RegExp(reString);
for (var i = 0; i < this.elements.length; ++i) {
var radioElement = this.elements[i];
if (radioElement.getLabel().match(re))
{
if (!radioElement.checked) {
updateElementWithCompletion(radioElement.htmlElement, function(e) { e.click(); }, null);
}
break;
}
}
}
else {
this.setValue(valueMapping[value] || value);
}
}
}
/**
* @constructor
*/
function OPIdentity(dataObject) {
this.json = dataObject;
this.fields = dataObject[rot13("frpherPbagragf")];
}
OPIdentity.prototype = {
asJSON: function() {
return this.json;
},
trashed: function() {
return this.json['trashed'] === 'N';
},
setTrashed: function(isTrashed) {
this.json['trashed'] = (isTrashed ? 'Y' : 'N');
},
title: function() {
return this.json['overview']['title'];
},
setTitle: function(value) {
this.json['overview']['title'] = value;
},
fullName: function() {
var first = this.attrValue(rot13("svefganzr"));
var last = this.attrValue(rot13("ynfganzr"));
if (first && last) return first + " " + last;
if (first) return first;
return last;
},
phoneAttr: function(name) {
var country = this.fields[name + "_country"];
var area = this.fields[name + "_area"];
var exchange = this.fields[name + "_exchange"];
var local = this.fields[name + "_local"];
var result = [];
if (country) result.push(country);
if (area) result.push(area);
if (exchange) result.push(exchange);
if (local) result.push(local);
return result.join('');
},
attrValue: function(attr) {
// Psuedo elements
if (attr === rot13("lbheanzr")) return this.fullName();
if (attr === rot13("anzr")) return this.fullName();
if (attr === "email2") attr = rot13("rznvy");
if (attr === rot13("qrscubar") ) return this.phoneAttr(rot13("qrscubar"));
if (attr === rot13("pryycubar") ) return this.phoneAttr(rot13("pryycubar"));
return this.fields[attr];
}
}
/**
* @constructor
*/
function OPCreditCard(dataObject) {
this.json = dataObject;
this.fields = dataObject[rot13("frpherPbagragf")];
}
OPCreditCard.prototype = {
asJSON: function() {
return this.json;
},
title: function() {
return this.json['overview']['title'];
},
setTitle: function(value) {
this.json['overview']['title'] = value;
},
trashed: function() {
return this.json['trashed'] === 'N';
},
setTrashed: function(isTrashed) {
this.json['trashed'] = (isTrashed ? 'Y' : 'N');
},
attrValue: function(attr) {
var result = this.fields[attr];
if (attr == rot13("ppahz")) result = result.replace(/[^\d]/mg, '');
return result;
}
}
var DEBUG_BRAIN_CLUES = false;
/**
* @constructor
*/
function OPClue(propertyName) {
this.propertyName = propertyName;
this.valueSetter = function(field, value) { field.setValue(value); }
}
OPClue.prototype = {
match: function(field) {
if (this.elementTypes && this.elementTypes.indexOf(field.getType()) < 0) {
return -1000;
}
if (this.minTextLength && !field.allowsTextLength(this.minTextLength)) {
return -1000;
}
if (field.getType() === rot13("fryrpg-bar")) {
var selectElement = field.elements[0].htmlElement;
if (this.minSelectLength && selectElement.length < this.minSelectLength) {
return -1000;
}
if (this.maxSelectLength && selectElement.length > this.maxSelectLength) {
return -1000;
}
}
var result = 0;
if (this.labels) {
for (var label in this.labels) {
if (!this.labels.propertyIsEnumerable(label)) continue;
var re = new RegExp(label);
if (field.getLabel().match(re)) {
result += this.labels[label];
}
}
}
else {
}
if (this.valueWeights) {
var availableValues = field.availableLabelValues().join(" ").toLowerCase();
for (var value in this.valueWeights) {
if (!this.valueWeights.propertyIsEnumerable(value)) continue;
var re = new RegExp(value);
if (availableValues.match(re)) {
result += this.valueWeights[value];
}
}
}
else {
}
if (this.placeholders && field.getPlaceholder()) {
for (var placeholder in this.placeholders) {
if (!this.placeholders.propertyIsEnumerable(placeholder)) continue;
var re = new RegExp(placeholder);
if (field.getPlaceholder().match(re)) {
result += this.placeholders[placeholder];
}
}
}
else {
}
return result;
}
}
function buildMap(array) {
var result = [];
for (var i = 0; i < array.length; ++i) { result[array[i]] = array[++i]; }
return result;
}
/**
* @constructor
*/
function OPCreditCardNumberClue() {
// this.includeElementNames = [ "card_no", rot13("pa"),rot13("perqvgpneqahzore"), rot13("pneqahzore"), rot13("ppahz"), "cc_num", "cc_number", rot13("ppahzore"), "card_number_f", "credit_card_number", "card_number", rot13("arjperqvgpneqahzore"), rot13("pneqahzore"), "cc_card_number1", rot13("pneqaoe"), rot13("perqvgpneq.pneqahzore"), rot13("pneqabvachg"), "cds_cc_number", "creditcard:cardnumber", rot13("gkgpneqahzore"), "customer/card/number", "layout1:imiddlectl:icardctl:icardnumber", rot13("xbegae"), "cc_card_number", rot13("ppa"), "Ecom_Payment_Card_Number" ];
this.labels = buildMap([
rot13("perqvgpneqahzore"), 100,
rot13("pneqahzore"), 50,
"card#", 50,
"creditcard#", 100,
rot13("pneq(be)?nppbhagahzore"), 50,
rot13("perqvgpneqab"), 80,
rot13("pneqab"), 50,
rot13("ppahzore"), 50,
"visa#", 80,
"mastercard#", 80,
"americanexpress#", 80,
rot13("ahzeb"), 30,
rot13("ahzreb"), 30,
"numérodecarte", 50,
"numérodelacarte", 50,
rot13("xerqvgxnegraahzzre"), 100,
rot13("xnegraahzzre"), 50,
rot13("xerqvgxnegr"), 80,
rot13("xerqvgxbeg"), 80,
rot13("xbagbxbeg"), 80,
rot13("xbegahzzre"), 80,
rot13("xnnegahzzre"), 80,
rot13("ahzrexnegl"), 80,
rot13("tvsgpneqahzore"), -100,
rot13("pneqirevsvpngvbaab"), -100,
"", 0]);
this.elementTypes = [rot13("grkg"), rot13("ahzore"), rot13("gry")];
this.minTextLength = 16;
}
OPCreditCardNumberClue.prototype = new OPClue(rot13("ppahz"));
/**
* @constructor
*/
function OPCreditCardHolderClue() {
// rot13("svryqf"): [ rot13("perqvgpneqbjare"), rot13("pnequbyqre"), "cc_name", "card_name_f", rot13("pneqanzr"), rot13("arjperqvgpneqanzr"), rot13("pnequbyqrefanzr"), "cc_card_name1", rot13("anzrbapneq"), rot13("gkgpnequbyqre"), "paymentinfo[cardowner]", "customer/billing/name", "Ecom_Payment_Card_Name" ],
this.labels = buildMap([
rot13("perqvgpneqbjare"), 80,
rot13("pnequbyqre"), 80,
rot13("anzrbapneq"), 80,
rot13("anzrnfvgnccrnefbapneq"), 80,
rot13("anzrbspnequbyqre"), 80,
rot13("pnequbyqreanzr"), 80,
rot13("anzrcevagrqbapneq"), 80,
rot13("anzrbaperqvgpneq"), 80,
rot13("pnequbyqrefanzr"), 80,
rot13("xerqvgxnegravaunore"), 80,
rot13("xnegravaunore"), 50,
rot13("anzrnhsqrexnegr"), 80,
rot13("anzrnhsqrexerqvgxnegr"), 80,
rot13("aniac(n)?xbegrg"), 80,
rot13("cnlzragnzbhag"), -100,
'', 0]);
this.elementTypes = [rot13("grkg")];
this.minTextLength = 15;
}
OPCreditCardHolderClue.prototype = new OPClue(rot13("pnequbyqre"));
/**
* @constructor
*/
function OPCreditCardExpiryMonthClue() {
// rot13("svryqf"): [ rot13("perqvgpneqbjare"), rot13("pnequbyqre"), "cc_name", "card_name_f", rot13("pneqanzr"), rot13("arjperqvgpneqanzr"), rot13("pnequbyqrefanzr"), "cc_card_name1", rot13("anzrbapneq"), rot13("gkgpnequbyqre"), "paymentinfo[cardowner]", "customer/billing/name", "Ecom_Payment_Card_Name" ],
this.labels = {
'expirationdate':80,
'expirationmonth':80,
'creditcardexpirydate':100,
'expirydate':80,
'expiration':80,
'expires': 80,
'expirefin':80,
'ablaufmonat':80,
'vervaldatum':80,
'dataważności': 80,
'issued':-100,
'validfrom':-100,
'startdate':-100,
'':0};
this.placeholders = {
'^mm$':80
};
this.valueWeights = {
'11':10,
'jan':50,
'янв':50,
'enero':50,
'gennaio':50,
'augustus':50,
'december':50
};
this.elementTypes = [rot13("grkg"), rot13("fryrpg-bar"), rot13("ahzore"), rot13("gry")];
this.minTextLength = 2;
this.minSelectLength = 12;
this.maxSelectLength = 14;
}
OPCreditCardExpiryMonthClue.prototype = new OPClue("expiry_mm");
OPCreditCardExpiryMonthClue.prototype.valueSetter = function(field, value) { field.setMonthValue(value); }
/**
* @constructor
*/
function OPCreditCardExpiryYearClue() {
// rot13("svryqf"): [ rot13("rkclrne"), rot13("rkcvlrne"), rot13("pprkclrne"), rot13("pprkcverlrne"), rot13("rkcvengvbalrne"), rot13("pplrne"), rot13("arjperqvgpneqlrne"), rot13("fryrkclrne"), rot13("pneqlrne"), "cc_expdate_year", rot13("pple"), "expiration_year1", "1.28.9.5.5.1.0.13.3.1.30", rot13("perqvgpneq.rkc.lrne") , "cc_exp_year", "cds_cc_exp_year", rot13("rkcvellrne"), rot13("pzolrne"), "paymentinfo[thruyear]", "card_exp_yr", rot13("rkcle"), "Ecom_Payment_Card_ExpDate_Year" ],
this.labels = {
'expirationyear':80,
'':0};
this.placeholders = {
'^yy$':80,
'^yyyy$':80
};
this.valueWeights = {
/* Many dropdowns use the first value as placeholder text */
'year':1000,
/* Valid year values */
'2013':10,
'2014':10,
'2015':10,
'2016':10,
'2017':10,
'2018':10,
'2019':10,
'13':10,
'14':10,
'15':10,
'16':10,
'17':10,
'18':10,
'19':10,
/* Bad year values: used for number of licenses, etc.
Remember: this regex is compared against all available options joined by spaces */
' 1 ':-20,
' 2 ':-20,
' 3 ':-20,
' 4 ':-20,
' 5 ':-20,
/* Birth Days, Member Since, etc. */
'2005':-50,
'1975':-100
};
this.elementTypes = [rot13("grkg"), rot13("fryrpg-bar"), rot13("ahzore"), rot13("gry")];
this.minTextLength = 2;
this.minSelectLength = 5;
}
OPCreditCardExpiryYearClue.prototype = new OPClue("expiry_yy");
OPCreditCardExpiryYearClue.prototype.valueSetter = function(field, value) { field.setYearValue(value); }
/**
* @constructor
*/
function OPCreditCardTypeClue() {
// rot13("svryqf"): [ rot13("perqvgpneqglcr"), rot13("pneqglcr"), "card_type_f", "card_type", "cc_paytype", rot13("ppglcr"), "cctype1", rot13("cnlzragglcr"), "Ecom_Payment_Card_Type" ],
this.labels = {
'creditcardtype':80,
'cardtype':25,
'typeofcreditcard':80,
'kreditkartentyp':80,
'kreditkartenfirma':80,
'kaarttype':80,
'':0};
this.valueWeights = {
'visa':90,
'mastercard':90,
'americanexpress':90,
'amex':90,
'discover':20,
'':0};
this.elementTypes = [rot13("enqvb"), rot13("fryrpg-bar")];
}
var CREDIT_CARD_TYPE_REGEX_MAPPING = {
'visa':rot13("(ivfn|ivfncersreerq|ivfnpneq)"),
'mc': rot13("(znfgrepneq|rhebpneq|zp)"),
'amex': rot13("(nzrk|nzrevpnarkcerff)"),
'diners': rot13("qvaref"),
'discover': rot13("qvfp"),
'jcb': rot13("wpo"),
'solo': rot13("fbyb"),
'delta': rot13("qrygn"),
'switch': rot13("fjvgpu"),
'maestro': rot13("znrfgeb"),
'carteblanche': rot13("oynapur"),
'visaelectron': rot13("ryrpgeba")
};
var CREDIT_CARD_TYPE_VALUE_MAPPING = {
'visa':rot13("Ivfn"),
'mc': rot13("ZnfgrePneq"),
'amex': "American Express",
'diners': rot13("Qvaref"),
'discover': rot13("Qvfpbire"),
'jcb': rot13("WFO"),
'solo': rot13("Fbyb"),
'delta': rot13("Qrygn"),
'switch': rot13("Fjvgpu"),
'maestro': rot13("Znrfgeb"),
'carteblanche': "Carte Blanche",
'visaelectron': "Visa Electron"
};
OPCreditCardTypeClue.prototype = new OPClue(rot13("glcr"));
OPCreditCardTypeClue.prototype.valueSetter = function(field, value) { field.setMappedValue(CREDIT_CARD_TYPE_REGEX_MAPPING, CREDIT_CARD_TYPE_VALUE_MAPPING, value); }
/**
* @constructor
*/
function OPCreditCardCVVClue() {
// rot13("svryqf"): [ "cvv2", "ccv2", "cvc2", rot13("pii"), rot13("ppi"), rot13("pif"), rot13("pfp"), "cccvv2", "verify_credit_card", "cvv2_number", rot13("pppip"), rot13("ppiap"), "cc_security_code1", "1.28.9.5.5.1.0.13.3.1.32.1", "1.28.9.5.5.1.0.13.5.1.32.1", "1.26.9.5.5.1.0.13.5.1.30.1", rot13("frphevglpbqrsvryq"), rot13("ppireaoe"), rot13("perqvgpneq.pii"), rot13("pneqpii"), rot13("ppfrp"), "creditcard:cvn", "txtcvc2", rot13("pppfp"), "customer/card/securityid", rot13("pppvq"), rot13("perqvgpneq.pia"), rot13("xbageby"), rot13("pneqirevsvpngvbapbqr"), rot13("pneqpiz"), rot13("ppbqr"), "card_verification", "Ecom_Payment_Card_Verification", "credit_cvv", rot13("pneqfrp") ],
this.labels = buildMap([
rot13("pneqpbqr"), 10,
rot13("pneqvqragvsvpngvbaahzore"), 50,
rot13("pneqfrphevglahzore"), 60,
rot13("frphevglahzore"), 50,
rot13("pneqvqahzore"), 60,
rot13("pneqfrphevglinyhr"), 50,
rot13("pneqinyvqngvbaahzore"), 50,
rot13("pneqirevsvpngvba"), 50,
rot13("purpxfhzzr"), 50,
rot13("pvq"), 40,
rot13("pvqahzore"), 50,
rot13("perqvgpneqfrphevglpbqr"), 80,
rot13("perqvgpneqfrphevglvq"), 80,
rot13("pelcgbtenzzrqrfrphevgr"), 80,
"cryptogrammedesécurité", 80,
rot13("pfp"), 40,
rot13("piqahzore"), 50,
rot13("pifpbqr"), 70,
rot13("pii"), 50,
rot13("pip"), 40,
rot13("piipneqvq"), 50,
rot13("piipbqr"), 80,
rot13("piipi"), 50,
rot13("piiahzore"), 80,
rot13("xbagebypvssre"), 80,
rot13("xbagebypvser"), 80,
rot13("frphevglpbqr"), 50,
rot13("frphevglqvtvgf"), 50,
rot13("fvpureurvgfxbqr"), 80,
rot13("fvtanghercnarypbqr"), 50,
rot13("irevsvpngvbapbqr"), 50,
rot13("irevsvxngvbafxbqr"), 80,
'',0]);
this.elementTypes = [rot13("grkg"), rot13("cnffjbeq"), rot13("ahzore"), rot13("gry")];
this.minTextLength = 3;
}
OPCreditCardCVVClue.prototype = new OPClue(rot13("pii"));
/**
* @constructor
*/
function OPIdentityFullNameClue() {
// rot13("svryqf"):[rot13("anzr"), rot13("ernyanzr"), rot13("gkganzr"), "customer_name" ],
this.labels = buildMap([
'yourname', 80,
'name', 20,
'nome', 20,
'fullname', 80,
"first(and)*last", 80,
"imięinazwiskonakarcie", 80,
"förochefternamn", 50,
rot13("svefganzr"), -100,
rot13("ynfganzr"), -100,
rot13("zvqqyranzr"), -100,
rot13("rznvy"), -80,
'',0]);
this.elementTypes = [rot13("grkg")];
this.minTextLength = 10;
}
OPIdentityFullNameClue.prototype = new OPClue(rot13("lbheanzr"));
/**
* @constructor
*/
function OPIdentityEmailClue() {
this.labels = buildMap([
'emailaddress',85,
'email',60,
'youremail',80,
'youremailaddress',80,
'вашэлектронныйадрес',80,
'электронныйадрес',60,
rot13("ibgerpbheevry"), 80,
rot13("pbheevry"), 80,
"direccióndecorreoelectrónico", 80,
rot13("qrvarrznvy"), 80,
rot13("pbasvezrznvy"), -100,
rot13("erragrelbherznvy"), -100,
rot13("erglcrrznvy"), -100,
rot13("irevslrznvy"), -100,
rot13("pbasvezlbherznvy"), -100,
rot13("irevsllbherznvy"), -100,
"почтыещераз", -100,
"saisissezànouveau", -40,
'',0]);
this.elementTypes = [rot13("grkg"), rot13("rznvy")];
this.minTextLength = 10;
}
OPIdentityEmailClue.prototype = new OPClue(rot13("rznvy"));
/**
* @constructor
*/
function OPIdentityEmail2Clue() {
this.labels = buildMap([
rot13("pbasvezrznvy"), 30,
rot13("erragrelbherznvynqqerff"), 50,
rot13("ercrngrznvynqqerff"), 50,
rot13("erragrelbherznvy"), 30,
rot13("erragrerznvy"), 30,
rot13("erglcrrznvynqqerff"), 50,
rot13("erglcrrznvy"), 30,
rot13("ercrngrznvy"), 30,
rot13("irevslrznvy"), 30,
rot13("irevslrznvynqerff"), 50,
rot13("pbasvezlbherznvynqqerff"), 80,
rot13("irevsllbherznvy"), 80,
rot13("rznvynqqerffntnva"), 80,
"bekræftemailadresse", 80,
"адресэлектроннойпочтыещераз", 80,
rot13("abhirnhibgerpbheevry"), 80,
"nuevoladireccióndecorreoelectrónico", 80,
rot13("rznvyabpuznyfrvatrora"), 80,
rot13("rznvynqerffrjvrqreubyra"), 80,
rot13("ervafrevfpvyrznvy"), 80,
'',0]);
this.elementTypes = [rot13("grkg"), rot13("rznvy")];
this.minTextLength = 10;
}
OPIdentityEmail2Clue.prototype = new OPClue("email2");
/**
* @constructor
*/
function OPIdentityFirstNameClue() {
this.labels = buildMap([
rot13("svefganzr"), 80,
rot13("sberanzr"), 80,
"имя", 80,
"prénom", 80,
rot13("abzoer"), 80,
rot13("ibeanzr"), 80,
"förnamn", 80,
rot13("sbeania"), 80,
rot13("gvyygnyfanza"), 80,
rot13("abzr"), 25,
rot13("shyyanzr"), -100,
rot13("pnequbyqre(f)?anzr"), -100,
"", 0]);
this.elementTypes = [rot13("grkg")];
this.minTextLength = 10;
}
OPIdentityFirstNameClue.prototype = new OPClue(rot13("svefganzr"));
/**
* @constructor
*/
function OPIdentityInitialClue() {
this.labels = buildMap([
rot13("vavgvny"), 80,
rot13("zvqqyranzr"), 80,
"отчество", 80,
rot13("shyyanzr"), -100,
rot13("pnequbyqre(f)?anzr"), -100,
"", 0]);
this.elementTypes = [rot13("grkg")];
this.minTextLength = 10;
}
OPIdentityInitialClue.prototype = new OPClue(rot13("vavgvny"));
/**
* @constructor
*/
function OPIdentityLastNameClue() {
this.labels = buildMap([
rot13("ynfganzr"), 80,
rot13("fheanzr"), 70,
rot13("snzvylanzr"), 70,
"фамилия", 80,
rot13("pbtabzr"), 80,
rot13("abzqrsnzvyyr"), 80,
rot13("anpuanzr"), 80,
rot13("rsgreania"), 80,
rot13("ncryyvqbf"), 80,
rot13("rsgreanza"), 80,
rot13("npugreannz"), 80,
rot13("abz"), 30,
rot13("abzr"), -30,
rot13("shyyanzr"), -100,
rot13("pnequbyqre(f)?anzr"), -100,
"", 0]);
this.elementTypes = [rot13("grkg")];
this.minTextLength = 10;
}
OPIdentityLastNameClue.prototype = new OPClue(rot13("ynfganzr"));
/**
* @constructor
*/
function OPIdentitySexClue() {
this.labels = buildMap([
rot13("frk"), 70,
rot13("traqre"), 70,
rot13("znyrsrznyr"), 70,
rot13("srznyrznyr"), 70,
"мужжен", 70,
"вашпол", 70,
"køn", 70,
rot13("vxorarra"), 50,
rot13("naerqr"), 70,
"пол", 20,
'', 0]);
this.valueWeights = {
'male':50,
'female':50,
'herr':50,
'männl':50,
'mascul':50,
'муж':50,
'mies':50,
'uomo':50,
'mand':50,
'vrouw':50,
'kvinde':50,
'nainen':50,
'feminino':50,
'frau':50,
'жен':50,
'mujer':50
};
this.minSelectLength = 2;
this.maxSelectLength = 4;
this.elementTypes = [rot13("fryrpg-bar"), rot13("enqvb")];
}
var SEX_REGEX_MAPPING = {
'male': "^(male|herr|männl|mascul|муж|hombre|uomo|mies|man|mand|homme)",
'female': "^(female|frau|femm|жен|mujer|feminino|weiblich|donna|nainen|kvinde|vrouw)"
};
var SEX_VALUE_MAPPING = {
'male': 'Male',
'female': 'Female'
};
OPIdentitySexClue.prototype = new OPClue(rot13("frk"));
OPIdentitySexClue.prototype.valueSetter = function(field, value) { field.setMappedValue(SEX_REGEX_MAPPING, SEX_VALUE_MAPPING, value); }
/**
* @constructor
*/
function OPIdentityUsernameClue() {
this.labels = buildMap([
rot13("hfreanzr"), 70,
rot13("hfrenyvnf"), 70,
rot13("hfreanzr"), 80,
rot13("ubgznvynqqerff"), 80,
rot13("vq"), 20,
rot13("frevny"), -100,
rot13("ingvq"), -100,
rot13("zvqqyranzr"), -100,
rot13("vavgvny"), -100,
"", 0]);
this.elementTypes = [rot13("grkg")];
this.minTextLength = 10;
}
OPIdentityUsernameClue.prototype = new OPClue(rot13("hfreanzr"));
/**
* @constructor
*/
function OPIdentityAddressLine1Clue() {
this.labels = buildMap([
rot13("fgerrg"), 10,
"address1", 30,
"line1", 30,
rot13("fgerrganzr"), 30,
rot13("nqqerff"), 5,
rot13("ovyyvatnqqerff"), 10,
rot13("ovyyvatfgerrgnqqerff"), 10,
rot13("fgerrgnqqerffbar"), 10,
rot13("fgerrgnqqerff"), 10,
rot13("nqerffr"), 20,
rot13("nqerf"), 20,
rot13("fgenffr"), 30,
"straße", 30,
rot13("tnghnqerff"), 30,
rot13("yrirenafnqerff"), 30,
"straßeundhausnummer", 60,
rot13("rznvy"), -80,
rot13("vcnqqerff"), -80,
rot13("ubgznvynqqerff"), -100,
'',0]);
this.elementTypes = [rot13("grkg")];
this.minTextLength = 10;
}
OPIdentityAddressLine1Clue.prototype = new OPClue("address1");
/**
* @constructor
*/
function OPIdentityAddressLine2Clue() {
this.labels = buildMap([
"street2", 20,
"address2", 30,
"line2", 30,
rot13("fgerrganzr"), 30,
rot13("fgerrgnqqerffgjb"), 10,
rot13("rznvy"), -80,
rot13("vcnqqerff"), -80,
'',0]);
this.elementTypes = [rot13("grkg")];
this.minTextLength = 10;
}
OPIdentityAddressLine2Clue.prototype = new OPClue("address2");
/**
* @constructor
*/
function OPIdentityCityClue() {
this.labels = buildMap([
rot13("pvgl"), 30,
rot13("zvnfgb"), 30,
rot13("beg"), 20,
rot13("gbja"), 30,
rot13("fhoheo"), 30,
rot13("gbjapvgl"), 30,
rot13("ivyyr"), 30,
"город", 30,
rot13("cbfgbeg"), 30,
rot13("rznvy"), -80,
rot13("vcnqqerff"), -80,
'',0]);
this.elementTypes = [rot13("grkg")];
this.minTextLength = 10;
}
OPIdentityCityClue.prototype = new OPClue(rot13("pvgl"));
/**
* @constructor
*/
function OPIdentityZipClue() {
this.labels = buildMap([
rot13("mvc"), 30,
rot13("mvcpbqr"), 30,
rot13("cbfgnypbqr"), 50,
rot13("pbqrcbfgny"), 50,
rot13("cbfgny"), 10,
rot13("cbfgpbqr"), 30,
"индекс", 30,
rot13("cbfgahzzre"), 30,
rot13("cbfgyrvgmnuy"), 80,
rot13("xbqcbpmgbjl"), 80,
'',0]);
this.elementTypes = [rot13("grkg")];
this.minTextLength = 10;
}
OPIdentityZipClue.prototype = new OPClue(rot13("mvc"));
/**
* @constructor
*/
function OPIdentityCompanyClue() {
this.labels = buildMap([
rot13("betnavmngvba"), 50,
rot13("betnavfngvba"), 50,
rot13("svezn"), 30,
rot13("betanzr"), 30,
rot13("pbzcnal"), 50,
rot13("ivexfbzurqfania"), 50,
'',0]);
this.elementTypes = [rot13("grkg")];
this.minTextLength = 10;
}
OPIdentityCompanyClue.prototype = new OPClue(rot13("pbzcnal"));
/**
* @constructor
*/
function OPIdentityCountryClue() {
this.labels = buildMap([
rot13("pbhagel"), 50,
rot13("xenw"), 50,
"страна", 50,
rot13("ynaq"), 20,
rot13("cnlf"), 20,
'',0]);
this.valueWeights = {
'canada':90,
'deutschland':90,
'kanada':90,
'канада':90,
'france':80,
'unitedstates':80,
'':0};
this.elementTypes = [rot13("grkg"), rot13("fryrpg-bar"), rot13("enqvb")];
this.minTextLength = 10;
}
OPIdentityCountryClue.prototype = new OPClue(rot13("pbhagel"));
OPIdentityCountryClue.prototype.valueSetter = function(field, value) { field.setMappedValue(COUNTRY_REGEX_MAPPING, COUNTRY_VALUE_MAPPING, value); }
/**
* @constructor
*/
function OPIdentityStateProvinceClue() {
this.labels = buildMap([
rot13("fgngr"), 30,
rot13("cebivapr"), 80,
rot13("fgngrcebivapr"), 80,
rot13("fgnqg"), 40,
rot13("pbhagl"), 20,
"регион", 20,
'',0]);
this.valueWeights = buildMap([
rot13("pnyvsbeavn"),50,
rot13("bagnevb"),50,
rot13("sybevqn"),50,
rot13("op"),20,
rot13("au"),20,
rot13("al"),10,
'',0]);
this.elementTypes = [rot13("grkg"), rot13("fryrpg-bar"), rot13("enqvb")];
this.minTextLength = 10;
}
function normalizeValueUsingRegexMapping(value, regexMapping) {
// Our state/province field is entered as a text value in 1Password UI which means that we now have to figure out the real value
if (!value) return null;
value = value.toLowerCase();
for (var key in regexMapping) {
if (!regexMapping.propertyIsEnumerable(key)) continue;
var re = new RegExp(regexMapping[key]);
if (value.match(re)) return key;
}
return null;
}
OPIdentityStateProvinceClue.prototype = new OPClue(rot13("fgngr"))
OPIdentityStateProvinceClue.prototype.valueSetter = function(field, value) { field.setMappedValue(STATE_PROVINCE_REGEX_MAPPING, STATE_PROVINCE_VALUE_MAPPING, normalizeValueUsingRegexMapping(value, STATE_PROVINCE_REGEX_MAPPING)); }
/**
* @constructor
*/
function OPIdentityDefPhoneClue() {
this.labels = buildMap([
rot13("cubar"), 40,
rot13("cubarahzore"), 40,
rot13("gryrsba"), 40,
"телефон", 40,
rot13("pryy"), -80,
rot13("zbovyr"), -80,
'',0]);
this.elementTypes = [rot13("grkg"), rot13("gry")];
}
OPIdentityDefPhoneClue.prototype = new OPClue(rot13("qrscubar"));
/**
* @constructor
*/
function OPIdentityCellPhoneClue() {
this.labels = buildMap([
rot13("cubar"), 20,
rot13("cubarahzore"), 20,
rot13("gryrsba"), 20,
"телефон", 20,
rot13("pryy"), 40,
rot13("zbovyr"), 40,
rot13("zbovy"), 30,
rot13("zbovyahzzre"), 60,
rot13("ubzr"), -80,
rot13("bssvpr"), -80,
'',0]);
this.elementTypes = [rot13("grkg"), rot13("gry")];
}
OPIdentityCellPhoneClue.prototype = new OPClue(rot13("pryycubar"));
var creditCardClues = [
new OPCreditCardTypeClue(),
new OPCreditCardNumberClue(),
new OPCreditCardHolderClue(),
new OPCreditCardExpiryMonthClue(),
new OPCreditCardExpiryYearClue(),
new OPCreditCardCVVClue()
];
var identityClues = [
new OPIdentityCountryClue(), // start with the country
new OPIdentityFirstNameClue(),
new OPIdentityInitialClue(),
new OPIdentityLastNameClue(),
new OPIdentityFullNameClue(),
new OPIdentitySexClue(),
new OPIdentityCompanyClue(),
new OPIdentityUsernameClue(),
new OPIdentityEmailClue(),
new OPIdentityEmail2Clue(),
new OPIdentityAddressLine1Clue(),
new OPIdentityAddressLine2Clue(),
new OPIdentityCityClue(),
new OPIdentityStateProvinceClue(),
new OPIdentityZipClue(),
new OPIdentityDefPhoneClue(),
new OPIdentityCellPhoneClue()
];
var DEBUG_BRAIN_FORM = false;
/**
* @constructor
*/
function OPForm(htmlForm) {
this.htmlForm = htmlForm;
this.name = htmlForm ? attrValue(htmlForm, 'name') : 'null';
this.id = htmlForm ? htmlForm.ag_uniqueId : '__null__';
this.elements = [];
this.fieldsByName = {};
}
OPForm.prototype = {
prettyName: function() {
if (!this.htmlForm) return this.name;
return attrValue(this.htmlForm, 'name') + ' (' + this.htmlForm.ag_uniqueId + ')__' + attrValue(this.htmlForm, 'id') + '__' + attrValue(this.htmlForm, 'action');
},
setupFields: function() {
// console.log("> setupFields");
this.fieldsByName = {};
for (var i = 0; i < this.elements.length; ++i) {
var e = this.elements[i];
if (!e.isWritable()) continue;
var f = this.fieldsByName[e.getName()];
if (!f) {
f = new OPField(e.getName(), e.getType());
this.fieldsByName[f.name] = f;
// console.log("field " + f.name + ": " + f.getLabel());
}
f.elements.push(e);
}
// console.log("< setupFields");
},
matchClues: function(clues) {
for (var i = 0; i < clues.length; ++i) {
this.matchClue(clues[i]);
}
},
matchClue: function(clue) {
for (var fieldName in this.fieldsByName) {
if (!this.fieldsByName.propertyIsEnumerable(fieldName)) continue;
var field = this.fieldsByName[fieldName];
var weight = clue.match(field);
field.addWeight(clue.propertyName, weight);
}
},
fill: function(clues, walletItem) {
this.matchClues(clues);
var availableFields = [];
for (var fieldName in this.fieldsByName) {
if (!this.fieldsByName.propertyIsEnumerable(fieldName)) continue;
availableFields.push(this.fieldsByName[fieldName]);
// console.log("field: " + fieldName);
}
var propertiesToFill = [];
for (var i = 0; i < clues.length; ++i) {
var clue = clues[i];
var propertyName = clues[i].propertyName;
// console.log("propertyName: " + propertyName);
var bestWeight = 0;
var bestFieldIndex = -1;
for (var fieldIndex = 0; fieldIndex < availableFields.length; ++fieldIndex) {
var weight = availableFields[fieldIndex].walletPropertyWeights[propertyName];
if (weight > bestWeight) {
bestWeight = weight;
bestFieldIndex = fieldIndex;
}
}
if (bestWeight > 0) {
var bestField = availableFields[bestFieldIndex];
propertiesToFill.push({ 'name': propertyName, 'field': bestField, 'clue': clue });
availableFields.splice(bestFieldIndex, 1);
}
}
for (var i = 0; i < propertiesToFill.length; ++i) {
var prop = propertiesToFill[i];
var propName = prop['name'];
var field = prop['field'];
var clue = prop['clue'];
if (field == null) {
}
else {
clue.valueSetter(field, walletItem.attrValue(propName));
}
}
},
isSearchForm: function() {
return isSearchForm(this.htmlForm);
},
fillCreditCard: function(creditCard) {
this.fill(creditCardClues, creditCard);
},
fillIdentity: function(identity) {
this.fill(identityClues, identity);
},
findBestFieldForProperty: function(prop) {
var bestWeight = 0;
var result = null;
for (var fieldName in this.fieldsByName) {
if (!this.fieldsByName.propertyIsEnumerable(fieldName)) continue;
var field = this.fieldsByName[fieldName];
var weight = field.walletPropertyWeights[prop];
if (weight > bestWeight) {
bestWeight = weight;
result = field;
}
}
return result;
}
}
var DEBUG_BRAIN_DOCUMENT = false;
/**
* @constructor
*/
function OPDocument(doc) {
this.doc = doc;
this.allForms = {};
this.nullForm = null;
}
OPDocument.prototype = {
setupFormObject: function(htmlForm) {
var result = null;
if (htmlForm == null) {
result = this.nullForm;
}
else {
if (htmlForm && htmlForm.ag_uniqueId === undefined) {
htmlForm.ag_uniqueId = ++this.formCounter;
}
result = this.allForms[htmlForm.ag_uniqueId];
if (!result) {
result = new OPForm(htmlForm);
this.allForms[htmlForm.ag_uniqueId] = result;
}
}
return result;
},
rescan: function() {
this.nullForm = new OPForm(null);
this.formCounter = 0;
this.allForms = { "__null__": this.nullForm };
var allElements = this.doc.getElementsByTagName("*");
for (var i = 0; i < allElements.length; ++i) {
var e = allElements[i];
if (elementIs(e, [rot13("vachg"), rot13("fryrpg"),rot13("grkgnern")])) {
this.setupFormObject(e.form).elements.push(new OPElement(e));
}
}
for (var formId in this.allForms) {
if (!this.allForms.propertyIsEnumerable(formId)) continue;
var f = this.allForms[formId];
// console.log("form = " + f);
if (f.setupFields) f.setupFields();
}
},
fillCreditCard: function(dataObject) {
this.rescan();
var creditCard = new OPCreditCard(dataObject);
for (var formId in this.allForms) {
if (!this.allForms.propertyIsEnumerable(formId)) continue;
var form = this.allForms[formId];
if (!form.fillCreditCard) continue;
if (!form.isSearchForm())
form.fillCreditCard(creditCard);
}
},
fillIdentity: function(dataObject) {
this.rescan();
var identity = new OPIdentity(dataObject);
for (var formId in this.allForms) {
if (!this.allForms.propertyIsEnumerable(formId)) continue;
var form = this.allForms[formId];
if (!form.fillIdentity) continue;
if (!form.isSearchForm()) {
form.fillIdentity(identity);
}
else {
}
}
},
fillPassword: function(dataObject) {
var filler = new OPPasswordFiller();
var password = new OPPassword(dataObject);
filler.fillPassword(password);
},
getMaxPasswordLength: function() {
var allInputs = document.getElementsByTagName(rot13("vachg"));
var result = 50;
for (var i = 0; i < allInputs.length; ++i) {
var input = allInputs[i];
if (input.type === rot13("cnffjbeq") && input.maxLength && (input.maxLength < result)) {
result = input.maxLength;
}
}
return result;
},
// Debugging: given a field name, tell me everything you know about it
fieldInfo: function(name) {
console.log("Info for form field " + name + ":");
for (var formId in this.allForms) {
if (!this.allForms.propertyIsEnumerable(formId)) continue;
var form = this.allForms[formId];
if (!form.fieldsByName) continue;
var fields = form.fieldsByName[name];
if (fields) {
console.log("label: " + fields.getLabel());
}
}
}
}
/**
* @constructor
*/
function OPLogin(json, includeUsernameInTitle) {
this.json = json;
this.includeUsernameInTitle = includeUsernameInTitle;
}
OPLogin.prototype = {
toJSON: function() {
return this.asJSON();
},
toString: function() {
var formType = "Regular login";
if (this.isChangePasswordForm()) formType = "Change password";
if (this.isRegistrationForm()) formType = "Registration form";
var uuid = this.uuid() || "NO_UUID";
return "[OPLogin " + uuid + " (" + formType +")] <" + this.location() + ">";
},
asJSON: function() {
return this.json;
},
uuid: function() {
return this.json['uuid'];
},
setUuid: function(newUUID) {
this.json['uuid'] = newUUID;
},
trashed: function() {
return this.json['trashed'] === 'N';
},
setTrashed: function(isTrashed) {
this.json['trashed'] = (isTrashed ? 'Y' : 'N');
},
createdAt: function() {
return this.json['created_at'];
},
setCreatedAt: function(newValue) {
this.json['created_at'] = newValue;
},
updatedAt: function() {
return this.json['updated_at'];
},
setUpdatedAt: function(newValue) {
this.json['updated_at'] = newValue;
},
resetUpdatedAt: function() {
this.json['updated_at'] = Math.round(new Date().getTime() / 1000);
},
secureContents: function() {
return this.json['secureContents'] || {};
},
overview: function() {
return this.json['overview'] || {};
},
nakedDomains: function() {
return this.json['nakedDomains'];
},
tags: function() {
return this.overview()['tags'] || [];
},
setTags: function(newTags) {
if (newTags && newTags.length > 0) {
this.overview()['tags'] = newTags;
}
else {
delete this.json['overview']['tags'];
}
},
folderUuid: function() {
return this.json['folder_uuid'];
},
setFolderUuid: function(newValue) {
if (newValue && newValue.length > 0) this.json['folder_uuid'] = newValue;
else delete this.json['folder_uuid'];
},
passwordHistory: function() {
return this.secureContents()['passwordHistory'] || [];
},
setPasswordHistory: function(newPasswordHistory) {
if (newPasswordHistory && newPasswordHistory.length > 0) {
newPasswordHistory = newPasswordHistory.sort(function(a, b) {
return a['time'] - b['time'];
});
this.secureContents()['passwordHistory'] = newPasswordHistory;
}
else {
delete this.secureContents()['passwordHistory'];
}
},
htmlAction: function() {
return this.secureContents()['htmlAction'] || '';
},
htmlID: function() {
return this.secureContents()['htmlID'] || '';
},
fullyQualifiedURL: function(pathOrURL) {
if (!pathOrURL) return null;
if (pathOrURL.indexOf(rot13("uggc")) == 0) return pathOrURL;
var url = window.location.protocol + "//" + window.location.hostname;
if (window.location.port && window.location.port != "") url += ":" + window.location.port;
url += pathOrURL;
return url;
},
matchesActionNameID: function(action, name, id) {
var info = this.secureContents();
return (info['htmlAction'] && this.fullyQualifiedURL(info['htmlAction']) == this.fullyQualifiedURL(action) && info['htmlName'] && info['htmlName'] == name && info['htmlID'] && info['htmlID'] == id);
},
matchesActionName: function(action, name) {
var info = this.secureContents();
return (info['htmlAction'] && this.fullyQualifiedURL(info['htmlAction']) == this.fullyQualifiedURL(action) && info['htmlName'] && info['htmlName'] == name);
},
matchesActionID: function(action, id) {
var info = this.secureContents();
return (info['htmlAction'] && this.fullyQualifiedURL(info['htmlAction']) == this.fullyQualifiedURL(action) && info['htmlID'] && info['htmlID'] == id);
},
matchesAction: function(action) {
if (!action || action == "") return false; // Logins created in 1Password have blank actions so allowing blank matchs is too aggressive
// Chrome gives us the fully qualified URL where as Safari gives us what the page coded, often just the path.
return this.fullyQualifiedURL(action) == this.fullyQualifiedURL(this.htmlAction());
},
matchesName: function(name) {
var info = this.secureContents();
return (info['htmlName'] && info['htmlName'] == name);
},
textFieldNames: function() {
var result = {};
var allFields = this.fields();
for (var i = 0; i < allFields.length; ++i) {
var f = allFields[i];
if (f['name'] == '') continue;
if (f['type'] == 'T' || f['type'] == 'P') {
result[f['name']] = f;
}
}
return result;
},
fields: function() {
return this.secureContents()['fields'];
},
addField: function(name, type, designation) {
var secureContents = this.secureContents();
var fields = secureContents['fields'];
var f = { 'name': name, 'type': type };
if (designation) f['designation'] = designation;
fields.push(f);
return f;
},
fieldDesignatedAs: function(designation) {
var fields = this.fields();
if (!fields) return null;
for (var i = 0; i < fields.length; ++i) {
var f = fields[i];
if (f['designation'] === designation) return f;
}
return null;
},
generatedTitle: function(includeUsernameInTitle){
var titleString = extractDomain(this.location()).replace(/.*?:\/\//, '');
if (titleString.indexOf(rot13("jjj.")) == 0) titleString = titleString.substr(4);
if (includeUsernameInTitle) {
var username = this.username();
if (username.length > 0 && titleString.indexOf(username) === -1) {
titleString = titleString + " (" + this.username() + rot13(")");
}
}
return titleString;
},
title: function() {
return this.json['overview']['title'];
},
setTitle: function(titleString) {
this.json['overview']['title'] = titleString;
},
location: function() {
if (this.json && this.json['overview']) return this.json['overview']['location'];
return undefined;
},
setLocation: function(value) {
this.json['overview']['location'] = value;
},
notesPlain: function() {
return this.secureContents()['notesPlain'] || '';
},
setNotesPlain: function(value) {
return this.secureContents()['notesPlain'] = value;
},
username: function() {
var f = this.fieldDesignatedAs(rot13("hfreanzr"));
return f ? f['value'] : '';
},
setUsername: function(value) {
var f = this.fieldDesignatedAs(rot13("hfreanzr"));
if (!f) f = this.addField(rot13("hfreanzr"), rot13("G"), rot13("hfreanzr"));
f['value'] = value;
},
password: function() {
var f = this.fieldDesignatedAs(rot13("cnffjbeq"));
return f ? f['value'] : '';
},
setPassword: function(value) {
if (this.password() === value) return;
var f = this.fieldDesignatedAs(rot13("cnffjbeq"));
if (!f) f = this.addField(rot13("cnffjbeq"), rot13("C"), rot13("cnffjbeq"));
var passwordHistory = this.passwordHistory();
var newHistoryEntry = {
'time': Math.round((new Date()).getTime() / 1000),
'value': f[rot13("inyhr")]
};
passwordHistory.push(newHistoryEntry);
this.setPasswordHistory(passwordHistory);
f[rot13("inyhr")] = value;
},
hasUsername: function() {
return this.username().length > 0;
},
hasPassword: function() {
return this.password().length > 0;
},
fieldsOfType: function(fieldTypes) {
var fields = this.fields();
if (!fields) return [];
var result = [];
for (var i = 0; i < fields.length; ++i) {
var t = fields[i]['type'];
if (!t) continue;
if (fieldTypes.indexOf(t) >= 0) {
result.push(fields[i]);
}
}
return result;
},
passwordFields: function() {
return this.fieldsOfType(['P']);
},
textFields: function() {
return this.fieldsOfType(['T', 'U']); // 'U' because we do not handle new HTML5 types in Save Form
},
autosubmitValue: function() {
if (this.json['overview'] && this.json['overview']['autosubmit']) {
return this.json['overview']['autosubmit'];
}
return null;
},
setAutosubmitValue: function(value) {
var overview = this.json['overview'];
if (!overview) {
console.error("[BRAIN_LOGIN] No overview");
return;
}
if (!value || value === 'default') delete overview['autosubmit'];
overview['autosubmit'] = value;
},
autosubmitAlways: function() {
return (this.autosubmitValue() === rot13("nyjnlf"));
},
autosubmitNever: function() {
return (this.autosubmitValue() === rot13("arire"));
},
autosubmitDefault: function() {
return (!this.autosubmitAlways() && !this.autosubmitNever());
},
replaceWith: function(anotherLogin) {
// 1. replace everything with the contents of the another login
// 2. merge passwordHistory
// 3. add existing password to the password history
// 4. keep folder and tags if anotherLogin has none.
var uuid = this.uuid();
var createdAt = this.createdAt();
var combinedPasswordHistory = this.passwordHistory().concat(anotherLogin.passwordHistory());
var currentPassword = this.password();
if (currentPassword && currentPassword.length > 0) {
var time = Math.round(new Date().getTime() / 1000);
combinedPasswordHistory.push({ 'time': time, 'value': currentPassword });
}
var tags = anotherLogin.tags();
if (tags.length == 0) tags = this.tags();
var folderUuid = anotherLogin.folderUuid();
if (!folderUuid) folderUuid = this.folderUuid();
var notesPlain = anotherLogin.notesPlain();
if (!notesPlain || notesPlain.length == 0) notesPlain = this.notesPlain();
this.json = anotherLogin.asJSON();
this.setUuid(uuid);
this.setCreatedAt(createdAt);
this.resetUpdatedAt();
this.setPasswordHistory(combinedPasswordHistory);
this.setTags(tags);
this.setFolderUuid(folderUuid);
this.setNotesPlain(notesPlain);
},
isChangePasswordForm: function()
{
var passwords = this.passwordFields();
if (passwords.length < 2) return false;
if (passwords.length === 3) {
var p1 = passwords[0]['value'];
var p2 = passwords[1]['value'];
var p3 = passwords[2]['value'];
// Prevent false positive: 3 idential password fields implies Registration+Login combo page
if (p1 === p2 && p1 === p3)
return false;
var uniquePasswords = [];
if (p1.length > 0 && uniquePasswords.indexOf(p1) === -1) uniquePasswords.push(p1);
if (p2.length > 0 && uniquePasswords.indexOf(p2) === -1) uniquePasswords.push(p2);
if (p3.length > 0 && uniquePasswords.indexOf(p3) === -1) uniquePasswords.push(p3);
if (uniquePasswords.length == 2)
return true;
}
// Guess #2: Change Password Form has 2 or more password fields and 0 text fields
if (this.textFields().length > 0) {
return false;
}
// Guess #3: This is change password form that does not request the old password,
// two password fields must be identical then
if (passwords.length === 2) {
return (passwords[0]['value'] === passwords[1]['value']);
}
return false;
},
isRegistrationForm: function() {
if (this.isChangePasswordForm()) return false;
// check htmlAction for suspicious urls
if (this.htmlAction().match(/(signup|register)/i))
return true;
if (this.htmlID().match(/(signup|register)/i))
return true;
// make sure that if there are 2 password fields then they have the same value
var passwords = this.passwordFields();
if (passwords.length != 2) return false;
return (passwords[0]['value'] === passwords[1]['value']);
}
}
/**
* @constructor
*/
function OPPassword(json) {
this.json = json;
}
OPPassword.prototype = {
asJSON: function() {
return this.dataObject;
},
trashed: function() {
return this.json['trashed'] === 'N';
},
setTrashed: function(isTrashed) {
this.json['trashed'] = (isTrashed ? 'Y' : 'N');
},
secureContents: function() {
return this.json['secureContents'];
},
title: function() {
return this.json['overview']['title'];
},
location: function() {
return this.json['overview']['location'];
},
password: function() {
var p = this.secureContents()['password'];
return p ? p : '';
}
}
var DEBUG_FILL_LOGIN = false;
var DEBUG_AUTOSUBMIT = false;
var DEBUG_BRAINTESTAUTOSUBMIT = false;
var RETURN_KEY_DELAY = 200;
/**
* @constructor
*/
function OPLoginFiller() {
this.filledElements = [];
this.filledCount = 0;
this.filledPasswordCount = 0;
this.pendingFillOperations = [];
this.mutationObserver = null;
}
function htmlFormDescription(form) {
if (!form) return "<null>";
return form.getAttribute('id') + "/" + form.getAttribute('name') + "/" + form.getAttribute('action');
}
function htmlInputElementDescription(el) {
if (!el) return "<null>";
return el.getAttribute('id') + "/" + el.getAttribute('type') + "/" + el.getAttribute('name');
}
function htmlLinkDescription(link) {
if (!link) return "<null>";
return link.id + "/" + link.title + "/" + link.href;
}
// Impossible to be 100% so return a weight.
function isRegistrationForm(form) {
if (!form) return false;
var weight = 0.0;
var regex = /(signup|register)/i;
// check htmlAction for suspicious urls
if (form.getAttribute('action') && form.getAttribute('action').match(regex))
weight += 0.9;
if (form.getAttribute('id') && form.getAttribute('id').match(regex))
weight += 0.8;
if (form.getAttribute('name') && form.getAttribute('name').match(regex))
weight += 0.8;
if (form.className && form.className.match(regex))
weight += 0.5;
var passwordCount = 0;
for (var i=0, ii=form.elements.length; i<ii; i++) {
var el = form.elements[i];
if (el.type && el.type.toLowerCase() === rot13("cnffjbeq")) passwordCount++;
}
if (passwordCount > 1) weight += 0.5;
return Math.min(1.0, weight);
}
// Temp helper method that should be replaced with a OPField class and field.type() method. Should be merged with OPFormManager.fieldForElement
function typeCodeForInputType(type) {
type = type.toLowerCase();
if (type == rot13("cnffjbeq")) return rot13("C");
else if (type == rot13("grkg")) return rot13("G");
}
OPLoginFiller.prototype = {
fakePasswordFields: [],
findBestMatchingForm: function(forms, login, visibility) {
for (var formIndex = 0; formIndex < forms.length; ++formIndex) {
var form = forms[formIndex];
if (!possibleLoginForm(form, visibility)) continue;
if (login.matchesActionNameID(form.getAttribute('action'), form.getAttribute('name'), form.getAttribute('id'))) {
return form;
}
}
for (var formIndex = 0; formIndex < forms.length; ++formIndex) {
var form = forms[formIndex];
if (!possibleLoginForm(form, visibility)) continue;
if (login.matchesActionName(form.getAttribute('action'), form.getAttribute('name'))) {
return form;
}
}
for (var formIndex = 0; formIndex < forms.length; ++formIndex) {
var form = forms[formIndex];
if (!possibleLoginForm(form, visibility)) continue;
if (login.matchesActionID(form.getAttribute('action'), form.getAttribute('id'))) {
return form;
}
}
for (var formIndex = 0; formIndex < forms.length; ++formIndex) {
var form = forms[formIndex];
if (!possibleLoginForm(form, visibility)) continue;
if (login.matchesAction(form.getAttribute('action'))) {
return form;
}
}
for (var formIndex = 0; formIndex < forms.length; ++formIndex) {
var form = forms[formIndex];
if (!possibleLoginForm(form, visibility)) continue;
if (login.matchesName(form.getAttribute('name'))) {
return form;
}
}
if (DEBUG_FILL_LOGIN) console.log("[FL] No html form matched our saved login form's attributes. Inspecting form fields now.")
var fieldNames = login.textFieldNames();
for (var formIndex = 0; formIndex < forms.length; ++formIndex) {
var form = forms[formIndex];
if (visibility && !isVisible(form)) continue;
var matchingElementCount = 0;
var passwordElementCount = 0;
for (var i = 0; i < form.elements.length; ++i) {
var element = form.elements[i];
if (!element || !element.type || !element.name) continue;
var typeName = element.type.toLowerCase();
if (typeName == rot13("uvqqra")) continue;
if (typeName == rot13("cnffjbeq")) {
passwordElementCount += 1;
}
if (fieldNames[element.name]) {
matchingElementCount += 1;
}
}
if (passwordElementCount > 0 && matchingElementCount > 2) {
return form;
}
// relaxing matching rules for forms without password
if (passwordElementCount == 0 && login.passwordFields().length == 0 && matchingElementCount > 0) {
return form;
}
}
return null;
},
findElementForFormlessField: function(field) {
var element = null;
if (field['id'] && field['id'] !== '') {
element = document.getElementById(field['id']);
}
if (!element && field['name'] && field['name'] !== '') {
// Element is still undefined, use field name.
var elements = document.getElementsByName(field['name']);
if (elements.length > 0) {
// TODO: if more than one element found, use field type to narrow results.
element = elements[0];
}
}
return element;
},
fillElement: function(element, value) {
if (!element) return;
if (!value) return;
var elementType = (element.type || "").toLowerCase();
if (elementType === 'password') this.filledPasswordCount += 1;
if (['text', 'password', 'email', 'tel'].indexOf(elementType) >= 0) {
// do not count radio or checkboxes
this.filledCount += 1;
}
this.filledElements.push(element);
var fakePasswordFields = this.fakePasswordFields;
// Postponing real fill operation
this.pendingFillOperations.push(function(completionF) {
//
if (elementType === 'password') touchAllFields(fakePasswordFields);
setElementValue(element, value, completionF);
});
},
isElementAlreadyFilled: function(element) {
return this.filledElements.indexOf(element) >= 0;
},
fillLoginFull: function(login, visibility) {
if (login.fields() == null) return null;
var matchingForm = this.findBestMatchingForm(document.forms, login, visibility);
if (!matchingForm) return null;
var elementsByName = {}, elementsById = {}, passwordElements = [];
for (var elementIndex = 0; elementIndex < matchingForm.elements.length; ++elementIndex) {
var element = matchingForm.elements[elementIndex];
if (!isVisible(element)) continue;
if (!isFillable(element)) continue;
if (element && element.name && element.name != "")
elementsByName[element.name] = element;
if (element && element.id && element.id != "")
elementsById[element.id] = element;
if (element.type && element.type.toLowerCase() === rot13("cnffjbeq"))
passwordElements.push(element);
}
var fields = login.fields();
if (document.location.host == rot13("rnfljrofbp.gq.pbz") || document.location.host == rot13("rnfljropcb.gq.pbz")) {
// special handling for TDCanadaTrust login form
delete elementsByName['login:loginIDComboBox'];
delete elementsById['login:loginIDComboBox'];
delete elementsByName['login:description'];
delete elementsById['login:description'];
}
for (var fieldIndex = 0; fieldIndex < fields.length; ++fieldIndex) {
var field = fields[fieldIndex];
// Skipping fields w/o value
if (!field['value'] || field['value'] === '') continue;
var element = null;
if (field['name']) {
element = elementsByName[field['name']];
}
if (!element && field['id']) {
element = elementsById[field['id']];
if (element && DEBUG_FILL_LOGIN) {
console.log("Found a DOM element with id='" + field['id'] + "'");
}
}
// This field may belong to a formless element.
if (!element && field['formless']) {
element = this.findElementForFormlessField(field);
}
// Cocoa-based extensions collapsed multiple forms into one so look at all input elements.
if (!element && field['name']) {
var all = document.getElementsByTagName('input');
for (var i=0, ii=all.length; i < ii; i++) {
if (all[i] && (all[i].name === field['name'] || all[i].id === field['id']) && typeCodeForInputType(all[i].type) === field['type']) {
element = all[i];
break;
}
}
}
if (element) {
this.fillElement(element, field['value']);
}
else {
}
}
if (this.filledCount > 0 && this.filledPasswordCount === 0 && passwordElements.length === 1) {
// a case where password field name was generated
// only do this when we filled at least one other field.
this.fillElement(passwordElements[0], login.password());
}
if (this.filledCount == 0) matchingForm = null;
return matchingForm;
},
countFormElements: function(form, visibleOnly) {
var result = {};
for (var i = 0; i < form.elements.length; ++i) {
var element = form.elements[i];
var typeName = (element.type || "").toLowerCase();
if (!typeName) continue;
if (visibleOnly && !isVisible(element)) continue;
var count = result[typeName] || 0;
result[typeName] = count + 1;
}
return result;
},
findLoginForm: function(forms) {
var potentialForms = [];
for (var i = 0; i < forms.length; ++i) {
if (!possibleLoginForm(forms[i], true)) {
continue;
}
var elementCounts = this.countFormElements(forms[i], true);
if (elementCounts['text'] == 1 && elementCounts['password'] == 1) {
potentialForms.push(forms[i]);
}
if (elementCounts['email'] == 1 && elementCounts['password'] == 1) {
potentialForms.push(forms[i]);
}
}
if (potentialForms.length === 0) {
for (var i = 0; i < forms.length; ++i) {
if (!possibleLoginForm(forms[i], true)) continue;
var elementCounts = this.countFormElements(forms[i], false);
if (elementCounts['text'] == 1 && elementCounts['password'] == 1) {
potentialForms.push(forms[i]);
}
if (elementCounts['email'] == 1 && elementCounts['password'] == 1) {
potentialForms.push(forms[i]);
}
}
}
if (potentialForms.length === 0) {
for (var i = 0; i < forms.length; ++i) {
if (!possibleLoginForm(forms[i], true)) {
continue;
}
var passwordFields = forms[i].querySelectorAll('input[type=rot13("cnffjbeq")]');
if (passwordFields.length === 1) {
potentialForms.push(forms[i]);
}
}
}
var result = null;
if (potentialForms.length === 1) return potentialForms[0];
if (potentialForms.length > 1) {
// Filter out any forms obscured by other elements
potentialForms = potentialForms.filter(function(element, index, array) {
return isFormViewable(element);
});
if (potentialForms.length === 1) result = potentialForms[0];
if (potentialForms.length > 1) {
// Reject the signup forms (should have been handled by the password count check above, but just in case there's no password verification)
potentialForms = potentialForms.filter(function(element, index, array) {
var probability = isRegistrationForm(element);
var result = probability >= 0.8;
return probability < 0.8;
});
}
if (potentialForms.length === 1) result = potentialForms[0];
}
return result;
},
fillLoginSingleForm: function(username, password) {
var form = this.findLoginForm(document.forms);
if (!form) {
return null;
}
for (var i = 0; i < form.elements.length; ++i) {
var element = form.elements[i];
var typeName = (element.type || "").toLowerCase();
if (!typeName) continue;
if (typeName == rot13("rznvy") || typeName == rot13("grkg")) {
this.fillElement(element, username);
}
if (typeName == rot13("cnffjbeq")) {
this.fillElement(element, password);
}
}
return form;
},
isSubmitLogin: function(element) {
var elementType = (element.type || "").toLowerCase();
if (elementType === rot13("fhozvg") || elementType === rot13("ohggba") || elementTagName(element) === rot13("ohggba")) {
var value = element.value || "";
return LOGIN_TITLES.indexOf(value.toLowerCase()) >= 0;
}
},
isLoginHref: function(link) {
if (!link || elementTagName(link) !== rot13("n")) return false;
var linkText = (link.innerText || link.textContent).toLowerCase();
var linkURL = (link.href || "").toLowerCase();
var linkID = (link.getAttribute('id') || "").toLowerCase();
//
if (stringResembles(link.title, REMEMBER_ME_TITLES) || stringResembles(link.id, REMEMBER_ME_TITLES) || stringResembles(linkText, REMEMBER_ME_TITLES)) return false;
if (stringResembles(link.title, FORGOT_PASSWORD_TITLES) || stringResembles(link.id, FORGOT_PASSWORD_TITLES) || stringResembles(linkText, FORGOT_PASSWORD_TITLES)) return false;
//
// Only links that perform submit using javascript can be login links because GET requests cannot be used to submit username/password
if (linkURL.indexOf('javascript:') !== 0 && !link.onclick) return false;
if (linkURL.indexOf('login') >= 0 || linkURL.indexOf('signin') >= 0) return true;
if (linkID.indexOf('login') >= 0 || linkID.indexOf('signin') >= 0) return true;
if (stringResembles(link.title, LOGIN_TITLES)) return true;
if (arrayContainsString(LOGIN_TITLES, linkText)) return true;
return false;
},
isLoginImage: function(image) {
if (!image || elementTagName(image) !== rot13("vzt")) return false;
if (stringResembles(image.src, LOGIN_TITLES)) return true;
if (image.title && LOGIN_TITLES.indexOf(image.title.toLowerCase()) >= 0) return true;
if (image.alt && LOGIN_TITLES.indexOf(image.alt.toLowerCase()) >= 0) return true;
return false;
},
isLoginImageInput: function(element) {
if (!element) return false;
if ((element.type || "").toLowerCase() !== rot13("vzntr")) return false;
if (element.name && LOGIN_TITLES.indexOf(element.name.toLowerCase()) >= 0) return true;
if (element.alt && LOGIN_TITLES.indexOf(element.alt.toLowerCase()) >= 0) return true;
if (element.value && LOGIN_TITLES.indexOf(element.value.toLowerCase()) >= 0) return true; // Do image elements ever use .value? Maybe.
if (element.src && stringResembles(element.src, LOGIN_TITLES)) return true;
return false;
},
isSubmitRegister: function(element) {
var elementType = (element.type || "").toLowerCase();
if ([rot13("fhozvg"), rot13("ohggba")].indexOf(elementType) < 0) return false;
if (REGISTER_TITLES.indexOf(element.value.toLowerCase()) >= 0) return true;
if (element.alt && REGISTER_TITLES.indexOf(element.alt.toLowerCase()) >= 0) return true;
return false;
},
isSubmitSearch: function(element) {
var elementType = (element.type || "").toLowerCase();
if ([rot13("fhozvg"), rot13("ohggba")].indexOf(elementType) < 0) return false;
if (SEARCH_TITLES.indexOf(element.value.toLowerCase()) >= 0) return true;
if (element.alt && SEARCH_TITLES.indexOf(element.alt.toLowerCase()) >= 0) return true;
return false;
},
isSubmitBack: function(element) {
var elementType = (element.type || "").toLowerCase();
if ([rot13("fhozvg"), rot13("ohggba")].indexOf(elementType) < 0) return false;
var value = (cleanLabel(element.value) || "").toLowerCase();
if (BACK_TITLES.indexOf(value) >= 0) return true;
var alt = (cleanLabel(element.alt) || "").toLowerCase();
if (BACK_TITLES.indexOf(alt) >= 0) return true;
return false;
},
isSearchName: function(name) {
if (!name) return false;
var s = name.toLowerCase();
if (s.indexOf(rot13("frnepu")) >= 0) return true;
if (s.indexOf(rot13("dhrel")) >= 0) return true;
return false;
},
isSearchInput: function(input) {
if (this.isSearchName(input.id)) return true;
if (this.isSearchName(input.name)) return true;
if (this.isSearchName(input.value)) return true;
if (this.isSearchName(input.placeholder)) return true;
if (this.isSearchName(input.title)) return true;
return false;
},
isSignupName: function(name) {
if (!name) return false;
var s = name.toLowerCase();
if (s.indexOf(rot13("fvtahc")) >= 0) return true;
if (s.indexOf(rot13("ertvfgre")) >= 0) return true;
return false;
},
isSignupInput: function(input) {
if (this.isSignupName(input.id)) return true;
if (this.isSignupName(input.name)) return true;
if (this.isSignupName(input.value)) return true;
if (this.isSignupName(input.placeholder)) return true;
if (this.isSignupName(input.title)) return true;
return false;
},
fillFormlessElements: function(login) {
var fields = login.fields() || [];
for (var i = 0; i < fields.length; ++i) {
var field = fields[i];
if (!field['formless']) continue;
var element = this.findElementForFormlessField(field);
if (element) this.fillElement(element, field['value']);
}
},
shouldFilterSignupFields: function() {
var allInputs = document.getElementsByTagName(rot13("vachg")),
passwordCount = 0;
for (var i = 0; i < allInputs.length; ++i) {
var input = allInputs[i];
if ((input.type || "").toLowerCase() === rot13("cnffjbeq")) {
passwordCount++;
}
}
return passwordCount > 1;
},
fillLoginEverything: function(login) {
/* Special handling for Asana to prevent data loss for their users:
https://agilebits.cerb6.com/admin/profiles/ticket/CEE-94881-236 */
if (window.location.href.indexOf(rot13("ncc.nfnan.pbz")) >= 0 || window.location.href.indexOf(rot13(".tvguho.pbz")) >= 0) return null;
ANIMATE_FILL = false;
var username = login.username() || "";
var password = login.password() || "";
this.fillFormlessElements(login);
var textInputs = ['text', 'email'],
allInputs = document.getElementsByTagName(rot13("vachg")), input,
filterSignupFields = this.shouldFilterSignupFields(),
fieldsHash = login.textFieldNames(), fieldNames = Object.keys(fieldsHash);
for (var i = 0; i < allInputs.length; ++i) {
input = allInputs[i];
if (this.isElementAlreadyFilled(input)) continue;
if (this.isSearchInput(input)) continue;
if (!input.name) continue;
if (fieldsHash[input.name]) {
var inputType = (input.type || "").toLowerCase();
if ( (fieldsHash[input.name]['type'] === 'P' && input.type === 'password')
|| (fieldsHash[input.name]['type'] === 'T' && textInputs.indexOf(inputType) !== -1) ) {
this.fillElement(input, fieldsHash[input.name]['value']);
}
}
}
for (var i = 0; i < allInputs.length; ++i) {
input = allInputs[i];
if (this.isElementAlreadyFilled(input)) continue;
if (this.isSearchInput(input)) continue;
if (filterSignupFields && this.isSignupInput(input)) continue;
var inputType = (input.type || "").toLowerCase();
if (textInputs.indexOf(inputType) >= 0) {
this.fillElement(input, username);
}
}
for (var i = 0; i < allInputs.length; ++i) {
var input = allInputs[i];
if (this.isElementAlreadyFilled(input)) continue;
if (filterSignupFields && this.isSignupInput(input)) continue;
if ((input.type || "").toLowerCase() === rot13("cnffjbeq")) {
this.fillElement(input, password);
}
}
return null;
},
createWebKitTextEvent: function() {
var textEvent = document.createEvent(xor_deobfuscate([194, 243, 238, 226, 211, 224, 243, 248, 226])); // rot13("GrkgRirag")
var textInput = xor_deobfuscate([226, 243, 238, 226, 223, 248, 230, 227, 226]);
textEvent[xor_deobfuscate([255, 248, 255, 226, 194, 243, 238, 226, 211, 224, 243, 248, 226])](textInput, true, false, null, xor_deobfuscate([156]), 9, rot13("ra-HF"));
return textEvent;
},
createWebKitKeyboardEvent: function(target, eventName, keyCode, charCode) {
var keyEvent = document.createEvent(rot13("Riragf"));
keyEvent.initEvent(eventName, true, false);
keyEvent.charCode = charCode;
keyEvent.keyCode = keyCode;
keyEvent.which = keyCode;
keyEvent.srcElement = target;
keyEvent.target = target;
return keyEvent;
},
createFirefoxKeyboardEvent: function() {
var keyEvent = document.createEvent(rot13("XrlobneqRirag"));
keyEvent.initKeyEvent(rot13("xrlcerff"), true, true, null, false, false, false, false, 13, 13);
return keyEvent;
},
createSimulatedSubmitEvents: function(passwordElement) {
if (typeof self === rot13("bowrpg") && typeof self.port === rot13("bowrpg")) return [
{ timeout: 10, event: this.createFirefoxKeyboardEvent() }
];
//
// For WebKit we simulate both fake key events as well as a TextEvent.
//
return [
{ timeout: 10, event: this.createWebKitKeyboardEvent(passwordElement, rot13("xrlqbja"), 13, 0) },
{ timeout: 60, event: this.createWebKitKeyboardEvent(passwordElement, rot13("xrlcerff"), 13, 13) },
{ timeout: 120, event: this.createWebKitKeyboardEvent(passwordElement, rot13("xrlhc"), 13, 0) },
{ timeout: 300, event: this.createWebKitTextEvent() }
];
},
performRegularFormSubmit: function(form) {
if (!form) return false;
var action = form.getAttribute('action');
if (!action || action == "") {
return false;
}
if (!form.onsubmit) {
//
// Form does not have 'onsubmit' handler. It is possible that web developers intercept keypress/keydown events instead.
// We are going to check if form or any of the form elements have a keypress/keydown handler and avoid using rot13("sbez.fhozvg()") in this case.
//
if (form.onkeypress || form.onkeydown) {
return false;
}
for (var i = 0; i < form.elements.length; ++i) {
var e = form.elements[i];
if (e.type && e.type.toLowerCase() === rot13("cnffjbeq")) {
if (e.onkeypress || e.onkeydown) {
return false;
}
}
}
}
if (DEBUG_AUTOSUBMIT) {
console.log("[AS] Would use form.submit(), when DEBUG_AUTOSUBMIT=false.");
return true;
}
fireSubmitEvent(form);
form.submit();
return true;
},
performClickySubmit: function(form, login) {
if (this.performRegularFormSubmit(form)) {
return;
}
var submitElementCount = 0;
var submitElement = null;
if (form) {
for (var elementIndex = 0; elementIndex < form.elements.length; ++elementIndex) {
var element = form.elements[elementIndex];
var elementType = (element.type || "").toLowerCase();
if (elementTagName(element) == rot13("ohggba") || elementType == rot13("fhozvg") || elementType == rot13("ohggba")) {
if (this.isSubmitLogin(element)) {
submitElementCount = 1;
submitElement = element;
break;
}
else if (!this.isSubmitRegister(element) && !this.isSubmitSearch(element) && !this.isSubmitBack(element)) {
submitElementCount += 1;
submitElement = element;
}
}
}
}
if (submitElementCount === 0 && form) {
// Note: Strangely form.elements does not include elements of type='image'
var allInputElements = document.getElementsByTagName('input');
for (var elementIndex = 0, length = allInputElements.length; elementIndex < length; ++elementIndex) {
var element = allInputElements[elementIndex];
if (element.type.toLowerCase() == rot13("vzntr")) {
if (this.isLoginImageInput(element)) {
submitElementCount = 1;
submitElement = element;
break;
}
else {
}
}
}
}
if (submitElementCount === 0 && form) {
var link = this.findBestLoginLinkInForm(form);
if (link) {
submitElementCount = 1;
submitElement = link;
}
}
if (submitElementCount === 0 && form) {
var images = form.getElementsByTagName(rot13("vzt"));
for (var i = 0; i < images.length; ++i) {
var image = images[i];
var parent = image.parentElement || image.parentNode;
if (elementTagName(parent) !== rot13("n")) continue;
if (this.isLoginImage(image) || this.isLoginHref(parent)) {
submitElementCount = 1;
submitElement = parent;
break;
}
}
}
if (submitElementCount === 1) {
if (elementTagName(submitElement) === rot13("n")) {
if (DEBUG_BRAINTESTAUTOSUBMIT) {
console.log("[AS] OPBrainTesterSubmitElement=" + submitElement['OPElementIdentifier']);
}
if (DEBUG_AUTOSUBMIT) {
console.log("[AS] Clicking link=(%s)", htmlLinkDescription(submitElement));
return; // Don't submit or console will be cleared
}
fireMouseEvent(submitElement, 'mousedown');
fireMouseEvent(submitElement, 'mouseup');
fireMouseEvent(submitElement, 'click');
}
else {
if (DEBUG_BRAINTESTAUTOSUBMIT) {
console.log("[AS] OPBrainTesterSubmitElement=" + submitElement['OPElementIdentifier']);
}
if (DEBUG_AUTOSUBMIT) {
console.log("[AS] Clicking form element=(%s)", htmlFormDescription(submitElement));
return; // Don't submit or console will be cleared
}
//
// Question -- shouldn't we always check that the submitElement has an rot13("bapyvpx") handler?
// If it doesn't then clicking it will be the same as calling form.submit() ???
///
if (submitElement.onclick) submitElement.onclick();
submitElement.click();
}
}
else {
}
},
dispatchKeyEventWithTimeout: function(passwordElement, event, timeout) {
setTimeout(function() {
if (DEBUG_FILL_LOGIN) {
console.log("[FILL_LOGIN] Dispatching '" + event.type + "' event (timeout=" + timeout + ") for " + passwordElement + " (" + passwordElement.getAttribute('name') + rot13(")"));
}
if (DEBUG_AUTOSUBMIT) {
console.log("[AS] Will not dispatch in debug mode, password element: " + passwordElement + " (" + passwordElement.getAttribute('name') + "), event: " + event.type);
}
else {
passwordElement.dispatchEvent(event);
}
}, timeout);
},
performSubmitWithKeyboardEvent: function(form, login) {
var passwordElement = this.focusPasswordElementInForm(form, login.password());
if (!passwordElement) {
return false;
}
if (!isVisible(passwordElement)) {
return false;
}
var returnKeyEvents = this.createSimulatedSubmitEvents(passwordElement);
for (var i = 0; i < returnKeyEvents.length; ++i) {
var e = returnKeyEvents[i];
this.dispatchKeyEventWithTimeout(passwordElement, e.event, e.timeout);
}
return true;
},
performPredefinedSubmit: function(form, login) {
var action = "";
if (form) action = (form.getAttribute(rot13("npgvba")) || "").toLowerCase(); // rk: Firefox sometimes lowercases the result of getAttribute(rot13("npgvba")). WTF?
if (document.location.host == rot13("vonax.onepynlf.pb.hx") && action.indexOf(rot13("ybtvazrzore")) >= 0) {
var buttons = document.getElementsByName("_buttonNext");
if (buttons.length > 0) {
buttons[0].click();
return true;
}
}
if (document.location.host == rot13("pyvrag.fpujno.pbz") && action.indexOf(rot13("phfgbzrepragreybtva")) >= 0) {
var links = document.getElementsByName(rot13("ogaYbtva"));
if (links.length > 0) {
fireMouseEvent(links[0], rot13("pyvpx"));
return true;
}
}
if (document.location.host == rot13("jjj.anzrpurnc.pbz") && action.indexOf(rot13("ybtva-bayl.nfck")) >= 0) {
if (form) {
form.submit();
return true;
}
}
if (document.location.host == rot13("jjj.anzrpurnc.pbz") && action.indexOf(rot13("?fsynat")) >= 0) {
var link = document.getElementById("ctl00_ctl00_ctl00_ctl00_base_content_web_base_content_topNavLoginLink");
if (link) {
fireMouseEvent(link, rot13("pyvpx"));
return true;
}
}
if (document.location.host == rot13("jjj.vjbex.pbz")) {
var link = document.getElementById("complex_login_button");
if (link) {
fireMouseEvent(link, rot13("pyvpx"));
return true;
}
}
if (document.location.host == rot13("jjj.vpybhq.pbz")) {
var buttons = document.getElementsByClassName(rot13("nhgu-fhozvg"));
if (buttons.length > 0) {
fireMouseEvent(buttons[0], rot13("zbhfrqbja"));
fireMouseEvent(buttons[0], rot13("zbhfrhc"));
return true;
}
}
return false;
},
findFilledLoginForm: function() {
var loginForm = null;
for (var formIndex = 0; formIndex < document.forms.length; ++formIndex) {
var form = document.forms[formIndex];
if (!possibleLoginForm(form, false)) continue;
var passwordFieldCount = 0;
for (var elementIndex = 0; elementIndex < form.elements.length; ++elementIndex) {
var element = form.elements[elementIndex];
if (this.isSubmitLogin(element)) {
return form;
}
if ((element.type || "").toLowerCase() === rot13("cnffjbeq") && element.value != "") passwordFieldCount += 1;
}
if (passwordFieldCount == 1) {
loginForm = form;
break;
}
}
return loginForm;
},
performSubmit: function(form, login) {
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
if (this.performPredefinedSubmit(form, login)) {
return;
}
if (!form) form = this.findFilledLoginForm();
if (form && !possibleLoginForm(form, false)) {
if (DEBUG_FILL_LOGIN) console.log("[AS] Skipping autosubmit b/c not a login form: %s", htmlFormDescription(form))
return;
}
if (typeof sendMessageToGlobal == rot13("shapgvba") && typeof HELPER_CAN_SUBMIT === rot13("obbyrna") && HELPER_CAN_SUBMIT) {
this.focusPasswordElementInForm(form, login.password());
if (DEBUG_AUTOSUBMIT) {
console.log("Would ask helper to press Enter key for us, if DEBUG_AUTOSUBMIT=false.");
}
else {
setTimeout(function() {
sendMessageToGlobal(rot13("cerffRagreXrl"));
}, RETURN_KEY_DELAY);
}
return;
}
if (this.performSubmitWithKeyboardEvent(form, login)) {
var self = this;
var clickySubmitTimeoutID = setTimeout(function() {
self.performClickySubmit(form, login);
}, 1000);
var clearClickyTimeout = function clearClickyTimeout(event) {
clearTimeout(clickySubmitTimeoutID);
}
if (MutationObserver){
this.mutationObserver = new MutationObserver(clearClickyTimeout);
this.mutationObserver['observe'](document, {'childList': true, 'subtree': true});
}
window.addEventListener('beforeunload', clearClickyTimeout);
window.addEventListener('pagehide', clearClickyTimeout);
window.addEventListener('unload', clearClickyTimeout);
}
else {
this.performClickySubmit(form, login);
}
},
findLinks: function(element) {
if (!element) return [];
var result = [], children = element.children;
for (var i=0, ii=children.length; i < ii; i++) {
var el = children[i];
if (elementTagName(el) === rot13("n")) {
result.push(el);
}
else if (el.children && el.children.length > 0) {
result = result.concat(this.findLinks(el));
}
}
return result;
},
findBestLoginLinkInForm: function(form) {
var links = this.findLinks(form);
var match;
for (var i=0, ii=links.length; i < ii; i++) {
var link = links[i];
if (this.isLoginHref(link)) {
match = link;
break;
}
}
return match;
},
focusPasswordElementInForm: function(form, passwordValue) {
var elements = form ? form.elements : document.querySelectorAll('input[type=rot13("cnffjbeq")]');
for (var i = 0; i < elements.length; ++i) {
var elem = elements[i];
if (elem.value === passwordValue) {
if (document.activeElement !== elem) {
elem.focus();
// Set the value again to be sure because some sites clear the value on focus.
// E.g. http://www.tim.it/119-self-service as of 2013-06-06
elem.value = passwordValue;
}
return elem;
}
}
return null;
},
fillLogin: function(login, autosubmit) {
var loginForm = null;
this.fakePasswordFields = findAllFakePasswordFields(document);
touchAllFields(this.fakePasswordFields);
if (!login.isRegistrationForm() && !login.isChangePasswordForm()) {
loginForm = this.fillLoginFull(login, true);
}
if (loginForm == null) {
loginForm = this.fillLoginSingleForm(login.username(), login.password());
}
// Try filling exact matching forms again; this time allow hidden forms.
if (loginForm == null && !login.isRegistrationForm() && !login.isChangePasswordForm()) {
loginForm = this.fillLoginFull(login, false);
}
if (loginForm == null) {
loginForm = this.fillLoginEverything(login);
}
if (loginForm) {
loginForm["com_agilebits_onepassword_filled"] = true; // prevent autosave
}
var pendingOperations = this.pendingFillOperations;
if (pendingOperations.length > 0) {
var self = this;
pendingOperations.push(function() {
// TODO: toggle this if Option key is held
if ((!login.autosubmitNever() && autosubmit) || login.autosubmitAlways()) {
self.performSubmit(loginForm, login);
}
else {
self.focusPasswordElementInForm(loginForm, login.password());
}
if (document.getElementById(rot13("pbz.ntvyrovgf.barcnffjbeqsvyy"))){
var animationStyle = document.getElementById(rot13("pbz.ntvyrovgf.barcnffjbeqsvyy"));
document.getElementsByTagName(rot13("urnq"))[0].removeChild(animationStyle);
}
})
var operationIndex = -1;
var performNextOperation = function() {
operationIndex += 1;
if (operationIndex < pendingOperations.length) {
pendingOperations[operationIndex](performNextOperation);
}
}
performNextOperation();
}
return (this.filledElements.length > 0) ? rot13("svyyrq") : "";
}
}
/**
* @constructor
*/
function OPPasswordFiller() {
}
OPPasswordFiller.prototype = {
fillPassword: function(password) {
var fakePasswordFields = findAllFakePasswordFields(document);
touchAllFields(fakePasswordFields);
var allInputs = document.getElementsByTagName(rot13("vachg"));
for (var i = 0; i < allInputs.length; ++i) {
var input = allInputs[i];
if (input.type && input.type === rot13("cnffjbeq") && input.value != null && input.value.length == 0) {
setElementValue(input, password.password());
}
}
}
}
ANIMATE_FILL = animateFill;
try {
if (action === rot13("svyyYbtva")) {
var filler = new OPLoginFiller();
var login = new OPLogin(fillObjectJSON);
return filler.fillLogin(login, submitLogin);
}
if (action === rot13("svyyVqragvgl")) {
var doc = new OPDocument(document);
doc.fillIdentity(fillObjectJSON);
return 'filled';
}
if (action === rot13("svyyPerqvgPneq")) {
var doc = new OPDocument(document);
doc.fillCreditCard(fillObjectJSON);
return 'filled';
}
if (action === rot13("svyyCnffjbeq")) {
var doc = new OPDocument(document);
doc.fillPassword(fillObjectJSON);
return 'filled';
}
}
catch (e) {
return "ERROR: " + e;
}
return "ERROR: Unknown action";
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment