Page 1 of 2

Some troubles with add-ons?

Posted: Fri Mar 01, 2013 3:20 pm
by ChrissyToph
Hi there,

I absolutely love NoScript and, for the most part, is trouble-free except there's two add-ons it doesn't seem to like. First of all, I have the Nectar toolbar installed and, when I visit a website like eBay where I can redeem points, the red bar that normally appears with text telling me to collect points is just blank and has no text Image
This is not hugely problematic but would be great if someone knew a solution.

The second add-on it doesn't like is slightly more problematic for me. I have an add-on installed called the GfK Internet Monitor, whereby they invite me to take part in surveys and such from monitoring my internet usage. When I open my browser, what it normally should do is bring up a pop-up box with the software's name and logo, etc. and also an option to choose my 'user name' (i.e. whether I'm myself, or a guest and not the usual user of the laptop, etc.). Ever since installing No Script, I've noticed that the option to choose a user name has gone and is now just a blank box Image.
Even though technically the add-on is still (partially) 'working' and installed on my laptop, I've been emailed by the Gfk team who tell me that it comes up on their system that I'm inactive with the internet monitor.

I've tried looking for solutions myself by enabling things like nectar and GfK's website but that doesn't seem to help. Does anyone have any ideas? Really appreciate any help at all!

Re: Some troubles with add-ons?

Posted: Fri Mar 01, 2013 11:43 pm
by Thrawn
What sites are showing up on NoScript's menu? Or failing that, the Recently Blocked Sites submenu? If NoScript is blocking something, then it should show up.

If there's nothing, then please look in the Error Console (Ctrl+Shift+J), especially the Info and Errors sections (not Warnings), and post any NoScript-related messages here.

Re: Some troubles with add-ons?

Posted: Sat Mar 02, 2013 8:35 pm
by ChrissyToph
Hi Thrawn,

Nothing shows up on the NoScript menu or Recently Blocked Sites submenu. I opened up the Error Console (didn't know that existed!) and it showed this (I've print screened cause I couldn't find a way to copy and paste the messages):

Image

Image

Re: Some troubles with add-ons?

Posted: Sun Mar 03, 2013 5:49 pm
by access2godzilla
ChrissyToph wrote:I've tried looking for solutions myself by enabling things like nectar and GfK's website but that doesn't seem to help.
First of all, why do you need those things at all? I don't know about you, but in my personal experience, the only things third-party toolbars and addons do is to invade your privacy and claim real estate on the screen.

Please post the screenshot of the Noscript menu, that might help, though probably allowing freecause.com might help for the toolbar, though they have some issues with the scripts on their side also (lone comment closing pair "/*!", in the 2nd shot you posted).

Re: Some troubles with add-ons?

Posted: Mon Mar 04, 2013 6:25 pm
by ChrissyToph
access2godzilla wrote:First of all, why do you need those things at all? I don't know about you, but in my personal experience, the only things third-party toolbars and addons do is to invade your privacy and claim real estate on the screen.

Please post the screenshot of the Noscript menu, that might help, though probably allowing freecause.com might help for the toolbar, though they have some issues with the scripts on their side also (lone comment closing pair "/*!", in the 2nd shot you posted).

Using both of those toolbars/add-ons give me financial (albeit small) benefits.

Wait, lemme just clarify something: when we say 'Noscript menu', we're referring to this?:

Image


And allowing freecause.com didn't have any effect :(

Re: Some troubles with add-ons?

Posted: Mon Mar 04, 2013 6:28 pm
by ChrissyToph
Sorry, I don't know why Imageshack cut off my image but here's a direct link to it:

http://img688.imageshack.us/img688/1794/noscriptv.png

Re: Some troubles with add-ons?

Posted: Mon Mar 04, 2013 9:27 pm
by Thrawn
Well, your screenshots of the Error Console clearly show some errors related to freecause.com, which presumably is Nectar...are there any other sites visible on the menu when you go to a site like eBay, rather than Google?

Can you try this in a clean profile with only NoScript and Nectar installed?

Re: Some troubles with add-ons?

Posted: Sun Mar 10, 2013 1:20 pm
by ChrissyToph
Thrawn wrote:Well, your screenshots of the Error Console clearly show some errors related to freecause.com, which presumably is Nectar...are there any other sites visible on the menu when you go to a site like eBay, rather than Google?

Can you try this in a clean profile with only NoScript and Nectar installed?

Ah, the Nectar toolbar works now. I enabled both freecause.com and http://client.freecause.com and now it's fine.

I used a clean profile with just GFK and NoScript installed and this came up in the error console:

Image
Image

Re: Some troubles with add-ons?

Posted: Sun Mar 10, 2013 7:48 pm
by Thrawn
Looks like GFK Internet Monitor is running something locally, in which case, you're probably running into ABE. Strange that there were no ABE-related messages in the Error Console...can you look again for them?

Also, try adding this to Options-Advanced-ABE-SYSTEM, above the built-in rule:

Code: Select all

Site http://127.0.0.1:9768
Accept GET

Re: Some troubles with add-ons?

Posted: Mon Mar 11, 2013 5:57 pm
by ChrissyToph
Thrawn wrote:Looks like GFK Internet Monitor is running something locally, in which case, you're probably running into ABE. Strange that there were no ABE-related messages in the Error Console...can you look again for them?

Also, try adding this to Options-Advanced-ABE-SYSTEM, above the built-in rule:

Code: Select all

Site http://127.0.0.1:9768
Accept GET
I added the built-in rule but didn't seem to do anything. Not sure if it's any help but I found this when I opened the ABE-system section:

# Prevent Internet sites from requesting LAN resources.
Site LOCAL
Accept from LOCAL
Deny

^Is that what might be affecting the internet monitor?


As for the error console - it came up with this super massive thing in the 'message' tab and the forum won't let me post it saying I triggered the 'anti spam' feature... so I don't know what to do :S

Re: Some troubles with add-ons?

Posted: Mon Mar 11, 2013 10:15 pm
by Thrawn
ChrissyToph wrote: ^Is that what might be affecting the internet monitor?
Yes, but don't take it out :). It's there for a good reason. Let's write a proper, specific exception to it.
As for the error console - it came up with this super massive thing in the 'message' tab and the forum won't let me post it saying I triggered the 'anti spam' feature... so I don't know what to do :S
That happens a lot. Please send the error message to one of the moderators via private message (you should be able to right-click on the message and select Copy), and we can post it for you.

Re: Some troubles with add-ons?

Posted: Thu Mar 14, 2013 8:37 pm
by ChrissyToph
Thrawn wrote:
ChrissyToph wrote: ^Is that what might be affecting the internet monitor?
Yes, but don't take it out :). It's there for a good reason. Let's write a proper, specific exception to it.
As for the error console - it came up with this super massive thing in the 'message' tab and the forum won't let me post it saying I triggered the 'anti spam' feature... so I don't know what to do :S
That happens a lot. Please send the error message to one of the moderators via private message (you should be able to right-click on the message and select Copy), and we can post it for you.

Do I message you Thrawn?

Re: Some troubles with add-ons?

Posted: Fri Mar 15, 2013 5:22 am
by Thrawn
ChrissyToph wrote: Do I message you Thrawn?
Sure, I'll do :).

Re: Some troubles with add-ons?

Posted: Tue Mar 19, 2013 5:28 pm
by ChrissyToph
Sorry about my late reply - I've sent the messages (had to split it into 3 bits) now!

Re: Some troubles with add-ons?

Posted: Mon Apr 01, 2013 12:35 pm
by Thrawn
OK, so >90% of this looks like just a dump of the GFK Internet Monitor script, but here goes:

Code: Select all

Error: this.docShell is null
Source File: chrome://global/content/bindings/browser.xml
Line: 323


Warning: Unknown property 'align-self'.  Declaration dropped.
Source File: resource://gre-resources/ua.css
Line: 45
Warning: Unknown property 'order'.  Declaration dropped.
Source File: resource://gre-resources/ua.css
Line: 46
Warning: XUL box for _moz_generated_content_after element contained an inline #text child, forcing all its children to be wrapped in a block.
Source File: chrome://browser/content/browser.xul
Line: 0
Warning: Expected color but found 'top'.  Error in parsing value for 'background-image'.  Declaration dropped.
Source File: about:home
Line: 0
Warning: Expected color but found 'top'.  Error in parsing value for 'background-image'.  Declaration dropped.
Source File: about:home
Line: 0

Messages:
Could not read chrome manifest 'file:///C:/Program%20Files%20(x86)/Mozilla%20Firefox/extensions/%7B972ce4c6-7e08-4474-a285-3208198ce6fd%7D/chrome.manifest'.
Using Components.utils.import for global singleton
Imported
Registered for Extension events
Local Tracklet URL=file://C:/Program%20Files%20(x86)/GfK%20Internet-Monitor//tracklet.js
Successful load of local tracklet
/*ScriptletVersion: 270*/
var scriptlet_version = '270';
var component_versions = {"config_version":"69","helper":{"Helper":"103","CustomEventHelper":"104","Logger":"112"},"components":{"GfKBase":"105","GoogleInstantTracker":"106","WWSCookieTracker":"107","PageCookieTracker":"108","Fixes":"109","DomainCookieTracker":"110","GoogleSERPReferrerTracking":"111","ViewTimeMeasurement":"113","GlobalConfiguration":"114","ChromeFixes":"115"}};

//===================================================================
// UCTWinScriptlets: tracklet/helper/Helper.js
//===================================================================

/*jsl:declare Base64 */
/*jsl:declare JSON */

// Return a boolean value telling whether // the first argument is an Array object.

/**
* Encodes a given object to JSON
* @function
* @param object obj The object to be JSON encoded
* @returns string JSON string representing the object
*/
function json_encode(obj) {
    var json = null;
    if (JSON.stringify) {
        json = JSON.stringify(obj);
    } else if (JSON.toString) {
        json = JSON.toString(obj);
    }
    return json;
}

/**
* Converts a given object to JSON an encodes the result to Base64
* @function
* @param object obj The object to be JSON encoded
* @returns string Base64 string representing the object
*/
function base64_json_encode(obj) {
   return Base64.encode(json_encode(obj));
}

/**
* Checks wether an object is an array
* @function
* @param object obj The object to be checked
* @returns boolean True if the object is an array
* @example
* var test = new Array();
* isArray(test);
*/
function isArray() {
  if (typeof arguments[0] == 'object') { 
    var criterion = arguments[0].constructor.toString().match(/array/i);
    return (criterion !== null); 
  }
  return false;
}

// Hilfsfunktion zum browserspezifischen Aufbau einer XHR Verbindung zu AdSimulator und serverseitigem Logging
/**
* Creates a browser independent XMLHTTPRequest
* @function
* @returns object XMLHttpRequest object
* @example
* var xhr=CreateXmlHttp();
* if (xhr) {
*   xhr.open('GET', "http://example.de/test.php");
*   xhr.send(null);
* }
*/
function CreateXmlHttp() {
  if (GacelaStorageService.getStatic("BrowserType")=="Chrome") {
   // This creates a simplified XMLHttpRequest Object which does not support all features, but can do Cross-Domain Request on Chrome
   return createSimpleXMLHTTPRequest();
  }
  var xmlhttp = false;
  var hasXMLHttpRequest = false;
  try {
    if (XMLHttpRequest) hasXMLHttpRequest=true;
  }
  catch (err) {
    hasXMLHttpRequest = false;
  }
  if (hasXMLHttpRequest) {
    xmlhttp = new XMLHttpRequest();
  }
  else if (ActiveXObject) {// code for IE
    try {
      xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
    }
    catch (err) {
      try {
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
      }
      catch (err2) {
        xmlhttp=false;
      }
    }
  }
  return xmlhttp;
}


/**
* Sends data to an URL. Automatically checks if a & or a ? is needed when concatenating the extendedparams to the URL. <br />
* Adds a parameter <b>ts</b> to the end, which contains a timestamp to prevent caching effects. The answer of the server is not checked.
* @function
* @param string url The URL where the params should be sent to
* @param string extendedparams A string of GET parameters
* @returns boolean True if request has been sent, otherwise False
* @example
* var url = "http:example.de/test.php?id=12345";
* var extendedparams = "test=daten&daten=mist";
* BlindSend(url, extendedparams);
*/
function BlindSend(url, extendedparams){
  try{
    var glue = '?';
    if(url.indexOf('?') >= 0) glue = '&';
    var target = url + glue + extendedparams + "&ts=" + new Date().getTime();
    var xhr=CreateXmlHttp();
    if (xhr) {
      xhr.open('GET', target);
      xhr.onreadystatechange = function(){};
      xhr.send(null);
      return true;
    }
    return false;
  }
  catch(e){
    return false;
  }
}


/**
* Creates HTML Nodes from a JSON Object
* @param object doc The document object.
* @param object value The JSON object to create the node of.
* @returns object HTML Node
*/
function CreateNodeFromJSON(doc, value){
  //create and return text node
  if(value.tag == "#text") return doc.createTextNode(value.value);

  //create node with tag
  var node = doc.createElement(value.tag);
  if(node === null || typeof(node) == 'undefined'){
    Logger.log("ERROR", "CreateNodeFromJSON: Unable to create node for tag " + value.tag);
  }
  if(typeof(value.attributes) != 'undefined'){
    for(var i = 0; i < value.attributes.length; i++){
      try{
        node.setAttribute(value.attributes[i].name, value.attributes[i].value);
      }
      catch(e){
        Logger.log("ERROR", "CreateNodeFromJSON: Unable to set attribute " + value.attributes[i].name + "=" + value.attributes[i].value + " for tag " + value.tag);
      }
    }
  }
  if(typeof(value.styles) != 'undefined'){
    for(var j = 0; j < value.styles.length; j++){
      try{
        node.style[value.styles[j].name] = value.styles[j].value;
      }
      catch(e){
        Logger.log("ERROR", "CreateNodeFromJSON: Unable to set style " + value.styles[j].name + "=" + value.styles[j].value + " for tag " + value.tag);
      }
    }
  }
  if(typeof(value.children) != 'undefined'){
    for(var k = 0; k < value.children.length; k++){
      try{
        var child = this.CreateNodeFromJSON(doc, value.children[k]);
        node.appendChild(child);
      }
      catch(e){
        Logger.log("ERROR", "CreateNodeFromJSON: Unable to set childnode " + child + " with tag " + value.children[k].tag + " in tag " + value.tag);
      }
    }
  }
  try{
    if (typeof(value.className) != 'undefined') {
      node.className = value.className;
    }
  }
  catch(e){
    Logger.log("ERROR", "CreateNodeFromJSON: Unable to set className " + value.className + " in tag " + value.tag);
  }
  try{
    if (typeof(value.innerHTML) != 'undefined') {
      node.innerHTML = value.innerHTML;
    }
  }
  catch(e){
    Logger.log("ERROR", "CreateNodeFromJSON: Unable to set innerHTML " + value.innerHTML + " in tag " + value.tag);
  }
  return node;
}

/**
* Compares two version numbers. <br />
* <font color='red'>Only works for Versions which consist of 2 numbers (e.g. <b>1.1</b> <b>10.2</b>)</font>
* @function
* @param string version1 First version number to be compared
* @param string version2 Second version number to be compared
* @returns int Returns <b>1</b> if version1 is bigger and <b>-1</b> if version2 is bigger. Returns <b>0</b> if version numbers are equal
* @example
* if(CompareVersion(curver, '10.2') == 1 || CompareVersion(curver, '10.3') < 1){
*   //do something
* }
*/
function CompareVersion(version1, version2){
    if(!version1){
      return -1;
    }
    if(!version2){
      return 1;
    }
    if (version1==version2) return 0;
    var versionparts1 = version1.split('.');
    var versionparts2 = version2.split('.');
    var i = 0;
    try {
      for(; i < versionparts1.length; i++){
        var v1=parseInt(versionparts1[i], 10);
        var v2=parseInt(versionparts2[i], 10);
        if(!v2){
          return 1;
        }
        if(v1 > v2){
          return 1;
        }
        if(v1 < v2){
          return -1;
        }
      }
    }
    catch(E) {
      return 1;
    }
    if(versionparts1.length < versionparts2.length){
      return -1;
    }
    return 0;
  }

//===================================================================
// UCTWinScriptlets: tracklet/helper/CustomEventHelper.js
//===================================================================

/*jsl:option explicit*/
/*jsl:declare GacelaTrackingService*/
/*jsl:declare Base64*/
/*jsl:declare base64_json_encode */
/*global Base64, GacelaTrackingService*/


/** 
* @class Provides a method to send CustomEvents
* @author Team Dev
* @dependency tracklet Helper 15
*/
var CustomEventHelper = {
   /**
   * Creates a CustomEvent. The data from the 4 parameters will be converted to a CustomEvent and the complete CustomEvent is logged.
   * @function
   * @param event event The Gacela Event whose Id and timestamp should be sent
   * @param string key A key which is used for indexing of the CustomEvent
   * @param string type The type of the CustomEvent
   * @param object messageObject The messageObject which should be sent. It is automatically converted to JSON and Base64 encoded.
   */
   sendCustomevent : function (event, key, type, messageObject) {
      var message, entry;
      message = base64_json_encode(messageObject);
      entry = '<customevent ';
      entry += 'eid="' + GacelaTrackingService.eventIDToString(event.eid) + '" ';
      entry += 'timestamp="' + event.timestamp + '" ';
      entry += 'type="' + GacelaTrackingService.makeAttributeValid(type) + '" ';
      entry += 'key="' + GacelaTrackingService.makeAttributeValid(key) + '" ';
      entry += '>' + message + '</customevent>';
      GacelaTrackingService.logData(entry);
   }
};

//===================================================================
// UCTWinScriptlets: tracklet/components/GfKBase.js
//===================================================================

/*jsl:option explicit*/
/*jsl:declare GacelaStorageService*/
/*jsl:declare GacelaQuestionnaireService*/
/*jsl:declare GacelaEventService*/
/*jsl:declare GacelaTrackingService*/
/*jsl:declare GacelaNavigateService*/
/*jsl:declare GacelaStatusService*/
/*jsl:declare Base64*/
/*jsl:declare json_encode */
/*jsl:declare base64_json_encode */
/*jsl:declare GacelaWindow*/
/*jsl:declare ActiveXObject*/
/*jsl:declare XMLHttpRequest*/
/*jsl:declare CompareVersion*/
/*jsl:declare persons*/

/*global GacelaStorageService, GacelaStatusService, GacelaTrackingService, GacelaNavigateService, CompareVersion, GacelaEventService, GacelaQuestionnaireService, Logger, alert, persons*/

//======================
// regular GfK Internet-Monitor behaviour
//======================

/**
* Controls the default behaviour of the addon. Handles the authentication routine for Firefox and Microsoft Internet Explorer.
*
* @class Regular GfK Internet-Monitor behaviour
* @author Team Dev
* @public
* @param object configIn The configuration object for GfKBase Component
* @param object personIn The persons object
* @dependency tracklet Helper 15
* @dependency tracklet Logger 15
* @dependency updatescript ConfigureBrowserHostLogin 12
*/
function GfKBase(configIn, personsIn) {
   "use strict";
   this.config = configIn;
   this.persons = personsIn;
   this.preventLoginDialog = false;
   this.authurl = 'http://127.0.0.1:9768/deliver/dialogs/UserSelectionDialog.html';
   this.browserWindowCount = GacelaNavigateService.getBrowserWindowCount();
   this.activeSSLException = false;

   /**
   * Checks if an given registry key exists and if it contains <b>"Yes"</b>.
   * @function
   * @private   
   * @param string configName Name of the registry key
   * @param bool [def] Value to be returned if key is not defined.
   * @returns {bool|string} As default returns a bool, if specified returns <b>def</b> in case the Key not exists or
   * not contains "Yes"
   */
   this.checkOption = function (configName, def) {
      var flag;
      if (!def) {
         def = false;
      }
      try {
         flag = GacelaStorageService.getStatic(configName);
         if (flag === null || typeof (flag) === "undefined") {
            return def;
         }
         return (flag === "Yes");
      } catch (e) {
         return def;
      }
   };

   /**
   * Sets the GacelaTrackingMode.
   * @private
   * @function
   * @param event e NavigateComplete event object
   */
   this.startTracking = function (e) {
      var user_id, trackingmode, ssltrackingmode, index;
      user_id = this.updateTrackingTags(e);
      GacelaStatusService.setState('hidden');
      GacelaStatusService.allowDisable(false);
      trackingmode = this.config.guest_trackingmode;
      ssltrackingmode = this.config.guest_ssl_trackingmode;
      if (this.getTrack(user_id)) {
         trackingmode = this.config.default_trackingmode;
         ssltrackingmode = this.config.default_ssl_trackingmode;
         if (this.config.default_ssl_trackingmode_exceptions) {
            if (e.url) {
               if (e.url.indexOf('https://') !== 0) {
                  this.activeSSLException = false;
               } else {
                  for (index = 0; index < this.config.default_ssl_trackingmode_exceptions.length; index += 1) {
                     if (e.url.match(this.config.default_ssl_trackingmode_exceptions[index].white_regex)) {
                        this.activeSSLException = index;
                        ssltrackingmode = this.config.default_ssl_trackingmode_exceptions[index].mode;
                     }
                  }
               }
            } else {
               if (this.activeSSLException !== false) {
                  ssltrackingmode = this.config.default_ssl_trackingmode_exceptions[this.activeSSLException].mode;
               }
            }
         }
      }
      GacelaTrackingService.setTrackingMode(trackingmode);
      GacelaTrackingService.setSSLTrackingMode(ssltrackingmode);
      this.updateAboutUrl(e);
   };

   /**
   * Sets the TrackingTags sent with each PageImpression.
   * @private
   * @function
   * @param event e NavigateComplete or UserChanged event object
   * @returns string user_id ID of the current authenticated user
   */
   this.updateTrackingTags = function (e) {
      var user_id, tags;
      user_id = this.getCurrentUserId(e);
      tags = {};
      tags.household_id = GacelaStorageService.getStatic('GacelaPanelId');
      tags.user_id = user_id;
      tags.user_id_mapping = GacelaStorageService.get('UserIDMapping');
      if (!tags.user_id_mapping) {
         tags.user_id_mapping = "undefined";
      }
      tags.install_id = GacelaStorageService.getStatic('GacelaInstallId');
      tags.win_version = GacelaStorageService.getStatic('WinVersion');
      tags.addon_version = GacelaStorageService.getStatic('GacelaExtensionVersion');
      tags.tracklet_version = GacelaStorageService.getStatic('GacelaTrackletVersion');
      tags.snifflet_version = GacelaStorageService.getStatic('GacelaSniffletVersion');
      tags.updatelet_version = GacelaStorageService.getStatic('GacelaUpdateletVersion');
      tags.browser_version = GacelaStorageService.getStatic('BrowserType') + ' ' + GacelaStorageService.getStatic('BrowserVersion');
      GacelaTrackingService.setTrackingTags(tags);
      return user_id;
   };

   /**
   * Creates the URL to call the about dialog with all needed parameters.
   * @private
   * @function
   * @param event e UserChanged event object   
   */
   this.updateAboutUrl = function (e) {
      var bitmaskConverter, user_id, abouturl, aboutwidth, aboutheight, index, trackingtext, issimpleabout, multiple_user_id, multiple_user_names, userMapping, userMap, a, b, activeUserID, key, active_user_id, currentversion, name;
      /**
      * Class to split the 32bit Bitmask-Userid to it's single informations.
      * @class Class which handles the user id when it's encoded in the bitmask
      * @augments GfKBase
      * @private
      * @author Team Dev      
      */
      bitmaskConverter = {
         /**
         * @property Array users An array containing all logged in user ids from the Bitmask
         */
         users: [],
         MAX_USERS: 16,
         /**
         * @property string guest_gender The gender of the guest (Only set if the bitmask contains a guest user, otherwise undefined)
         */
         guest_gender: undefined,
         /**
         * @property int guest_age The age of the guest (Only set if the bitmask contains a guest user, otherwise undefined)
         */
         guest_age: undefined,
         user_count: 0,
         /**
         * This function fills the properties of this class with informations.
         * @function
         * @param int bitmask The bitmask containing the user informations
         * @param object config Configuration object of GfKBase component
         */
         convertBack: function (bitmask, config) {
            var binaryCount, age, index;
            for (index = 1; index <= this.MAX_USERS; index += 1) {
               if (bitmask & (1 << index)) {
                  this.users[this.users.length] = index;
               }
            }
            if (bitmask & (1 << 29)) {
               this.users[this.users.length] = 99;
               if (bitmask & (1 << 17)) {
                  this.guest_gender = config.text_gender.male;
               } else {
                  this.guest_gender = config.text_gender.female;
               }
               age = 0;
               binaryCount = 1;
               for (index = 18; index <= 24; index += 1) {
                  if (bitmask & (1 << index)) {
                     age += binaryCount;
                  }
                  binaryCount *= 2;
               }
               this.guest_age = age;
            }
         }
      };

      user_id = GacelaStorageService.get("CurrentAuthenticatedUser");
      aboutwidth = 324;
      aboutheight = 280;
      trackingtext = this.config.text_contacts;
      if (this.getTrack(user_id)) {
         if (GacelaNavigateService.currentURL !== null && typeof (GacelaNavigateService.currentURL) !== "undefined" && !GacelaNavigateService.currentURL.match("https:.*")) {
            trackingtext = this.config.text_contacts_with_ads;
         }
      }
      issimpleabout = (user_id == 98);
      if (issimpleabout) {
         abouturl = "http://127.0.0.1:9768/delivertemplate/dialogs/SimpleAbout.html?ts=" + new Date().getTime();
         aboutwidth = GacelaStorageService.getStatic("SimpleAboutWidth");
         aboutheight = GacelaStorageService.getStatic("SimpleAboutHeight");
      } else {
         abouturl = "http://127.0.0.1:9768/delivertemplate/dialogs/About.html?ts=" + new Date().getTime();
         if (this.checkOption("AllowConcurrentLogins")) {
            bitmaskConverter.convertBack(user_id, this.config);
            multiple_user_id = "";
            multiple_user_names = "";
            userMapping = "";
            userMap = {};
            a = 0;
            b = 0;
            activeUserID = bitmaskConverter.users[b];
            for (key in this.persons) {
               if (this.persons.hasOwnProperty(key)) {
                  if (key != 99) {
                     a += 1;
                     if (a >= activeUserID) {
                        userMap[activeUserID] = key;
                        userMapping += activeUserID + ":" + key + ",";

                        if (b + 1 == bitmaskConverter.users.length) {
                           break;
                        }
                        b += 1;
                        activeUserID = bitmaskConverter.users[b];
                     }
                  }
               }
            }
            if (activeUserID == 99) {
               userMap[activeUserID] = 99;
               userMapping += "99:99,";
            }
            userMapping = userMapping.slice(0, -1);
            GacelaStorageService.set("UserIDMapping", userMapping);
            this.updateTrackingTags(e);
            for (index = 0; index < bitmaskConverter.users.length; index += 1) {
               active_user_id = bitmaskConverter.users[index];
               multiple_user_names += encodeURIComponent(this.getUsername(userMap[active_user_id])) + ", ";
               multiple_user_id += userMap[active_user_id] + ", ";
            }
            multiple_user_names = multiple_user_names.slice(0, -2);
            multiple_user_id = multiple_user_id.slice(0, -2);
            abouturl += "&name=" + multiple_user_names;
            abouturl += "&userid=" + multiple_user_id;
            if (this.checkOption("AskForGuestSocio") && (multiple_user_id.search(/99/) != -1)) {
               abouturl += "&guest_age=" + bitmaskConverter.guest_age;
               abouturl += "&guest_gender=" + bitmaskConverter.guest_gender;
            }
         } else {
            GacelaStorageService.set("UserIDMapping", "undefined");
            abouturl += "&name=" + encodeURIComponent(this.getUsername(user_id));
            abouturl += "&userid=" + user_id;
         }

         abouturl += "&tracking=" + encodeURIComponent(trackingtext);
         //Use About Size of config
         currentversion = GacelaStorageService.getStatic('GacelaExtensionVersion');
         if (this.config.aboutsizes) {
            for (name in this.config.aboutsizes) {
               if (this.config.aboutsizes.hasOwnProperty(name)) {
                  if (CompareVersion(this.config.aboutsizes[name].min_version, currentversion) <= 0 && CompareVersion(this.config.aboutsizes[name].max_version, currentversion) > 0) {
                     aboutwidth = this.config.aboutsizes[name].width;
                     if (this.checkOption("AskForGuestSocio") && (abouturl.search(/userid=(.*)99/) !== -1)) {
                        aboutheight = this.config.aboutsizes[name].height + 15;
                     } else {
                        aboutheight = this.config.aboutsizes[name].height;
                     }
                     break;
                  }
               }
            }
         }
      }
      GacelaStatusService.setAboutDialog(abouturl, parseInt(aboutwidth, 10), parseInt(aboutheight, 10));

   };



   /**
   * Reads the name of the person with the given person id
   * @private
   * @function
   * @param int person_id ID of a person
   * @returns string Name of the person, or in case of failure an empty string
   */
   this.getUsername = function (person_id) {
      try {
         return this.persons[person_id].name;
      } catch (e) {
         return "";
      }
   };

   /**
   * Checks if the given person is member of a group with the name <b>default_tracking</b>
   * @private
   * @function
   * @param int person_id ID of a person
   * @returns bool true if the person is member of a group called <b>default_tracking</b>, otherwise false
   */
   this.getTrack = function (person_id) {
      var groups, index;
      try {
         groups = this.persons[person_id].groups;
         for (index = 0; index < groups.length; index += 1) {
            if (groups[index].group_name === 'default_tracking') {
               return true;
            }
         }
      } catch (e) {
      }
      return false;
   };

   /**
   * Gets the id of the current authenticated user from the registry.
   * @private
   * @function
   * @param event e NavigateComplete or UserChanged event object
   * @returns string The id of the current authenticated user
   */
   this.getCurrentUserId = function (e) {
      var now, session_auth_key, last_activity, last_activity_age, muid, cuid, last_login_timestamp;
      now = Math.floor(new Date().getTime() / 1000);
      session_auth_key = String(e.eid.browsersessionid) + '.authentication';
      last_activity =  0;
        last_login_timestamp = 0;
      try {
         last_activity = parseInt(GacelaStorageService.get('LastActivityTstamp'), 10);
      } catch (E) {}
      try {
            last_login_timestamp = GacelaStorageService.getInt('B64_TGFzdExvZ2luVGltZXN0YW1w'); //LastLoginTimestamp set by BrowserHost
        } catch (E) {}
        last_activity = (last_login_timestamp>last_activity) ? last_login_timestamp : last_activity;
        last_activity_age = now - last_activity;
      muid = GacelaStorageService.get(session_auth_key);
      if (isNaN(last_activity_age) || last_activity_age < 30 * 60) {
         cuid = GacelaStorageService.get('CurrentAuthenticatedUser');
         if ((cuid !== null) && (typeof (cuid) !== 'undefined') && cuid !== "98") {
            this.setCurrentUserId(e, cuid);
            return cuid;
         }
      }
      if (muid) {
            // This updates LastActivityTstamp in turn.
         this.setCurrentUserId(e, muid);
         return muid;
      }
      return "98";
   };

   /**
   * Sets the id of the current authenticated user to the registry.
   * @private
   * @function
   * @param event e NavigateComplete or UserChanged event object
   * @param string uid The id to set as the current authenticated user
   */
   this.setCurrentUserId = function (e, uid) {
      var now, session_auth_key;
      now = new Date().getTime() / 1000;
      session_auth_key = String(e.eid.browsersessionid) + '.authentication';
      GacelaStorageService.set('LastActivityTstamp', now);
      GacelaStorageService.set(session_auth_key, uid);
      GacelaStorageService.set("LastAuthenticatedUser", uid);
      GacelaStorageService.set("LastAuthenticatedUser" + GacelaStorageService.getStatic('BrowserType'), uid);
      GacelaStorageService.set("CurrentAuthenticatedUser", uid);
      GacelaStorageService.setInt('B64_TGFzdExvZ2luVGltZXN0YW1w', now); //LastLoginTimestamp
   };
   
   
   
   /**
   * Prepares the authentication and sets the registry key for the current session
   * @private
   * @function
   * @param event e NavigateComplete or UserChanged event object   
   */
   this.initAuthentication = function (e) {
      try {
         GacelaStorageService.unset('UserLoginShowing');
      } catch (exception) {}
      GacelaStorageService.setInt('UserLoginShowing', '0');
      GacelaStorageService.set(e.eid.browsersessionid + '.authentication', '98');
      if (this.browserWindowCount <= 1) {
         GacelaStorageService.set('LastAuthenticatedUser' + GacelaStorageService.getStatic('BrowserType'), '98');
      }
   };


   /**
   * Unsets the registry key for the current session
   * @private
   * @function
   * @param event e NavigateComplete or UserChanged event object   
   */
   this.uninitAuthentication = function (e) {
      GacelaStorageService.unset(e.eid.browsersessionid + '.authentication');
   };


   /**
   * Sets the id of the current authenticated user to <b>0</b> on GacelaQuestionnaireErrorEvent
   * @private
   * @function
   * @param event e GacelaQuestionnaireErrorEvent event object   
   */
   this.OnQuestionnaireError = function (e) {
      var selectedid, now;
      if (e.questionnaire_id === 'Authentication') {
         selectedid = '0';
         now = new Date().getTime() / 1000;
         GacelaStorageService.set(e.eid.browsersessionid + '.authentication', selectedid);
         GacelaStorageService.setInt(e.eid.browsersessionid + '.loggedin', 1); // Login has been done, even if unsuccessful
         GacelaStorageService.set('LastAuthenticatedUser' + GacelaStorageService.getStatic('BrowserType'), selectedid);
         GacelaStorageService.set('LastAuthenticatedUser', selectedid);
         GacelaStorageService.set('CurrentAuthenticatedUser', selectedid);
         GacelaStorageService.setInt('B64_TGFzdExvZ2luVGltZXN0YW1w', now); // LastLoginTimestamp
      }
   };


   /**
   * Sets preventLoginDialog to true on UserLoginShowing event. This variable triggers the visibility of the login dialog.
   * @private
   * @function
   * @param event e UserLoginShowing event object   
   */
   this.OnUserLoginShowing = function (e) {
      this.preventLoginDialog = true;
   };

   /**
   * Formats person ids and the last authenticated user for usage in the dialogs.
   * @deprecated Since Nerva
   * @private   
   * @function   
   * @param object persons persons object
   * @param {string|int} lastid Id of the last authenticated user
   * @returns string String with formatted persons for the UserSelectionDialog or About dialog URL
   */
   this.persons_to_uinfo = function (persons, lastid) {
      var result, person_id;
      result = String(lastid);
      for (person_id in this.persons ) {
         if (this.persons.hasOwnProperty(person_id)) {
            result += ";" + person_id + ":" + encodeURIComponent(this.persons[person_id].name);
         }
      }
      return result;
   };

   /**
   * Builds the complete URL for the Login Dialog (UserSelectionDialog)
   * @private
   * @function
   * @param {int|string} lastAuthenticatedPerson Id of the last authenticated person   
   */
   this.prepareLoginUrl = function (lastAuthenticatedPerson) {
      var preparedUrl, loginUrl, separator, userInfo, anchorSeparatedLoginUrl = "";
      loginUrl = GacelaStorageService.getStatic("LoginURL");
      anchorSeparatedLoginUrl = loginUrl.split('#');
      separator = (loginUrl.indexOf('?') >= 0) ? '&' : '?';
      if (anchorSeparatedLoginUrl[1] && anchorSeparatedLoginUrl[1].indexOf('?') >= 0) {
         anchorSeparatedLoginUrl[0] += anchorSeparatedLoginUrl[1].substring(anchorSeparatedLoginUrl[1].indexOf('?'));
         anchorSeparatedLoginUrl[1] = anchorSeparatedLoginUrl[1].substring(0, anchorSeparatedLoginUrl[1].indexOf('?'));
      }
      preparedUrl = anchorSeparatedLoginUrl[0] + separator + "ts=" + new Date().getTime();
      preparedUrl += '&LastAuthenticatedUser=' + lastAuthenticatedPerson;
      if (anchorSeparatedLoginUrl[1]) {
         userInfo = anchorSeparatedLoginUrl[1].replace(/^NoLastSelection;/, lastAuthenticatedPerson + ";");
         userInfo = anchorSeparatedLoginUrl[1].replace(/^undefined;/, lastAuthenticatedPerson + ";");
      }
      preparedUrl += "#" + userInfo;
      return preparedUrl;
   };

   /**
   * Handles the authentication for Firefox and Microsoft Internet Explorer. Shows login dialog and starts tracking.
   * @private
   * @function
   * @param event e NavigateComplete event object
   */
   this.authenticate = function (e) {
      var user_id, loginUrl, loginWidth, loginHeight, loggedin;
      if (e.mainframe) {// We don't react on frameload events, this leads to bugs in Chrome
         try {
            user_id = GacelaStorageService.get(e.eid.browsersessionid + '.authentication');
            loggedin = GacelaStorageService.getInt(e.eid.browsersessionid + '.loggedin');
            if (user_id === null || typeof (user_id) === 'undefined') {
               user_id = "98";
            }
            if (loggedin!==1) {
               if (this.showAuthDialog()) {
                  if (!this.preventLoginDialog) {   //multi userdialog prevention for existing windows
                     if (GacelaStorageService.getStatic("BrowserType") !== "Chrome") {
                        if (!this.urlInAuthBlacklist(e.url)) {
                           if (!this.isInOfflineMode()) {
                              if (GacelaStorageService.incrementInt('UserLoginShowing', '1') == '0') {//multi userdialog prevention for multiple windows
                                 GacelaEventService.dispatchEventGlobally("UserLoginShowing", {});
                                 loginUrl = this.prepareLoginUrl(GacelaStorageService.get("LastAuthenticatedUser"));
                                 loginWidth = this.config && this.config.userSelectionDialog && this.config.userSelectionDialog.width;
                                 loginWidth = loginWidth || 334;
                                 loginHeight = this.config && this.config.userSelectionDialog && this.config.userSelectionDialog.height;
                                 loginHeight = loginHeight || 280;
                                 GacelaQuestionnaireService.showQuestionnaire(loginUrl, 'Authentication', loginWidth, loginHeight, false);
                              }
                           }
                        }
                     }
                  }
               } else {
                  var noLoginUser = GacelaStorageService.getStatic("noLoginUserId");
                  if (typeof (noLoginUser) !== "undefined" && noLoginUser !== "undefined") {
                     this.setCurrentUserId(e, noLoginUser);
                  } else {
                     this.setCurrentUserId(e, 1);
                  }
               }
               this.startTracking(e);
            }
         } catch (E) {
         }
      }
   };


   /**
   * Checks if a given version conforms a given match version
   * @private
   * @function
   * @param string version The version to compare
   * @param string matchversion The version to compare against. Can contain wildcards.
   * @returns bool True if the version is newer than the needed matchversion, otherwise false.
   */
   this.MinVersionMatch = function (version, matchversion) {
      var versionparts, matchversionparts, index;
      versionparts = version.split('.');
      matchversionparts = matchversion.split('.');
      for (index = 0; index < matchversionparts.length; index += 1) {
         if (matchversionparts[index] === "*") {
            return true;
         }
         if (!versionparts[index]) {
            return false;
         }
         if (matchversionparts[index] > versionparts[index]) {
            return false;
         }
      }
      return true;
   };

   /**
   * Checks if the browser is in offline mode.
   * @private
   * @function
   * @since 10.1.206 (If version below, returns false)
   * @returns bool True if in offline mode, otherwise false.
   */
   this.isInOfflineMode = function () {
      if (this.MinVersionMatch(GacelaStorageService.getStatic("GacelaExtensionVersion"), '10.1.206')) {
         try {
            return GacelaNavigateService.isInOfflineMode();
         } catch (E) {
            return false;
         }
      }
      return false;
   };

   /*If a new Window is opened and a person is selected throw a UserChange-Event to init the Components.*/
   /**
   * If a new Window is opened and a person is selected throw a UserChange-Event to init the Components.
   * @private
   * @function   
   * @param event e GacelaNewWindow event object
   */
   this.AuthNewWindow = function (e) {
      var user_id = GacelaStorageService.get("CurrentAuthenticatedUser");
      if (user_id !== null || typeof (user_id) !== 'undefined') {
         if (user_id != "98") {
            GacelaEventService.dispatchEvent("UserChanged", {"user_id": user_id});
         }
      }
   };

   /**
   * Handles the questionnaire authentication.
   * @private
   * @function   
   * @param event e GacelaQuestionnaireEvent event object
   */
   this.authQuestionnaireEvent = function (e) {
      if (e.questionnaire_id === 'Authentication') {
         var selectedid = this.parseUrlQuery(e.url).userlist;
         GacelaStorageService.set(e.eid.browsersessionid + '.authentication', selectedid);
         GacelaStorageService.setInt(e.eid.browsersessionid + '.loggedin', 1); // Login has been done
         GacelaEventService.dispatchEventGlobally("UserChanged", {"user_id": selectedid});
         this.setCurrentUserId(e, selectedid);
      }
   };

   /**
   * Checks the registry for <b>showLoginDialog</b>. With this key it's possible to control the visibility of the login dialog.
   * @private
   * @function   
   * @returns bool True if the key exists and contains <b>true</b> otherwise false.
   */
   this.showAuthDialog = function () {
      var showLogin = GacelaStorageService.getStatic("showLoginDialog");
      if (typeof (showLogin) !== "undefined" && showLogin !== "undefined" && showLogin !== null && showLogin !== "") {
         return (showLogin === "true") ? true : false;
      } else {
         return true;
      }
   };

   // Userlist is filled by URL Parameters in latest version, for Chrome Compatibility
   // So this filling function is only needed for older Versions.
   /**
   * Fills the user list of the login dialog.
   * @deprecated Only needed for older versions.
   * @private
   * @function   
   * @param event e GacelaQuestionnaireDocumentCompleteEvent event object
   */
   this.authDocumentComplete = function (e) {
      var lastid, sel, newopt, person_id;
      if (e.questionnaire_id === 'Authentication' && e.url.substring(0, e.url.indexOf('?')) === this.authurl) {
         lastid = GacelaStorageService.get("LastAuthenticatedUser");
         sel = e.document.getElementById('userlist');
         if (sel !== null && typeof (sel) !== "undefined") {
            for (person_id in this.persons ) {
               if (this.persons.hasOwnProperty(person_id)) {
                  newopt = e.document.createElement('option');
                  newopt.text = this.persons[person_id].name;
                  newopt.value = person_id;
                  try {
                     sel.add(newopt, null);
                  } catch (ex) {
                     sel.add(newopt);
                  }
                  if (person_id == lastid) {
                     sel.selectedIndex = sel.length - 1;
                  }
                  if (sel.length === 1) {
                     sel.selectedIndex = 0;
                  }
               }
            }
            sel.focus();
         }
      }
   };

   /**
   * Checks if an URL matches the blacklist which contains pages for that no login dialog should be displayed.
   * @private
   * @function   
   * @param string url The url of the page to check
   * @returns bool True if url not specified or in auth blacklist, otherwise false.
   */
   this.urlInAuthBlacklist = function (url) {
      var index;
      if (!url) {
         return true;
      }
      for (index = 0; index < this.config.authblacklist.length; index += 1) {
         if (url.match(this.config.authblacklist[index])) {
            return true;
         }
      }
      return false;
   };

   /**
   * Splits an URL to its GET parameters.
   * @private
   * @function   
   * @param string url The url to check
   * @returns Array Array of GET parameters contained in the given url.
   */
   this.parseUrlQuery = function (urlstr) {
      var url, qPos, params, paramstr, paramParts, parts, name, value, index;
      url = String(urlstr);
      qPos = url.indexOf('?');
      params = {};
      if (qPos === -1) {
         return params;
      }
      paramstr = url.substr(qPos + 1);
      if (paramstr) {
         paramParts = paramstr.split('&');
         for (index = 0; index < paramParts.length; index += 1) {
            parts = paramParts[index].split('=');
            if (parts.length === 2) {
               name = parts[0];
               value = decodeURIComponent(parts[1].replace(/\+/g, '%20'));
               params[name] = value;
            } else {
               Logger.log(Logger.logLevelWarning, "Invalid GET Parameter in GfKBase.parseUrlQuery (missing =): '" + paramParts[index] + "' in " + url);
            }
         }
      }
      return params;
   };

   /**
   * Handles the behaviour when the user tries to close the authentication dialog.
   * @private
   * @function   
   * @param event e GacelaQuestionnaireCancelEvent event object
   */
   this.authAbortDialog = function (e) {
      e.allowCancel = false;
      if (this.config.text_choose_user) {
         alert(this.config.text_choose_user);
      } else {
         alert("Please choose a user");
      }
   };

   /**
   * Starts tracking on new window
   * @private
   * @function   
   * @param event e GacelaNewWindow event object
   */
   //start tracking
   this.newwindow = function (e) {
      this.startTracking(e);
   };

   /**
   * Starts tracking on browser startup.
   * @private
   * @function   
   * @param event e GacelaBrowserStartup event object
   */
   //start tracking
   this.startup = function (e) {
      this.startTracking(e);
   };


   GacelaQuestionnaireService.setUrlErrorPattern('^res:.*');
   GacelaStatusService.allowDisable(false);
   var self = this;
   GacelaEventService.addListener('GacelaBrowserStartup', function (e) {self.initAuthentication(e); });
   GacelaEventService.addListener('GacelaBrowserShutdown', function (e) {self.uninitAuthentication(e); });
   GacelaEventService.addListener('GacelaQuestionnaireErrorEvent', function (e) {self.OnQuestionnaireError(e); });
   GacelaEventService.addListener("UserLoginShowing", function (e) {self.OnUserLoginShowing(e); });
   GacelaEventService.addListener('GacelaNavigateComplete', function (e) {self.authenticate(e); self.startTracking(e); });
   GacelaEventService.addListener('GacelaNewWindow', function (e) {self.AuthNewWindow(e); });
   GacelaEventService.addListener('GacelaQuestionnaireEvent', function (e) {self.authQuestionnaireEvent(e); });
   GacelaEventService.addListener('UserChanged', function (e) {self.updateAboutUrl(e); });
   GacelaEventService.addListener('UserChanged', function (e) {self.startTracking(e); });
   if (CompareVersion("10.1.397", GacelaStorageService.getStatic('GacelaExtensionVersion')) >= 0) {
      GacelaEventService.addListener('GacelaQuestionnaireDocumentCompleteEvent', function (e) {self.authDocumentComplete(e); });
   }
   GacelaEventService.addListener("GacelaQuestionnaireCancelEvent", function (e) {self.authAbortDialog(e); });
   GacelaEventService.addListener('GacelaBeforeNavigate', function (e) {if (e.mainframe) {self.startTracking(e); } });
   GacelaEventService.addListener('GacelaDocumentComplete', function (e) {if (e.mainframe) {self.startTracking(e); } });
   GacelaEventService.addListener('GacelaNewWindow', function (e) {self.newwindow(e); });
   GacelaEventService.addListener('GacelaBrowserStartup', function (e) {self.startup(e); });
}