/*
 * Copyright (C) 2009-2011 Akamai Technologies, Inc.  All Rights Reserved.
 *
 * WARNING! You may not modify this library file, dlm.js. Akamai does not support
 * applications using modified versions of the NetSession DLM library. You may be
 * required to purchase Akamai services to resolve incidents or issues that arise
 * from modification, including changes to the file contents, its URL, or its
 * usage as specified by Akamai.
 *
 */

// DLM class
// Params: (parameters dlmParams, containerId and linkId are optional)
//    cid - customer ID number
//    url - URL of a file to be downloaded
//    dlmParams - associative array (object) of DLM properties to be set for this download, 
//                such as downloadName, i.e., {"downloadName":"DLM"};
//                can be skipped completely or left empty {} if following params are needed
//    containerId - optional parameter specifying a DIV element's ID
//                  into which this DLM will be automatically deployed
//    linkId - optional parameter specifying link or button element's ID
//             the onclick event of which is going to be used to start the download
function DLM(cid, url, dlmParams, containerId, linkId)
{
    // Internal state variables.
    var me                = document.createElement("div");
    me.prototype          = DLM;
    me.urlSetId           = null; 
    me.registeredUrl      = false;   
    me.initialized        = false;
    me.style.display      = "none";
    me.className          = "DLM";
    me.version            = "jsapi_1.8.3"; 
    if (me.version.indexOf("VERSION") != -1)
    {
      me.version = "jsapi_foo";
    }
    me.intendedState      = "STOPPED";
    me.polling            = false;
    me.computedLanguage   = "en"; // Set by calling 'me.setLanguage';
    me.pauseBlackout      = false;
    me.shouldWait         = false;   // If true we will start out paused.
    me.checkContentMd5    = false;   // If true we will enforce Content-MD5 header if preset

    // Determines if the Registering process should start from scratch
    me.resetDownload         = false;
    me.pathSelectionPending  = true;
    me.hasValidPath = false;
    me.showErrorLink      = false;
    me.errorInDisplay     = false;
    // Flag to denote if DLM has gone into an Insufficient Disk Space
    me.insufficientDiskSpace        = false ;
    me.insufficientDiskSpaceResumed = false ;

    // Flag to denote whether the direct download content has already been added
    me.directDownloadLinkCreated    = false ;

    me.clientWasAlreadyInstalled = false;

    // Time estimation state variables.
    me.lastETA = 0;
    me.mult    = 0.80;

    // User configuration variables.
    me.openOnComplete    = true;
    me.cid               = cid;
    me.downloadName      = "";
    me.exeName           = "";
    me.languageDefault   = "en";
    me.language          = "auto";
    me.targetSpeed       = "";
    me.url               = url;
    me.ignoreQueryString = false;
    me.downloadPath      = ""; // "prompt"|empty string (for cache)
    me.originOnly        = true;
    me.cookiestring      = "";
    me.queryauth         = "";
    me.basicauth_username = "";
    me.basicauth_password = "";
    me.resumeURL         = "";
    me.autopause         = true;
    me.onComplete        = null;
    me.onCancel          = null;
    me.onProgress        = null;
    me.onStatusUpdate    = null;
    // Set up the defaults for the file we'll be downloading.
    me.file            = new Object();
    me.file.dlrate     = 0;
    me.file.path       = "";
    me.file.size       = 0;
    me.file.dlStatus   = "WAITING";
    me.file.uniquerecv = 0;
    me.file.error      = 0;
    me.file.suberror   = 0;
    me.file.unpausable = false;
    me.file.verifiedContentMd5 = "";

    // Set user-specified parameters
    if ( dlmParams && typeof( dlmParams ) == "object" ) {
        for ( par in dlmParams ) me[ par ] = dlmParams[ par ];
    }

    // We put ourself in the global list of DLMs and keep track of where we are in that list.
    me.dlmId = DLMHelper.register( me );

    // Message shown to explain paused status (e.g., file not found) 
    me.pausedStatusReason = "";

    // ################################################################################################################
    me.setCookieAuth = function( cookieString ) {
      me.cookiestring = cookieString;
      if ( !cookieString ) {
        me.cookiestring = "";
      }
    }

    // ################################################################################################################
    me.setQueryAuth = function( queryAuth ) {
      me.queryauth = queryAuth;
      if ( !queryAuth ) {
        me.queryauth = "";
      }
    }

    // ################################################################################################################
    me.setBasicAuth = function( basicAuthUsername, basicAuthPassword ) {
      me.basicauth_username = basicAuthUsername;
      me.basicauth_password = basicAuthPassword;
      if ( !basicAuthUsername && !basicAuthPassword ) {
        me.basicauth_username = "";
        me.basicauth_password = "";
      }
    }

    // ################################################################################################################
    // When you want to make the 'pause' button appear, call this function, and it will select the appropriate
    // button.
    me.showPauseButton = function()
    {
        var pauseClass = "DLMpause";
        if(me.file && me.file.unpausable)
        {
          pauseClass = "DLMcancel";
        }
        me._pauseImg.className = pauseClass;
    }

    // ################################################################################################################
    me.getSizeString = function(size)
    {
        // @todo: do these need translation? I sort of doubt it.
        var suffixes = ["B", "KB", "MB", "GB", "TB", "PB"];
        var suffix = 0;
        while (size >= 1024)
        {
            size /= 1024;
            suffix++;
        }
        size = (Math.round(size * 100) / 100);
        size = size.toString().replace(/(\.\d\d)*$/, "$1") + suffixes[suffix];
        return size;
    }

    // ################################################################################################################
    me.showResumeButton = function()
    {
        me._pauseImg.className = "DLMresume";
    }

    // ################################################################################################################
    me.beginDownload = function(){
        DLMHelper.log( "downloadClicked" );

        // Make sure that we've initialized all our localized strings, and that the window is visible.
        me.setLanguage();
        me.style.display = "block";
        me.showErrorLink      = false;
        me.errorInDisplay     = false;

        // Hack for IE, since it doesn't like setting this for elements not already in the DOM.
        // Presumably we're in the DOM by now (hopefully).
        me._autoStartCheckbox.checked = me.openOnComplete ? true : false; 

        // "STOPPED" is the state that new DLMs are in before ever being requested to download anything. If we're in
        // this state, we check to see if the client's installed, and if so, try and download our file. If not, we
        // tell the helper library to install it for us and wait for the client to get installed.
        if ( ( me.intendedState == "STOPPED" ) || ( me.intendedState == "CANCELLED" ) 
                                               || ( me.intendedState == "INSTALLING" ) ) {

            // If customer enabled uploads, and user hasn't accepted EULA
            // (but don't prompt more than once)
            if ( DLMHelper.installed
                 && DLMHelper.uploadEnabled && !DLMHelper.acceptedEULA
                 && !DLMHelper.eulaSelectionDone ) {
                
                // only the first DLM needs to actually request the prompt;
                // the rest can simply poll and wait
                if ( !DLMHelper.eulaSelectionRequested ) {
                    DLMHelper.promptEULA( me.dlmId );                
                }
                
                me.intendedState = "EULAPROMPT";

                // Don't show the DLM box until the user has responded to the prompt
                // (there is no separate UI state)
                me.style.display = "none";
                
                if (!me.polling) {
                    me.poll();
                }
            }
            // If customer enabled uploads, user has accepted EULA, and uploads disabled
            // (but don't prompt more than once)
            else if ( DLMHelper.installed
                 && DLMHelper.uploadEnabled && DLMHelper.acceptedEULA
                 && DLMHelper.askEnableUploads && !DLMHelper.isUploadEnabled
                 && !DLMHelper.enableUploadsSelectionDone ) {
                
                // only the first DLM needs to actually request the prompt;
                // the rest can simply poll and wait
                if ( !DLMHelper.enableUploadsSelectionRequested ) {
                    DLMHelper.promptEnableUploads( me.dlmId );                
                }
                
                me.intendedState = "ENABLEUPLOADSPROMPT";

                // Don't show the DLM box until the user has responded to the prompt
                // (there is no separate UI state)
                me.style.display = "none";
                
                if (!me.polling) {
                    me.poll();
                }
            }
            // If we're not installed...
            else if ( !DLMHelper.installed ) {
                if("function" == typeof DLMHelper.onStartInstall) {
                    // Don't show the DLM box right away. Wait till either the INSTALL COMPLETION
                    // OR the INSTALL FAILURE
                    me.style.display = "none";
                }
                else {
                    me.setUIState( "WAITING" );
                }
                me.intendedState = "INSTALLING";
                DLMHelper.startInstall( me.exeName );
            }
            // Must be installed and EULA accepted or not required...
            else {
              if ( me.shouldWait ) {
                me.intendedState = "PAUSED";
                me.showResumeButton();
              } else {
                me.intendedState = "DOWNLOADING";
                me.showPauseButton();
              }
              me.setUIState( "DOWNLOADING" );
              me.clientWasAlreadyInstalled = true;
              me.download( );
            }
        }

        // If the state is anything other than "STOPPED", then we've already done all
        // this, so we just silently return.
    }

    // ###############################################################################################################
    // Sets the DLM UI ready for a direct download
    me.directDownload = function() {
        // Make sure that we've initialized all our localized strings, and that the window is visible.
        me.setLanguage();
        me.style.display = "block";

        // Since the Single and Bundled DLM would display the direct-download links separately, call a method
        // which would be implemented differently by Single and Bundled DLMs.
        me.displayDirectDownloadLinks();
        me.intendedState = "INSTALLFAILED";
        me.setUIState("INSTALLFAILED");
    }

    // ###############################################################################################################
    // Displays the direct download link for a Single DLM
    me.displayDirectDownloadLinks = function() {
        if(me.directDownloadLinkCreated) return;
        var singleDirectDownloadLink = document.createElement("div");
        var url = me.url + ( "" == me.queryauth ? "" : ( "?" + me.queryauth ) ) ;
        singleDirectDownloadLink.innerHTML = me.localize("singleDirectDownloadLink", url);
        me._installFailedDiv.appendChild(singleDirectDownloadLink);
        me.directDownloadLinkCreated = true;
    }

    // ################################################################################################################
    me.beginDownloadPaused = function() {
      me.shouldWait = true;
      me.beginDownload();
    }

    // ################################################################################################################
    me.unpause = function() {
      me.shouldWait = false;
      if ( me.intendedState == "PAUSED") {
        me.pauseResume();
      }
    }

    // ################################################################################################################
    me.createElement = function( type, className, attribs ) {
        var e = document.createElement( type );
        e.className = "DLM" + className;
        for ( a in attribs ) e.setAttribute( a, attribs[ a ] );
        return e;
    }

    // ################################################################################################################
    // Tells the client to start downloading the current value of 'me.url'.
    me.download = function(){
        if ( !DLMHelper.installed ) return;

        var dlURL  = "";
        // Get a url set id
        if ( !me.urlSetId ) {
          dlURL = "http://127.0.0.1:9421/api?function=createUrlSet&cid=" + me.cid;
          DLMHelper.sendRequest( me.dlmId, "CREATE_URL_SET", dlURL );
          return;
        }

        var dlPath = "";
        var iqs    = "";
        var ts     = "";
        var cs     = "";
        var qa     = "";
        var ba     = "";
        var saveAs = "";
        var oo     = "";
        var url    = me.url;
        var resurl = "";
        var resfilename = "";
        var autopause = "";
        var wait = "";
        var checkContentMd5 = "";

        if ( me.ignoreQueryString ) {
            iqs = "&originurl=" + encodeURIComponent( me.url );
            url = url.replace( /\?.*$/, "" );
        }
        if ( me.originOnly               ) oo     = "&originonly";
        if ( me.targetSpeed              ) ts     = "&targetspeed=" + me.targetSpeed;
        if ( me.cookiestring             ) cs     = "&cookiestring=" + encodeURIComponent( me.cookiestring );
        if ( me.queryauth                ) qa     = "&queryauth=" + encodeURIComponent( me.queryauth );
        if ( me.basicauth_username && me.basicauth_password ) {
            ba = "&basicauth=" + encodeURIComponent( me.authString( me.basicauth_username, me.basicauth_password ) );
        }
        if (me.resumeURL ) {   
          resurl = "&resumeurl=" + encodeURIComponent( me.resumeURL );
          if ( me.downloadName )
          {
            resfilename = "&resumefilename=" + encodeURIComponent( me.downloadName );
          }
        }
        if (me.autopause) autopause = "&autopause=30";
        if (me.shouldWait) wait = "&wait=true"; 
        if (me.checkContentMd5) checkContentMd5 = "&checkcontentmd5=true"; 

        var funcName;
        if ((me.downloadPath == "prompt") && !me.registeredUrl)
        {
          wait = "&wait=true";
          saveAs = "&saveas=true";
          funcName = "registerUrl";          
        }
        else
        {
          funcName = "downloadFile";
          if (!me.initialized)
          {
            wait = "&wait=true";
          }
        }
        dlURL = "http://127.0.0.1:9421/api?function=" + funcName + autopause + "&cid=" + me.cid + "&url=" + 
          encodeURIComponent( url ) + ts + iqs + saveAs + dlPath + oo + cs + qa + ba + resurl + 
          resfilename + wait + checkContentMd5 + "&urlSetId=" + me.urlSetId;
        if (me.version){
                dlURL += "&apiversion=" + me.version;
        }  
        if ( !me.registeredUrl ) {
          dlURL += ( me.resetDownload ? "&resetdownload=true" : "" ) ;
          DLMHelper.sendRequest( me.dlmId, "REGISTER", dlURL );
        } else if ( ! me.initialized ) {
          wait = "&wait=true";
          // Note: if neither wait nor saveas is set, this will start the download
          dlURL = "http://127.0.0.1:9421/api?function=closeUrlSet" + wait + "&cid=" + me.cid + 
            "&urlSetId=" + me.urlSetId;
          if ( me.downloadPath == "prompt" ) {
            dlURL += "&saveas=true";
          }
          DLMHelper.sendRequest( me.dlmId, "CLOSE_URL_SET", dlURL );
          // Note: if wait is not set but saveas is, this will start the download
        } else {
          // Note: we are only normally here because of pause/resume
          DLMHelper.sendRequest( me.dlmId, "DOWNLOAD", dlURL);
        }
    }

    // ################################################################################################################
    // Take a number of seconds and create a nicely formatted, localized string representing the same amount of time.
    me.formatTime = function( seconds ) {
        if ( seconds <= 0 ) return "";
        seconds = Math.round( seconds );
        if ( seconds == 1 ) return "1 " + me.localize( "second" );
        if ( seconds < 60 ) return seconds + " " + me.localize( "seconds" );
        if ( seconds < ( 60 * 60 ) ) {
            if ( Math.round( seconds / 60 ) == 1 ) return "1 " + me.localize( "minute" );
            else return ( Math.round( seconds / 60 ) ) + " " + me.localize( "minutes" );
        }
        var minutes = Math.floor( seconds / 60 );
        var hours =   Math.floor( minutes / 60 );
        minutes %= 60;
        if ( isNaN( hours ) || isNaN( minutes ) ) return "";
        return hours + me.localize( "hourAbbr" ) + ", " + minutes + me.localize( "minAbbr" );
    }
    
    // ################################################################################################################
    // Returns base64 encoded credentials for HTTP Basic Authentication
    me.authString = function( username, password ) {
        var base64chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
        var output = "";
        var input = username + ":" + password;
        var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
        var pos = 0;
        do {
            chr1 = input.charCodeAt(pos++);
            chr2 = input.charCodeAt(pos++);
            chr3 = input.charCodeAt(pos++);
            enc1 = chr1 >> 2;
            enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
            enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
            enc4 = chr3 & 63;
            if (isNaN(chr2)) enc3 = enc4 = 64; else if (isNaN(chr3)) enc4 = 64;
            output = output + base64chars.charAt(enc1) + base64chars.charAt(enc2) + base64chars.charAt(enc3) + 
                base64chars.charAt(enc4);
        } while (pos < input.length);
        return output;
    }

    // ################################################################################################################
    // Estimates time remaining for the current download.
    me.getETA = function( speed, size, progress ){
        if ( me.file.dlStatus == "PAUSED" ) return me.lastETA;
        if ( ! ( speed && size && progress ) ) return -1;

        var newETA = ( size - progress ) / speed;

        if ( me.lastETA == 0 ) me.lastETA = newETA;
        else me.lastETA = me.lastETA - ( me.mult * ( me.lastETA - newETA ) );

        if ( me.mult >= 0.06 ) me.mult -= 0.05;
        return me.lastETA;
    }

    me.downloadIfReady = function() {
        // If we've got a valid path and we're supposed to start the download, do so
        if ((!me.shouldWait) && (!me.waitingToStart)) {
          me.download();
        }
    }
    // ################################################################################################################
    // This function gets called by DLMHelper's response handler, it passes a request type as sent to
    // DLMHelper.sendRequest, as well as the json response from the client.
    me.handleResponse = function( type, json ) {
        switch ( type ) {
            case "EULA_PROMPT_UPDATE":
                var pending = json["pending"];
                var accepted = json["accepted"];
              
                if (!pending) {
                    DLMHelper.processEULASelection(accepted);
                }
                break;
            case "ENABLE_UPLOADS_PROMPT_UPDATE":
                var pending = json["pending"];
                var enabled = json["enabled"];
              
                if (!pending) {
                    DLMHelper.processEnableUploadsSelection(enabled);
                }
                break;
            case "PATH_UPDATE":
                // In case we get a resetDownload = "true" in one of the calls, we should block the calls
                // to handle 'PATH_UPDATE' until the DLM re-initializes properly.
                if (me.initialized)
                {
                  me.pathSelectionPending = json["pending"];
                  me.hasValidPath = json["hasvalidpath"];
               
                  // If we're still waiting on path selection, keep waiting
                  if (me.pathSelectionPending) {
                    break;
                  }

                  // If we've got a valid path and we're supposed to start the download, do so
                  if ((typeof(me.hasValidPath) != "undefined") && (me.hasValidPath == true)) {
                    me.downloadIfReady();
                  }
               
                  // As we're no longer waiting on path selection, we should immediately check on the file attributes.
                  // If path selection failed, this means we will detect that and move to a cancelled state. If we 
                  // succeeded and are a BundledDLM, then me.waitingToStart is false. This will trigger an immediate 
                  // check on all the files in the bundle, and assuming those all work that will begin the download. 
                  // Finally, if we just really started the download this will just get us the latest file states.
                  me.poll(); 
                }
                break;
            case "UPDATE":
                // In case we get a resetDownload = "true" in one of the calls, we should block the calls
                // to 'handleUpdate' until the DLM re-initializes properly.
                if (me.initialized)
                {
                  me.handleUpdate(json);
                }
                break;
            case "CREATE_URL_SET":
                if (json["urlSetId"]) {
                  me.urlSetId = json["urlSetId"];
                  me.download();
                }
                else if(json["error"]) {
                    me.urlSetId = null;
                    me.resetDLM() ;
                }
                break;
            case "REGISTER":
                me.handleRegister(json);                
                break;
            case "CLOSE_URL_SET":
                me.initialized = true;
                me.resetDownload = false ;
                if (!me.polling) {
                    me.poll();
                }
                
                // If we've got a valid path and we're supposed to start the download, do so
                if ((me.downloadPath != "prompt")) {
                  me.downloadIfReady();
                }
                break;
            case "DOWNLOAD":
                // just keep the warning from firing.
                break;
            case "PAUSE":
                // just keep the warning from firing.
                break;
            case "OPEN":
                for ( var url in json ) if ( json[ url ] ) throw( json[ url ] );
                break;
            default:
                DLMHelper.warn( "Unknown type sent to 'handleResponse()': " + type );
        }
    }

    // ################################################################################################################
    // This handles responses to 'update' requests sent to the client.
    me.handleUpdate = function( json ) {

        // This iterates across a list of files, even though we only expect to have one.
        // As such, the data we keep will be for the last file in the list, if more than
        // one were returned.

        for (var i in json)
        {
            me.file.size = json[i]["size"];
            me.file.dlStatus = json[i]["status"];
            me.file.dlrate = json[i]["downloadrate"];
            me.file.uniquerecv = json[i]["uniquerecv"];
            me.file.path = json[i]["path"];
            me.file.error = json[i]["error"];
            me.file.suberror = json[i]["suberror"];
            me.file.unpausable = json[i]["unpausable"];
            me.file.verifiedContentMd5 = json[i]["verifiedcontentmd5"];
        }

        // Check if we are not downloading the file at all (This can happen if the saveas 
        // dialog is canceled or cache was cleared out or any other event occured and we have 
        // simply deleted the download.)
        if ( typeof( me.file.dlStatus ) == "undefined" ) {
            // Reinitialize the download and hide the DLM
            me.resetDLM( ) ;
            return;
        }

        if( me.file.dlStatus == "INSUFFICIENTDISKSPACE" ) {
            me.insufficientDiskSpace = true ;
        }
        else {
            me.insufficientDiskSpace = false ;          
        }

        if( me.initialized && ( ( me.insufficientDiskSpace && me.insufficientDiskSpaceResumed ) || ( true == json[i]["resetdownload"] ) ) ) {
            me.file.dlrate     = 0;
            me.file.path       = "";
            me.file.size       = 0;
            me.file.dlStatus   = "WAITING";
            me.file.uniquerecv = 0;
            me.file.error      = 0;
            me.file.suberror   = 0;

            me.initialized = false ;
            me.registeredUrl = false ;
            me.resetDownload = true ;
            me.pathSelectionPending    = true;
            me.insufficientDiskSpace = false ;
            me.insufficientDiskSpaceResumed = false ;
            me.hasValidPath = false;

            me._progressDiv.style.width = "0%" ;
            me._progressDiv.lastPercent = 0;
            me._progressDiv.measuredPercent = 0;

            if (me.intendedState == "DOWNLOADING") 
            {
              me.download( ) ;
            }

            return ;
        }
        me.pausedStatusReason = ""; // Clear the error description        

        if (me.onStatusUpdate) {
          me.onStatusUpdate(me.url, me.file.dlStatus);
        }

        var dlStatus = me.file.dlStatus;

        switch(dlStatus)
        {
            case "COMPLETE":
            {
                var oldIntendedState = me.intendedState;
                me.intendedState = "COMPLETE";
                DLMHelper.log( "downloadCompleted" );
                me.setUIState( "COMPLETE" );
                if (oldIntendedState != "COMPLETE" && me.onComplete)
                {
                    me.onComplete(); // run the onComplete callback if defined
                }
                if (oldIntendedState != "COMPLETE" && me.openOnComplete)
                {
                    me.openFile(); // open the file if requested
                }
                return;
            }
            case "PAUSED":
            case "INITIALIZING":
            case "WAITING":
            case "DOWNLOADING":
            {
                // Set the progress regardless of our blacked-outedness.
                var percent = 0;
                if (me.file.size > 0)
                {
                    percent = (me.file.uniquerecv / me.file.size) * 100;
                }

                // Set the progress to 100% when it's unknown but not zero.
                if (me.file.uniquerecv && !me.file.size)
                {
                    percent = 100;
                    if(me._progressDiv.className == "DLMprogress")
                    {
                        me._progressDiv.className = "DLMprogressDisabled";
                    }
                }
                else
                {
                    percent = Math.round(percent * 100) / 100;
                    if(me._progressDiv.className == "DLMprogressDisabled")
                    {
                        me._progressDiv.className = "DLMprogress";
                    }
                }

                // Progress is 0 if we're paused and unpausable (because we'll have to start over when we resume).
                if(dlStatus == "PAUSED" && me.file.unpausable)
                {
                    percent = 0;
                }
                me._progressDiv.style.width = percent + "%";
                
                if (me.onProgress) {
                  me.onProgress(me.url, percent);
                }

                if(!me.pauseBlackout)
                {
                    if(dlStatus == "PAUSED")
                    {
                        me.intendedState = "PAUSED";
                        me.showResumeButton();
                        me.pausedStatusReason = me.getErrorString(me.file.error, me.file.suberror);
                        
                        if ((typeof(me.onError) == "function") && me.file.error != 0)
                        {
                            me.onError(dlStatus, me.file.error, me.file.suberror);          
                        }
                    }
                    else
                    {
                        me.intendedState = "DOWNLOADING";
                        me.showPauseButton();
                    }
                }
                break;
            }
            case "NOTFOUND":
            case "INSUFFICIENTDISKSPACE":
            case "FORBIDDEN":
            {
                me.showResumeButton();
                me.pausedStatusReason = me.getErrorString(me.file.error, me.file.suberror);
              
                if (me.intendedState != "PAUSED") 
                {
                    me.intendedState = "PAUSED";
                    if (typeof(me.onError) == "function")
                    {
                        me.onError(dlStatus, me.file.error, me.file.suberror);          
                    }
                }
                break;
            }
            case "DISCONNECTED":
            {
                me.pausedStatusReason = me.localize("pausedDisconnected");
                break;
            }
            default:
                // ??? We should add specific handling here for new states.
        }

        // Update the status text message.
        me.writeStatusText();
    }

    // ################################################################################################################
    me.handleRegister = function( json ) {
      if( json[ "error" ] ) {
        me.resetDLM( ) ;
        return ;
      }
      me.registeredUrl = true;
      me.download();
    }

    // ###############################################################################################################
    // Resets the DLM in the following cases:
    // 1) Error while creating URLSetId
    // 2) Error while registering the URLs
    // 3) 'File Not Found.' error (Clear-cache / User cancelling the Save-as / File write error in the client)
    me.resetDLM = function( ) {
        me.polling = false;
        me.pathSelectionPending     = true;
        me.hasValidPath = false;
        me.file.dlrate     = 0;
        me.file.path       = "";
        me.file.size       = 0;
        me.file.dlStatus   = "WAITING";
        me.file.uniquerecv = 0;
        me.file.unpausable = false;
        me.file.verifiedContentMd5 = "";
        me.intendedState = "STOPPED";
        me.setUIState( "WAITING" );
        me.showPauseButton();
        me.style.display  = "none";
        me.registeredUrl = false ;
        me.initialized = false ;
        return ;
    }

    // ################################################################################################################
    me.localize = function( key ) {
        return DLMHelper.localize( me.computedLanguage, key, arguments ) ;
    }

    // ####################################################################################################################
    me.populateErrorDetails = function(pausedStatusReason) {
        me._errorMessageDiv.innerHTML = me.localize(pausedStatusReason);
        me.showErrorLink = true;
    }
    
    // ################################################################################################################
    me.closeErrorPopup = function( evt ){        
        me._errorPopupDiv.style.display = "none";
        me.errorInDisplay = false;
        me.showErrorLink = true;
        return false;
    }
    
    // ####################################################################################################################
    me.getErrorString = function( errorCode, subErrorCode ) {
        var localizedErrorString;
        if (errorCode == 0 || (typeof(DLMHelper.errorCodes[errorCode]) == "undefined"))
        {
            return "";
        }
        else
        {
            localizedErrorString = me.localize(DLMHelper.errorCodes[errorCode][0]);
        }
        
        if (subErrorCode == 0 || (typeof(DLMHelper.errorCodes[errorCode][subErrorCode]) == "undefined"))
        {
            return localizedErrorString;
        }
        else 
        {
            localizedErrorString +=  " (" + 
            me.localize(DLMHelper.errorCodes[errorCode][subErrorCode]) + ")";                    
        }
        return localizedErrorString;
    }
    
    // ################################################################################################################
    // This is a pseudo-event-handler that lets the DLMHelper object send us messages that we can
    // act on. Notably, the DLMHelper can let us know as soon as the client has been installed so
    // we can proceed with our download.
    me.notify = function( message ){
        switch ( message ) {
            case "INSTALLED":
                // Start downloading if the EULA is accepted, we don't require one, or we've already prompted the user.
                // Similarly, start downloading if DLMHelper.askEnableUploads is satisfied (no prompt required).
                // Also, if the install was reported as FAILED previously, don't change the status.
                //
                // The anticipated states commented below are what we expect to happen when beginDownload() is called;
                // unfortunately, we can't simply check me.intendedState because in theory DLMHelper.setInstalled() might
                // send this notification before beginDownload() sets the state.
                if( (!DLMHelper.uploadEnabled || DLMHelper.acceptedEULA || DLMHelper.eulaSelectionDone) && // anticipated state: EULAPROMPT
                    (!DLMHelper.askEnableUploads || !DLMHelper.uploadEnabled || // anticipated state: ENABLEUPLOADSPROMPT
                        (!DLMHelper.acceptedEULA && DLMHelper.eulaSelectionDone) ||
                        (DLMHelper.acceptedEULA && DLMHelper.isUploadEnabled) || DLMHelper.enableUploadsSelectionDone) &&
                    ("INSTALLFAILED" != me.intendedState) ) {
                    
                    me.setUIState( "DOWNLOADING" );
                    if( me.intendedState == "INSTALLING" ) {
                        me.intendedState = "DOWNLOADING";
                        me.style.display = "block";
                        me.download();
                        if ( !me.polling ) me.poll();
                    }
                }
                break;
                
            case "EULAACCEPTED":
            case "EULADECLINED":
                var accepted = ("EULAACCEPTED" == message); // we proceed with download either way, but this might be handy in the future
                // If we're waiting for the prompt to return, then as soon as we get this
                // message we're ready to go and can start downloading.
                if( "EULAPROMPT" == me.intendedState ) {
                    me.style.display = "block";
                    me.intendedState = "DOWNLOADING";
                    me.showPauseButton();
                    me.setUIState( "DOWNLOADING" );
                    me.download();
                    if ( !me.polling ) me.poll();
                }
                break;
                
            case "ENABLEUPLOADSACCEPTED":
            case "ENABLEUPLOADSDECLINED":
                var accepted = ("ENABLEUPLOADSACCEPTED" == message); // we proceed with download either way, but this might be handy in the future
                // If we're waiting for the prompt to return, then as soon as we get this
                // message we're ready to go and can start downloading.
                if( "ENABLEUPLOADSPROMPT" == me.intendedState ) {
                    me.style.display = "block";
                    me.intendedState = "DOWNLOADING";
                    me.showPauseButton();
                    me.setUIState( "DOWNLOADING" );
                    me.download();
                    if ( !me.polling ) me.poll();
                }
                break;
                
            case "INSTALLFAILED":
                // If the Install was marked as 'Failed', display the direct download links if we were in DOWNLOADING
                // previously.
                if( "INSTALLING" == me.intendedState ) {
                    me.directDownload();
                }
                break;
                
            case "INSTALLSTOPPED":
                // If the install popup was closed (without either a success or a failure), reset to a stopped state.
                // If the same link is clicked again, we'll start afresh.
                if( "INSTALLING" == me.intendedState ) {
                    me.style.display = "none";
                    me.intendedState = "STOPPED";
                }
                break;
                
            default:
                DLMHelper.warn( "'notify()' called with unsupported message: " + message );
        }
    }

    // ################################################################################################################
    me.openFile = function( evt ){
        DLMHelper.sendRequest(
            me.dlmId,
            "OPEN",
            "http://127.0.0.1:9421/api?function=openFile&cid=" + me.cid + "&url=" + encodeURIComponent( me.url )
        );

        // Prevent following links in the case that this function was called via an onclick handler.
        if ( evt && evt.preventDefault ) evt.preventDefault();
        else if ( window.event ) window.event.returnValue = false;
    }

    // ################################################################################################################
    me.pauseResume = function() {
        var blackoutMS = 3000; // Number of milliseconds we're blacked out for after calling this function.
        switch( me.intendedState ) {
            case "STOPPED":
            case "PAUSED":
                me.intendedState = "DOWNLOADING";
                me.showErrorLink      = false;
                me.errorInDisplay     = false;
                me.showPauseButton();
                if( me.insufficientDiskSpace ) {
                    me.insufficientDiskSpaceResumed = true ;
                }
                else {
                    me.insufficientDiskSpaceResumed = false ;
                }
                me.shouldWait = false;
                me.writeStatusText();
                me.download();
                if (!me.polling)
                {
                    me.poll();
                }
                me.pauseBlackout = true;
                setTimeout(function(){me.pauseBlackout = false}, blackoutMS);
                break;
            case "DOWNLOADING":
                me.intendedState = "PAUSED";
                me.showResumeButton();
                // Paused 'unpausable' files show 0 progress because they reset on start.
                // This has no effect for bundledDLMs.
                if (me.file && me.file.unpausable)
                {
                    me._progressDiv.style.width = "0%";
                }
                if(me.url)
                {
                    DLMHelper.sendRequest(
                        me.dlmId,
                        "PAUSE",
                        "http://127.0.0.1:9421/api?function=pauseFile&cid=" + me.cid + "&url=" +
                            encodeURIComponent(me.url)
                    );
                }
                me.writeStatusText();
                me.pauseBlackout = true;
                setTimeout(function(){me.pauseBlackout = false}, blackoutMS);
                break;
            case "CANCELLED":
            case "COMPLETE":
            case "EULAPROMPT":
                break;
            default:
                DLMHelper.warn( "In unsupported state: " + me.intendedState );
        }
        return false; // To ignore standard event when invoked from onclick event on anchor
    }
    // ################################################################################################################
    me.poll = function() {
        if (!me.polling)
        {
            me.polling = true;
            setTimeout( me.poll, 1000 );
            return;
        }

        if ( me.file.dlStatus == "COMPLETE" || me.intendedState == "STOPPED" )
        {
            return;
        }
        
        var funcName = "";
        var type = "";
        
        if (true === DLMHelper.eulaSelectionRequested)
        {
          funcName = "getEulaSelectionStatus";
          type = "EULA_PROMPT_UPDATE";
        }
        else if (true === DLMHelper.enableUploadsSelectionRequested)
        {
          funcName = "getEnableUploadsSelectionStatus";
          type = "ENABLE_UPLOADS_PROMPT_UPDATE";
        }
        else if ((me.downloadPath == "prompt") && (true == me.pathSelectionPending))
        {
          funcName = "getPathSelectionStatus";
          type = "PATH_UPDATE";
        }
        else
        {
          funcName = "getFileAttributes";
          type = "UPDATE";
        }
        
        DLMHelper.sendRequest(
            me.dlmId,
            type,
            "http://127.0.0.1:9421/api?cid=" + me.cid +
            "&function=" + funcName + "&complete&url=" + encodeURIComponent(me.url) + "&urlSetId=" + me.urlSetId
        );
        setTimeout( me.poll, 1000 );
    }

    // ################################################################################################################
    // Promts the user to download the installer exe again.
    me.reopenInstaller = function( evt ){
        DLMHelper.startInstall( me.exeName );
        if ( evt && evt.preventDefault ) evt.preventDefault();
        else if ( window.event ) window.event.returnValue = false;
    }
    // ################################################################################################################
    me.setDownloadName = function( name ){
        me.downloadName = name;
        me.setLanguage();
    }

    // ################################################################################################################
    me.setExeName = function( name ){
        me.exeName = name;
        me.setLanguage();
    }

    // ################################################################################################################
    me.setLanguageDefault = function( lang ){
        me.languageDefault = lang;
        me.setLanguage();
    }

    // ################################################################################################################
    me.setLanguage = function() {
        me.computedLanguage = DLMHelper.getComputedLanguage( me.language, me.defaultLanguage ) ;

        // Clear everything out before we reset it.
        var nodes = [
            me._startMsgDiv, me._relaunchMsgStart, me._relaunchLink, me._relaunchMsgEnd,
            me._titleDiv, me._autoStartLabel, me._completeTitle, me._completeLink, me._completeText,
            me._cancelledTitle, me._cancelledMsg
        ];
        for ( var i = 0; i < nodes.length; i++ )
            while ( nodes[ i ].childNodes.length ) nodes[ i ].removeChild( nodes[ i ].childNodes[ 0 ] );
        
        // Get the name of the download.
        var dlName = ( me.downloadName ) ? me.downloadName : me.url.replace( /^.*\//, "" );

        // 'WAITING' state strings.
        me._startMsgDiv.appendChild(      document.createTextNode( me.localize( "startTitle"       ) ) );
        me._relaunchMsgStart.appendChild( document.createTextNode( me.localize( "relaunchMsgStart" ) ) );
        me._relaunchLink.appendChild(     document.createTextNode( me.localize( "relaunchLink"     ) ) );
        me._relaunchMsgEnd.appendChild(   document.createTextNode( me.localize( "relaunchMsgEnd"   ) ) );

        // 'DOWNLOADING' state strings.
        me._titleDiv.appendChild(       document.createTextNode( me.localize( "title", dlName    ) ) );
        me._autoStartLabel.appendChild( document.createTextNode( me.localize( "autoStart" )        ) );
        me.writeStatusText();
        
        // 'COMPLETE' state strings.
        me._completeTitle.appendChild( document.createTextNode( me.localize( "completeTitle" )        ) );
        me._completeLink.appendChild(  document.createTextNode( me.localize( "completeText", dlName ) ) );

        // 'CANCELLED' state strings.
        me._cancelledTitle.appendChild( document.createTextNode( me.localize( "cancelledTitle", dlName ) ) );
        me._cancelledMsg.appendChild( document.createTextNode( me.localize( "cancelledMsg" ) ) );
    }

    // ################################################################################################################
    me.setTargetSpeed = function( speed ){
        me.targetSpeed = speed;
    }

    // ################################################################################################################
    me.getVerifiedContentMd5 = function() {
      var md5 = "";
      if (("object" == typeof me.file) && ("string" == typeof me.file.verifiedContentMd5))
      {
        md5 = me.file.verifiedContentMd5;
      }
        
      return md5;
    }

    // ################################################################################################################
    // This function is called to set the UI to one of it's three primary states, which are "WAITING" when we're
    // waiting for installation to complete, "DOWNLOADING" while we're in the process of download a file (including
    // while we're paused), and "COMPLETE" after the file has finished.
    me.setUIState = function( state, extraElements ) {
        var a, i, setTo, activationArray;

        // Downloading elements.
        var downloading = [
            me._titleDiv,
            me._progressBarDiv,
            me._pauseImg,
            me._statusDiv,
            me._autoStartDiv
        ];

        // Waiting elements.
        var waiting = [
            me._startDiv
        ];

        // Complete elements.
        var complete = [
            me._completeDiv
        ];
        
        // Cancelled elements.
        var cancelled = [

        ];

        // Direct Download elements.
        var installFailed = [
            me._installFailedDiv
        ];

        // Add any user-specified extra elements. This is here for extending the DLM class.
        if(extraElements){
            var lists = ["downloading", "waiting", "complete", "cancelled", "installFailed"];
            for(var ii = 0; ii < lists.length; ii++){
                var current;
                eval("current = " + lists[ii]);
                if(extraElements[lists[ii]]){
                    if(extraElements[lists[ii]].length){
                        for(var jj = 0; jj < extraElements[lists[ii]].length; jj++)
                            current.push(extraElements[lists[ii]][jj]);
                    }
                    else
                        current.push(extraElements[lists[ii]]);
                }
            }
        }

        switch( state ) {
            case "WAITING":     activationArray = waiting;     break;
            case "DOWNLOADING": activationArray = downloading; break;
            case "COMPLETE":    activationArray = complete;    break;
            case "CANCELLED":   activationArray = cancelled;   break;
            case "INSTALLFAILED": activationArray = installFailed; break;
            default:
                activationArray = waiting;
                DLMHelper.warn( "Tried to set UI State to unsupported state: " + state );
        }
        var all = [ waiting, downloading, complete, cancelled, installFailed ];
        for( var a = 0; a < all.length; a++ ) {
            setTo = ( all[ a ] === activationArray ) ? null : "none";
            for ( i = 0; i < all[ a ].length; i++ ) {
                // If we're setting display to 'none', we save the current display property, and then do the set, but
                // multiple calls to this shouldn't break our old display style, so we don't do this multiple times.
                if( setTo == "none" && all[ a ][ i ].style.display != "none" ){
                        all[ a ][ i ].old_style_display = all[ a ][ i ].style.display;
                        all[ a ][ i ].style.display = "none";
                }
                // If setTo is the default value (null), we set the element back to it's old display value, unless
                // it's not set, in which case we use the empty string (which should act as default).
                else if( setTo == null ) {
                    var osd = ( all[ a ][ i ].old_style_display == undefined ) ? "" : all[ a ][ i ].old_style_display; 
                    all[ a ][ i ].style.display = osd;
                }
            }
        }
    }

    // ################################################################################################################
    me.writeStatusText = function() {
        var statusText = "";
        switch ( me.intendedState ){
            case "STOPPED":
                statusText = me.localize( "waiting" );
                break;
            case "PAUSED":
                if (me.pausedStatusReason) statusText = me.pausedStatusReason;  
                break;
            case "DOWNLOADING":
                if( me.pausedStatusReason )
                {
                    statusText = me.pausedStatusReason;
                }
                else if(me.file && me.file.uniquerecv && !me.file.size)
                {
                    statusText = me.getSizeString(me.file.uniquerecv) + "/?";
                }
                else
                {                
                    var timestring = me.formatTime( me.getETA( me.file.dlrate, me.file.size, me.file.uniquerecv ) );                    
                    if (timestring != "") statusText = me.localize( "timeLabel", timestring );                    
                    else statusText = me.localize( "calcTime" );
                }
                break;
            case "COMPLETE":
                statusText = "";
                break;
            case "EULAPROMPT":
                statusText = "";
                break;
            default:
                DLMHelper.warn( "Couldn't write status text for state " + me.intendedState );
                break;
        }
        // If we're blank, insert a unicode non-breaking space to keep the whole element from disappearing.
        if(!statusText)
        {
            statusText = "\u00A0";
        }
        while ( me._statusDiv.childNodes.length ) me._statusDiv.removeChild( me._statusDiv.childNodes[ 0 ] );
        me._statusDiv.appendChild( document.createTextNode( statusText ) );
    }

    // Set the default contents of our div element. ###################################################################

    // Downloading state elements.
    me._titleDiv          = me.createElement( "div",   "title"            );
    me._progressBarDiv    = me.createElement( "div",   "progressBar"      );
    me._progressDiv       = me.createElement( "div",   "progress"         );
    me._pauseImg          = me.createElement( "div",   "pause"            ); // Div instead of IMG to allow full css control of the image src (IE shows blank icon when src not set and we don't have a transparent image)
    me._pauseImgClick     = me.createElement( "span",  "pauseclick"       ); // This is a hack for IE8 to make the div parent clickable
    me._statusDiv         = me.createElement( "div",   "status"           );
    me._autoStartDiv      = me.createElement( "div",   "autoStart"        );
    me._autoStartCheckbox = me.createElement( "input", "autoStartCB",
                            { "type": "checkbox", "id": "DLM" + me.dlmId + "ascb", "checked": "checked" } );
    me._autoStartLabel    = me.createElement( "label", "autoStartLabel",
                            { "for": "DLM" + me.dlmId + "ascb" } );

    // Complete state elements.
    me._completeDiv       = me.createElement( "div",   "complete" );
    me._completeTitle     = me.createElement( "div",   "completeTitle"    );
    me._completeText      = me.createElement( "div",   "completeText"     );
    me._completeLink      = me.createElement( "a",     "completeLink",
                            { "href": "" } );

    // Waiting state elements.
    me._startDiv          = me.createElement( "div",   "start" );
    me._startMsgDiv       = me.createElement( "div",   "startMsg"         );
    me._relaunchDiv       = me.createElement( "div",   "relaunch"         );
    me._relaunchMsgStart  = me.createElement( "span",  "relaunchMsgStart" );
    me._relaunchLink      = me.createElement( "a",     "relaunchLink",
                            { "href": "" } );
    me._relaunchMsgEnd    = me.createElement( "span",  "relaunchMsgEnd"   );

    // 'Install Failed' state elements
    me._installFailedDiv  = me.createElement( "div",   "installFailed" );

    // TODO: these exist solely for BundledDLM support at the moment. They should also be made to function with a
    // single-file DLM.
    me._cancelledTitle = me.createElement("div", "cancelledTitle");
    me._cancelledMsg = me.createElement("a", "cancelledMsg");

    // Error Div components
    me._closeButton = me.createElement("div", DLMHelper.closeErrorClass);
    me._errorMessageDiv = me.createElement("div", DLMHelper.errorMsgClass);
    me._errorHeaderDiv = me.createElement("div", DLMHelper.errorHeaderClass);
    me._errorHeaderDiv.innerHTML = me.localize("errorPopUpHeader");
    me._innerErrorPopup = me.createElement("div", DLMHelper.errorDivClass);
    me._innerErrorPopup.appendChild(me._errorHeaderDiv);
    me._innerErrorPopup.appendChild(me._closeButton);
    me._innerErrorPopup.appendChild(me._errorMessageDiv);    
    
    // Build tree for Error popup
    me._errorPopupDiv = me.createElement("div", DLMHelper.errorPopupClass);
    me._errorPopupDiv.style.display = "none";
    me._errorPopupDiv.appendChild(me._innerErrorPopup);                
    // Build a tree.
    me._relaunchDiv.appendChild(    me._relaunchMsgStart  );
    me._relaunchDiv.appendChild(    me._relaunchLink      );
    me._relaunchDiv.appendChild(    me._relaunchMsgEnd    );
    me._startDiv.appendChild(       me._startMsgDiv       );
    me._startDiv.appendChild(       me._relaunchDiv       );
    me._completeDiv.appendChild(    me._completeTitle     );
    me._completeDiv.appendChild(    me._completeText      );
    me._completeDiv.appendChild(    me._completeLink      );
    me._progressBarDiv.appendChild( me._progressDiv       );
    me._autoStartDiv.appendChild(   me._autoStartCheckbox );
    me._autoStartDiv.appendChild(   me._autoStartLabel    );
    me.appendChild(                 me._titleDiv          );
    me.appendChild(                 me._progressBarDiv    );
    me.appendChild(                 me._pauseImg          );
    me._pauseImg.appendChild(       me._pauseImgClick     );
    me.appendChild(                 me._statusDiv         );
    me.appendChild(                 me._autoStartDiv      );
    me.appendChild(                 me._completeDiv       );
    me.appendChild(                 me._startDiv          );
    me.appendChild(                 me._installFailedDiv  );
    me.appendChild(                 me._errorPopupDiv     );

    // Attach event handlers.
    if ( window.attachEvent ) {
        me._pauseImg.attachEvent(          "onclick", me.pauseResume                                       );
        me._completeLink.attachEvent(      "onclick", me.openFile                                          );
        me._autoStartCheckbox.attachEvent( "onclick", function(){ me.openOnComplete = !me.openOnComplete } );
        me._relaunchLink.attachEvent(      "onclick", me.reopenInstaller                                   );
        me._closeButton.attachEvent(       "onclick", me.closeErrorPopup                                   );
    }
    else if ( window.addEventListener ) {
        me._pauseImg.addEventListener(          "click", me.pauseResume, false                                       );
        me._completeLink.addEventListener(      "click", me.openFile, false                                          );
        me._autoStartCheckbox.addEventListener( "click", function(){ me.openOnComplete = !me.openOnComplete }, false );
        me._relaunchLink.addEventListener(      "click", me.reopenInstaller, false                                   );
        me._closeButton.addEventListener(       "click", me.closeErrorPopup, false                                   );
    }

    // If the client is installed, default to the downloading state.
    if ( DLMHelper.installed ) {
        me.setUIState( "DOWNLOADING" );
        me.showResumeButton();
    }
    // Otherwise, default to the waiting state.
    else {
        me.setUIState( "WAITING" );
    }

    // Call 'setLanguage' to localize our strings.
    me.setLanguage();

    // (Optional) deployment into DLM-container
    if ( containerId ) {
        var dlmContainer = document.getElementById( containerId );
        if ( dlmContainer ) dlmContainer.appendChild( me );
    }
    
    // (Optional) set up download link onclick event to start the download
    if ( linkId ) {
        var clickLink = document.getElementById( linkId );
        if ( clickLink ) clickLink.onclick = function () {
            me.beginDownload();
            return false;
        }
    }

    // Return our modified div 'me'.
    return me;
}

// ####################################################################################################################
// ####################################################################################################################
// New BundledDLM object for bundled downloads. Takes the same arguments as DLM, except that 'url' is replaced with
// 'urls', which is now an array.
// ####################################################################################################################
// ####################################################################################################################
function BundledDLM(cid, urls, dlmParams, containerId, linkId)
{
    // Warn if we didn't get an array of URLs. This probably means we should be making a DLM instead of a
    // BundledDLM.
    if ( !urls || typeof( urls ) != "object" || !(urls instanceof Array)) {
        DLMHelper.warn("BundledDLM created with non-array urls parameter.");
    }

    // Initialize myself via our base class.
    var me = new DLM(cid, "", dlmParams, containerId, linkId); 

    // We no longer use these parameters.
    me.file = null;

    // We add some extra parameters.
    me.waitingToStart = true; // Turn this off once all our files are PAUSED or COMPLETE.
    me.skipFailedUrls = false;
    me.urls = urls;
    me.unregisteredURLs = [];   // We remove files from this list as they are added to the bundle.
    me.incompleteURLs = [];   // We remove files from this list as they complete.
    me.files = {};
    me.url = null; // the url of the file in the bundle currently being downloaded.
    me.fileToOpen = null;

    // Per url auth parameters
    me.cookieStringPerUrl = {};
    me.queryAuthPerUrl = {};
    me.basicAuthUsernamePerUrl = {};
    me.basicAuthPasswordPerUrl = {};

    // Initialize our URLs.
    for(var ii = 0; ii < me.urls.length; ii++) me.unregisteredURLs.push(me.urls[ii]);
    for(var ii = 0; ii < me.urls.length; ii++) me.incompleteURLs.push(me.urls[ii]);

    // Initialize all our files.
    for(var ii = 0; ii < me.urls.length; ii++){
        var file        = new Object();
        file.dlrate     = 0;
        file.path       = "";
        file.size       = 0;
        file.dlStatus   = "WAITING";
        file.uniquerecv = 0;
        file.error      = 0;
        file.suberror   = 0;
        file.unpausable = false;
        file.verifiedContentMd5 = "";
        me.files[me.urls[ii]] = file;
    }

    // We require this to be set to *something*, as automatically setting it to the URL is no longer practical.
    if ( !me.downloadName ) {
      me.downloadName = "bundle";
    }

    // setUIState extends but doesn't really replace the parent class' function.
    me.parentSetUIState = me.setUIState;
    me.setUIState = function(state){
        var extraElements = {
            "downloading": [me._progressBarDiv2, me._statusDiv2],
            "cancelled": [me._cancelledTitle, me._cancelledMsg]
        }
        me.parentSetUIState(state, extraElements);
    }
    // The parent class has initialized some UI State, so we need to reinitialize it with our updated function.
    /* Is this really necesary? Doesn't it get called anywhere else?
    // If the client is installed, default to the downloading state.
    if ( DLMHelper.installed ) {
        me.setUIState( "DOWNLOADING" );
        me.showResumeButton();
    }
    // Otherwise, default to the waiting state.
    else {
        me.setUIState( "WAITING" );
    }
    */

    // ################################################################################################################
    // When you want to make the 'pause' button appear, call this function, and it will select the appropriate
    // button.
    me.showPauseButton = function()
    {
        var pauseClass = "DLMpause";
        if(me.url && me.files && me.files[me.url] && me.files[me.url].unpausable)
        {
          pauseClass = "DLMcancel";
        }
        me._pauseImg.className = pauseClass;
    }

    // ################################################################################################################
    me.unpause = function() {
      me.shouldWait = false;
      if ( me.waitingToStart ) {
        me.intendedState = "DOWNLOADING";
        me.showPauseButton();
      } else if (me.intendedState == "PAUSED") {
        me.pauseResume();
      }
    }
    // ################################################################################################################
    // Like with setUIState, we need to add a small amount of functionality here without replacing everything.
    me.parentSetLanguage = me.setLanguage;
    me.setLanguage = function(){
        me.parentSetLanguage();
        me._statusDiv2.innerHTML = me.localize("defaultStatus2");
    }

    // ################################################################################################################
    me.setCookieAuthForUrl = function( url, cookieString ) {
      me.cookieStringPerUrl[url] = cookieString;
      if ( !cookieString) {
        delete me.cookieStringPerUrl[url];
      }
    }

    // ################################################################################################################
    me.setQueryAuthForUrl = function( url, queryAuth ) {
      me.queryAuthPerUrl[url] = queryAuth;
      if ( !queryAuth) {
        delete me.queryAuthPerUrl[url];
      }
    }

    // ################################################################################################################
    me.setBasicAuthForUrl = function( url, basicAuthUsername, basicAuthPassword ) {
      me.basicAuthUsernamePerUrl[url] = basicAuthUsername;
      me.basicAuthPasswordPerUrl[url] = basicAuthPassword;
      if ( !basicAuthUsername && !basicAuthPassword ) 
      {
        delete me.basicAuthUsernamePerUrl[url];
        delete me.basicAuthPasswordPerUrl[url];
      }
    }

    // ################################################################################################################
    me.getVerifiedContentMd5ForUrl = function( url ) {
      var md5 = "";
      if ((me.files[url]) && 
          ("object" == typeof me.files[url]) && ("string" == typeof me.files[url].verifiedContentMd5))
      {
        md5 = me.files[url].verifiedContentMd5;
      }
      return md5;
    }

    // ################################################################################################################
    me.appendAuth = function( url ) {
      var cookieString = "";
      var queryAuth = "";
      var basicAuth = "";
      if ( me.cookiestring ) cookieString = "&cookiestring=" + encodeURIComponent( me.cookiestring );
      if ( me.queryauth ) queryAuth = "&queryauth=" + encodeURIComponent( me.queryauth );
      if ( me.basicauth_username && me.basicauth_password ) {
        basicAuth = "&basicauth=" + encodeURIComponent( me.authString( me.basicauth_username, 
                                                                       me.basicauth_password ) );
      }
      if ( url != null )
      {
        if ( me.cookieStringPerUrl[url] ) {
          cookieString = "&cookiestring=" + encodeURIComponent( me.cookieStringPerUrl[url] );
        }
        if ( me.queryAuthPerUrl[url] ) {
          queryAuth = "&queryauth=" + encodeURIComponent( me.queryAuthPerUrl[url] );
        }
        if ( me.basicAuthUsernamePerUrl[url] && me.basicAuthPasswordPerUrl[url] ) {
          basicAuth = "&basicauth=" + encodeURIComponent( me.authString( me.basicAuthUsernamePerUrl[url], 
                                                                  me.basicAuthPasswordPerUrl[url] ) );
        }
      }
      return cookieString + queryAuth + basicAuth;
    }

    // ################################################################################################################
    me.isFinished = function( dlStatus ) {
      if ((dlStatus == "COMPLETE") ||
          (me.skipFailedUrls && 
           ((dlStatus == "NOTFOUND") || 
            (dlStatus == "FORBIDDEN")))) {
        return true;
      } else {
        return false;
      }
    }

    // ################################################################################################################
    me.predictedURL = null;
    me.download = function(predictive){
        // Copy from DLM() object. Needs to act on multiple files!
        if ( !DLMHelper.installed ) return;
        
        var dlURL  = "";
        // Get a url set id
        if ( !me.urlSetId ) {
          dlURL = "http://127.0.0.1:9421/api?function=createUrlSet&cid=" + me.cid;
          DLMHelper.sendRequest( me.dlmId, "CREATE_URL_SET", dlURL );
          return;
        }

        var dlPath = "";
        var iqs    = "";
        var ts     = "";
        var saveAs = "";
        var oo     = "";
        var resurl = "";
        var resfilename = "";
        var autopause = "";
        var wait = "";
        var checkContentMd5 = "";

        // This should work, right?
        // var dlPath, iqs, ts, cs, qa, ba, saveAs, oo, resurl = "";

        if ( me.ignoreQueryString ) {
            iqs = "&originurl=" + encodeURIComponent( me.url );
            url = url.replace( /\?.*$/, "" );
        }
        if ( me.originOnly               ) oo     = "&originonly";
        if ( me.targetSpeed              ) ts     = "&targetspeed=" + me.targetSpeed;
        if ( me.downloadPath == "prompt" ) saveAs = "&saveas=true";

        if (me.resumeURL ) {
          resurl = "&resumeurl=" + encodeURIComponent( me.resumeURL );          
          if ( me.resumeAddUrlSetId )          
          {            
            resurl += encodeURIComponent( ( ( me.resumeURL.indexOf( "?" ) == -1 ) ? "?" : "&" ) + me.resumeAddUrlSetId 
              + "=" + me.urlSetId );
          }
          if ( me.downloadName )
          {
            resfilename = "&resumefilename=" + encodeURIComponent( me.downloadName );
          }
        }
        if ( me.autopause             ) autopause = "&autopause=30";
        if ( me.shouldWait || !me.initialized ) wait = "&wait=true"; 
        if ( me.checkContentMd5      ) checkContentMd5 = "&checkcontentmd5=true"; 

        var funcName;
        funcName = "downloadFile";  
               
        dlURL = "http://127.0.0.1:9421/api?function=" + funcName + autopause + "&cid=" + me.cid + ts + iqs +
          dlPath + oo + resurl + resfilename + wait + checkContentMd5 + "&urlSetId=" + 
          me.urlSetId; 

        // Set the pause blackout, otherwise we may move from one 'complete' file to the next, see it's paused, and
        // assume it was caused by an outside influence.
        me.pauseBlackout = true;
        setTimeout(function(){me.pauseBlackout = false}, 3000);

        // The first time, we don't actually start any downloads.
        if(!me.initialized){
          if (me.unregisteredURLs.length > 0) 
          {
            if (me.downloadPath == "prompt") 
            {
              funcName = "registerUrl";
              wait = "&wait=true";
              saveAs = "&saveas=true";
            }

            dlURL = "http://127.0.0.1:9421/api?function=" + funcName + autopause + "&cid=" + me.cid + ts + iqs +
                     saveAs + dlPath + oo + resurl + resfilename + wait + checkContentMd5 + "&urlSetId=" + 
                      me.urlSetId; 
            dlURL += "&url=" + encodeURIComponent(me.unregisteredURLs[0]);
            dlURL += me.appendAuth( me.unregisteredURLs[0] );
            dlURL += ( me.resetDownload ? "&resetdownload=true" : "" ) ;

            DLMHelper.sendRequest( me.dlmId, "REGISTER", dlURL );
            return; 
          }
          else
          {
            wait = "&wait=true";
            dlURL = "http://127.0.0.1:9421/api?function=closeUrlSet" + wait + "&cid=" + me.cid + 
              "&urlSetId=" + me.urlSetId;
            if ( me.downloadPath == "prompt" ) {
              dlURL += "&saveas=true";
            }
            DLMHelper.sendRequest( me.dlmId, "CLOSE_URL_SET", dlURL );
            return;
          }
        }
        else{
            // If we were called with the 'predictive' flag, we try to start the next file from the incompleteURLs
            // list. This will fire again in a couple seconds, but that's ok.
            if(predictive && me.incompleteURLs.length > 1 && me.predictedURL != me.incompleteURLs[1]){
                dlURL += "&url=" + encodeURIComponent(me.incompleteURLs[1]);
                dlURL += me.appendAuth(me.incompleteURLs[1]);
                me.predictedURL = me.incompleteURLs[1];
            }
            else if(predictive){
                return;
            }
            // If there's a current file and it's not complete, try starting it.
            else if(me.url && !(me.isFinished(me.files[me.url].dlStatus))) {
                dlURL += "&url=" + encodeURIComponent(me.url);
                dlURL += me.appendAuth(me.url);
            }
            // Otherwise, there's no url, or it's COMPLETE, so start the next file, if we've got one.
            else if(me.incompleteURLs.length){
                dlURL += "&url=" + encodeURIComponent(me.incompleteURLs[0]);
                dlURL += me.appendAuth(me.incompleteURLs[0]);
                me.url = me.incompleteURLs[0];
            }
            if (me.version){
                dlURL += "&apiversion=" + me.version;
            }
            me.predictedURL = null;
            DLMHelper.sendRequest( me.dlmId, "DOWNLOAD", dlURL);
        }
    }

    // ################################################################################################################
    // Displays the direct download links (one-per-file) for the BundledDLM
    me.displayDirectDownloadLinks = function() {
        if(me.directDownloadLinkCreated) return ;
        var bundleDirectDownloadMsg = document.createElement("div");
        bundleDirectDownloadMsg.innerHTML = me.localize("bundleDirectDownloadMessage");
        var bundleDirectDownloadLinks = me.createElement("div", "directDownloadContainer");
        var innerHTML = "";
        for( var i = 0; i < me.urls.length; i ++ ) {
            var url = me.urls[i];
            if( ( "undefined" != typeof me.queryAuthPerUrl[me.urls[i]] ) && 
                ( "" != me.queryAuthPerUrl[me.urls[i]] ) ) {
                url += ( "?" + me.queryAuthPerUrl[me.urls[i]] ) ;
            }
            else if( "" != me.queryauth ){
                url += ( "?" + me.queryauth ) ;
            }

            innerHTML += "<a href='" + url + "'title='" + me.urls[i] + "' target='_blank'>" + me.urls[i] + "</a>";
        }
        bundleDirectDownloadLinks.innerHTML = innerHTML ;
        me._installFailedDiv.appendChild(bundleDirectDownloadMsg);
        me._installFailedDiv.appendChild(bundleDirectDownloadLinks);
        me.directDownloadLinkCreated = true;
    }

    // ################################################################################################################
    me.getETA = function( speed, size, progress ){
        // This is an unknowable value with the current implementation, since we don't know the size of all our
        // files until we begin the last one.
        return -1;
    }

    // ################################################################################################################
    me.handleUpdate = function( json ) {
        // Update the status of all our files.
        for (var i in json) {
            if(json[i] == "File not found."){
                me.resetDLM( ) ;

                /*
                 * Call the handler, if defined
                 */
                if ( "function" == typeof me.onCancel ) {
                  me.onCancel();
                }
                return;
            }
            var oldStatus = me.files[i].dlStatus;

            me.files[i].size       = json[i]["size"        ];
            me.files[i].dlStatus   = json[i]["status"      ];
            me.files[i].dlrate     = json[i]["downloadrate"];
            me.files[i].uniquerecv = json[i]["uniquerecv"  ];
            me.files[i].path       = json[i]["path"        ];
            me.files[i].unpausable = json[i]["unpausable"  ];
            me.files[i].verifiedContentMd5 = json[i]["verifiedcontentmd5"  ];
            me.files[i].error      = json[i]["error"  ];
            me.files[i].suberror   = json[i]["suberror"  ];

            if (me.onStatusUpdate) {
              me.onStatusUpdate(i, me.files[i].dlStatus);
            }

            if( me.files[i].dlStatus == "INSUFFICIENTDISKSPACE" ) {
                me.insufficientDiskSpace = true ;
            }
            else {
                me.insufficientDiskSpace = false ;                
            }

            if( me.initialized && ( ( me.insufficientDiskSpace && me.insufficientDiskSpaceResumed ) || ( true == json[i]["resetdownload"] ) ) ) {
                me.waitingToStart = true;
                me.initialized = false;

                /*
                 * Reset the URLs, so that on restart, the process begins from scratch
                 */
                me.unregisteredURLs = [];
                me.incompleteURLs = [];
                for(var ii = 0; ii < me.urls.length; ii++){
                    var file        = new Object();
                    file.dlrate     = 0;
                    file.path       = "";
                    file.size       = 0;
                    file.dlStatus   = "WAITING";
                    file.uniquerecv = 0;
                    file.verifiedContentMd5 = "";
                    file.error      = 0;
                    file.suberror   = 0;
                    me.files[me.urls[ii]] = file;
                    me.incompleteURLs.push(me.urls[ii]);
                    me.unregisteredURLs.push(me.urls[ii]);
                }
                me.url = null;

                /*
                 * Reset the UI state of the progress bars
                 */
                me._progressDiv.style.width = "0%" ;
                me._progressDiv.lastPercent = 0;
                me._progressDiv.measuredPercent = 0;
                me._progressDiv2.style.width = "0%" ;
                me._progressDiv2.lastPercent = 0;
                me._progressDiv2.measuredPercent = 0;
                me.resetDownload = true ;
                me.pathSelectionPending = true;
                me.insufficientDiskSpace = false ;
                me.insufficientDiskSpaceResumed = false ;
                me.showErrorLink = false;
                me.errorInDisplay = false;
                me.hasValidPath = false;

                if (me.intendedState == "DOWNLOADING") 
                {
                  me.download( ) ;
                }

                return ;
            }

            // If we just completed a file, then we remove it from our update list.
            if(me.isFinished(json[i]["status"]) && (json[i]["status"] != oldStatus)) {
                for(var ii = 0; ii < me.incompleteURLs.length; ii++){
                    if(me.incompleteURLs[ii] == i){
                        me.incompleteURLs.splice(ii, 1); // Remove completed files from the incomplete list.
                        // If the file finished, but not because it reached COMPLETE, there's an error we should notify
                        // users of.
                        if ((json[i]["status"] != "COMPLETE") && (typeof(me.onError) == "function")) {
                          me.onError(json[i]["status"], json[i]["error"], json[i]["suberror"], me.incompleteURLs[ii]);
                        }
                        if(!me.waitingToStart){
                            // Start another file downloading.
                            if(me.intendedState == "DOWNLOADING") {
                                me.download();
                            }
                        }
                        break;
                    }
                }
            }
        }

        // File completion prediction to avoid downtime between files.
        // Causes some odd behavior (specifically with pausing downloads), so not currently enabled
        /*
        var cf = me.files[me.url];
        if(cf && ((cf.size - cf.uniquerecv) / cf.dlrate) < 2 ){
            me.download(true); // start a predictive download.
        }
        */

        if(me.waitingToStart){
            // Check and see if everything's PAUSED or COMPLETE.
            var allArePausedorComplete = true;
            for(var ii = 0; ii < me.incompleteURLs.length; ii++){
                if(me.files[me.incompleteURLs[ii]].dlStatus != "PAUSED"){
                    if(me.files[me.incompleteURLs[ii]].dlStatus == "DOWNLOADING"){
                        // Files shouldn't be downloading. Pause them.
                        // This can happen if the DLM page is reloaded.
                        DLMHelper.sendRequest(
                            me.dlmId,
                            "PAUSE",
                            "http://127.0.0.1:9421/api?function=pauseFile&cid=" + me.cid + "&url=" + 
                                encodeURIComponent( me.incompleteURLs[ii] )
                        );
                    }
                    allArePausedorComplete = false;
                    break;
                }
            }
            if(allArePausedorComplete){
                me.waitingToStart = false;
                me.downloadIfReady();
            }
        }

        // Check if we are not downloading the file at all (This can happen if the saveas 
        // dialog is canceled or cache was cleared out or any other event occured and we have 
        // simply deleted the download.)
        /* Not sure how important this is. May leave out for now.
        if ( typeof( me.file.dlStatus ) == "undefined" ) {
            // Reinitialize the download and hide the DLM
            me.polling = false;
            me.file.dlrate     = 0;
            me.file.path       = "";
            me.file.size       = 0;
            me.file.dlStatus   = "WAITING";
            me.file.uniquerecv = 0;
            me.intendedState = "STOPPED";
            me.setUIState( "WAITING" );
            me.showPauseButton();
            me.style.display  = "none";
            return;
        }
        */

        // If we're complete, just mark everything as complete and return.
        if(me.incompleteURLs.length == 0 && me.intendedState != "COMPLETE"){
            me.intendedState = "COMPLETE";
            DLMHelper.log( "downloadCompleted" );
            me.setUIState( "COMPLETE" );
            if ( me.onComplete ) me.onComplete(); // run the onComplete callback if defined
            if ( me.openOnComplete ) me.openFile(); // open the file if requested
            return;
        }

        // Error states
        me.pausedStatusReason = ""; // Clear the error description        
        var pausedStatusReason = "";
        for(var ii = 0; ii < me.incompleteURLs.length; ii++){
            var s = me.files[me.incompleteURLs[ii]].dlStatus;
            if ( s == "NOTFOUND" || s == "INSUFFICIENTDISKSPACE" || s == "FORBIDDEN" ) {
                me.showResumeButton();
                var strings = { "NOTFOUND": "pausedNotFound", "INSUFFICIENTDISKSPACE": "pausedInsufficientDiskSpace",
                                "FORBIDDEN": "pausedForbidden" };
                
                pausedStatusReason = me.getErrorString(me.files[me.incompleteURLs[ii]].error, 
                                                          me.files[me.incompleteURLs[ii]].suberror);
                if ( me.intendedState != "PAUSED") 
                {
                  me.intendedState = "PAUSED";
                  if (!me.errorInDisplay)
                  {                
                    me.populateErrorDetails(pausedStatusReason);
                  }
                  if (typeof(me.onError) == "function") 
                  {
                    me.onError(s, me.files[me.incompleteURLs[ii]].error, me.files[me.incompleteURLs[ii]].suberror, me.incompleteURLs[ii]);
                  }
                }
            }
        }

        // Setting of DLM state based on only the current file.
        if(me.url){
            var dlStatus = me.files[me.url].dlStatus;
            switch(dlStatus)
            {
                case "PAUSED":
                case "INITIALIZING":
                case "WAITING":
                case "DOWNLOADING":
                {
                    if(!me.pauseBlackout)
                    {
                        if(dlStatus == "PAUSED")
                        {
                            me.intendedState = "PAUSED";
                            me.showResumeButton();
                            pausedStatusReason = me.getErrorString(me.files[me.url].error, me.files[me.url].suberror);                       
                            if (!me.errorInDisplay && me.files[me.url].error != 0)
                            {
                                me.populateErrorDetails(pausedStatusReason);
                            }
                            if ((typeof(me.onError) == "function" ) && me.files[me.url].error != 0)
                            {
                                me.onError(dlStatus, me.files[me.url].error, me.files[me.url].suberror, me.url);          
                            }
                        }
                        else
                        {
                            me.intendedState = "DOWNLOADING";
                            me.showPauseButton();
                        }
                    }
                    break;
                }
                case "DISCONNECTED":
                {
                    me.pausedStatusReason = me.localize("pausedDisconnected");
                    break;
                }
                // Other cases handled outside this switch block.
            }
        }

        // intendedState-specific actions.
        switch ( me.intendedState ) {
            // If we're downloading, we need to update the progress bars.
            // Actually, do this in a "PAUSED" state, too, since it can change for a second after pausing.
            case "DOWNLOADING":
            case "PAUSED":
                var filePercent = 0;
                var bundlePercent = 0;
                // Per-file progress bar.

                // We will force the progress bars backwards to match our current progress if we try to pause (and
                // therefore effectively cancel) an unpausable file.
                var forceProgressBarsBackwards = false;

                var currentFileSize = 0;
                var currentFileRecv = 0;
                if(me.url){
                    var f = me.files[me.url];
                    if(f.size > 0)
                    {
                        filePercent = ( f.uniquerecv / f.size ) * 100;
                    }
                    currentFileSize = f.size;
                    currentFileRecv = f.uniquerecv;

                    // Progress is 0 if we're paused and unpausable (because we'll have to start over when we resume).
                    if(f.dlStatus == "PAUSED" && f.unpausable)
                    {
                        filePercent = 0;
                        forceProgressBarsBackwards = true;
                    }
                }

                if(!currentFileSize && currentFileRecv)
                {
                    me._progressDiv.style.width = "100%";
                    me._progressDiv.className = "DLMprogressDisabled";
                }
                else
                {
                    // Reset if we're recovering from the disabled state.
                    if (me._progressDiv.className == "DLMprogressDisabled")
                    {
                        me._progressDiv.className = "DLMprogress";
                        me._progressDiv.style.width = filePercent + "%";
                        me._progressDiv.measuredPercent = filePercent;
                    }
                    me._progressDiv.lastPercent = me._progressDiv.measuredPercent;
                    me._progressDiv.measuredPercent = filePercent;

                    // Overall progress bar.
                    bundlePercent = ((me.urls.length - me.incompleteURLs.length) / me.urls.length) * 100;
                    bundlePercent += me._progressDiv.measuredPercent / me.urls.length;

                    me._progressDiv2.lastPercent = me._progressDiv2.measuredPercent;
                    me._progressDiv2.measuredPercent = bundlePercent;

                    // Hack to make sure bundle progress bar never runs too far ahead. Sure wish Tyler wasn't on
                    // vacation and could review this.
                    if ((me._progressDiv2.measuredPercent - me._progressDiv2.lastPercent) > 5) {
                      me._progressDiv2.lastPercent = me._progressDiv2.measuredPercent - 5;
                    }

                    me.updateProgressBarCounter = 0;
                    me.updateProgressBarsSmooth(forceProgressBarsBackwards);
                }

                if (me.onProgress) {
                  me.onProgress(me.url, filePercent, bundlePercent);
                }

                break;
            default:
                // do nothing.
        }

        // Update the status text message.
        me.writeStatusText();
    }

    // ################################################################################################################
    me.handleRegister = function( json ) {
      if( json[ "error" ] ) {
        me.resetDLM( ) ;
        return ;
      }
      for (var i in json) {
        for(var ii = 0; ii < me.unregisteredURLs.length; ii++) {
          if (me.unregisteredURLs[ii] == i) {
            me.unregisteredURLs.splice(ii, 1); // Remove completed files from the unregistered list.
          }
        }
      }
      me.download();
    }

    // ################################################################################################################
    // Resets the DLM in the following cases:
    // 1) Error while creating URLSetId
    // 2) Failure while registering the URLs
    // 3) 'File Not Found.' error (Clear-cache / User cancelling the Save-as / File write error in the client)
    me.resetDLM = function( ) {
        me.waitingToStart = true;
        me.initialized = false;
        me.intendedState = "CANCELLED";
        me.setUIState( "CANCELLED" );
        me.pathSelectionPending     = true;
        mevalidPath = false;
        /*
         * Reset the URLs, so that on restart, the process begins from scratch
         */
        me.unregisteredURLs = [];
        me.incompleteURLs = [];
        for(var ii = 0; ii < me.urls.length; ii++){
            var file        = new Object();
            file.dlrate     = 0;
            file.path       = "";
            file.size       = 0;
            file.dlStatus   = "WAITING";
            file.uniquerecv = 0;
            me.files[me.urls[ii]] = file;
            me.incompleteURLs.push(me.urls[ii]);
            me.unregisteredURLs.push(me.urls[ii]);
        }
        me.url = null;

        /*
         * Reset the UI state of the progress bars
         */
        me._progressDiv.style.width = "0%" ;
        me._progressDiv.lastPercent = 0;
        me._progressDiv.measuredPercent = 0;
        me._progressDiv2.style.width = "0%" ;
        me._progressDiv2.lastPercent = 0;
        me._progressDiv2.measuredPercent = 0;
    }

    // ################################################################################################################
    me.updateProgressBarTimer = null;
    me.updateProgressBarCounter = 0;
    me.progressLastFileChecked = null;
    me.updateProgressBarsSmooth = function(force){

        // If we've got a count of 0, then we reset. Also, if we've gone a full second, then we reset.
        if(me.updateProgressBarCounter == 0 || me.updateProgressBarCounter >= 20){
            if(me.updateProgressBarTimer){
                clearInterval(me.updateProgressBarTimer);
                me.updateProgressBarTimer = null;
            }
        }

        var done = 0; // Number of progress bars done updating.
        var bars = [me._progressDiv, me._progressDiv2];

        // If our counter is zero, we update our progress bars to indicate actual progress.
        // Otherwise, we estimate based on the time.
        for(var ii = 0; ii < bars.length; ii++){
            var percent = 0;
            if(me.updateProgressBarCounter >= 20){
                var offset = bars[ii].measuredPercent - bars[ii].lastPercent;
                var percent = bars[ii].lastPercent + offset;
                done++;
            }
            else if(bars[ii].lastPercent == 0){
                percent = bars[ii].measuredPercent;
            }
            else{
                var offset = ((bars[ii].measuredPercent - bars[ii].lastPercent) / 20) * me.updateProgressBarCounter;
                percent = bars[ii].measuredPercent + offset;
            }
            if(me.progressLastFileChecked == me.url){
                var old = parseFloat(bars[ii].style.width.replace(/%$/, ""));

                // Allow dropping backwards *only* if we're going all the way to zero.
                if(percent && old > percent)
                {
                    percent = old;
                }
            }
            if (force === true)
            {
              percent = bars[ii].measuredPercent;
            }
            if(percent > 100) percent = 100;
            if(percent < 0) percent = 0;
            bars[ii].style.width = (Math.round( percent * 100 ) / 100) + "%";
        }

        // If there are unfinished progress bars, and our interval isn't already set, and we're on our zeroth
        // iteration, then set a timer.
        if(done < bars.length && me.updateProgressBarTimer == null && me.updateProgressBarCounter == 0){
            me.updateProgressBarTimer = setInterval(me.updateProgressBarsSmooth, 50);
        }
        // Update for the next run through.
        me.progressLastFileChecked = me.url;
        me.updateProgressBarCounter++;
    }

    // ################################################################################################################
    me.setFileToOpen = function( name ){
        me.fileToOpen = name;
        me.setLanguage();
    }

    // ################################################################################################################
    me.parentOpenFile = me.openFile;
    me.openFile = function( evt ){
        if(!me.fileToOpen){
            DLMHelper.warn("Called openFile, but no fileToOpen has been set!");
        }
        else if(!me.files[me.fileToOpen]){
            DLMHelper.warn("Called openFile, but fileToOpen set to invalid URL.");
        }
        else{
            DLMHelper.sendRequest(
                me.dlmId,
                "OPEN",
                "http://127.0.0.1:9421/api?function=openFile&cid=" + me.cid + "&url=" +
                encodeURIComponent( me.fileToOpen )
            );
        }

        // Prevent following links in the case that this function was called via an onclick handler.
        if ( evt && evt.preventDefault ) evt.preventDefault();
        else if ( window.event ) window.event.returnValue = false;
    }

    // ################################################################################################################
    me.poll = function() {
        if (!me.polling)
        {
            me.polling = true;
            setTimeout(me.poll, 1000);
            return;
        }
        if(me.incompleteURLs.length == 0 || me.intendedState == "CANCELLED"){
            me.polling = false;
            return;
        }

        var funcName;
        var type;

        var urlString = "";
        var urlSetIdString = "&urlSetId=" + me.urlSetId;
        
        if (true === DLMHelper.eulaSelectionRequested)
        {
            funcName = "getEulaSelectionStatus";
            type = "EULA_PROMPT_UPDATE";
        
            DLMHelper.sendRequest(
                me.dlmId,
                type,
                "http://127.0.0.1:9421/api?cid=" + me.cid + "&function=" + funcName
            );
        }
        else if (true === DLMHelper.enableUploadsSelectionRequested)
        {
          funcName = "getEnableUploadsSelectionStatus";
          type = "ENABLE_UPLOADS_PROMPT_UPDATE";
        
          DLMHelper.sendRequest(
              me.dlmId,
              type,
              "http://127.0.0.1:9421/api?cid=" + me.cid + "&function=" + funcName
          );
        }
        // If we've got a url, we only check on that file. This implies we've completed all initialization.
        else if(me.url){
            funcName = "getFileAttributes";
            type = "UPDATE";

            urlString += "&url=" + encodeURIComponent(me.url);
            DLMHelper.sendRequest(
                me.dlmId,
                type,
                "http://127.0.0.1:9421/api?cid=" + me.cid + "&function=" + funcName + "&complete" + urlString
            );
        }
        // Otherwise, we have to check on everything, so we can tell when we're ready to actually start downloading.
        else if (me.unregisteredURLs.length == 0) {
            if ((me.downloadPath == "prompt") && (true == me.pathSelectionPending))
            {
              funcName = "getPathSelectionStatus";
              type = "PATH_UPDATE";
              if (me.urls.length)
              {
                urlString += "&url=" + encodeURIComponent(me.urls[0]);
              }
              DLMHelper.sendRequest(
                      me.dlmId,
                      type,
                      "http://127.0.0.1:9421/api?cid=" + me.cid + "&function=" + funcName + "&complete" + urlString + urlSetIdString
                  );
            }
            else
            {
              for(var ii = 0; ii < me.incompleteURLs.length; ii++){
                urlString = "&url=" + encodeURIComponent(me.incompleteURLs[ii]);                
                funcName = "getFileAttributes";
                type = "UPDATE";
                
                DLMHelper.sendRequest(
                    me.dlmId,
                    type,
                    "http://127.0.0.1:9421/api?cid=" + me.cid + "&function=" + funcName + "&complete" + urlString
                );
              }
            }
        }
        setTimeout(me.poll, 1000);
    }

    // ################################################################################################################
    me.writeStatusText = function() {
        var statusText = me.localize("waitStatus");
        var percent = me.localize("percentage", (Math.round(me._progressDiv.measuredPercent * 100) / 100));
        var totalPercent = me.localize("percentage", (Math.round(me._progressDiv2.measuredPercent * 100) / 100));
        var titleText = me.localize("titleTextProgress", totalPercent);
        var fileNum = me.urls.length - me.incompleteURLs.length + 1;
        var fileOf = me.urls.length;
        switch ( me.intendedState ){
            case "STOPPED":
                break;
            case "PAUSED":
                if(me.url)
                    statusText = me.localize("statusProgress", me.url.replace(/^.*[\\\/]/, ""),
                        fileNum, fileOf, percent);
                if (!me.showErrorLink)
                {
                    titleText = me.localize("titleTextPaused", totalPercent);
                }
                
                if ( me.pausedStatusReason )
                {
                    statusText += " " + me.pausedStatusReason;  
                }
                break;
            case "DOWNLOADING":
                if( me.pausedStatusReason )
                {
                    statusText = me.pausedStatusReason;
                }
                else if(me.url)
                {
                    if (me.files && me.files[me.url] && me.files[me.url].uniquerecv && !me.files[me.url].size)
                    {
                        statusText = me.localize("statusProgress", me.url.replace(/^.*[\\\/]/, ""),
                            fileNum, fileOf, me.getSizeString(me.files[me.url].uniquerecv) + "/?");
                    }
                    else
                    {
                        statusText = me.localize("statusProgress", me.url.replace(/^.*[\\\/]/, ""),
                            fileNum, fileOf, percent);
                    }
                }
                break;
            case "COMPLETE":
                statusText = "&nbsp;";
                break;
            case "EULAPROMPT":
                statusText = "&nbsp;";
                break;
            default:
                DLMHelper.warn( "Couldn't write status text for state " + me.intendedState );
                break;
        }
        me._statusDiv.innerHTML = statusText;
            
        // Display the "Show details" link        
        if (me.showErrorLink && !me.errorInDisplay)
        {
            var showDetails = document.createElement("span");
            showDetails.onclick = function(){
                me._errorPopupDiv.style.display = "block";
                me.errorInDisplay = true;
            }
            showDetails.appendChild(document.createTextNode(me.localize("showDetailsTitle")));
            showDetails.className = DLMHelper.showErrorClass;
            me._statusDiv2.innerHTML = titleText + (" ") + (me.localize("errorTitle")) +(" (");
            me._statusDiv2.appendChild(showDetails);
            me._statusDiv2.appendChild(document.createTextNode(")"));            
        }
        else
        {
            me._statusDiv2.innerHTML = titleText;
        }
    }

    // New UI elements.
    me._progressBarDiv2 = me.createElement("div", "progressBar2");
    me._progressDiv2 = me.createElement("div", "progress2");
    me._progressBarDiv2.appendChild(me._progressDiv2);
    me._progressBarDiv.parentNode.insertBefore(me._progressBarDiv2, me._progressBarDiv);
    me._statusDiv2 = me.createElement("div", "statusDiv2");
    me._progressBarDiv2.parentNode.insertBefore(me._statusDiv2, me._progressBarDiv2);

    // TODO: Defaults for these are not currently set in the single-file DLM, but they *should* be.
    me._cancelledMsg.href = "#";
    me._cancelledMsg.onclick = function(){
        /*
         * Since the UI state and the URLs have been already reset, we can proceed with the
         * download, using the previously set URLSetId
         */
        if( "function" == typeof me.onResume ) me.onResume( ) ;
        me.beginDownload( ) ;
        return false;
    }

    me._titleDiv.parentNode.insertBefore(me._cancelledTitle, me._titleDiv.nextSibling);
    me._titleDiv.parentNode.insertBefore(me._cancelledMsg, me._cancelledTitle.nextSibling);

    // Moved UI elements.
    me._progressBarDiv.parentNode.insertBefore(me._statusDiv.parentNode.removeChild(me._statusDiv), me._progressBarDiv);

    // TODO: This is a hack and should be set somewhere else.
    me._statusDiv.style.marginTop = "0.5em";
    me._statusDiv2.style.marginTop = "0.5em";

    // Initialization for drawing smooth progress bars.
    me._progressDiv.lastPercent = 0;
    me._progressDiv.measuredPercent = 0;
    me._progressDiv2.lastPercent = 0;
    me._progressDiv2.measuredPercent = 0;

    // ################################################################################################################
    // Re-attach event handlers that have changed. This needs to be done because of how scoping works in javascript.
    // We also need to remove the exiting event handlers.
    if (window.attachEvent){
        me._completeLink.detachEvent("onclick", me.parentOpenFile);
        me._completeLink.attachEvent("onclick", me.openFile);
    }
    else if (window.addEventListener){
        me._completeLink.removeEventListener("click", me.parentOpenFile, false);
        me._completeLink.addEventListener("click", me.openFile, false);
    }

    // Done initializing this object.
    return me;
}

// ####################################################################################################################
// pseudoDLM class, used for using DLMHelper without a DLM
// ####################################################################################################################
function pseudoDLM( request, callback)
{
    // Internal state variables.
    var me                = document.createElement( "div" );
    me.request            = request;
    me.callback           = callback;
    me.style.display      = "none";
    // We put ourself in the global list of DLMs and keep track of where we are in that list.
    me.dlmId = DLMHelper.register( me );
    // ################################################################################################################
    // This function gets called by DLMHelper's response handler, it passes a request type as sent to
    // DLMHelper.sendRequest, as well as the json response from the client.
    me.handleResponse = function( type, json ) {
      callback( json );
    }

    // ################################################################################################################
    // This is a pseudo-event-handler that lets the DLMHelper object send us messages that we can
    // act on. Notably, the DLMHelper can let us know as soon as the client has been installed so
    // we can proceed with our download.
    me.notify = function( message ){
      switch ( message ) {
            case "INSTALLED":
                DLMHelper.sendRequest( me.dlmId, "PSEUDO", me.request );
                break;
            case "EULAACCEPTED":
            case "EULADECLINED":
            case "ENABLEUPLOADSACCEPTED":
            case "ENABLEUPLOADSDECLINED":
                break;
            default:
                DLMHelper.warn( "'notify()' called with unsupported message: " + message );
        }
    }

    if ( DLMHelper.installed ) {
      me.notify("INSTALLED");
    } else {
      DLMHelper.startInstall( );
    }

    // Return our modified div 'me'.
    return me;
}

// ####################################################################################################################
// DLMHelper is an Object, rather than a 'Class'. It's a singleton and can not be instantiated. #######################
// ####################################################################################################################
var DLMHelper = new Object();

// Configuration
DLMHelper.enableQueryLog = false;

// Global state variables.
DLMHelper.DLMs             = new Array();
DLMHelper.installed        = false;
DLMHelper.lookingForClient = false;
DLMHelper.lookedForClient  = false;
DLMHelper.installClientOnceLookedFor = false;
// Default EXE name, if one wasn't specified.
DLMHelper.exeName          = "installer";
DLMHelper.supportedBrowser = false;
DLMHelper.acceptedEULA     = false;
DLMHelper.isUploadEnabled      = false; // disabled; this is the client's upload state, not to be confused with customer flag 'uploadEnabled'
DLMHelper.eulaSelectionRequested = false; // true => we're sending promptEULA to the client
DLMHelper.eulaSelectionDone = false; // true => the user has chosen accept/decline at least once (so don't ask again on this page)
DLMHelper.enableUploadsSelectionRequested = false; // true => we're sending promptEnableUploads to the client
DLMHelper.enableUploadsSelectionDone = false; // true => the user has chosen accept/decline at least once (so don't ask again on this page)
DLMHelper.logEvents        = {};
DLMHelper.onClientInstall  = null;
DLMHelper.uploadEnabled    = false;
DLMHelper.askEnableUploads = false; // set to enable promptEnableUploads when the user has disabled uploads
DLMHelper.modalPopupDivId  = "DLMmodalDiv";
DLMHelper.popupPopupDivId  = "DLMpopupDiv";
DLMHelper.modalClass       = "dlmModal";
DLMHelper.popupClass       = "dlmPopup";
DLMHelper.closeErrorClass  = "closeError";
DLMHelper.errorMsgClass    = "errorMsg";
DLMHelper.errorPopupClass  = "error";
DLMHelper.showErrorClass   = "DLMshowErrorDetails";
DLMHelper.errorDivClass    = "errorDiv";
DLMHelper.errorHeaderClass = "errorHeader";
DLMHelper.installFailed    = false;
DLMHelper.newInstallerUrl  = "https://client.akamai.com/conf/install.html";
DLMHelper.oldInstallerUrl  = "https://client.akamai.com/conf/install_" + 
                              (window.navigator.userAgent.match( /OS X/ ) ? "mac" : "win") + ".html";
DLMHelper.installerUrl     = null;

// ####################################################################################################################
// Helper functions from here on down. ################################################################################
// ####################################################################################################################

// ####################################################################################################################
// Auxiliary functions to support multiple downloads:

// Starts download of all DLMs in the group.
// Parameter group is optional. If not provided, all DLMs registered with DLMHelper are started. 
DLMHelper.downloadAll = function( group ) {
    var dlms = DLMHelper.DLMs; 
    if ( group ) dlms = group;
    for ( var i = 0; i < dlms.length; i++ )
        dlms[ i ].beginDownload();
    return false; // prevents standard event handler when invoked by click on anchor
}

// Starts download of all DLMs in the group having their checkboxes checked. 
// If they don't have a checkbox they are started too.
// Parameter group is optional. If not provided, all DLMs registered with DLMHelper are started. 
DLMHelper.downloadSelected = function( group ) {
    var dlms = DLMHelper.DLMs; 
    if ( group ) dlms = group;
    for ( var i = 0; i < dlms.length; i++ ) {
        if ( dlms[ i ].checkbox ) {
            var checkbox = document.getElementById( dlms[ i ].checkbox );
            if ( checkbox && !checkbox.checked ) continue;
        }
        dlms[i].beginDownload();
    }
    return false; // prevents standard event handler when invoked by click on anchor
}

// Pauses or resumes (depending on current state) all the DLMs in a group 
// or if group not specified pauses/resumes all DLMs registered with the DLMHelper. 
DLMHelper.pauseResumeAll = function( group ) {
    var dlms = DLMHelper.DLMs; 
    if ( group ) dlms = group;
    for ( var i = 0; i < dlms.length; i++ )
        dlms[ i ].pauseResume();
    return false; // prevents standard event handler when invoked by click on anchor
}

// Checks/unchecks all checkboxes for DLMs in a group. Param checked is true (to check) or false (to uncheck).
// Parameter group is optional. If not provided, all DLMs registered with DLMHelper and having checkboxes are
// (un)checked.
DLMHelper.checkAll = function( checked, group ) {
    var dlms = DLMHelper.DLMs; 
    if ( group ) dlms = group;
    for ( var i = 0; i < dlms.length; i++ ) {
        if ( dlms[ i ].checkbox ) {
            var checkbox = document.getElementById( dlms[ i ].checkbox );
            if ( checkbox ) checkbox.checked = checked;
        }
    }
    return false; // prevents standard event handler when invoked by click on anchor
}

// ####################################################################################################################
// Creates a new script tag with the provided source url. A random number is appended to avoid caching.
// The script tag is removed after 10 seconds.
DLMHelper.scriptRequest = function( url ) {
    var s = document.createElement( "script" );
    s.type = "text/javascript";
    s.src = url + "&r=" + Math.random();
    document.getElementsByTagName( "head" )[ 0 ].appendChild( s );
    setTimeout( function(){ s.parentNode.removeChild( s ) }, 10000 );
}

// ####################################################################################################################
// When we get responses from the client, we send the response back to the same DLM that made the request in the first
// place.
DLMHelper.dispatchResponse = function( dlmId, type, json ) {
    try        { DLMHelper.DLMs[ dlmId ].handleResponse( type, json ); }
    catch( e ) {
        DLMHelper.warn("Couldn't call 'handleResponse()' for DLM " + dlmId + ", Error: " + e);
        throw( e );
    }
}

// ####################################################################################################################
// This is used to locate the Akamai client. Optionally runs repeatedly until the client is found.
DLMHelper.findClient = function( delay ) {
    if ( DLMHelper.installed ) return;
    var cid = 1;
    try{
        eval("cid = DLMCID");
    }
    catch(e){
        // Whatever, I guess they didn't define DLMCID, use 1.
    }
    
    // Akamai developers: Keep this in sync with euc_cn dynamic config setting DesignatedInternalCpCode.
    var installCpCode = 78333;
    try{
        eval("installCpCode = INSTALL_CP_CODE");
    }
    catch(e){}

    if(cid == 1 && DLMHelper.DLMs[0]) cid = DLMHelper.DLMs[0].cid;
    DLMHelper.scriptRequest( "http://127.0.0.1:9421/api?function=getClientAttributes&installcpcode=" +
        installCpCode +"&cid=" + cid + "&complete&wrapper=DLMHelper.setInstalled(*);" );
    if ( delay ) setTimeout( function(){ DLMHelper.findClient( delay ) }, delay );
}

// ####################################################################################################################
// Initialize everything that's required for this library to function.
DLMHelper.init = function() {

    var osOK      = false;
    var browserOK = false;

    // Regexes to check for supported OSes (Windows, OS X).
    // Supported Mac OS X - 10.5 through 10.9 (Intel only)
    // Supported Windows OS - WinXP and newer ( WinXP, Vista, Windows 7... )
    var sOSes = [
        /Intel Mac OS X 10(_|\.)[5-9]/,
        /Windows NT ((5\.[^0])|[6-9])/
    ];

    // Regexes to check for supported browsers:
    var sBrowsers = [
        /Firefox\/([3-9]|(\d\d+))/,  // Firefox 3+
        /MSIE ([6-9]|(\d\d+))/, // IE 6+
        /Version\/([4-9]|(\d\d+))[0-9.]+ Safari\//, // Safari 4+
        /Chrome\/[0-9.]+ Safari\// // Any version of Chrome.
    ];

    for (var i = 0; i < sBrowsers.length; i++)
    {
        if (sBrowsers[i].exec(window.navigator.userAgent))
        {
          browserOK = true;
          break;
        }
    }

    for (var i = 0; i < sOSes.length; i++)
    {
        if (sOSes[i].exec(window.navigator.userAgent))
        {
          osOK = true;
          break;
        }
    }

    if ( osOK && browserOK ) {
        DLMHelper.supportedBrowser = true;
        DLMHelper.findClient( 0 );
    }

    // Default the onInstallFailure to displayDirectDownloadLinks()
    DLMHelper.onInstallFailure = DLMHelper.displayDirectDownloadLinks;
    DLMHelper.language         = DLMHelper.getComputedLanguage();

    //Enabling new install experience by default
    DLMHelper.onStartInstall   = DLMHelper.displayInstallerPopup;

    window.onbeforeunload = function() {
        for ( var i = 0; i < DLMHelper.DLMs.length; i++ )
            if ( DLMHelper.DLMs[ i ].intendedState == "DOWNLOADING" )
                return DLMHelper.DLMs[ i ].localize( "unloadMsg" );
    }

    // We want to log that this page was loaded, but we want to know if the client was already installed.
    setTimeout( function(){
        DLMHelper.lookedForClient = true;
        if( DLMHelper.installed ) {
          if ( DLMHelper.onClientInstall && "function" == typeof DLMHelper.onClientInstall ) {
            DLMHelper.onClientInstall( /*newInstall=*/false ) ;
          }
          DLMHelper.log( "loadAlreadyInstalled" );
        } else {
          DLMHelper.log( "loadNotInstalled" );
          if (DLMHelper.installClientOnceLookedFor)
          {
            DLMHelper.startInstall( );
          }
        }
    }, 1000 );
}

// ####################################################################################################################
DLMHelper.open = function( a, b, c, d ) {
    if ( window.attachEvent ) { // should be IE.
        DLMHelper.startInstall( d );
    }
    return window.open( a, b, c );
}

// ####################################################################################################################
DLMHelper.register = function( dlm ){
    DLMHelper.DLMs.push( dlm );
    return DLMHelper.DLMs.length - 1;
}

// ####################################################################################################################
// Sends requests to the client in a format that guarantees we'll be able to give the response back to the correct DLM
// object.
DLMHelper.sendRequest = function( dlmId, type, url ) {
    DLMHelper.scriptRequest( url + "&wrapper=DLMHelper.dispatchResponse(" + dlmId + ", '" + type + "',*);" );
}

// ####################################################################################################################
// Used as the callback via the 'findClient' function, simply sets the installed flag to true on any response from the
// client.
DLMHelper.setInstalled = function( json ) {
    if (DLMHelper.installed) 
    {
      return;
    }
    var cid = 1;
    try{
        eval("cid = DLMCID");
    }
    catch(e){
        // I guess they didn't define DLMCID, use 1.
    }
    DLMHelper.installed = true;
    if (DLMHelper.logEvents["loadNotInstalled"]) {// Keeps from logging before we've find out we were already there.
        DLMHelper.log("installCompleted");
        if ( "function" == typeof DLMHelper.onClientInstall ) {
            DLMHelper.onClientInstall( /*newInstall=*/true ) ;
        }

        // For the popup-based installation experience, hide the popup
        if( "function" == typeof DLMHelper.onStartInstall ) {
            DLMHelper.hideInstallerPopup();
        }
    }

    // If the EULA had already been accepted before we even figured out the client had been installed, then a 
    // user must have accepted it to start the installation. This means we'll have to notify the client that
    // the EULA's been installed.
    var alreadyAcceptedEULA = DLMHelper.acceptedEULA;

    // See if a EULA's been accepted.
    if( json[ "acceptedeula" ] && json[ "acceptedeula" ] == true ) {
        DLMHelper.acceptedEULA = true;
    }
    
    // See if uploads are enabled.
    if( 0 === json[ "uploadspauseduntil" ] ) {
        DLMHelper.isUploadEnabled = true;
    }
    
    // Notify any existing DLMs that the client's been installed.
    for ( var i = 0; i < DLMHelper.DLMs.length; i++ ) {
        if ( DLMHelper.DLMs[ i ] ){
            DLMHelper.DLMs[ i ].notify( "INSTALLED" );
            if ( DLMHelper.acceptedEULA )
                DLMHelper.DLMs[ i ].notify( "EULAACCEPTED" );
        }
    }
}

// ####################################################################################################################
// Processes the user's choice of accept/decline in response to the promptEULA dialog.
// Call this method when getEulaSelectionStatus responds with pending == false.
// Notifies all DLMs of accept/decline.
//
// Intended state before calling: Client is installed, EULA not accepted, and request is pending
DLMHelper.processEULASelection = function( accepted ) {
    if ( !DLMHelper.installed || DLMHelper.acceptedEULA || !DLMHelper.eulaSelectionRequested )
    {
        return;
    }

    DLMHelper.acceptedEULA = accepted;
    DLMHelper.eulaSelectionRequested = false;
    DLMHelper.eulaSelectionDone = true;

    // Notify any existing DLMs that the EULA's been accepted/declined.
    for ( var i = 0; i < DLMHelper.DLMs.length; i++ )
    {
        if ( DLMHelper.DLMs[ i ] ) 
        {
            DLMHelper.DLMs[ i ].notify( accepted ? "EULAACCEPTED" : "EULADECLINED" );
        }
    }
}

// ####################################################################################################################
// Intended state before calling: Client is installed, EULA not accepted, and request is not pending
DLMHelper.promptEULA = function( cid ) {
    if ( !DLMHelper.installed || DLMHelper.acceptedEULA || DLMHelper.eulaSelectionRequested )
    {
        return;
    }
    
    DLMHelper.eulaSelectionRequested = true;
    
    //  Ask the client to prompt the user with the EULA
    var url = "http://127.0.0.1:9421/api?cid=" + cid + "&function=promptEULA" +
        "&wrapper=function ignore(){var ig = *;return false;}";
    DLMHelper.scriptRequest( url );
}

// ####################################################################################################################
// Processes the user's choice of accept/decline in response to the promptEnableUploads dialog.
// Call this method when getEnableUploadsSelectionStatus responds with pending == false.
// Notifies all DLMs of upload state.
//
// Intended state before calling: Client is installed, EULA accepted, uploads disabled, and request is pending
DLMHelper.processEnableUploadsSelection = function( enabled ) {
    if ( !DLMHelper.installed || !DLMHelper.acceptedEULA || DLMHelper.isUploadEnabled || !DLMHelper.enableUploadsSelectionRequested )
    {
        return;
    }

    DLMHelper.isUploadEnabled = enabled;
    DLMHelper.enableUploadsSelectionRequested = false;
    DLMHelper.enableUploadsSelectionDone = true;

    // Notify any existing DLMs that enabling uploads been accepted/declined.
    for ( var i = 0; i < DLMHelper.DLMs.length; i++ )
    {
        if ( DLMHelper.DLMs[ i ] ) 
        {
            DLMHelper.DLMs[ i ].notify( enabled ? "ENABLEUPLOADSACCEPTED" : "ENABLEUPLOADSDECLINED" );
        }
    }
}

// ####################################################################################################################
// Intended state before calling: Client is installed, EULA accepted, uploads disabled, and request is not pending
DLMHelper.promptEnableUploads = function( cid ) {
    if ( !DLMHelper.installed || !DLMHelper.acceptedEULA || DLMHelper.isUploadEnabled || DLMHelper.enableUploadsSelectionRequested )
    {
        return;
    }
    
    DLMHelper.enableUploadsSelectionRequested = true;
    
    //  Ask the client to prompt the user to enable uploads
    var url = "http://127.0.0.1:9421/api?cid=" + cid + "&function=promptEnableUploads" +
        "&wrapper=function ignore(){var ig = *;return false;}";
    DLMHelper.scriptRequest( url );
}

// ####################################################################################################################
// This pops up the dialog box to download and run the installer.
DLMHelper.startInstall = function( exeName ) {

    // For an unsupported OS+Browser combo OR if we've already encountered a failure before,
    // call the failure-handler immediately
    if( !DLMHelper.isPlatformSupported() || true === DLMHelper.installFailed ) {
        DLMHelper.onInstallFailure();
        return;
    }

    if ( exeName ) {
      DLMHelper.exeName = exeName;
    }

    if ( !DLMHelper.lookedForClient ) {
      DLMHelper.installClientOnceLookedFor = true;
      return;
    }
    
    // Once we've had someone start an install, we begin checking for the client every second until it's found.
    if ( !DLMHelper.lookingForClient ) {
        DLMHelper.lookingForClient = true;
        DLMHelper.findClient( 1000 );
    }

    if ( DLMHelper.installed ) return;

    // Display some install specific messages (over-rideable)
    if( "function" == typeof DLMHelper.onStartInstall ) {
        DLMHelper.onStartInstall();
    }
    // Download the NetSession client installer
    else {
        DLMHelper.downloadInstaller( DLMHelper.exeName ) ;
    }
}

// ####################################################################################################################
// Downloads the NetSession client installer
DLMHelper.downloadInstaller = function( exeName ) {
    // For Internet Explorer, we only want to run this if we're running as part of an onclick event handler.
    // If we're called from any other context, we'll be blocked by the pop-up blocker anyway, so we just return now to
    // avoid causing a yellow bar at the top of the window.
    if ( window.attachEvent ) { // should be IE.
        if ( !window.event || window.event.type != "click" ) return;
    }

    if(!DLMHelper.installerUrl) {
      DLMHelper.useUpdatedInstallerSet();
    }

    if("string" != typeof exeName) exeName = DLMHelper.exeName;

    var iframe           = document.createElement( "iframe" );
    iframe.id            = "DLMDownloadInstallerIframe";
    iframe.style.width   = "0";
    iframe.style.height  = "0";
    iframe.style.display = "none";
    iframe.src = DLMHelper.installerUrl + "?file=" + encodeURIComponent( exeName.replace( / /g, "_" ) ) + 
                 "&upload=" + DLMHelper.uploadEnabled.toString();
    document.body.appendChild( iframe );
    return false;
}

// ####################################################################################################################
// Determines whether the Browser+OS combination is supported or not
DLMHelper.isPlatformSupported = function( ) {
    return DLMHelper.supportedBrowser ;
}

// ####################################################################################################################
// Determines whether the Netsession client is installed or not
DLMHelper.isClientInstalled = function( ) {
    return DLMHelper.installed ;
}

// ####################################################################################################################
// Configures the name to be given to the EXE/DMG installer
DLMHelper.setExeName = function( exeName ) {
    if( "string" == typeof exeName) {
        DLMHelper.exeName = exeName ;
    }
}

// ####################################################################################################################
// Sets the URL from which the installer is loaded
DLMHelper.setInstallerUrl = function( installerUrl ) {
    if( "string" == typeof installerUrl ) {
        DLMHelper.installerUrl = installerUrl ;
    }
}

// ####################################################################################################################
// Sets the URL to point to the new set of installers (new == 1.5.7+)
DLMHelper.useUpdatedInstallerSet = function( ) {
    DLMHelper.setInstallerUrl( DLMHelper.newInstallerUrl ) ;
}

// ####################################################################################################################
// Sets the URL to point to the older set of installers (old == pre-1.5.7)
DLMHelper.useBasicInstallerSet = function( ) {
    DLMHelper.setInstallerUrl( DLMHelper.oldInstallerUrl ) ;
}

// ####################################################################################################################
// Creates the necessary UI for displaying the installer popup
DLMHelper.displayInstallerPopup = function( ) {
    // We're either here for the first time OR the user is retrying the installation.
    // Until the user complains, reset the value.
    DLMHelper.installFailed = false;
    var modalDiv = document.getElementById(DLMHelper.modalPopupDivId);
    var popupDiv = document.getElementById(DLMHelper.popupPopupDivId);
    if( !modalDiv || !popupDiv ) {
        modalDiv = document.createElement("div");
        modalDiv.setAttribute("id", DLMHelper.modalPopupDivId);
        modalDiv.className = DLMHelper.modalClass;
        document.body.appendChild(modalDiv);

        popupDiv = document.createElement("div");
        popupDiv.setAttribute("id", DLMHelper.popupPopupDivId);
        popupDiv.className = DLMHelper.popupClass;
        document.body.appendChild(popupDiv);
    }
    popupDiv.innerHTML = DLMHelper.localize( DLMHelper.language, "popupContent", ["installMsg",DLMHelper.localize( DLMHelper.language, "installMsg" )] ) ;
    modalDiv.style.display = "block";
    popupDiv.style.display = "block";
    return false;
}

// ####################################################################################################################
// Hide the installer popup. If the installation was reported "failed", reset the UI for the next time
DLMHelper.hideInstallerPopup = function() {
    var modalDiv = document.getElementById(DLMHelper.modalPopupDivId);
    var popupDiv = document.getElementById(DLMHelper.popupPopupDivId);
    if(!modalDiv || !popupDiv) 
    {
        return;
    }
    modalDiv.style.display = "none";
    popupDiv.style.display = "none";

    if (!DLMHelper.installed)
    {
        if (true === DLMHelper.installFailed) {
            DLMHelper.onInstallFailure();
        }
        else {
            // The popup is being closed, and the installation is neither complete nor failed.
            // Notify the DLMs about this state and expect them to reset themselves.
            for (var i = 0; i < DLMHelper.DLMs.length; i++)
            {
                if (DLMHelper.DLMs[i])
                {
                    DLMHelper.DLMs[i].notify( "INSTALLSTOPPED" );
                }
            }
        }
    }
    return false;
}

// ####################################################################################################################
// Display (and hide) certain messages explaining the installation failure to the end user.
DLMHelper.setInstallFailure = function() {
    DLMHelper.installFailed = true;
    var popupDiv = document.getElementById(DLMHelper.popupPopupDivId);
    if(popupDiv)
    {
        popupDiv.innerHTML = DLMHelper.localize( DLMHelper.language, "popupContent", ["installFailureMsg",DLMHelper.localize( DLMHelper.language, "installFailureMsg" )] ) ;
    }
    return false;
}

// ####################################################################################################################
// Display Direct Download links for the waiting DLM
DLMHelper.displayDirectDownloadLinks = function() {
    for ( var i = 0; i < DLMHelper.DLMs.length; i++ ) {
        if ( DLMHelper.DLMs[ i ] ){
            DLMHelper.DLMs[ i ].notify( "INSTALLFAILED" );
        }
    }
}

// ####################################################################################################################
// Display warnings as alerts. This may be replaced with a logging mechanism.
DLMHelper.warn = function( warning ) {
     // alert( warning ); // temporarily disabled
}

// ####################################################################################################################
DLMHelper.queryLog = function( colName ) {
    if ( !DLMHelper.enableQueryLog ) 
        return;
    var sSrc = "http://qg.redswoosh.akadns.net/query?t=dlmstats&c=" + colName + "&o=inc&w=count";
    DLMHelper.scriptRequest( sSrc );
}

// ####################################################################################################################
DLMHelper.log = function( eventKey ) {
    if( DLMHelper.logEvents["loadAlreadyInstalled"] )
        return; // If the client was installed when we got here, then we never log anything besides that.
    if( DLMHelper.logEvents[eventKey] )
        return; // We don't log the same event more than once.
    DLMHelper.logEvents[eventKey] = true;
    DLMHelper.queryLog( eventKey );
}

// ####################################################################################################################
DLMHelper.getUrlSetId = function( urlSetIdCallback ) {
  new pseudoDLM("http://127.0.0.1:9421/api?function=createUrlSet&cid=" + DLMCID, 
                function( json ) { 
                  for ( var i in json ) {
                    if ( i == "urlSetId" ) {
                      urlSetIdCallback(json[i]);
                      return;
                    }
                  }
                });
}

// ####################################################################################################################
  DLMHelper.getUrlSet = function( urlSetId, urlSetCallback ) {
  new pseudoDLM("http://127.0.0.1:9421/api?function=getUrlSet&cid=" + DLMCID + "&urlSetId=" + urlSetId, 
                function( json ) { 
                  for ( var i in json ) {
                    if ( i == "urls" ) {
                      urlSetCallback(eval(json[i]));
                    }
                  }
                });
}

// ####################################################################################################################
// Sets the end-user installer experience
DLMHelper.setRecommendedInstall = function( installHandler ) {
    if( "function" == typeof installHandler ) {
        DLMHelper.onStartInstall = installHandler ;
    }
}

// ####################################################################################################################
// Returns the localized string, based on the key+language pair. The args are used for substituting
// in the localized string.
DLMHelper.localize = function( language, key, args ) {
    if(!DLMHelper.languages[language])
        return key;
    else if(!DLMHelper.languages[language][key] && DLMHelper.languages[language][key] !== "")
        return key;
    else{
        var val = DLMHelper.languages[language][key];
        // Do substitution on our list of arguments.
        var argIdx = 1;
        val = val.replace(/%s/g, function(){
            if(argIdx >= args.length) return "";
            else return args[argIdx++];
        });
        return val;
    }
}

// ####################################################################################################################
// Compute the applicable DLM language
DLMHelper.getComputedLanguage = function( language, defaultLanguage ) {
    if( "undefined" == typeof language ) {
        language = "auto";
    }
    if( "undefined" == typeof defaultLanguage ) {
        defaultLanguage = "en";
    }

    if(language != "auto" && !DLMHelper.languages[language]){
        DLMHelper.warn("Language set to '" + language + "', but we don't have that translation, trying 'auto'.");
        language = "auto";
    }
    if(language == "auto"){
        var lvars = [navigator.browserLanguage, navigator.userLanguage, navigator.systemLanguage,
            navigator.language];
        for(var i = 0; i < lvars.length; i++){
            if(lvars[i]){
                if(DLMHelper.languages[lvars[i]]){
                    language = lvars[i];
                    break;
                } else if(DLMHelper.languages[lvars[i].substr(0,2)]){
                    language = lvars[i].substr(0, 2);
                    break;
                }
                else
                    DLMHelper.warn("Browser wanted language '" + i + "', but no translation available.");
            }
        }
    }
    // Couldn't figure out which language to use.
    if(!DLMHelper.languages[language]){
        if(DLMHelper.languages[defaultLanguage]){
            DLMHelper.warn("Couldn't determine language from browser, using default: " + defaultLanguage);
            language = defaultLanguage;
        }
        else if(DLMHelper.languages["en"]){
            DLMHelper.warn("No translation for default language '" + defaultLanguage + "', using English.");
            language = "en";
        }
    }
    return language;
}

// Create the default stylesheet for DLM objects.
// WARNING! This must be a full URL, with the protocol, domain, path, and file name!
DLMHelper.css = "http://client.akamai.com/dlm/dlm.css";
try{
    DLMHelper.css = DLMCSS;
}
catch(e){
    // We don't actually care about this error, we're just trying to trap 'DLMCSS' being undefined.
}

if(DLMHelper.css){
    // For already loaded DOMs.
    if(document.getElementsByTagName("head").length){
        var style = document.createElement("link");
        style.type = "text/css";
        style.rel = "stylesheet";
        style.href = DLMHelper.css;
        document.getElementsByTagName("head")[0].appendChild(style);
    }
    // For DOMs currently loading. (Not sure if this is ever called).
    else document.write( "<link rel='stylesheet' href='" + DLMHelper.css + "' type='text/css' />" );
}


// Set all the strings used for all of our supported languages.
DLMHelper.languages = {
    cs: {
        "startTitle": "Klikněte na možnost Spustit nebo Otevřít, tím spustíte instalační program.",
        "relaunchMsgStart": "Nezobrazil se instalační program? ",
        "relaunchLink": "Zkuste jej znovu otevřít.",
        "relaunchMsgEnd": "",
        "title": "Stahování souboru %s",
        "autoStart": " Automaticky otevřít po dokončení.",
        "completeTitle": "Stahování dokončeno!",
        "completeText": "Otevřít soubor %s",
        "timeLabel": "%s do konce.",
        "waiting": "Čekám.",
        "paused": "Pozastaveno.",
        "pausedNotFound": "Soubor nenalezen!",
        "pausedInsufficientDiskSpace": "Nedostatečné místo na disku!",
        "pausedForbidden": "Přístup odepřen!",
        "pausedDisconnected": "Odpojeno od serveru, zkouším znovu...",
        "unloadMsg": "Právě probíhá stahování. Pokud stránku opustíte, stahování bude ihned přerušeno.",
        "minute": "minuta",
        "minutes": "minut(y)",
        "second": "sekunda",
        "seconds": "sekund(y)",
        "download": "Stáhnout",
        "hourAbbr": "h",
        "minAbbr": "m",
        "calcTime": "Výpočet zbývající doby.",
        // New Bundled DLM strings. Also adds localizable percentage format.
        "waitStatus": "Čekám...",
        "defaultStatus2": "Inicializace...",
        "titleTextProgress": "Celkový průběh – %s",
        "titleTextPaused": "Celkový průběh – %s – POZASTAVENO",
        "statusProgress": "%s (%s ze %s): %s",
        "percentage": "%s%",
        "cancelledTitle": "Zrušeno – %s",
        "cancelledMsg": "Spustit stahování znovu.",
        // New error strings
        "unexpectedHttpResponse": "Přijata neočekávaná odpověď od HTTP",
        "missingRange": "Chybí hlavička Rozsah",
        "missingRangeProxy": "Chybí hlavička Rozsah. Možná nekompatibilita proxy",
        "zeroContentLength": "Chybí délka obsahu",
        "zeroContentLengthProxy": "Chybí délka obsahu. Možná nekompatibilita proxy",
        "invalidFileSize": "Neočekávaná velikost souboru",
        "invalidFileSizeProxy": "Neočekávaná velikost souboru. Možná nekompatibilita proxy",
        "invalidRange": "Neplatná hlavička odpovědi Rozsah obsahu",
        "invalidRangeProxy": "Neplatná hlavička odpovědi Rozsah obsahu. Možná nekompatibilita proxy",
        "negativeSize": "Neplatná hlavička odpovědi Rozsah obsahu",
        "negativeSizeProxy": "Neplatná hlavička odpovědi Rozsah obsahu. Možná nekompatibilita proxy",
        "503Response": "Služba je dočasně nedostupná",
        "unrecognizedResponse": "Odpověď nebyla rozpoznána",
        "unrecognizedResponseProxy": "Odpověď nebyla rozpoznána. Možná nekompatibilita proxy",
        "tooManyRedirects": "Příliš mnoho přesměrování HTTP",
        "missingLocationHeader": "Chybí hlavička Umístění",
        "missingLocationHeaderProxy": "Chybí hlavička Umístění“ Možná nekompatibilita proxy",
        "invalidLocationHeader": "Neplatná hlavička Umístění",
        "invalidLocationHeaderProxy": "Neplatná hlavička Umístění. Možná nekompatibilita proxy",
        "timeOutError": "Překročen časový limit požadavku",
        "contentVerficationError": "Chyba ověření obsahu",
        "noRsmd": "Nelze stanovit správnost obsahu",
        "contentInvalid": "Neplatný obsah",
        "connectivityError": "Výpadek konektivity",
        "serverUnreachable": "Server je nedostupný",
        "deletionInProgress": "Probíhá mazání",
        "diskError": "Chyba disku",
        "noPermissions": "Přístup zakázán",
        "fileReadOnly": "Došlo k pokusu o zápis do souboru či zařízení umožňujícího pouze přístup ke čtení",
        "tooManyFiles": "Příliš mnoho otevřených souborů",
        "dirNotFound": "Daný soubor či adresář neexistuje nebo jej nelze najít",
        "noSpace": "Na zařízení není volné místo",
        "crossDeviceError": "Došlo k pokusu o přemístění souboru na jiné zařízení",
        "popupContent": "<div id='DLMtitleBar'><div id='DLMpopupClose' onclick='return DLMHelper.hideInstallerPopup();'></div><div id='DLMlogo'></div><span id='DLMpopupTitle'>Akamai NetSession Interface</span></div><div class='DLMheaderPadding'></div><div id='DLMpopupContainer'>%s</div><div class='DLMheaderPadding'></div>",
        "installMsg": "<div class='DLMinstallMsgHeight'><div>K dokončení stahování je nutné nainstalovat Akamai NetSession Interface, což je správce stahování, který zkracuje dobu stahování a zvyšuje kvalitu. Instalace zabere maximálně několik minut. Poté bude Vaše stahování obnoveno.</div><br /><div> Postupujte podle následujících pokynů:</div><br /><ol><li>Stáhněte si instalační program kliknutím na níže uvedený odkaz.</li><li>Spusťte stažený instalační program – dojde ke spuštění NetSession Interface.</li><li>Po dokončení instalace se toto okno zavře a stahování bude znovu spuštěno v prohlížeči.</li></ol><br /><div> Stahování spustíte kliknutím na tento odkaz: <a href='#' onclick='return DLMHelper.downloadInstaller();'>stáhnout instalační program</a>.</div><br /><div>Máte-li dotazy nebo si přejete získat více informací o Akamai NetSession Interface, navštivte naše <a href='http://www.akamai.com/client' target=_blank>domovské stránky</a>.</div><br /><div>Pokud se Vám nedaří instalaci dokončit, <a href='#' onclick='return DLMHelper.setInstallFailure();'>klikněte sem</a>.</div></div>",
        "installFailureMsg": "<div class='DLMfailureMsgHeight'><div>Mrzí nás, že se Vám instalaci nepodařilo dokončit. Věnujte nám prosím chvíli a poskytněte nám <a href='http://www.akamai.com/html/misc/akamai_client/dlm_feedback.html' target='_blank'> zpětnou vazbu </a> ohledně procesu instalace.</div><br /><br /><div> Stisknutím tlačítka <span style='font-weight: bold; margin: 0;'>OK</span> vyskakovací okno a budete mít možnost zkusit jiný postup stahování .<br />Stisknutím tlačítka <span style='font-weight:bold; margin: 0;'>Opakovat</span> se vrátíte na předchozí obrazovku. Tam zkuste instalaci opakovat.</div><br /><input type='submit' value='OK' onclick='return DLMHelper.hideInstallerPopup();' /><input type='submit' value='Opakovat' onclick='return DLMHelper.displayInstallerPopup();' style='margin-left: 20px;' /></div>",
        "singleDirectDownloadLink": "Stahování pomocí prohlížeče spustíte kliknutím <a href=\"%s\" target=\"_blank\">zde</a>.",
        "bundleDirectDownloadMessage": "Stahování pomocí prohlížeče spustíte kliknutím na odkazy jednotlivých souborů.",
        "errorPopUpHeader" : "Podrobnosti o chybě:",
        "errorTitle": "CHYBA",
        "showDetailsTitle": "Zobrazit podrobnosti"
    },
    da : {
        "startTitle": "Klik på \"kør\" eller \"åbn\" for at starte installationsprogrammet.",
        "relaunchMsgStart": "Kan du ikke se installationsprogrammet? ",
        "relaunchLink": "Prøv at åbne det igen.",
        "relaunchMsgEnd": "",
        "title": "Overfører %s",
        "autoStart": " Åbn automatisk, når udført.",
        "completeTitle": "Overførslen udført!",
        "completeText": "Åbn %s",
        "timeLabel": "%s tilbage.",
        "waiting": "Venter.",
        "paused": "Stoppet midlertidigt.",
        "pausedNotFound": "Fil ikke fundet!",
        "pausedInsufficientDiskSpace": "Utilstrækkelig plads på disken!",
        "pausedForbidden": "Adgang nægtet!",
        "pausedDisconnected": "Forbindelse til serveren afbrudt, prøver igen...",
        "unloadMsg": "Overførsel i gang. Hvis du forlader siden nu, afbrydes overførslen om et øjeblik.",
        "minute": "minut",
        "minutes": "minutter",
        "second": "sekund",
        "seconds": "sekunder",
        "download": "Overfør",
        "hourAbbr": "t",
        "minAbbr": "m",
        "calcTime": "Beregner tiden tilbage.",
        // New Bundled DLM strings. Also adds localizable percentage format.
        "waitStatus": "Venter...",
        "defaultStatus2": "Initialiserer...",
        "titleTextProgress": "Samlet status %s",
        "titleTextPaused": "Samlet status %s STOPPET MIDLERTIDIGT",
        "statusProgress": "%s (%s af %s): %s",
        "percentage": "%s%",
        "cancelledTitle": "Annulleret %s",
        "cancelledMsg": "Genstart overførslen.",
        // New error strings
        "unexpectedHttpResponse": "Modtog et uventet HTTP svar",
        "missingRange": "Mangler \“Område\” overskrift",
        "missingRangeProxy": "Mangler \“Område\” overskrift. Mulig proxy inkompatibilitet",
        "zeroContentLength": "Mangler indhold længde",
        "zeroContentLengthProxy": "Mangler indhold længde. Mulig proxy inkompatibilitet",
        "invalidFileSize": "Uventet filstørrelse",
        "invalidFileSizeProxy": "Uventet filstørrelse. Mulig proxy inkompatibilitet",
        "invalidRange": "Ugyldig \“Indhold-område\” svar overskrift",
        "invalidRangeProxy": "Ugyldig \“Indhold-område\” svar overskrift. Mulig proxy inkompatibilitet",
        "negativeSize": "Ugyldig \“Indhold-område\” svar overskrift",
        "negativeSizeProxy": "Ugyldig \“Indhold-område\” svar overskrift. Mulig proxy inkompatibilitet",
        "503Response": "Servicen er midlertidigt utilgængelig",
        "unrecognizedResponse": "Svar ikke genkendt",
        "unrecognizedResponseProxy": "Svar ikke genkendt. Mulig proxy inkompatibilitet",
        "tooManyRedirects": "For mange HTTP omadresseringer",
        "missingLocationHeader": "Mangler \“Lokation\” overskrift",
        "missingLocationHeaderProxy": "Mangler \“Lokation\” overskift. Mulig proxy inkompatibilitet",
        "invalidLocationHeader": "Ugyldig \“Lokation\” overskift",
        "invalidLocationHeaderProxy": "Ugyldig \“Lokation\” overskift. Mulig proxy inkompatibilitet",
        "timeOutError": "Forespørgsel timeout",
        "contentVerficationError": "Indhold verifikation fejl",
        "noRsmd": "Kan ikke bestemme indholds korrekthed",
        "contentInvalid": "Indhold ugyldigt",
        "connectivityError": "Konnektivitet fejl",
        "serverUnreachable": "Server kan ikke nås",
        "deletionInProgress": "Sletning i gang",
        "diskError": "Disk fejl",
        "noPermissions": "Tilladelse afvist",
        "fileReadOnly": "Det blev forsøgt at skrive til en fil, eller enhed åbnede for read-only adgang",
        "tooManyFiles": "For mange åbne filer",
        "dirNotFound": "Den angivne fil eller sti findes ikke eller kan ikke findes",
        "noSpace": "Ikke mere plads på enheden",
        "crossDeviceError": "Det blev forsøgt at flytte en fil til en anden enhed",
        "popupContent": "<div id='DLMtitleBar'><div id='DLMpopupClose' onclick='return DLMHelper.hideInstallerPopup();'></div><div id='DLMlogo'></div><span id='DLMpopupTitle'>Akamai NetSession Interface</span></div><div class='DLMheaderPadding'></div><div id='DLMpopupContainer'>%s</div><div class='DLMheaderPadding'></div>",
        "installMsg": "<div class='DLMinstallMsgHeight'><div>For at fuldføre denne download, må du installere Akamai NetSession Interface, en download manager, der bruges til at reducere downloadtiden og øge kvaliteten. Denne installation bør højst tage nogle få minutter, hvorefter din download kan fortsætte.</div><br /><div>Følg følgende trin:</div><br /><ol><li>Download installeren ved at klikke på linket nedenfor.</li><li> Kør den downloade installer – den vil sætte NetSession Interface op.</li><li> Når installationen er udført, vil denne pop-op lukke, og downloaden vil fortsætte i browser-vinduet.</li></ol><br /><div> Klik her for at begynde: <a href='#' onclick='return DLMHelper.downloadInstaller();'>download installeren</a>.</div><br /><div>Hvis du har nogen spørgsmål, eller ønsker mere information om Akamai NetSession Interface, bedes du besøge vores <a href='http://www.akamai.com/client' target=_blank>hjemmeside</a>.</div><br /><div>Hvis du ikke kan udføre installationen, <a href='#' onclick='return DLMHelper.setInstallFailure();'>klik her</a>.</div></div>",
        "installFailureMsg": "<div class='DLMfailureMsgHeight'><div>Vi beklager, at installationen mislykkedes. Brug venligst et øjeblik på at dele din <a href='http://www.akamai.com/html/misc/akamai_client/dlm_feedback.html' target='_blank'>feedback</a> vedrørende denne installationsproces.</div><br /><br /><div>Tryk på <span style='font-weight: bold; margin: 0;'>OK</span> for at lukke denne pop-op og forsøge en alternativ metode til download.<br />Tryk på <span style='font-weight:bold; margin: 0;'>Forsøg igen</span> for at returnere til den forrige skærm og forsøge installation igen.</div><br /><input type='submit' value='OK' onclick='return DLMHelper.hideInstallerPopup();' /><input type='submit' value='Forsøg igen' onclick='return DLMHelper.displayInstallerPopup();' style='margin-left: 20px;' /></div>",
        "singleDirectDownloadLink": "Klik <a href=\"%s\" target=\"_blank\">her</a> for at downloade ved brug af din browser.",
        "bundleDirectDownloadMessage": "Klik på de enkelte fil-links for at downloade ved brug af din browser.",
        "errorPopUpHeader" : "Fejl detaljer:",
        "errorTitle": "FEJL",
        "showDetailsTitle": "Vis detaljer"
    },
    de: {
        "startTitle": "Klicken Sie auf \„Ausführen\“ oder \„Öffnen\“, um das Installationsprogramm zu öffnen.",
        "relaunchMsgStart": "Das Installationsprogramm wird nicht angezeigt? ",
        "relaunchLink": "Öffnen Sie das Programm erneut.",
        "relaunchMsgEnd": "",
        "title":  "Wird heruntergeladen: %s",
        "autoStart": " Nach Beenden Datei automatisch öffnen.",
        "completeTitle": "Download beendet!",
        "completeText": " öffnen",
        "timeLabel": "Noch %s.",
        "waiting": "Warten.",
        "paused": "Angehalten.",
        "pausedNotFound": "Datei nicht gefunden.",
        "pausedInsufficientDiskSpace": "Festplattenspeicher nicht ausreichend.",
        "pausedForbidden": "Zugriff verweigert.",
        "pausedDisconnected": "Verbindung unterbrochen.",
        "unloadMsg": "Es wird derzeit ein Download durchgeführt. Wenn Sie diese Seite jetzt verlassen, wird der Download in Kürze angehalten.",
        "minute": "Minute",
        "minutes": "Minuten",
        "second": "Sekunde",
        "seconds": "Sekunden",
        "download": "Download",
        "hourAbbr": "Std",
        "minAbbr": "Min",
        "calcTime": "Dauer wird berechnet.",
		"waitStatus": "Warten ...",
        "defaultStatus2": "Initialisieren ...",
        "titleTextProgress": "Gesamtfortschritt %s",
        "titleTextPaused": "Gesamtfortschritt %s PAUSIERT",
        "statusProgress": "%s (%s von %s): %s",
        "percentage": "%s %",
        "cancelledTitle": "%s abgebrochen",
        "cancelledMsg": "Starten Sie den Download erneut.",
        // New error strings
        "unexpectedHttpResponse": "Eine unerwartete HTTP-Antwort wurde empfangen",
        "missingRange": "Fehlender \„Range\“-Header",
        "missingRangeProxy": "Fehlender \„Range\“-Header. Mögliche Proxy-Inkompatibilität",
        "zeroContentLength": "Fehlende Inhaltslänge",
        "zeroContentLengthProxy": "Fehlende Inhaltslänge. Mögliche Proxy-Inkompatibilität",
        "invalidFileSize": "Unerwartete Dateigröße",
        "invalidFileSizeProxy": "Unerwartete Dateigröße. Mögliche Proxy-Inkompatibilität",
        "invalidRange": "Ungültiger \„Content-Range\”-Response-Header",
        "invalidRangeProxy": "Ungültiger \„Content-Range\”-Response-Header. Mögliche Proxy-Inkompatibilität",
        "negativeSize": "Ungültiger \„Content-Range\”-Response-Header",
        "negativeSizeProxy": "Ungültiger \„Content-Range\”-Response-Header. Mögliche Proxy-Inkompatibilität",
        "503Response": "Der Service ist vorübergehend nicht verfügbar",
        "unrecognizedResponse": "Antwort nicht erkannt",
        "unrecognizedResponseProxy": "Antwort nicht erkannt. Mögliche Proxy-Inkompatibilität",
        "tooManyRedirects": "Zu viele HTTP-Weiterleitungen",
        "missingLocationHeader": "Fehlender \„Location\“-Header",
        "missingLocationHeaderProxy": "Fehlender \„Location\“-Header. Mögliche Proxy-Inkompatibilität",
        "invalidLocationHeader": "Ungültiger \„Location\“-Header",
        "invalidLocationHeaderProxy": "Ungültiger \„Location\“-Header. Mögliche Proxy-Inkompatibilität",
        "timeOutError": "Timeout anfordern",
        "contentVerficationError": "Fehler bei Inhaltsverifizierung",
        "noRsmd": "Bestimmung des korrekten Inhalts nicht möglich",
        "contentInvalid": "Inhalt ungültig",
        "connectivityError": "Verbindungsfehler",
        "serverUnreachable": "Server nicht erreichbar",
        "deletionInProgress": "Löschen in Bearbeitung",
        "diskError": "Festplattenfehler",
        "noPermissions": "Zugriff verweigert",
        "fileReadOnly": "Es wurde versucht, in eine Datei oder ein Gerät mit reinem Lesezugriff zu schreiben",
        "tooManyFiles": "Zu viele geöffnete Dateien",
        "dirNotFound": "Die angegebene Datei oder das Verzeichnis existiert nicht oder konnte nicht gefunden werden",
        "noSpace": "Kein Platz mehr auf dem Gerät vorhanden",
        "crossDeviceError": "Es wurde versucht, eine Datei in ein anderes Gerät zu verschieben",
        "popupContent": "<div id='DLMtitleBar'><div id='DLMpopupClose' onclick='return DLMHelper.hideInstallerPopup();'></div><div id='DLMlogo'></div><span id='DLMpopupTitle'>Akamai NetSession Interface</span></div><div class='DLMheaderPadding'></div><div id='DLMpopupContainer'>%s</div><div class='DLMheaderPadding'></div>",
        "installMsg": "<div class='DLMinstallMsgHeight'><div>Installieren Sie das Akamai NetSession Interface, um diesen Download-Vorgang abschließen zu können. Hierbei handelt es sich um einen Download-Manager, der den Download beschleunigt und die Qualität verbessert. Die Installation nimmt nur ein paar Minuten in Anspruch. Anschließend wird der Download-Vorgang fortgesetzt.</div><br /><div>Gehen Sie bitte wie folgt vor:</div><br /><ol><li>Klicken Sie auf den folgenden Link, um das Installationsprogramm herunterzuladen.</li><li> Starten Sie das Installationsprogramm – die Einrichtung des NetSession Interface erfolgt automatisch.</li><li>Sobald der Installationsprozess abgeschlossen ist, wird das Popup-Fenster automatisch geschlossen und der Download im Browser-Fenster fortgesetzt.</li></ol><br /><div>Zum Starten hier klicken: <a href='#' onclick='return DLMHelper.downloadInstaller();'>Installationsprogramm herunterladen</a>.</div><br /><div>Wenn Sie Fragen bezüglich des NetSession Interface von Akamai haben oder weitere Informationen benötigen, besuchen Sie sich bitte unsere <a href='http://www.akamai.com/client' target=_blank>Homepage</a>.</div><br /><div>Wenn Sie die Installation nicht beenden können, <a href='#' onclick='return DLMHelper.setInstallFailure();'>klicken Sie bitte hier</a>.</div></div>",
        "installFailureMsg": "<div class='DLMfailureMsgHeight'><div>Leider ist die Installation fehlgeschlagen. Bitte nehmen Sie sich einen Moment Zeit und geben Sie Ihr <a href='http://www.akamai.com/html/misc/akamai_client/dlm_feedback.html' target='_blank'>Feedback</a> zum Installationsvorgang ab.</div><br /><br /><div>Klicken Sie auf <span style='font-weight: bold; margin: 0;'>OK</span>, um dieses Popup-Fenster zu schließen und eine andere Download-Methode zu verwenden.<br />Klicken Sie auf <span style='font-weight:bold; margin: 0;'>Erneut versuchen</span> um zur vorherigen Seite zurückzukehren und mit der Installation erneut zu beginnen.</div><br /><input type='submit' value='OK' onclick='return DLMHelper.hideInstallerPopup();' /><input type='submit' value='Erneut versuchen' onclick='return DLMHelper.displayInstallerPopup();' style='margin-left: 20px;' /></div>",
        "singleDirectDownloadLink": "Klicken Sie <a href=\"%s\" target=\"_blank\">hier</a>, um den Download in Ihrem Browser zu starten.",
        "bundleDirectDownloadMessage": "Klicken Sie auf den jeweiligen Link der Dateien, um den Download in Ihrem Browser zu starten.",
        "errorPopUpHeader" : "Fehlerbeschreibung:",
        "errorTitle": "FEHLER",
        "showDetailsTitle": "Einzelheiten ansehen"
    },
    en: {
        "startTitle": "Click \"run\" or \"open\" to start the installer.",
        "relaunchMsgStart": "Don't see the installer? ",
        "relaunchLink": "Try reopening it.",
        "relaunchMsgEnd": "",
        "title": "Downloading %s",
        "autoStart": " Automatically open when complete.",
        "completeTitle": "Download Complete!",
        "completeText": "Open %s",
        "timeLabel": "%s remaining.",
        "waiting": "Waiting.",
        "paused": "Paused.",
        "pausedNotFound": "File not found!",
        "pausedInsufficientDiskSpace": "Insufficient disk space!",
        "pausedForbidden": "Access denied!",
        "pausedDisconnected": "Disconnected from server, retrying...",
        "unloadMsg": "There is currently a download in progress. If you leave now, the download will pause shortly.",
        "minute": "minute",
        "minutes": "minutes",
        "second": "second",
        "seconds": "seconds",
        "download": "Download",
        "hourAbbr": "h",
        "minAbbr": "m",
        "calcTime": "Calculating time remaining.",
        // New Bundled DLM strings. Also adds localizable percentage format.
        "waitStatus": "Waiting...",
        "defaultStatus2": "Initializing...",
        "titleTextProgress": "Total Progress %s",
        "titleTextPaused": "Total Progress %s PAUSED",
        "statusProgress": "%s (%s of %s): %s",
        "percentage": "%s%",
        "cancelledTitle": "Cancelled %s",
        "cancelledMsg": "Restart the download.",
        // New error strings
        "unexpectedHttpResponse": "Received an unexpected HTTP response",
        "missingRange": "Missing \"Range\" header",
        "missingRangeProxy": "Missing \"Range\" header. Possible proxy incompatibility",
        "zeroContentLength": "Missing content length",
        "zeroContentLengthProxy": "Missing content length. Possible proxy incompatibility",
        "invalidFileSize": "Unexpected file Size",
        "invalidFileSizeProxy": "Unexpected file Size. Possible proxy incompatibility",
        "invalidRange": "Invalid \"Content-Range\" response header",
        "invalidRangeProxy": "Invalid \"Content-Range\" response header. Possible proxy incompatibility",
        "negativeSize": "Invalid \"Content-Range\" response header",
        "negativeSizeProxy": "Invalid \"Content-Range\" response header. Possible proxy incompatibility",
        "503Response": "The service is temporarily unavailable",
        "unrecognizedResponse": "Response not recognized",
        "unrecognizedResponseProxy": "Response not recognized. Possible proxy incompatibility",
        "tooManyRedirects": "Too many HTTP redirects",
        "missingLocationHeader": "Missing \"Location\" header",
        "missingLocationHeaderProxy": "Missing \"Location\" header. Possible proxy incompatibility",
        "invalidLocationHeader": "Invalid \"Location\" header",
        "invalidLocationHeaderProxy": "Invalid \"Location\" header. Possible proxy incompatibility",
        "timeOutError": "Request Timeout",
        "contentVerficationError": "Content verification failure",
        "noRsmd": "Unable to determine content correctness",
        "contentInvalid": "Content invalid",
        "connectivityError": "Connectivity Error",
        "serverUnreachable": "Server unreachable",
        "deletionInProgress": "Deletion in progress",
        "diskError": "Disk Error",
        "noPermissions": "Permission denied",
        "fileReadOnly": "An attempt was made to write to a file or device opened for read-only access",
        "tooManyFiles": "Too many open files",
        "dirNotFound": "The specified file or directory does not exist or cannot be found",
        "noSpace": "Insufficient Disk Space",
        "crossDeviceError": "An attempt was made to move a file to a different device",
        "popupContent": "<div id='DLMtitleBar'><div id='DLMpopupClose' onclick='return DLMHelper.hideInstallerPopup();'></div><div id='DLMlogo'></div><span id='DLMpopupTitle'>Akamai NetSession Interface</span></div><div class='DLMheaderPadding'></div><div id='DLMpopupContainer'>%s</div><div class='DLMheaderPadding'></div>",
        "installMsg": "<div class='DLMinstallMsgHeight'><div>To complete this download, you need to install the Akamai NetSession Interface, a download manager used to reduce download time and increase quality. This install should take only a few minutes at most, after which your download can resume.</div><br /><div>Please take the following steps:</div><br /><ol><li>Download the installer by clicking the link below.</li><li>Run the downloaded installer - it will set up the NetSession Interface.</li><li>When the install has completed, this popup will close and the download will resume in the browser window.</li></ol><br /><div>Click here to begin: <a href='#' onclick='return DLMHelper.downloadInstaller();'>download the installer</a>.</div><br /><div>If you have questions or want more information about Akamai NetSession Interface, please visit our <a href='http://www.akamai.com/client' target=_blank>home page</a>.</div><br /><div>If you cannot complete the installation, <a href='#' onclick='return DLMHelper.setInstallFailure();'>click here</a>.</div></div>",
        "installFailureMsg": "<div class='DLMfailureMsgHeight'><div>We're sorry the installation failed. Please take a moment to share your <a href='http://www.akamai.com/html/misc/akamai_client/dlm_feedback.html' target='_blank'>feedback</a> regarding this installation process.</div><br /><br /><div>Press <span style='font-weight: bold; margin: 0;'>OK</span> to close this popup and try an alternate download method.<br />Press <span style='font-weight:bold; margin: 0;'>Retry</span> to return to the previous screen and try the installation again.</div><br /><input type='submit' value='OK' onclick='return DLMHelper.hideInstallerPopup();' /><input type='submit' value='Retry' onclick='return DLMHelper.displayInstallerPopup();' style='margin-left: 20px;' /></div>",
        "singleDirectDownloadLink": "Click <a href=\"%s\" target=\"_blank\">here</a> to download using your browser.",
        "bundleDirectDownloadMessage": "Click the individual file links to download using your browser.",
        "errorPopUpHeader" : "Error Details:",
        "errorTitle": "ERROR",
        "showDetailsTitle": "Show Details"
        },
    es: {
        "startTitle": "Haga clic en \"ejecutar\" o \"abrir\" para iniciar el instalador",
        "relaunchMsgStart": "¿No ve el instalador? ",
        "relaunchLink": "Pruebe a abrirlo de nuevo",
        "relaunchMsgEnd": "",
        "title": "Descargando %s",
        "autoStart": " Abrir el archivo automáticamente una vez finalizada la descarga",
        "completeTitle": "¡Descarga completa!",
        "completeText": "Abrir ",
        "timeLabel": "%s restante",
        "waiting": "Esperando",
        "paused": "Pausado",
        "pausedNotFound": "¡Archivo no encontrado!",
        "pausedInsufficientDiskSpace": "¡No hay suficiente espacio en el disco!",
        "pausedForbidden": "¡Acceso denegado!",
        "pausedDisconnected": "Desconectado",
        "unloadMsg": "Actualmente hay una descarga en proceso. Si abandona ahora, la descarga se detendrá en breve.",
        "minute": "minuto",
        "minutes": "minutos",
        "second": "segundo",
        "seconds": "segundos",
        "download": "Descarga",
        "hourAbbr": "h",
        "minAbbr": "m",
        "calcTime": "Calculando tiempo restante",
        "waitStatus": "Esperando...",
        "defaultStatus2": "Inicializando...",
        "titleTextProgress": "Progreso Total  %s",
        "titleTextPaused": "Progreso Total PAUSADO %s",
        "statusProgress": "%s (%s de %s): %s",
        "percentage": "%s%",
        "cancelledTitle": "Cancelado %s",
        "cancelledMsg": "Reiniciar la descarga.",
        // New error strings
        "unexpectedHttpResponse": "Se ha recibido una respuesta HTTP inesperada",
        "missingRange": "Falta cabecera del \"Rango\"",
        "missingRangeProxy": "Falta cabecera del \"Rango\". Posible incompatibilidad de Proxy",
        "zeroContentLength": "Falta longitud del contenido",
        "zeroContentLengthProxy": "Falta longitud del contenido. Posible incompatibilidad de Proxy",
        "invalidFileSize": "Tamaño de archivo inesperado",
        "invalidFileSizeProxy": "Tamaño de archivo inesperado. Posible incompatibilidad de Proxy",
        "invalidRange": "Cabecera de respuesta de \"Rango de Contenido\" no válida",
        "invalidRangeProxy": "Cabecera de respuesta de \"Rango de Contenido\" no válida\". Posible incompatibilidad de Proxy",
        "negativeSize": "Cabecera de respuesta de \"Rango de Contenido\" no válida\". Posible incompatibilidad de Proxy",
        "negativeSizeProxy": "Cabecera de respuesta de \"Rango de Contenido\" no válida\". Posible incompatibilidad de Proxy",
        "503Response": "El servicio no está disponible temporalmente",
        "unrecognizedResponse": "Respuesta no reconocida",
        "unrecognizedResponseProxy": "Respuesta no reconocida. Posible incompatibilidad de Proxy",
        "tooManyRedirects": "Demasiadas redirecciones HTTP",
        "missingLocationHeader": "Falta cabecera de \"Ubicación\"",
        "missingLocationHeaderProxy": "Falta cabecera de \"Ubicación\". Posible incompatibilidad de Proxy",
        "invalidLocationHeader": "Cabecera de  \"Ubicación\" no válida",
        "invalidLocationHeaderProxy": "Cabecera de  \"Ubicación\" no válida. Posible incompatibilidad de Proxy",
        "timeOutError": "Interrupción de la petición",
        "contentVerficationError": "Fallo en la verificación del contenido",
        "noRsmd": "Imposible determinar la corrección del contenido",
        "contentInvalid": "Contenido no válido",
        "connectivityError": "Error de Conectividad",
        "serverUnreachable": "No se puede llegar al servidor",
        "deletionInProgress": "Eliminación en progreso",
        "diskError": "Error del disco",
        "noPermissions": "Permiso denegado",
        "fileReadOnly": "Se ha realizado un intento para escribir en un archivo o dispositivo abierto con permiso de lectura solamente",
        "tooManyFiles": "Demasiados archivos abiertos",
        "dirNotFound": "El archivo o directorio especificado no existe o no puede encontrarse",
        "noSpace": "No queda espacio en el dispositivo",
        "crossDeviceError": "Se ha intentado mover un archivo a un dispositivo diferente",
        "popupContent": "<div id='DLMtitleBar'><div id='DLMpopupClose' onclick='return DLMHelper.hideInstallerPopup();'></div><div id='DLMlogo'></div><span id='DLMpopupTitle'>Akamai NetSession Interface</span></div><div class='DLMheaderPadding'></div><div id='DLMpopupContainer'>%s</div><div class='DLMheaderPadding'></div>",
        "installMsg": "<div class='DLMinstallMsgHeight'><div>Para completar esta descarga, necesita instalar Akamai NetSession Interface, un gestor de descargas que se utiliza para reducir el tiempo de descarga y aumentar la calidad. Esta instalación debería tardar sólo unos minutos como mucho, tras lo cual se retomará la descarga.</div><br /><div>Por favor siga los siguientes pasos:</div><br /><ol><li>Descargue el instalador haciendo clic en el siguiente enlace.</li><li>Ejecute el instalador que ha descargado – éste configurará la NetSession Interface.</li><li>Cuando la instalación se haya completado, esta ventana emergente se cerrará y se retomará la descarga en el navegador.</li></ol><br /><div>Haga clic aquí para comenzar: <a href='#' onclick='return DLMHelper.downloadInstaller();'>descargar el instalador</a>.</div><br /><div>Si tiene alguna duda o desea más información acerca de Akamai NetSession Interface, por favor visite nuestra <a href='http://www.akamai.com/client' target=_blank>página de inicio</a>.</div><br /><div>Si no puede completar la instalación, <a href='#' onclick='return DLMHelper.setInstallFailure();'>haga clic aquí</a>.</div></div>",
        "installFailureMsg": "<div class='DLMfailureMsgHeight'><div>Lo lamentamos, la instalación ha fallado. Le agradecemos que nos envíe sus <a href='http://www.akamai.com/html/misc/akamai_client/dlm_feedback.html' target='_blank'>comentarios</a> sobre este proceso de instalación.</div><br /><br /><div>Presione <span style='font-weight: bold; margin: 0;'>OK</span> para cerrar esta ventana emergente e intentar con un método de descarga alternativo.<br />Presione <span style='font-weight:bold; margin: 0;'>Reintentar</span> para volver a la pantalla anterior e intentar la instalación de nuevo.</div><br /><input type='submit' value='OK' onclick='return DLMHelper.hideInstallerPopup();' /><input type='submit' value='Reintentar' onclick='return DLMHelper.displayInstallerPopup();' style='margin-left: 20px;' /></div>",
        "singleDirectDownloadLink": "Haga clic <a href=\"%s\" target=\"_blank\">aquí</a> para iniciar la descarga usando su navegador.",
        "bundleDirectDownloadMessage": "Haga clic en los enlaces a cada archivo individual para descargarlo usando su navegador.",
        "errorPopUpHeader" : "Detalles del Error:",
        "errorTitle": "ERROR",
        "showDetailsTitle": "Mostrar Detalles"
    },
    fi: {
        "startTitle": "Käynnistä asennusohjelma valitsemalla suorita tai avaa.",
        "relaunchMsgStart": "Etkö näe asennusohjelmaa? ",
        "relaunchLink": "Yritä avata se uudelleen.",
        "relaunchMsgEnd": "",
        "title": "Ladataan kohdetta %s",
        "autoStart": " Avaa automaattisesti, kun tiedosto on ladattu.",
        "completeTitle": "Tiedosto on ladattu!",
        "completeText": "Avaa %s",
        "timeLabel": "%s jäljellä.",
        "waiting": "Odotetaan.",
        "paused": "Keskeytetty.",
        "pausedNotFound": "Tiedostoa ei löydy.",
        "pausedInsufficientDiskSpace": "Levytila ei riitä.",
        "pausedForbidden": "Käyttö on estetty.",
        "pausedDisconnected": "Yhteys palvelimeen on katkennut, yritetään uudelleen...",
        "unloadMsg": "Lataaminen on käynnissä. Jos poistut nyt, lataaminen keskeytyy hetkeksi.",
        "minute": "minuutti",
        "minutes": "minuuttia",
        "second": "sekunti",
        "seconds": "sekuntia",
        "download": "Lataa",
        "hourAbbr": "h",
        "minAbbr": "m",
        "calcTime": "Lasketaan kestoa jäljellä.",
        // New Bundled DLM strings. Also adds localizable percentage format.
        "waitStatus": "Odotetaan...",
        "defaultStatus2": "Alustetaan...",
        "titleTextProgress": "Kokonaisedistyminen: %s",
        "titleTextPaused": "Kokonaisedistyminen: %s. KESKEYTETTY",
        "statusProgress": "%s (%s / %s): %s",
        "percentage": "%s %",
        "cancelledTitle": "Peruutettu: %s",
        "cancelledMsg": "Käynnistä lataaminen uudelleen.",
        // New error strings
        "unexpectedHttpResponse": "Odottamaton HTTP-vastaus",
        "missingRange": "\"Range\" –ylätunniste puuttuu",
        "missingRangeProxy": "\"Range\" -ylätunniste puuttuu. Mahdollinen välityspalvelimen epäsopivuus",
        "zeroContentLength": "Puuttuva sisällön pituus",
        "zeroContentLengthProxy": "Puuttuva sisällön pituus. Mahdollinen välityspalvelimen epäsopivuus",
        "invalidFileSize": "Odottamaton tiedostokoko",
        "invalidFileSizeProxy": "Odottamaton tiedostokoko. Mahdollinen välityspalvelimen epäsopivuus",
        "invalidRange": "\"Content-Range\" –ylätunniste on virheellinen",
        "invalidRangeProxy": "\"Content-Range\" –ylätunniste on virheellinen. Mahdollinen välityspalvelimen epäsopivuus",
        "negativeSize": "\"Content-Range\" –ylätunniste on virheellinen",
        "negativeSizeProxy": "\"Content-Range\" –ylätunniste on virheellinen. Mahdollinen välityspalvelimen epäsopivuus",
        "503Response": "Palvelu on väliaikaisesti poissa käytöstä",
        "unrecognizedResponse": "Vastausta ei tunnisteta",
        "unrecognizedResponseProxy": "Vastausta ei tunnisteta. Mahdollinen välityspalvelimen epäsopivuus",
        "tooManyRedirects": "Liian monta HTTP:n uudelleenohjausta",
        "missingLocationHeader": "\"Location\" –ylätunniste puuttuu",
        "missingLocationHeaderProxy": "\"Location\" –ylätunniste puuttuu. Mahdollinen välityspalvelimen epäsopivuus",
        "invalidLocationHeader": "\"Location\" –ylätunniste on virheellinen",
        "invalidLocationHeaderProxy": "\"Location\" –ylätunniste on virheellinen. Mahdollinen välityspalvelimen epäsopivuus",
        "timeOutError": "Palvelimen odotusaika umpeutui",
        "contentVerficationError": "Sisällön varmennusvirhe",
        "noRsmd": "Sisällön oikeellisuutta ei pystytä varmistamaan",
        "contentInvalid": "Virheellinen sisältö",
        "connectivityError": "Yhteysvirhe",
        "serverUnreachable": "Palvelimeen ei saada yhteyttä",
        "deletionInProgress": "Poisto käynnissä",
        "diskError": "Levyvirhe",
        "noPermissions": "Käyttöoikeus kielletty",
        "fileReadOnly": "Yritys kirjoittaa lukutiedostona avatulle tiedostolle tai laitteelle",
        "tooManyFiles": "Liian monta aukiolevaa tiedostoa",
        "dirNotFound": "Hakemaasi tiedostoa tai hakemistoa ei ole olemassa tai sitä ei löydetty",
        "noSpace": "Laitteella ei ole tilaa",
        "crossDeviceError": "Yritys siirtää tiedosto toiselle laitteelle",
        "popupContent": "<div id='DLMtitleBar'><div id='DLMpopupClose' onclick='return DLMHelper.hideInstallerPopup();'></div><div id='DLMlogo'></div><span id='DLMpopupTitle'>Akamai NetSession Interface</span></div><div class='DLMheaderPadding'></div><div id='DLMpopupContainer'>%s</div><div class='DLMheaderPadding'></div>",
        "installMsg": "<div class='DLMinstallMsgHeight'><div>Saadaksesi tämän latauksen valmiiksi, sinun tulee asentaa Akamai NetSession Interface. Se on latauksen hallintaohjelma, jota käytetään vähentämään latausaikaa ja parantamaan laatua. Asennus kestää ainoastaan parin minuutin ajan, jonka jälkeen latauksesi voi jatkua.</div><br /><div>Suorita seuraavat toimenpiteet:</div><br /><ol><li>Lataa asennusohjelma napsauttamalla alla olevaa linkkiä.</li><li>Suorita ladattu asennusohjelma - se asentaa NetSession Interfacen.</li><li>Kun asennus on valmis, tämä ponnahdusikkuna sulkeutuu ja lataus jatkuu selaimen ikkunassa.</li></ol><br /><div>Aloita napsauttamalla tästä: <a href='#' onclick='return DLMHelper.downloadInstaller();'>lataa asennusohjelma</a>.</div><br /><div>Jos sinulla on kysyttävää tai jos haluat lisätietoja Akamai NetSession Interfacestä, vieraile <a href='http://www.akamai.com/client' target=_blank>kotisivullamme</a>.</div><br /><div>Jos et saa asennusta valmiiksi, <a href='#' onclick='return DLMHelper.setInstallFailure();'>napsauta tästä</a>.</div></div>",
        "installFailureMsg": "<div class='DLMfailureMsgHeight'><div>Pahoittelemme asennuksen epäonnistumista. Voit halutessasi antaa <a href='http://www.akamai.com/html/misc/akamai_client/dlm_feedback.html' target='_blank'>palautetta</a> asennusprosessin toimivuudesta.</div><br /><br /><div>Paina <span style='font-weight: bold; margin: 0;'>OK</span> sulkeaksesi tämän ponnahdusikkunan ja kokeile vaihtoehtoista latausmenetelmää.<br />Paina <span style='font-weight:bold; margin: 0;'>Yritä uudelleen</span> palataksesi edelliselle sivulle ja kokeile asennusta uudelleen.</div><br /><input type='submit' value='OK' onclick='return DLMHelper.hideInstallerPopup();' /><input type='submit' value='Yritä uudelleen' onclick='return DLMHelper.displayInstallerPopup();' style='margin-left: 20px;' /></div>",
        "singleDirectDownloadLink": "Napsauta <a href=\"%s\" target=\"_blank\">tästä</a> ladataksesi ohjelman selaimesi avulla.",
        "bundleDirectDownloadMessage": "Napsauta yksittäisiä tiedostojen linkkejä ladataksesi ohjelman selaimesi avulla.",
        "errorPopUpHeader" : "Virheen tiedot:",
        "errorTitle": "VIRHE",
        "showDetailsTitle": "Näytä tiedot"
    },
    fr: {
        "startTitle": "Cliquez sur \"exécuter\" ou \"ouvrir\" pour démarrer l’utilitaire d’installation.",
        "relaunchMsgStart": "L’utilitaire d’installation ne s’affiche pas ? ",
        "relaunchLink": "Essayez de l’ouvrir à nouveau.",
        "relaunchMsgEnd": "",
        "title": "Téléchargement %s",
        "autoStart": " Ouvrir le fichier automatiquement à la fin.",
        "completeTitle": "Téléchargement terminé.",
        "completeText": "Ouvrir ",
        "timeLabel": "%s de temps restant.",
        "waiting": "En attente.",
        "paused": "En suspens.",
        "pausedNotFound": "Fichier non trouvé !",
        "pausedInsufficientDiskSpace": "Espace de stockage insuffisant !",
        "pausedForbidden": "Accès refusé !",
        "pausedDisconnected": "Déconnecté.",
        "unloadMsg": "Téléchargement en cours. Si vous quittez la page maintenant, le téléchargement sera interrompu.",
        "minute": "minute",
        "minutes": "minutes",
        "second": "seconde",
        "seconds": "secondes",
        "download": "Téléchargement",
        "hourAbbr": "h",
        "minAbbr": "m",
        "calcTime": "Calcul du temps requis de temps restant.",
        // Nouvelles chaînes DLM groupées. Inclut aussi le format de pourcentage localisable.
        "waitStatus": "En attente...",
        "defaultStatus2": "Initialisation...",
        "titleTextProgress": "Progrès total %s",
        "titleTextPaused": "Progrès total %s EN ATTENTE",
        "statusProgress": "%s (%s de %s) : %s",
        "percentage": "%s%",
        "cancelledTitle": "%s d’annulation",
        "cancelledMsg": "Réinitialiser le téléchargement.",
        // New error strings
        "unexpectedHttpResponse": "Une réponse HTTP inattendue a été reçue",
        "missingRange": "En-tête Range manquante",
        "missingRangeProxy": "En-tête Range manquante. Possibilité d’incompatibilité avec le proxy",
        "zeroContentLength": "Longueur du contenu manquante",
        "zeroContentLengthProxy": "Longueur du contenu manquante. Possibilité d’incompatibilité avec le proxy",
        "invalidFileSize": "Taille de fichier inattendue",
        "invalidFileSizeProxy": "Taille de fichier inattendue. Possibilité d’incompatibilité avec le proxy",
        "invalidRange": "En-tête de réponse Content-Range  incorrecte",
        "invalidRangeProxy": "En-tête de réponse Content-Range  incorrecte. Possibilité d’incompatibilité avec le proxy",
        "negativeSize": "En-tête de réponse Content-Range  incorrecte",
        "negativeSizeProxy": "En-tête de réponse Content-Range  incorrecte. Possibilité d’incompatibilité avec le proxy",
        "503Response": "En-tête de réponse Content-Range  incorrecte. Possibilité d’incompatibilité avec le proxy ",
        "unrecognizedResponse": "Réponse non reconnue",
        "unrecognizedResponseProxy": "Réponse non reconnue. Possibilité d’incompatibilité avec le proxy",
        "tooManyRedirects": "Trop de redirections HTTP",
        "missingLocationHeader": "En-tête Location  manquante",
        "missingLocationHeaderProxy": "En-tête Location  manquante. Possibilité d’incompatibilité avec le proxy",
        "invalidLocationHeader": "En-tête Location  incorrecte",
        "invalidLocationHeaderProxy": "En-tête Location  incorrecte. Possibilité d’incompatibilité avec le proxy",
        "timeOutError": "Délai d’attente de la requête écoulé",
        "contentVerficationError": "Échec de vérification du contenu",
        "noRsmd": "Impossible de déterminer si le contenu est correct",
        "contentInvalid": "Contenu incorrect",
        "connectivityError": "Erreur de connectivité",
        "serverUnreachable": "Serveur injoignable",
        "deletionInProgress": "Suppression en cours",
        "diskError": "Erreur de disque",
        "noPermissions": "Permission refusée",
        "fileReadOnly": "Il y a eu une tentative d’écriture sur un fichier ou dispositif ouvert en lecture seule",
        "tooManyFiles": "Trop de fichiers ouverts",
        "dirNotFound": "Le fichier ou dossier spécifié est introuvable ou n’existe pas",
        "noSpace": "Plus d'espace libre sur le dispositif",
        "crossDeviceError": "Il y a eu une tentative de déplacement d’un fichier vers un dispositif différent",
        "popupContent": "<div id='DLMtitleBar'><div id='DLMpopupClose' onclick='return DLMHelper.hideInstallerPopup();'></div><div id='DLMlogo'></div><span id='DLMpopupTitle'>Akamai NetSession Interface</span></div><div class='DLMheaderPadding'></div><div id='DLMpopupContainer'>%s</div><div class='DLMheaderPadding'></div>",
        "installMsg": "<div class='DLMinstallMsgHeight'><div> Pour effectuer ce téléchargement, vous devez installer Akamai NetSession Interface, un gestionnaire de téléchargement utilisé pour réduire le temps de téléchargement et augmenter la qualité. Cette installation ne devrait prendre que quelques minutes tout au plus, après quoi le téléchargement pourra reprendre.</div><br /><div> Veuillez suivre les étapes suivantes:</div><br /><ol><li>Téléchargez le programme d'installation en cliquant sur le lien ci-dessous.</li><li>Exécutez le programme d'installation téléchargé pour configurer NetSession Interface.</li><li>Lorsque l'installation sera terminée, cette fenêtre se fermera et le téléchargement reprendra dans la fenêtre du navigateur.</li></ol><br /><div> Cliquez ici pour commencer: <a href='#' onclick='return DLMHelper.downloadInstaller();'>télécharger le programme d'installation</a>.</div><br /><div>Si vous avez des questions ou désirez plus d’informations à propos d’Akamai NetSession Interface, veuillez consulter notre <a href='http://www.akamai.com/client' target=_blank>page d’accueil</a>.</div><br /><div>Si vous ne pouvez pas terminer l’installation, <a href='#' onclick='return DLMHelper.setInstallFailure();'>cliquez ici</a>.</div></div>",
        "installFailureMsg": "<div class='DLMfailureMsgHeight'><div>Nous sommes désolés, l'installation a échoué. Veuillez prendre le temps de nous faire connaître votre <a href='http://www.akamai.com/html/misc/akamai_client/dlm_feedback.html' target='_blank'>opinion</a> sur ce processus d’installation.</div><br /><br /><div>Cliquez sur <span style='font-weight: bold; margin: 0;'>OK</span> pour fermer cette fenêtre et essayer une autre méthode de téléchargement.<br />Appuyez sur <span style='font-weight:bold; margin: 0;'>Réessayer</span> pour revenir à l'écran précédent et recommencer l'installation.</div><br /><input type='submit' value='OK' onclick='return DLMHelper.hideInstallerPopup();' /><input type='submit' value='Réessayer' onclick='return DLMHelper.displayInstallerPopup();' style='margin-left: 20px;' /></div>",
        "singleDirectDownloadLink": "Cliquez <a href=\"%s\" target=\"_blank\">ici</a> pour télécharger en utilisant votre navigateur.",
        "bundleDirectDownloadMessage": "Cliquez sur les liens individuels des fichiers pour les télécharger en utilisant votre navigateur.",
        "errorPopUpHeader" : "Détail de l’erreur:",
        "errorTitle": "ERREUR",
        "showDetailsTitle": "Voir le détail"
    },
    it: {
        "startTitle": "Per avviare l'installazione, fate clic su Esegui o Apri.",
        "relaunchMsgStart": "Il modulo di installazione non viene visualizzato? ",
        "relaunchLink": "Provate a riaprirlo.",
        "relaunchMsgEnd": "",
        "title": "Scaricamento in corso di %s",
        "autoStart": " Al termine, apri automaticamente.",
        "completeTitle": "Download completato.",
        "completeText": "Apri %s",
        "timeLabel": "%s rimanente.",
        "waiting": "In attesa.",
        "paused": "In pausa.",
        "pausedNotFound": "File non trovato.",
        "pausedInsufficientDiskSpace": "Spazio su disco insufficiente.",
        "pausedForbidden": "Accesso negato.",
        "pausedDisconnected": "Disconnesso dal server, nuovo tentativo...",
        "unloadMsg": "Al momento è in corso un download. Se si esce ora, il download verrà messo in pausa.",
        "minute": "minuto",
        "minutes": "minuti",
        "second": "secondo",
        "seconds": "secondi",
        "download": "Download",
        "hourAbbr": "h",
        "minAbbr": "m",
        "calcTime": "Calcolo del tempo necessario rimanente.",
        // New Bundled DLM strings. Also adds localizable percentage format.
        "waitStatus": "In attesa...",
        "defaultStatus2": "Inizializzazione in corso...",
        "titleTextProgress": "Avanzamento totale %s",
        "titleTextPaused": "Avanzamento totale %s IN PAUSA",
        "statusProgress": "%s (%s di %s): %s",
        "percentage": "%s%",
        "cancelledTitle": "%s annullato",
        "cancelledMsg": "Riavviate il download.",
        // New error strings
        "unexpectedHttpResponse": "Ricevuta una risposta HTTP non attesa",
        "missingRange": "Intestazione \"Range\" mancante",
        "missingRangeProxy": "Intestazione \"Range\" mancante. Possibile incompatibilità del proxy",
        "zeroContentLength": "Lunghezza contenuto mancante",
        "zeroContentLengthProxy": "Lunghezza contenuto mancante. Possibile incompatibilità del proxy",
        "invalidFileSize": "Dimensioni del file inattese",
        "invalidFileSizeProxy": "Dimensioni del file inattese. Possibile incompatibilità del proxy",
        "invalidRange": "Intestazione della risposta \"Campo-Contenuto\" non valida",
        "invalidRangeProxy": "Intestazione della risposta \"Campo-Contenuto\" non valida. Possibile incompatibilità del proxy",
        "negativeSize": "Intestazione della risposta \"Campo-Contenuto\" non valida",
        "negativeSizeProxy": "Intestazione della risposta \"Campo-Contenuto\" non valida. Possibile incompatibilità del proxy",
        "503Response": "Il servizio non è al momento disponibile",
        "unrecognizedResponse": "Risposta non riconosciuta",
        "unrecognizedResponseProxy": "Risposta non riconosciuta. Possibile incompatibilità del proxy",
        "tooManyRedirects": "Troppi reindirizzamenti HTTP",
        "missingLocationHeader": "Intestazione \"Posizione\" mancante",
        "missingLocationHeaderProxy": "Intestazione \"Posizione\" mancante. Possibile incompatibilità del proxy",
        "invalidLocationHeader": "Intestazione \"Posizione\" non valida",
        "invalidLocationHeaderProxy": "Intestazione \"Posizione\" non valida. Possibile incompatibilità del proxy",
        "timeOutError": "Richiesta fuori tempo massimo",
        "contentVerficationError": "Errore nella verifica del contenuto",
        "noRsmd": "Impossibile determinare la correttezza del contenuto",
        "contentInvalid": "Contenuto non valido",
        "connectivityError": "Errore del collegamento",
        "serverUnreachable": "Server non raggiungibile",
        "deletionInProgress": "Cancellazione in corso",
        "diskError": "Errore del disco",
        "noPermissions": "Permesso negato",
        "fileReadOnly": "Si è tentato di scrivere su un file o dispositivo aperti con l'accesso per sola lettura",
        "tooManyFiles": "Troppi file aperti",
        "dirNotFound": "Il file o cartella specificati non esistono o non possono essere trovati",
        "noSpace": "Nessun spazio sul dispositivo",
        "crossDeviceError": "Si è tentato di spostare un file in un dispositivo diverso",
        "popupContent": "<div id='DLMtitleBar'><div id='DLMpopupClose' onclick='return DLMHelper.hideInstallerPopup();'></div><div id='DLMlogo'></div><span id='DLMpopupTitle'>Akamai NetSession Interface</span></div><div class='DLMheaderPadding'></div><div id='DLMpopupContainer'>%s</div><div class='DLMheaderPadding'></div>",
        "installMsg": "<div class='DLMinstallMsgHeight'><div>Per completare questo download è necessario installare Akamai NetSession Interface, un download manager utilizzato per ridurre i tempi e la qualità dei download. L’installazione potrebbe impiegare alcuni minuti, dopodiché sarà possibile riprendere il download.</div><br /><div>Seguire i seguenti passi:</div><br /><ol><li>Scaricare l’installer cliccando sul link di seguito.</li><li>Avviare l’installer scaricato per installare NetSession Interface.</li><li>Una volta completata l’installazione questo pop-up si chiuderà e il download riprenderà nella finestra del browser.</li></ol><br /><div>Per iniziare cliccare qui: <a href='#' onclick='return DLMHelper.downloadInstaller();'>scarica installer</a>.</div><br /><div>Per qualsiasi domanda o ulteriori informazioni su Akamai NetSession Interface visitare la nostra <a href='http://www.akamai.com/client' target=_blank>pagina iniziale</a>.</div><br /><div>Se l’installazione non va a buon fine, <a href='#' onclick='return DLMHelper.setInstallFailure();'>cliccare qui</a>.</div></div>",
        "installFailureMsg": "<div class='DLMfailureMsgHeight'><div>Siamo spiacenti, l’installazione non è andata a buon fine. Fermatevi un momento per fornire il vostro <a href='http://www.akamai.com/html/misc/akamai_client/dlm_feedback.html' target='_blank'>feedback</a> sul processo d'installazione.</div><br /><br /><div>Premere <span style='font-weight: bold; margin: 0;'>OK</span> per chiudere questo pop-up e provare un metodo di download alternativo.<br />Premere <span style='font-weight:bold; margin: 0;'>Riprova</span> per tornare alla schermata precedente e riavviare l’installazione.</div><br /><input type='submit' value='OK' onclick='return DLMHelper.hideInstallerPopup();' /><input type='submit' value='Riprova' onclick='return DLMHelper.displayInstallerPopup();' style='margin-left: 20px;' /></div>",
        "singleDirectDownloadLink": "Cliccare <a href=\"%s\" target=\"_blank\">qui</a> per avviare il download con il proprio browser.",
        "bundleDirectDownloadMessage": "Cliccare i link dei singoli file per avviare il download con il proprio browser.",
        "errorPopUpHeader" : "Dettagli errore:",
        "errorTitle": "ERRORE",
        "showDetailsTitle": "Mostra dettagli"
    },
    ja: {
        "startTitle": "実行\"または\"開く\"をクリックして\"インストーラーを起動",
        "relaunchMsgStart": "インストーラーが見えない場合",
        "relaunchLink": "もう一度開く",
        "relaunchMsgEnd": "",
        "title": "ダウンロード中 %s",
        "autoStart": " 終了後、自動的にファイルを開きます。",
        "completeTitle": "ダウンロードが完了しました！",
        "completeText": "開く",
        "timeLabel": "%s残り",
        "waiting": "待機中",
        "paused": "停止",
        "pausedNotFound": "ファイルが見つかりません！",
        "pausedInsufficientDiskSpace": "ディスクスペースが不十分です！",
        "pausedForbidden": "アクセスが拒否されました！",
        "pausedDisconnected": "切断されました。",
        "unloadMsg": "現在ダウンロード中です。このページを閉じますと、ダウンロードは中断されます",
        "minute": "分", 
        "minutes": "分", 
        "second": "秒", 
        "seconds": "秒", 
        "download": "ダウンロード",
        "hourAbbr": "時間",
        "minAbbr": "分",
        "calcTime": "時間を計算中残り",
        "waitStatus": "待機中…",
        "defaultStatus2": "初期化処理中…",
        "titleTextProgress": "全体の進行状況 %s",
        "titleTextPaused": "全体の進行状況 %s 停止中",
        "statusProgress": "%s (%s 中 %s) : %s",
        "percentage": "%s%",
        "cancelledTitle": "キャンセル済み %s",
        "cancelledMsg": "ダウンロードを再開",
        // New error strings
        "unexpectedHttpResponse": "予期しない HTTP レスポンスを受信しました",
        "missingRange": "\『レンジ\』ヘッダーが見つかりません",
        "missingRangeProxy": "\『レンジ\』ヘッダーが見つかりません。 プロキシの互換性がない可能性があります",
        "zeroContentLength": "コンテンツの長さが不足しています",
        "zeroContentLengthProxy": "コンテンツの長さが不足しています。 プロキシの互換性がない可能性があります",
        "invalidFileSize": "予期しないファイルサイズです",
        "invalidFileSizeProxy": "予期しないファイルサイズです。 プロキシの互換性がない可能性があります",
        "invalidRange": "\『コンテンツ-レンジ\』レスポンス ヘッダーが無効です",
        "invalidRangeProxy": "\『コンテンツ-レンジ\』レスポンス ヘッダーが無効です。 プロキシの互換性がない可能性があります",
        "negativeSize": "\『コンテンツ-レンジ\』レスポンス ヘッダーが無効です",
        "negativeSizeProxy": "\『コンテンツ-レンジ\』レスポンス ヘッダーが無効です。 プロキシの互換性がない可能性があります",
        "503Response": "サービスは一時的に使用できません",
        "unrecognizedResponse": "レスポンスが認識されません",
        "unrecognizedResponseProxy": "レスポンスが認識されません。 プロキシの互換性がない可能性があります",
        "tooManyRedirects": "HTTP リダイレクトが多すぎます",
        "missingLocationHeader": "\『ロケーション\』ヘッダーが見つかりません",
        "missingLocationHeaderProxy": "\『ロケーション\』ヘッダーが見つかりません。 プロキシの互換性がない可能性があります",
        "invalidLocationHeader": "\『ロケーション\』ヘッダーが無効です",
        "invalidLocationHeaderProxy": "\『ロケーション\』ヘッダーが無効です。 プロキシの互換性がない可能性があります",
        "timeOutError": "リクエストのタイムアウト",
        "contentVerficationError": "コンテンツの認証に失敗しました",
        "noRsmd": "コンテンツの正当性を判断できません",
        "contentInvalid": "コンテンツが無効です",
        "connectivityError": "接続エラー",
        "serverUnreachable": "サーバーに接続できません",
        "deletionInProgress": "削除中",
        "diskError": "ディスクエラー",
        "noPermissions": "許可は拒否されました",
        "fileReadOnly": "読み取り専用ファイルまたはデバイスへの書き込みが行われようとしました",
        "tooManyFiles": "開いているファイルの数が多すぎます",
        "dirNotFound": "指定されたファイルまたはディレクトリは存在しないか、見つかりません",
        "noSpace": "デバイスに空き容量がありません",
        "crossDeviceError": "別のデバイスへのファイルの移動が行われようとしました",
        "popupContent": "<div id='DLMtitleBar'><div id='DLMpopupClose' onclick='return DLMHelper.hideInstallerPopup();'></div><div id='DLMlogo'></div><span id='DLMpopupTitle'>Akamai NetSession Interface</span></div><div class='DLMheaderPadding'></div><div id='DLMpopupContainer'>%s</div><div class='DLMheaderPadding'></div>",
        "installMsg": "<div class='DLMinstallMsgHeight'><div>このダウンロードを実行するには、Akamai NetSession Interface をインストールする必要があります。Akamai NetSession Interface は、ダウンロードの時間を短縮し質を向上するダウンロード・マネージャーです。 インストールは最長でも数分で完了し、その後ダウンロードを再開できます。</div><br /><div>次のステップに従ってください：</div><br /><ol><li>下記リンクをクリックしてインストーラをダウンロードします。</li><li>ダウンロードしたインストーラを実行します。これにより、NetSession Interface が設定されます。</li><li>インストールが完了すると、このポップアップ画面が消え、ブラウザの画面でダウンロードが再開されます。</li></ol><br /><div>こちらをクリックして開始：<a href='#' onclick='return DLMHelper.downloadInstaller();'>インストーラをダウンロードする。</a>.</div><br /><div> Akamai NetSession Interface の詳細や疑問点については、弊社<a href='http://www.akamai.com/client' target=_blank>ホームページ</a>でお確かめください。.</div><br /><div>インストールが完了しない場合は、<a href='#' onclick='return DLMHelper.setInstallFailure();'>こちらをクリック</a>してください。.</div></div>",
        "installFailureMsg": "<div class='DLMfailureMsgHeight'><div>インストールに失敗しました。 今回のインストールに関して、お客様の <a href='http://www.akamai.com/html/misc/akamai_client/dlm_feedback.html' target='_blank'>ご感想</a>をぜひお聞かせください。</div><br /><br /><div><span style='font-weight: bold; margin: 0;'>OK</span>ボタンをクリックしてポップアップ・ウィンドウを閉じ、他のダウンロード方法をお試しください。<br /><span style='font-weight:bold; margin: 0;'>再試行</span>をクリックすると、前の画面に戻って再度インストールを実行できます。</div><br /><input type='submit' value='OK' onclick='return DLMHelper.hideInstallerPopup();' /><input type='submit' value='再試行' onclick='return DLMHelper.displayInstallerPopup();' style='margin-left: 20px;' /></div>",
        "singleDirectDownloadLink": "お使いのブラウザでダウンロードするには<a href=\"%s\" target=\"_blank\">こちら</a>をクリックしてください。",
        "bundleDirectDownloadMessage": "お使いのブラウザでダウンロードするには、各ファイルリンクをクリックしてください。",
        "errorPopUpHeader" : "エラーの詳細:",
        "errorTitle": "エラー",
        "showDetailsTitle": "詳細を表示"
    },
    ko: {
        "startTitle": "설치 프로그램를 시작하려면 \"실행\" 또는 \"열기\"를 클릭하십시오.",
        "relaunchMsgStart": "설치 프로그램이 보이지 않으십니까? ",
        "relaunchLink": "설치 프로그램 다시 열기",
        "relaunchMsgEnd": "",
        "title": "%s를 다운로드 중",
        "autoStart": " 다운로드가 완료되면 자동으로 열기.",
        "completeTitle": "다운로드 완료!",
        "completeText": "%s 열기",
        "timeLabel": "%s 남음.",
        "waiting": "대기 중.",
        "paused": "일시 중지됨.",
        "pausedNotFound": "파일을 찾을 수 없습니다!",
        "pausedInsufficientDiskSpace": "디스크 공간이 부족합니다!",
        "pausedForbidden": "액세스가 거부되었습니다!",
        "pausedDisconnected": "서버 연결이 끊겼습니다. 다시 시도하는 중...",
        "unloadMsg": "현재 다운로드가 진행중입니다. 현재 웹페이지를 떠나시면, 다운로드는 즉각 중단됩니다.",
        "minute": "분",
        "minutes": "분",
        "second": "초",
        "seconds": "초",
        "download": "다운로드",
        "hourAbbr": "시간",
        "minAbbr": "분",
        "calcTime": "시간 계산 중 남음",
        // New Bundled DLM strings. Also adds localizable percentage format.
        "waitStatus": "대기 중...",
        "defaultStatus2": "초기화하는 중...",
        "titleTextProgress": "전체 진행률 %s",
        "titleTextPaused": "전체 진행률 %s 일시 중지",
        "statusProgress": "%s(%s/%s): %s",
        "percentage": "%s%",
        "cancelledTitle": "%s 취소",
        "cancelledMsg": "다운로드 재시작.",
        // New error strings
        "unexpectedHttpResponse": "예기치 않은 HTTP 응답을 받았습니다",
        "missingRange": "누락된 \”범위\” 헤더",
        "missingRangeProxy": "누락된 \”범위\” 헤더. 프록시 비호환성 때문일 수 있습니다",
        "zeroContentLength": "누락된 콘텐츠 길이",
        "zeroContentLengthProxy": "누락된 콘텐츠 길이. 프록시 비호환성 때문일 수 있습니다",
        "invalidFileSize": "예기치 않은 파일 크기",
        "invalidFileSizeProxy": "예기치 않은 파일 크기. 프록시 비호환성 때문일 수 있습니다",
        "invalidRange": "잘못된 \”콘텐츠-범위\” 응답 헤더",
        "invalidRangeProxy": "잘못된 \”콘텐츠-범위\” 응답 헤더. 프록시 비호환성 때문일 수 있습니다",
        "negativeSize": "잘못된 \”콘텐츠-범위\” 응답 헤더",
        "negativeSizeProxy": "잘못된 \”콘텐츠-범위\” 응답 헤더. 프록시 비호환성 때문일 수 있습니다",
        "503Response": "서비스를 일시적으로 사용할 수 없습니다",
        "unrecognizedResponse": "응답 인식 안 됨",
        "unrecognizedResponseProxy": "응답 인식 안 됨. 프록시 비호환성 때문일 수 있습니다",
        "tooManyRedirects": "HTTP 리디렉션이 너무 많음",
        "missingLocationHeader": "누락된 \”위치\” 헤더",
        "missingLocationHeaderProxy": "누락된 \”위치\” 헤더. 프록시 비호환성 때문일 수 있습니다",
        "invalidLocationHeader": "잘못된 \”위치\” 헤더",
        "invalidLocationHeaderProxy": "잘못된 \”위치\” 헤더. 프록시 비호환성 때문일 수 있습니다",
        "timeOutError": "요청 시간 초과",
        "contentVerficationError": "콘텐츠 확인 실패",
        "noRsmd": "콘텐츠의 정확성을 판단할 수 없습니다",
        "contentInvalid": "잘못된 콘텐츠",
        "connectivityError": "연결 오류",
        "serverUnreachable": "서버에 연결할 수 없음",
        "deletionInProgress": "삭제 진행 중",
        "diskError": "디스크 오류",
        "noPermissions": "허가가 거부됨",
        "fileReadOnly": "파일에 쓰려는 시도가 있었거나 읽기 전용으로 장치가 열렸습니다",
        "tooManyFiles": "열린 파일이 너무 많음",
        "dirNotFound": "특정 파일이나 디렉터리가 존재하지 않거나 찾을 수 없습니다",
        "noSpace": "장치에 남아 있는 공간이 없습니다",
        "crossDeviceError": "파일을 다른 장치로 옮기려는 시도가 있었습니다",
        "popupContent": "<div id='DLMtitleBar'><div id='DLMpopupClose' onclick='return DLMHelper.hideInstallerPopup();'></div><div id='DLMlogo'></div><span id='DLMpopupTitle'>Akamai NetSession Interface</span></div><div class='DLMheaderPadding'></div><div id='DLMpopupContainer'>%s</div><div class='DLMheaderPadding'></div>",
        "installMsg": "<div class='DLMinstallMsgHeight'><div>이 다운로드를 완료하려면, 다운로드 시간을 줄이고 품질을 개선시키는 데 사용되는 다운로드 매니저인 Akamai NetSession Interface를 설치하십시오. 이 설치를 하는 데 최대 몇 분이 소요되며, 이 작업이 끝난 후 다운로드가 재개됩니다.</div><br /><div>다음의 조치를 취하십시오.</div><br /><ol><li>설치파일을 다운로드하려면 아래 링크를 클릭하십시오.</li><li>다운로드한 설치파일을 실행하면 NetSession Interface가 설치됩니다.</li><li>설치가 완료되면, 팝업창이 닫히고 브라우저 창에서 다운로드가 재개됩니다.</li></ol><br /><div>시작하려면 이곳을 클릭하십시오: <a href='#' onclick='return DLMHelper.downloadInstaller();'>설치파일 다운로드</a>.</div><br /><div>Akamai NetSession Interface에 대해 문의 사항이 있거나 상세 정보가 필요하신 경우, 저희 <a href='http://www.akamai.com/client' target=_blank>홈페이지</a>를 방문하십시오.</div><br /><div>설치를 완료하지 못하신 경우, <a href='#' onclick='return DLMHelper.setInstallFailure();'>이곳을 클릭하십시오</a>.</div></div>",
        "installFailureMsg": "<div class='DLMfailureMsgHeight'><div>죄송합니다만 설치가 실패했습니다. 시간을 내셔서 이 설치 과정에 대한 귀하의 <a href='http://www.akamai.com/html/misc/akamai_client/dlm_feedback.html' target='_blank'>피드백</a>을 공유해 주십시오.</div><br /><br /><div><span style='font-weight: bold; margin: 0;'>확인</span>을 클릭하여 이 팝업을 닫고 다른 다운로드 방법을 시도하십시오.<br /><span style='font-weight:bold; margin: 0;'>재시도</span>를 눌러 이전 화면으로 돌아가서 설치를 다시 시도하십시오.</div><br /><input type='submit' value='확인' onclick='return DLMHelper.hideInstallerPopup();' /><input type='submit' value='재시도' onclick='return DLMHelper.displayInstallerPopup();' style='margin-left: 20px;' /></div>",
        "singleDirectDownloadLink": "귀하의 브라우저에서 <a href=\"%s\" target=\"_blank\">이곳</a>을 클릭하여 다운로드하십시오.",
        "bundleDirectDownloadMessage": "귀하의 브라우저에서 개별 파일 링크를 클릭하여 다운로드하십시오.",
        "errorPopUpHeader" : "오류 상세 내용:",
        "errorTitle": "오류",
        "showDetailsTitle": "상세 내용 표시"
    },
    nl: {
        "startTitle": "Klik op \"Uitvoeren\" of \"Openen\" om het installatieprogramma te starten.",
        "relaunchMsgStart": "Als het installatieprogramma niet wordt weergegeven, ",
        "relaunchLink": "probeer het dan opnieuw te openen.",
        "relaunchMsgEnd": "",
        "title": "Bezig met downloaden van %s",
        "autoStart": "  Automatisch openen nadat het downloaden is voltooid.",
        "completeTitle": "Het downloaden is voltooid.",
        "completeText": "%s openen",
        "timeLabel": "%s resterend.",
        "waiting": "Een ogenblik geduld.",
        "paused": "Onderbroken.",
        "pausedNotFound": "Bestand niet gevonden.",
        "pausedInsufficientDiskSpace": "Onvoldoende schijfruimte.",
        "pausedForbidden": "Toegang geweigerd.",
        "pausedDisconnected": "Verbinding met server verbroken. Bezig met opnieuw verbinding maken...",
        "unloadMsg": "Er wordt momenteel een bestand gedownload. Als u deze pagina nu verlaat, zal de download kortstondig worden stopgezet.",
        "minute": "minuut",
        "minutes": "minuten",
        "second": "seconde",
        "seconds": "seconden",
        "download": "Downloaden",
        "hourAbbr": "u",
        "minAbbr": "m",
        "calcTime": "Bezig met berekenen tijdsduur resterend.",
        // New Bundled DLM strings. Also adds localizable percentage format.
        "waitStatus": "Een ogenblik geduld…",
        "defaultStatus2": "Bezig met initialiseren….",
        "titleTextProgress": "Voortgang van %s",
        "titleTextPaused": "Voortgang van %s ONDERBROKEN",
        "statusProgress": "%s (%s van %s): %s",
        "percentage": "%s%",
        "cancelledTitle": "%s geannuleerd",
        "cancelledMsg": "Start het downloaden opnieuw.",
        // New error strings
        "unexpectedHttpResponse": "Onverwachte http-reactie ontvangen",
        "missingRange": "Bereik” header ontbreekt",
        "missingRangeProxy": "\"Bereik\" header ontbreekt. Proxy mogelijk niet compatibel",
        "zeroContentLength": "Lengte inhoud ontbreekt",
        "zeroContentLengthProxy": "Lengte inhoud ontbreekt. Proxy mogelijk niet compatibel",
        "invalidFileSize": "Onverwachte bestandsgrootte",
        "invalidFileSizeProxy": "Onverwachte bestandsgrootte. Proxy mogelijk niet compatibel",
        "invalidRange": "Ongeldige \"Inhoud-Bereik\" reactieheader",
        "invalidRangeProxy": "Ongeldige \"Inhoud-Bereik\" reactieheader. Proxy mogelijk niet compatibel",
        "negativeSize": "Ongeldige \"Inhoud-Bereik\" reactieheader",
        "negativeSizeProxy": "Ongeldige \"Inhoud-Bereik\" reactieheader. Proxy mogelijk niet compatibel",
        "503Response": "Deze service is tijdelijk niet beschikbaar",
        "unrecognizedResponse": "Reactie niet herkend",
        "unrecognizedResponseProxy": "Reactie niet herkend. Proxy mogelijk niet compatibel",
        "tooManyRedirects": "Te veel HTTP omleidingen",
        "missingLocationHeader": "\"Locatie\" header ontbreekt",
        "missingLocationHeaderProxy": "\"Locatie\" header ontbreekt. Proxy mogelijk niet compatibel",
        "invalidLocationHeader": "Ongeldige \"Locatie\" header",
        "invalidLocationHeaderProxy": "Ongeldige \"Locatie\" header. Proxy mogelijk niet compatibel",
        "timeOutError": "Time-out van verzoek",
        "contentVerficationError": "Fout bij inhoudscontrole",
        "noRsmd": "Juistheid inhoud kan niet worden bepaald",
        "contentInvalid": "Inhoud ongeldig",
        "connectivityError": "Verbindingsfout",
        "serverUnreachable": "Server is niet bereikbaar",
        "deletionInProgress": "Verwijdering wordt uitgevoerd",
        "diskError": "Schijffout",
        "noPermissions": "Toegang geweigerd",
        "fileReadOnly": "Er is getracht iets naar een bestand of apparaat weg te schrijven dat is geopend in alleen-lezen modus",
        "tooManyFiles": "Te veel bestanden geopend",
        "dirNotFound": "Opgegeven bestand of map bestaat niet of kan niet worden gevonden",
        "noSpace": "Geen ruimte beschikbaar op apparaat",
        "crossDeviceError": "Er is een poging gedaan een bestand te verplaatsen naar een ander apparaat",
        "popupContent": "<div id='DLMtitleBar'><div id='DLMpopupClose' onclick='return DLMHelper.hideInstallerPopup();'></div><div id='DLMlogo'></div><span id='DLMpopupTitle'>Akamai NetSession Interface</span></div><div class='DLMheaderPadding'></div><div id='DLMpopupContainer'>%s</div><div class='DLMheaderPadding'></div>",
        "installMsg": "<div class='DLMinstallMsgHeight'><div>Om deze download te voltooien, moet u de Akamai NetSession Interface installeren, een downloadmanager die wordt gebruikt om de downloadtijd te beperken en de kwaliteit te verhogen. Deze installatie duurt hooguit enkele minuten. Daarna kunt u het downloaden hervatten.</div><br /><div>Volg de volgende stappen:</div><br /><ol><li>Download het installatieprogramma door op de link hieronder te klikken.</li><li>Voer het gedownloade installatieprogramma uit. Het zal de NetSession Interface installeren.</li><li>Als de installatie voltooid is, zal dit pop-upvenster afgesloten worden en zal het downloaden in het browservenster hervatten.</li></ol><br /><div>Klik hier om te beginnen: <a href='#' onclick='return DLMHelper.downloadInstaller();'>download het installatieprogramma</a>.</div><br /><div>Als u vragen hebt of meer informatie wenst over Akamai NetSession Interface, bezoek dan onze <a href='http://www.akamai.com/client' target=_blank>startpagina</a>.</div><br /><div>Als u de installatie niet kunt voltooien, klik dan <a href='#' onclick='return DLMHelper.setInstallFailure();'>hier</a>.</div></div>",
        "installFailureMsg": "<div class='DLMfailureMsgHeight'><div>Het spijt ons dat de installatie is mislukt. We stellen het op prijs als u even de tijd neemt om ons <a href='http://www.akamai.com/html/misc/akamai_client/dlm_feedback.html' target='_blank'>feedback</a> te geven over dit installatieproces.</div><br /><br /><div>Klik op <span style='font-weight: bold; margin: 0;'>OK</span> om deze pop-up te sluiten en een andere downloadmethode te proberen.<br />Klik op <span style='font-weight:bold; margin: 0;'>Opnieuw</span> om terug te keren naar het vorige scherm en de installatie opnieuw te starten.</div><br /><input type='submit' value='OK' onclick='return DLMHelper.hideInstallerPopup();' /><input type='submit' value='Opnieuw' onclick='return DLMHelper.displayInstallerPopup();' style='margin-left: 20px;' /></div>",
        "singleDirectDownloadLink": "Klik <a href=\"%s\" target=\"_blank\">hier</a> om te downloaden via uw browser.",
        "bundleDirectDownloadMessage": "Klik op de links naar de individuele bestanden om te downloaden via uw browser.",
        "errorPopUpHeader" : "Foutdetails:",
        "errorTitle": "FOUT",
        "showDetailsTitle": "Details weergeven"
    },
    // Note: nb & no are both treated as Norwegian, as it is unclear which is 'right' (microsoft doc says no, 
    // mac testing shows nb)
    nb: {
        "startTitle": "Klikk på \"kjør\" eller \"åpne\" for å starte installeringsprogrammet.",
        "relaunchMsgStart": "Ser du ikke installeringsprogrammet? ",
        "relaunchLink": "Prøv å åpne det på nytt.",
        "relaunchMsgEnd": "",
        "title": "Laster ned %s",
        "autoStart": " Åpne automatisk når fullført.",
        "completeTitle": "Nedlasting fullført.",
        "completeText": "Åpne %s",
        "timeLabel": "%s gjenstår.",
        "waiting": "Venter.",
        "paused": "Stanset midlertidig.",
        "pausedNotFound": "Finner ikke filen.",
        "pausedInsufficientDiskSpace": "Ikke nok diskplass.",
        "pausedForbidden": "Ikke tilgang.",
        "pausedDisconnected": "Koblet fra server, prøver på nytt...",
        "unloadMsg": "En nedlastning foregår for øyeblikket.  Hvis du forlater siden nå, vil nedlastingen stoppe ganske snart.",
        "minute": "minutt",
        "minutes": "minutter",
        "second": "sekund",
        "seconds": "sekunder",
        "download": "Last ned",
        "hourAbbr": "t",
        "minAbbr": "m",
        "calcTime": "Beregner tid gjenstår.",
        // New Bundled DLM strings. Also adds localizable percentage format.
        "waitStatus": "Venter...",
        "defaultStatus2": "Initialiserer...",
        "titleTextProgress": "Total fremdrift: %s",
        "titleTextPaused": "Total fremdrift: %s STANSET MIDLERTIDIG",
        "statusProgress": "%s (%s av %s): %s",
        "percentage": "%s%",
        "cancelledTitle": "Avbrøt %s",
        "cancelledMsg": "Start nedlastingen på nytt.",
        // New error strings
        "unexpectedHttpResponse": "Mottok et uventet HTTP-svar",
        "missingRange": "Manglende \"Range\"-header",
        "missingRangeProxy": "Manglende \"Range\"-header Mulig proxy-inkompatibilitet",
        "zeroContentLength": "Manglende innholdslengde",
        "zeroContentLengthProxy": "Manglende innholdslengde\" Mulig proxy-inkompatibilitet",
        "invalidFileSize": "Uventet filstørrelse",
        "invalidFileSizeProxy": "Uventet filstørrelse\" Mulig proxy-inkompatibilitet",
        "invalidRange": "Ugyldig \"Innholds-Range\" svar-header",
        "invalidRangeProxy": "Ugyldig \"Innholds-Range\" svar-header Mulig proxy-inkompatibilitet",
        "negativeSize": "Ugyldig \"Innholds-Range\" svar-header",
        "negativeSizeProxy": "Ugyldig \"Innholds-Range\" svar-header Mulig proxy-inkompatibilitet",
        "503Response": "Denne tjenesten er midlertidig utilgjengelig",
        "unrecognizedResponse": "Svaret ble ikke gjenkjent",
        "unrecognizedResponseProxy": "Svaret ble ikke gjenkjent\" Mulig proxy-inkompatibilitet",
        "tooManyRedirects": "For mange HTTP-omdirigeringer",
        "missingLocationHeader": "Manglende \"Lokalitets\"-header",
        "missingLocationHeaderProxy": "Manglende \"Lokalitets\"-header\" Mulig proxy-inkompatibilitet",
        "invalidLocationHeader": "Ugyldig \"Lokalitets\"-header",
        "invalidLocationHeaderProxy": "Ugyldig \"Lokalitets\"-header\" Possible proxy incompatibility ",
        "timeOutError": "Anmodet tidsavbrudd",
        "contentVerficationError": "Innholdsverifisering mislykket",
        "noRsmd": "Kunne ikke avgjøre om innholdet er korrekt",
        "contentInvalid": "Ugyldig innhold",
        "connectivityError": "Forbindelsesfeil",
        "serverUnreachable": "Serveren kan ikke nås",
        "deletionInProgress": "Sletting pågår",
        "diskError": "Diskfeil",
        "noPermissions": "Tilgang avslått",
        "fileReadOnly": "Det ble gjort et forsøk til å skrive til en fil eller en enhet som er skrivebeskyttet",
        "tooManyFiles": "For mange åpne filer",
        "dirNotFound": "Den oppgitte filen eller katalogen eksisterer ikke, eller kan ikke finnes",
        "noSpace": "Ikke nok plass igjen på enheten",
        "crossDeviceError": "Det ble gjort et forsøk på å flytte en fil til en annen enhet",
        "popupContent": "<div id='DLMtitleBar'><div id='DLMpopupClose' onclick='return DLMHelper.hideInstallerPopup();'></div><div id='DLMlogo'></div><span id='DLMpopupTitle'>Akamai NetSession Interface</span></div><div class='DLMheaderPadding'></div><div id='DLMpopupContainer'>%s</div><div class='DLMheaderPadding'></div>",
        "installMsg": "<div class='DLMinstallMsgHeight'><div>For å fullføre denne nedlastningen, må du installere Akamai NetSession Interface, et nedlastningsprogram som brukes for å redusere nedlastningstiden og øke kvaliteten. Denne installasjonen skal maksimalt ta noen få minutter, og etter dette kan nedlastningen din fortsette.</div><br /><div>Utfør følgende skritt:</div><br /><ol><li>Last ned installasjonsprogrammet ved å klikke på lenken nedenfor.</li><li>Kjør installasjonsprogrammet du lastet ned – den vil sette opp NetSession Interface.</li><li>Når installasjonen er fullført, vil dette sprettoppvinduet lukkes, og nedlastningen vil fortsette i nettleservinduet.</li></ol><br /><div>Klikk her for å laste ned: <a href='#' onclick='return DLMHelper.downloadInstaller();'>installasjonsprogrammet</a>.</div><br /><div>Hvis du har noen spørsmål eller ønsker flere opplysninger om Akamai NetSession Interface, gå til vår <a href='http://www.akamai.com/client' target=_blank>hjemmeside</a>.</div><br /><div>Hvis du ikke kan fullføre installasjonen, <a href='#' onclick='return DLMHelper.setInstallFailure();'>klikk her</a>.</div></div>",
        "installFailureMsg": "<div class='DLMfailureMsgHeight'><div>Vi beklager at installasjonen var mislykket. Kan du ta deg tid til å dele din <a href='http://www.akamai.com/html/misc/akamai_client/dlm_feedback.html' target='_blank'>tilbakemelding</a> om installasjonsprosessen.</div><br /><br /><div>Trykk på <span style='font-weight: bold; margin: 0;'>OK</span> for å lukke dette popup-vinduet og forsøk en annen nedlastningsmetode.<br />Trykk på <span style='font-weight:bold; margin: 0;'>Forsøk igjen</span>, for å gå tilbake til forrige skjermbilde og forsøke å installere igjen.</div><br /><input type='submit' value='OK' onclick='return DLMHelper.hideInstallerPopup();' /><input type='submit' value='Forsøk igjen' onclick='return DLMHelper.displayInstallerPopup();' style='margin-left: 20px;' /></div>",
        "singleDirectDownloadLink": "Klikk <a href=\"%s\" target=\"_blank\">her</a> for å laste ned med nettleseren din.",
        "bundleDirectDownloadMessage": "Klikk på de enkelte fillenkene for å laste ned med nettleseren.",
        "errorPopUpHeader" : "Feildetaljer:",
        "errorTitle": "FEIL",
        "showDetailsTitle": "Vis detaljer"
    },
    no: {
        "startTitle": "Klikk på \"kjør\" eller \"åpne\" for å starte installeringsprogrammet.",
        "relaunchMsgStart": "Ser du ikke installeringsprogrammet? ",
        "relaunchLink": "Prøv å åpne det på nytt.",
        "relaunchMsgEnd": "",
        "title": "Laster ned %s",
        "autoStart": " Åpne automatisk når fullført.",
        "completeTitle": "Nedlasting fullført.",
        "completeText": "Åpne %s",
        "timeLabel": "%s gjenstår.",
        "waiting": "Venter.",
        "paused": "Stanset midlertidig.",
        "pausedNotFound": "Finner ikke filen.",
        "pausedInsufficientDiskSpace": "Ikke nok diskplass.",
        "pausedForbidden": "Ikke tilgang.",
        "pausedDisconnected": "Koblet fra server, prøver på nytt...",
        "unloadMsg": "En nedlastning foregår for øyeblikket.  Hvis du forlater siden nå, vil nedlastingen stoppe ganske snart.",
        "minute": "minutt",
        "minutes": "minutter",
        "second": "sekund",
        "seconds": "sekunder",
        "download": "Last ned",
        "hourAbbr": "t",
        "minAbbr": "m",
        "calcTime": "Beregner tid gjenstår.",
        // New Bundled DLM strings. Also adds localizable percentage format.
        "waitStatus": "Venter...",
        "defaultStatus2": "Initialiserer...",
        "titleTextProgress": "Total fremdrift: %s",
        "titleTextPaused": "Total fremdrift: %s STANSET MIDLERTIDIG",
        "statusProgress": "%s (%s av %s): %s",
        "percentage": "%s%",
        "cancelledTitle": "Avbrøt %s",
        "cancelledMsg": "Start nedlastingen på nytt.",
        // New error strings
        "unexpectedHttpResponse": "Mottok et uventet HTTP-svar",
        "missingRange": "Manglende \"Range\"-header",
        "missingRangeProxy": "Manglende \"Range\"-header Mulig proxy-inkompatibilitet",
        "zeroContentLength": "Manglende innholdslengde",
        "zeroContentLengthProxy": "Manglende innholdslengde\" Mulig proxy-inkompatibilitet",
        "invalidFileSize": "Uventet filstørrelse",
        "invalidFileSizeProxy": "Uventet filstørrelse\" Mulig proxy-inkompatibilitet",
        "invalidRange": "Ugyldig \"Innholds-Range\" svar-header",
        "invalidRangeProxy": "Ugyldig \"Innholds-Range\" svar-header Mulig proxy-inkompatibilitet",
        "negativeSize": "Ugyldig \"Innholds-Range\" svar-header",
        "negativeSizeProxy": "Ugyldig \"Innholds-Range\" svar-header Mulig proxy-inkompatibilitet",
        "503Response": "Denne tjenesten er midlertidig utilgjengelig",
        "unrecognizedResponse": "Svaret ble ikke gjenkjent",
        "unrecognizedResponseProxy": "Svaret ble ikke gjenkjent\" Mulig proxy-inkompatibilitet",
        "tooManyRedirects": "For mange HTTP-omdirigeringer",
        "missingLocationHeader": "Manglende \"Lokalitets\"-header",
        "missingLocationHeaderProxy": "Manglende \"Lokalitets\"-header\" Mulig proxy-inkompatibilitet",
        "invalidLocationHeader": "Ugyldig \"Lokalitets\"-header",
        "invalidLocationHeaderProxy": "Ugyldig \"Lokalitets\"-header\" Possible proxy incompatibility ",
        "timeOutError": "Anmodet tidsavbrudd",
        "contentVerficationError": "Innholdsverifisering mislykket",
        "noRsmd": "Kunne ikke avgjøre om innholdet er korrekt",
        "contentInvalid": "Ugyldig innhold",
        "connectivityError": "Forbindelsesfeil",
        "serverUnreachable": "Serveren kan ikke nås",
        "deletionInProgress": "Sletting pågår",
        "diskError": "Diskfeil",
        "noPermissions": "Tilgang avslått",
        "fileReadOnly": "Det ble gjort et forsøk til å skrive til en fil eller en enhet som er skrivebeskyttet",
        "tooManyFiles": "For mange åpne filer",
        "dirNotFound": "Den oppgitte filen eller katalogen eksisterer ikke, eller kan ikke finnes",
        "noSpace": "Ikke nok plass igjen på enheten",
        "crossDeviceError": "Det ble gjort et forsøk på å flytte en fil til en annen enhet",
        "popupContent": "<div id='DLMtitleBar'><div id='DLMpopupClose' onclick='return DLMHelper.hideInstallerPopup();'></div><div id='DLMlogo'></div><span id='DLMpopupTitle'>Akamai NetSession Interface</span></div><div class='DLMheaderPadding'></div><div id='DLMpopupContainer'>%s</div><div class='DLMheaderPadding'></div>",
        "installMsg": "<div class='DLMinstallMsgHeight'><div>For å fullføre denne nedlastningen, må du installere Akamai NetSession Interface, et nedlastningsprogram som brukes for å redusere nedlastningstiden og øke kvaliteten. Denne installasjonen skal maksimalt ta noen få minutter, og etter dette kan nedlastningen din fortsette.</div><br /><div>Utfør følgende skritt:</div><br /><ol><li>Last ned installasjonsprogrammet ved å klikke på lenken nedenfor.</li><li>Kjør installasjonsprogrammet du lastet ned – den vil sette opp NetSession Interface.</li><li>Når installasjonen er fullført, vil dette sprettoppvinduet lukkes, og nedlastningen vil fortsette i nettleservinduet.</li></ol><br /><div>Klikk her for å laste ned: <a href='#' onclick='return DLMHelper.downloadInstaller();'>installasjonsprogrammet</a>.</div><br /><div>Hvis du har noen spørsmål eller ønsker flere opplysninger om Akamai NetSession Interface, gå til vår <a href='http://www.akamai.com/client' target=_blank>hjemmeside</a>.</div><br /><div>Hvis du ikke kan fullføre installasjonen, <a href='#' onclick='return DLMHelper.setInstallFailure();'>klikk her</a>.</div></div>",
        "installFailureMsg": "<div class='DLMfailureMsgHeight'><div>Vi beklager at installasjonen var mislykket. Kan du ta deg tid til å dele din <a href='http://www.akamai.com/html/misc/akamai_client/dlm_feedback.html' target='_blank'>tilbakemelding</a> om installasjonsprosessen.</div><br /><br /><div>Trykk på <span style='font-weight: bold; margin: 0;'>OK</span> for å lukke dette popup-vinduet og forsøk en annen nedlastningsmetode.<br />Trykk på <span style='font-weight:bold; margin: 0;'>Forsøk igjen</span>, for å gå tilbake til forrige skjermbilde og forsøke å installere igjen.</div><br /><input type='submit' value='OK' onclick='return DLMHelper.hideInstallerPopup();' /><input type='submit' value='Forsøk igjen' onclick='return DLMHelper.displayInstallerPopup();' style='margin-left: 20px;' /></div>",
        "singleDirectDownloadLink": "Klikk <a href=\"%s\" target=\"_blank\">her</a> for å laste ned med nettleseren din.",
        "bundleDirectDownloadMessage": "Klikk på de enkelte fillenkene for å laste ned med nettleseren.",
        "errorPopUpHeader" : "Feildetaljer:",
        "errorTitle": "FEIL",
        "showDetailsTitle": "Vis detaljer"
    },
    pl: {
        "startTitle": "Kliknij przycisk „Run” (Uruchom) lub „Open” (Otwórz), aby uruchomić instalator.",
        "relaunchMsgStart": "Nie widzisz okna instalatora? ",
        "relaunchLink": "Otwórz instalator ponownie.",
        "relaunchMsgEnd": "",
        "title": "Pobieranie %s",
        "autoStart": " Otwórz automatycznie po zakończeniu pobierania.",
        "completeTitle": "Pobieranie zakończone!",
        "completeText": "Otwórz %s",
        "timeLabel": "%s pozostało.",
        "waiting": "Oczekiwanie.",
        "paused": "Wstrzymano.",
        "pausedNotFound": "Nie znaleziono pliku!",
        "pausedInsufficientDiskSpace": "Brak miejsca na dysku!",
        "pausedForbidden": "Odmowa dostępu!",
        "pausedDisconnected": "Rozłączono z serwerem. Trwa ponawianie...",
        "unloadMsg": "Obecnie trwa pobieranie danych. Jeśli wyjdziesz teraz, pobieranie zostanie wkrótce wstrzymane.",
        "minute": "min",
        "minutes": "min",
        "second": "s",
        "seconds": "s",
        "download": "Pobierz",
        "hourAbbr": "godz.",
        "minAbbr": "min.",
        "calcTime": "Obliczanie czasu pozostało.",
        // New Bundled DLM strings. Also adds localizable percentage format.
        "waitStatus": "Oczekiwanie...",
        "defaultStatus2": "Inicjalizacja...",
        "titleTextProgress": "Postęp całkowity %s",
        "titleTextPaused": "Postęp całkowity %s WSTRZYMANO",
        "statusProgress": "%s (%s z %s): %s",
        "percentage": "%s%",
        "cancelledTitle": "Anulowano %s",
        "cancelledMsg": "Rozpocznij pobieranie ponownie.",
        // New error strings
        "unexpectedHttpResponse": "Otrzymano nieoczekiwaną odpowiedź HTTP",
        "missingRange": "Brak nagłówka \„Zakres\”",
        "missingRangeProxy": "Brak nagłówka \„Zakres\”. Możliwa niezgodność z serwerem proxy",
        "zeroContentLength": "Brak długości zawartości",
        "zeroContentLengthProxy": "Brak długości zawartości. Możliwa niezgodność z serwerem proxy",
        "invalidFileSize": "Nieoczekiwany rozmiar pliku",
        "invalidFileSizeProxy": "Nieoczekiwany rozmiar pliku. Możliwa niezgodność z serwerem proxy",
        "invalidRange": "Nieprawidłowy nagłówek z odpowiedzią \„Zakres zawartości\”",
        "invalidRangeProxy": "Nieprawidłowy nagłówek z odpowiedzią \„Zakres zawartości\”. Możliwa niezgodność z serwerem proxy",
        "negativeSize": "Nieprawidłowy nagłówek z odpowiedzią \„Zakres zawartości\”",
        "negativeSizeProxy": "Nieprawidłowy nagłówek z odpowiedzią \„Zakres zawartości\”. Możliwa niezgodność z serwerem proxy",
        "503Response": "Usługa jest tymczasowo niedostępna",
        "unrecognizedResponse": "Nie rozpoznano odpowiedzi",
        "unrecognizedResponseProxy": "Nie rozpoznano odpowiedzi. Możliwa niezgodność z serwerem proxy",
        "tooManyRedirects": "Za dużo przekierowań HTTP",
        "missingLocationHeader": "Brak nagłówka \„Lokalizacja",
        "missingLocationHeaderProxy": "Brak nagłówka \„Lokalizacja\”. Możliwa niezgodność z serwerem proxy",
        "invalidLocationHeader": "Nieprawidłowy nagłówek \„Lokalizacja\”",
        "invalidLocationHeaderProxy": "Nieprawidłowy nagłówek \„Lokalizacja\”. Możliwa niezgodność z serwerem proxy",
        "timeOutError": "Przekroczono limit czasu żądania",
        "contentVerficationError": "Sprawdzanie zawartości nie powiodło się",
        "noRsmd": "Nie można określić poprawności zawartości",
        "contentInvalid": "Nieprawidłowa zawartość",
        "connectivityError": "Błąd połączenia",
        "serverUnreachable": "Serwer jest nieosiągalny",
        "deletionInProgress": "Usuwanie w toku",
        "diskError": "Błąd dysku",
        "noPermissions": "Odmowa uprawnień",
        "fileReadOnly": "Dokonano próby zapisu na otwartym pliku lub urządzeniu z dostępem tylko do odczytu",
        "tooManyFiles": "Za dużo otwartych plików",
        "dirNotFound": "Określony plik lub katalog nie istnieje lub nie może zostać odnaleziony",
        "noSpace": "Brak wolnego miejsca na urządzeniu",
        "crossDeviceError": "Dokonano próby przeniesienia pliku na inne urządzenie",
        "popupContent": "<div id='DLMtitleBar'><div id='DLMpopupClose' onclick='return DLMHelper.hideInstallerPopup();'></div><div id='DLMlogo'></div><span id='DLMpopupTitle'>Akamai NetSession Interface</span></div><div class='DLMheaderPadding'></div><div id='DLMpopupContainer'>%s</div><div class='DLMheaderPadding'></div>",
        "installMsg": "<div class='DLMinstallMsgHeight'><div>W celu ukończenia pobierania tego pliku, należy zainstalować Akamai NetSession Interface, menedżera pobierania plików, który skraca czas pobierania i polepsza jakość połączenia. Instalacja zajmie najwyżej kilka minut, po których pobieranie zostanie wznowione.</div><br /><div>Prosimy wykonać następujące kroki:</div><br /><ol><li>Pobierz instalator, klikając na poniższy link.</li><li>Uruchom pobrany instalator, który zainstaluje NetSession Interface.</li><li>Po zakończeniu instalacji, niniejsze okno zostanie zamknięte, a pobieranie pliku zostanie wznowione w oknie przeglądarki.</li></ol><br /><div>Kliknij tutaj, aby rozpocząć: <a href='#' onclick='return DLMHelper.downloadInstaller();'>pobierz instalator</a>.</div><br /><div>W przypadku jakichkolwiek pytań lub chęci uzyskania dodatkowych informacji na temat Akamai NetSession Interface, prosimy odwiedzić naszą <a href='http://www.akamai.com/client' target=_blank>stronę główną</a>.</div><br /><div>W przypadku problemów z instalacją,<a href='#' onclick='return DLMHelper.setInstallFailure();'>kliknij tutaj</a>.</div></div>",
        "installFailureMsg": "<div class='DLMfailureMsgHeight'><div>Przepraszamy, instalacja nie powiodła się. Prosimy o poświęcenie nam kilku minut na wyrażenie swojej <a href='http://www.akamai.com/html/misc/akamai_client/dlm_feedback.html' target='_blank'>opinii</a> na temat procesu instalacji.</div><br /><br /><div>Naciśnij przycisk <span style='font-weight: bold; margin: 0;'>OK</span>, aby zamknąć niniejsze okno i spróbować innego sposobu pobierania.<br />Naciśnij przycisk <span style='font-weight:bold; margin: 0;'>Ponów</span>, aby powrócić do poprzedniego ekranu i powtórzyć proces instalacji.</div><br /><input type='submit' value='OK' onclick='return DLMHelper.hideInstallerPopup();' /><input type='submit' value='Ponów' onclick='return DLMHelper.displayInstallerPopup();' style='margin-left: 20px;' /></div>",
        "singleDirectDownloadLink": "Kliknij <a href=\"%s\" target=\"_blank\">tutaj</a>, aby pobrać za pomocą przeglądarki",
        "bundleDirectDownloadMessage": "Aby pobrać pojedynczy plik za pomocą przeglądarki, kliknij odpowiadający mu link",
        "errorPopUpHeader" : "Szczegóły błędu:",
        "errorTitle": "BŁĄD",
        "showDetailsTitle": "Pokaż szczegóły"
    },
    pt: {
        "startTitle": "Clique em “executar” ou “abrir” para iniciar o installer.",
        "relaunchMsgStart": "Não vê o installer? ",
        "relaunchLink": "Tentar abrir novamente.",
        "relaunchMsgEnd": "",
        "title": "Fazendo o download de %s",
        "autoStart": " Abrir automaticamente quando concluído.",
        "completeTitle": "Download Concluído!",
        "completeText": "Abrir %s",
        "timeLabel": "Faltam %s.",
        "waiting": "Aguardando.",
        "paused": "Pausa.",
        "pausedNotFound": "Arquivo não encontrado!",
        "pausedInsufficientDiskSpace": "Espaço insuficiente no disco!",
        "pausedForbidden": "Acesso negado!",
        "pausedDisconnected": "Desconectado do servidor; tentando novamente",
        "unloadMsg": "Você está fazendo um download. Se sair agora, o download vai pausar por alguns minutos.",

        "minute": "minuto",
        "minutes": "minutos",
        "second": "segundo",
        "seconds": "segundos",
        "download": "Download",
        "hourAbbr": "h",
        "minAbbr": "min",
        "calcTime": "Calculando tempo.",

        // New Bundled DLM strings. Also adds localizable percentage format.
        "waitStatus": "Aguardando…",
        "defaultStatus2": "Iniciando…",
        "titleTextProgress": "Progresso total do %s",
        "titleTextPaused": "Progresso total do %s INTERROMPIDO",
        "statusProgress": "%s (%s de %s): %s",
        "percentage": "%s%",
        "cancelledTitle": "%s cancelado",
        "cancelledMsg": "Reiniciar o download.",
        // New error strings
        "unexpectedHttpResponse": "Recepção de uma resposta HTTP inesperada",
        "missingRange": "Cabeçalho \"Range\" em falta",
        "missingRangeProxy": "Cabeçalho \"Range\" em falta. Possível incompatibilidade de proxy",
        "zeroContentLength": "Comprimento de conteúdo em falta",
        "zeroContentLengthProxy": "Comprimento de conteúdo em falta. Possível incompatibilidade de proxy",
        "invalidFileSize": "Tamanho de Ficheiro inesperado",
        "invalidFileSizeProxy": "Tamanho de Ficheiro inesperado. Possível incompatibilidade de proxy",
        "invalidRange": "Cabeçalho de resposta \"Content-Range\" inválido",
        "invalidRangeProxy": "Cabeçalho de resposta \"Content-Range\" inválido. Possível incompatibilidade de proxy",
        "negativeSize": "Cabeçalho de resposta \"Content-Range\" inválido",
        "negativeSizeProxy": "Cabeçalho de resposta \"Content-Range\" inválido. Possível incompatibilidade de proxy",
        "503Response": "O serviço encontra-se temporariamente indisponível",
        "unrecognizedResponse": "Resposta não reconhecida",
        "unrecognizedResponseProxy": "Resposta não reconhecida. Possível incompatibilidade de proxy",
        "tooManyRedirects": "Demasiados redireccionamentos HTTP",
        "missingLocationHeader": "Cabeçalho de \"Local\" em falta",
        "missingLocationHeaderProxy": "Cabeçalho de \"Local\" em falta. Possível incompatibilidade de proxy",
        "invalidLocationHeader": "Cabeçalho de \"Local\" inválido",
        "invalidLocationHeaderProxy": "Cabeçalho de \"Local\" inválido. Possível incompatibilidade de proxy",
        "timeOutError": "Excedido o tempo de pedido",
        "contentVerficationError": "Verificação de conteúdo falhada",
        "noRsmd": "Impossível determinar se conteúdo está correcto",
        "contentInvalid": "Conteúdo inválido",
        "connectivityError": "Erro de Ligação",
        "serverUnreachable": "Impossível aceder ao Servidor",
        "deletionInProgress": "A eliminar",
        "diskError": "Erro de Disco",
        "noPermissions": "Autorização negada",
        "fileReadOnly": "Foi realizada uma tentativa de gravar num ficheiro ou dispositivo acessível apenas para leitura",
        "tooManyFiles": "Demasiados ficheiros abertos",
        "dirNotFound": "O ficheiro ou directório indicado não existe ou não é possível encontrá-lo",
        "noSpace": "Não existe espaço no dispositivo",
        "crossDeviceError": "Foi realizada uma tentativa de mover um ficheiro para um dispositivo diferente",
        "popupContent": "<div id='DLMtitleBar'><div id='DLMpopupClose' onclick='return DLMHelper.hideInstallerPopup();'></div><div id='DLMlogo'></div><span id='DLMpopupTitle'>Akamai NetSession Interface</span></div><div class='DLMheaderPadding'></div><div id='DLMpopupContainer'>%s</div><div class='DLMheaderPadding'></div>",
        "installMsg": "<div class='DLMinstallMsgHeight'><div>Para completar esta transferência, é necessário instalar a InterfaceAkamai NetSession, um gestor de transferências que reduz o tempo de transferência e aumenta a qualidade. A instalação demora apenas alguns minutos no máximo, após os quais poderá retomar a transferência.</div><br /><div>Proceda da seguinte forma:</div><br /><ol><li>Transfira o instalador clicando na ligação abaixo.</li><li>Execute o instalador transferido – este irá configurar a Interface NetSession.</li><li>Quando a instalação terminar, esta janela pop–up encerrará e a transferência irá ser retomada na janela do navegador.</li></ol><br /><div>Clique aqui para iniciar:<a href='#' onclick='return DLMHelper.downloadInstaller();'>transferir o instalador</a>.</div><br /><div>Se tiver dúvidas ou quiser obter mais informação sobre a Interface Akamai NetSession, por favor visite a nossa <a href='http://www.akamai.com/client' target=_blank>página de início</a>.</div><br /><div>Se não conseguir completar a instalação, <a href='#' onclick='return DLMHelper.setInstallFailure();'>clique aqui</a>.</div></div>",
        "installFailureMsg": "<div class='DLMfailureMsgHeight'><div>Lamentamos, a instalação falhou. Por favor, dispense um momento para nos enviar o seu <a href='http://www.akamai.com/html/misc/akamai_client/dlm_feedback.html' target='_blank'>comentário</a> relativo ao processo de instalação.</div><br /><br /><div>Pressione <span style='font-weight: bold; margin: 0;'>OK</span> para fechar este pop-up e tentar um método de transferência diferente.<br />Pressione <span style='font-weight:bold; margin: 0;'>Tentar Novamente</span> para voltar ao ecrã anterior e tentar instalar novamente.</div><br /><input type='submit' value='OK' onclick='return DLMHelper.hideInstallerPopup();' /><input type='submit' value='Tentar Novamente' onclick='return DLMHelper.displayInstallerPopup();' style='margin-left: 20px;' /></div>",
        "singleDirectDownloadLink": "Clique <a href=\"%s\" target=\"_blank\">aqui</a> para transferir com o seu navegador.",
        "bundleDirectDownloadMessage": "Clique nas ligações dos ficheiros individuais para fazer a transferência utilizando o seu navegador.",
        "errorPopUpHeader" : "Detalhes do Erro:",
        "errorTitle": "ERRO",
        "showDetailsTitle": "Ver Detalhes"
    },
    "pt-br": {
        "startTitle": "Clique em \"executar\" ou \"abrir\" para iniciar o instalador.",
        "relaunchMsgStart": "Não encontra o instalador? ",
        "relaunchLink": "Tente abri-lo novamente.",
        "relaunchMsgEnd": "",
        "title": "Fazendo download %s",
        "autoStart": " Abre automaticamente quando concluído.",
        "completeTitle": "Download concluído!",
        "completeText": "Abrir %s",
        "timeLabel": "%s estimado.",
        "waiting": "Aguardando.",
        "paused": "Pausado.",
        "pausedNotFound": "Arquivo não encontrado!",
        "pausedInsufficientDiskSpace": "Espaço em disco insuficiente!",
        "pausedForbidden": "Acesso negado!",
        "pausedDisconnected": "Desconectado do servidor, tentando novamente...",
        "unloadMsg": "Já há um download em andamento. Se sair agora, o download será pausado.",
        "minute": "minuto",
        "minutes": "minutos",
        "second": "segundo",
        "seconds": "segundos",
        "download": "Download",
        "hourAbbr": "h",
        "minAbbr": "m",
        "calcTime": "Calculando tempo estimado.",
        // New Bundled DLM strings. Also adds localizable percentage format.
        "waitStatus": "Aguardando...",
        "defaultStatus2": "Inicializando...",
        "titleTextProgress": "Andamento total %s",
        "titleTextPaused": "Andamento total %s PAUSADO",
        "statusProgress": "%s (%s de %s): %s",
        "percentage": "%s%",
        "cancelledTitle": "Cancelado %s",
        "cancelledMsg": "Reiniciar o download.",
        // New error strings
        "unexpectedHttpResponse": "Uma resposta HTTP inesperada foi recebida",
        "missingRange": "Ausência do \"Intervalo\" do cabeçalho",
        "missingRangeProxy": "Ausência do \"Intervalo\" do cabeçalho. Possível incompatibilidade de proxy",
        "zeroContentLength": "Comprimento do conteúdo ausente",
        "zeroContentLengthProxy": "Comprimento do conteúdo ausente. Possível incompatibilidade de proxy",
        "invalidFileSize": "Tamanho de arquivo inesperado",
        "invalidFileSizeProxy": "Tamanho de arquivo inesperado. Possível incompatibilidade de proxy",
        "invalidRange": "Cabeçalho de resposta \"Content-Range\" inválido",
        "invalidRangeProxy": "Cabeçalho de resposta \"Content-Range\" inválido. Possível incompatibilidade de proxy",
        "negativeSize": "Cabeçalho de resposta \"Content-Range\" inválido",
        "negativeSizeProxy": "Cabeçalho de resposta \"Content-Range\" inválido. Possível incompatibilidade de proxy",
        "503Response": "O serviço está temporariamente indisponível",
        "unrecognizedResponse": "Resposta não reconhecida",
        "unrecognizedResponseProxy": "Resposta não reconhecida. Possível incompatibilidade de proxy",
        "tooManyRedirects": "Redirecionamentos HTTP em excesso",
        "missingLocationHeader": "Ausência da \"Localização\" do cabeçalho",
        "missingLocationHeaderProxy": "Ausência da \"Localização\" do cabeçalho. Possível incompatibilidade de proxy ",
        "invalidLocationHeader": "Localização’ do cabeçalho inválida",
        "invalidLocationHeaderProxy": "Localização’ do cabeçalho inválida. Possível incompatibilidade de proxy",
        "timeOutError": "Solicitar tempo limite",
        "contentVerficationError": "Falha na verificação do conteúdo",
        "noRsmd": "Não foi possível determinar a exatidão do conteúdo",
        "contentInvalid": "Conteúdo inválido",
        "connectivityError": "Erro de Conectividade",
        "serverUnreachable": "Servidor inacessível",
        "deletionInProgress": "Exclusão em progresso",
        "diskError": "Erro de Disco",
        "noPermissions": "Permissão negada",
        "fileReadOnly": "Foi feita uma tentativa para gravar em um arquivo ou dispositivo aberto com acesso somente para  leitura",
        "tooManyFiles": "Há muitos arquivos abertos",
        "dirNotFound": "O arquivo ou diretório especificado não existe ou não pode ser encontrado",
        "noSpace": "Não há mais espaço no dispositivo",
        "crossDeviceError": "Foi feita uma tentativa para mover um arquivo para um dispositivo diferente",
        "popupContent": "<div id='DLMtitleBar'><div id='DLMpopupClose' onclick='return DLMHelper.hideInstallerPopup();'></div><div id='DLMlogo'></div><span id='DLMpopupTitle'>Akamai NetSession Interface</span></div><div class='DLMheaderPadding'></div><div id='DLMpopupContainer'>%s</div><div class='DLMheaderPadding'></div>",
        "installMsg": "<div class='DLMinstallMsgHeight'><div>Para concluir este download, você precisa instalar a Interface NetSession, da Akamai, um gerenciador de download usado para reduzir o tempo de download e melhorar a qualidade. A instalação deve durar apenas alguns minutos, depois da instalação o seu download pode continuar.</div><br /><div>Siga estes passos:</div><br /><ol><li>Faça o download do instalador clicando no link abaixo.</li><li>Execute o instalador, ele irá configurar a Interface NetSession.</li><li>Quando a instalação estiver concluída, esta janela pop-up fechará e o download continuará na janela do navegador.</li></ol><br /><div>Clique aqui para iniciar: <a href='#' onclick='return DLMHelper.downloadInstaller();'>download do instalador</a>.</div><br /><div>Se você tiver dúvidas ou desejar mais informações sobre a Interface NetSession, da Akamai, visite a nossa <a href='http://www.akamai.com/client' target=_blank>página inicial</a>.</div><br /><div>Se você não conseguiu concluir a instalação, <a href='#' onclick='return DLMHelper.setInstallFailure();'>clique aqui</a>.</div></div>",
        "installFailureMsg": "<div class='DLMfailureMsgHeight'><div>Desculpe, a instalação falhou. Compartilhe sua <a href='http://www.akamai.com/html/misc/akamai_client/dlm_feedback.html' target='_blank'>opinião</a> sobre este processo de instalação.</div><br /><br /><div>Clique em <span style='font-weight: bold; margin: 0;'>OK</span> para fechar esta janela e tente um método alternativo de download.<br />Clique em <span style='font-weight:bold; margin: 0;'>Repetir</span> para voltar à tela anterior e tentar fazer a instalação novamente.</div><br /><input type='submit' value='OK' onclick='return DLMHelper.hideInstallerPopup();' /><input type='submit' value='Repetir' onclick='return DLMHelper.displayInstallerPopup();' style='margin-left: 20px;' /></div>",
        "singleDirectDownloadLink": "Clique <a href=\"%s\" target=\"_blank\">aqui</a> para fazer o download usando o seu navegador.",
        "bundleDirectDownloadMessage": "Clique nos links de arquivo individual para fazer o download usando o seu navegador.",
        "errorPopUpHeader" : "Detalhes do Erro:",
        "errorTitle": "ERRO",
        "showDetailsTitle": "Exibir Detalhes"
    },
    ru: {
        "startTitle": "Нажмите \"run\" или \"open\" для запуска программы установки.",
        "relaunchMsgStart": "Не можете найти каталог, в который загрузили программу установки? ",
        "relaunchLink": "Нажмите эту ссылку.",
        "relaunchMsgEnd": "",
        "title": "Загрузка %s",
        "autoStart": " Открыть после окончания загрузки",
        "completeTitle": "Загрузка завершена!",
        "completeText": "Открыть %s",
        "timeLabel": "%s до окончания загрузки.",
        "waiting": "Ожидание.",
        "paused": "Приостановлено.",
        "pausedNotFound": "Файл не найден!",
        "pausedInsufficientDiskSpace": "Недостаточно свободного пространства на диске!",
        "pausedForbidden": "Доступ запрещен!",
        "pausedDisconnected": "Соединение с сервером прервано, выполняется попытка восстановить подключение...",
        "unloadMsg": "Загрузка не завершена. Если Вы уйдете со страницы, загрузка будет прекращена.",
        "minute": "мин.",
        "minutes": "мин.",
        "second": "сек.",
        "seconds": "сек.",
        "download": "Загрузить",
        "hourAbbr": "ч.",
        "minAbbr": "мин.",
        "calcTime": "Расчетное время до окончания загрузки.",
        // New Bundled DLM strings. Also adds localizable percentage format.
        "waitStatus": "Ожидание...",
        "defaultStatus2": "Инициализация...",
        "titleTextProgress": "Загрузка %s",
        "titleTextPaused": "Загрузка %s: приостановлено",
        "statusProgress": "%s (%s из %s): %s",
        "percentage": "%s%",
        "cancelledTitle": "Загрузка %s: отменено",
        "cancelledMsg": "Перезапустить загрузку.",
        // New error strings
        "unexpectedHttpResponse": "Неожиданный ответ HTTP",
        "missingRange": "Отсутствует заголовок \"Диапазон\"",
        "missingRangeProxy": "Отсутствует заголовок \"Диапазон\". Возможная несовместимость с прокси-сервером",
        "zeroContentLength": "Отсутствует информация о длине содержимого",
        "zeroContentLengthProxy": "Отсутствует информация о длине содержимого. Возможная несовместимость с прокси-сервером",
        "invalidFileSize": "Неожиданный размер файла",
        "invalidFileSizeProxy": "Неожиданный размер файла. Возможная несовместимость с прокси-сервером",
        "invalidRange": "Недопустимый заголовок ответа \"Диапазон содержимого\"",
        "invalidRangeProxy": "Недопустимый заголовок ответа \"Диапазон содержимого\". Возможная несовместимость с прокси-сервером",
        "negativeSize": "Недопустимый заголовок ответа \"Диапазон содержимого\"",
        "negativeSizeProxy": "Недопустимый заголовок ответа \"Диапазон содержимого\". Возможная несовместимость с прокси-сервером",
        "503Response": "Служба временно недоступна",
        "unrecognizedResponse": "Нераспознанный ответ",
        "unrecognizedResponseProxy": "Нераспознанный ответ. Возможная несовместимость с прокси-сервером",
        "tooManyRedirects": "Слишком много перенаправлений протокола HTTP",
        "missingLocationHeader": "Отсутствует заголовок \"Местоположение\"",
        "missingLocationHeaderProxy": "Отсутствует заголовок \"Местоположение\". Возможная несовместимость с прокси-сервером",
        "invalidLocationHeader": "Недопустимый заголовок \"Местоположение\"",
        "invalidLocationHeaderProxy": "Недопустимый заголовок \"Местоположение\". Возможная несовместимость с прокси-сервером",
        "timeOutError": "Время ожидания запроса истекло",
        "contentVerficationError": "Ошибка при проверке содержимого",
        "noRsmd": "Не удается определить правильность содержимого",
        "contentInvalid": "Недопустимое содержимое",
        "connectivityError": "Ошибка подключения",
        "serverUnreachable": "Сервер недоступен",
        "deletionInProgress": "Выполняется удаление",
        "diskError": "Ошибка диска",
        "noPermissions": "В разрешении отказано",
        "fileReadOnly": "Предпринята попытка выполнить запись в файл или устройство, открытые только для чтения",
        "tooManyFiles": "Слишком много открытых файлов",
        "dirNotFound": "Указанный файл или каталог не существует или не найден",
        "noSpace": "На устройстве нет свободного места",
        "crossDeviceError": "Предпринята попытка переместить файл на другое устройство",
        "popupContent": "<div id='DLMtitleBar'><div id='DLMpopupClose' onclick='return DLMHelper.hideInstallerPopup();'></div><div id='DLMlogo'></div><span id='DLMpopupTitle'>Akamai NetSession Interface</span></div><div class='DLMheaderPadding'></div><div id='DLMpopupContainer'>%s</div><div class='DLMheaderPadding'></div>",
        "installMsg": "<div class='DLMinstallMsgHeight'><div>Для завершения загрузки, вам необходимо установить программу Akamai NetSession Interface, для сокращения времени загрузки и повышения качества используется менеджер загрузки.  На установку потребуется максимум несколько минут, после чего загрузка может возобновиться.</div><br /><div>Выполните следующие шаги:</div><br /><ol><li>Загрузите программу установки, нажав на ссылку ниже.</li><li>Запустите загруженную программу установки – она создаст NetSession Interface.</li><li>После завершения установки это всплывающее окно закроется, и в окне браузера возобновится загрузка.</li></ol><br /><div>Нажмите сюда, чтобы <a href='#' onclick='return DLMHelper.downloadInstaller();'>Загрузить программу установки</a>.</div><br /><div>Если у вас возникли вопросы, или вы хотите узнать подробнее о программе Akamai NetSession Interface, посетите нашу <a href='http://www.akamai.com/client' target=_blank>главную страницу</a>.</div><br /><div>Если не удается выполнить установку,<a href='#' onclick='return DLMHelper.setInstallFailure();'>нажмите сюда</a>.</div></div>",
        "installFailureMsg": "<div class='DLMfailureMsgHeight'><div>К сожалению, при установке произошел сбой. Оставьте, пожалуйста,  свой <a href='http://www.akamai.com/html/misc/akamai_client/dlm_feedback.html' target='_blank'>отзыв</a> об этом процессе установки.</div><br /><br /><div>Нажмите <span style='font-weight: bold; margin: 0;'>OK</span>, чтобы закрыть это сообщение и выбрать другой способ загрузки.<br />Нажмите <span style='font-weight:bold; margin: 0;'>Повторить</span>, чтобы вернуться к предыдущему экрану и попытаться установить еще раз.</div><br /><input type='submit' value='OK' onclick='return DLMHelper.hideInstallerPopup();' /><input type='submit' value='Повторить' onclick='return DLMHelper.displayInstallerPopup();' style='margin-left: 20px;' /></div>",
        "singleDirectDownloadLink": "Нажмите <a href=\"%s\" target=\"_blank\">сюда</a>, чтобы загрузить при помощи браузера.",
        "bundleDirectDownloadMessage": "Нажмите на отдельные ссылки файлов, чтобы загрузить при помощи браузера.",
        "errorPopUpHeader" : "Сведения об ошибке:",
        "errorTitle": "ОШИБКА",
        "showDetailsTitle": "Подробнее"
    },
    sv: {
        "startTitle": "Klicka på \"kör\" eller  \"öppna\" för att starta installationsprogrammet.",
        "relaunchMsgStart": "Ser du inte installationsprogrammet? ",
        "relaunchLink": "Försök att öppna det igen.",
        "relaunchMsgEnd": "",
        "title": "Laddar ned  %s",
        "autoStart": "Öppna fil automatiskt efter installation.",
        "completeTitle": "Installation avslutad!",
        "completeText": "Öppna ",
        "timeLabel": "%s återstående.",
        "waiting": "Väntar.",
        "paused": "Pausad.",
        "pausedNotFound": "Fil kunde inte hittas!",
        "pausedInsufficientDiskSpace": "Otillräckligt med plats på hårddisken!",
        "pausedForbidden": "Åtkomst nekad!",
        "pausedDisconnected": "Frånkopplad.",
        "unloadMsg": "Det pågår en nedladdning. Om du går nu kommer nedladdningen att avbrytas tillfälligt. ",
        "minute": "minut",
        "minutes": "minuter",
        "second": "sekund",
        "seconds": "sekunder",
        "download": "Nedladdning",
        "hourAbbr": "h",
        "minAbbr": "m",
        "calcTime": "Beräknar tid återstående.",
        "waitStatus": "Väntar...",
        "defaultStatus2": "Initierar...",
        "titleTextProgress": "Totalt förlopp %s",
        "titleTextPaused": "Totalt förlopp %s PAUSAD",
        "statusProgress": "%s (%s av %s): %s",
        "percentage": "%s%",
        "cancelledTitle": "Avbruten %s",
        "cancelledMsg": "Starta om nedladdningen.",
        // New error strings
        "unexpectedHttpResponse": "Erhöll ett oväntat HTTP- svar",
        "missingRange": "\"Räckvidds\"-header saknas",
        "missingRangeProxy": "\"Räckvidds\"-header saknas . Möjlig proxy-inkompatibilitet",
        "zeroContentLength": "Innehållslängd saknas",
        "zeroContentLengthProxy": "Innehållslängd saknas. Möjlig proxy-inkompatibilitet",
        "invalidFileSize": "Oförutsedd filstorlek",
        "invalidFileSizeProxy": "Oförutsedd filstorlek. Möjlig proxy-inkompatibilitet",
        "invalidRange": "Ogiltig \"Content-range\"- respons-header",
        "invalidRangeProxy": "Ogiltig \" Content-range\"- respons-header. Möjlig proxy-inkompatibilitet",
        "negativeSize": "Ogiltig \"Content-range\"- respons-header",
        "negativeSizeProxy": "Ogiltig \" Content-range\"- respons-header. Möjlig proxy-inkompatibilitet",
        "503Response": "Tjänsten är för tillfället ej tillgänglig",
        "unrecognizedResponse": "Respons igenkänns ej",
        "unrecognizedResponseProxy": "Respons igenkänns ej. Möjlig proxy-inkompatibilitet",
        "tooManyRedirects": "För många HTTP-omdirigeringar",
        "missingLocationHeader": "\"Lokaliserings\"- header saknas",
        "missingLocationHeaderProxy": "\"Lokaliserings\"- header saknas. Möjlig proxy-inkompatibilitet ",
        "invalidLocationHeader": "Ogiltig \" Lokaliserings \"- header",
        "invalidLocationHeaderProxy": "Ogiltig \" Lokaliserings \"- header. Möjlig proxy-inkompatibilitet ",
        "timeOutError": "Begär timeout",
        "contentVerficationError": "Innehållsverifikation misslyckades",
        "noRsmd": "Kan ej avgöra inehållets korrekthet",
        "contentInvalid": "Innehållet ogiltigt",
        "connectivityError": "Uppkopplingsfel",
        "serverUnreachable": "Server ej nåbar",
        "deletionInProgress": "Radering pågår",
        "diskError": "Diskfel",
        "noPermissions": "Tillstånd nekas",
        "fileReadOnly": "Ett försök gjordes att skriva till en fil eller enhet som öppnats i endast läs-läge",
        "tooManyFiles": "För många filer är öppnade",
        "dirNotFound": "Den specifierade filen eller katalogen existerar ej eller kan ej hittas",
        "noSpace": "Inget utrymme kvar på enheten",
        "crossDeviceError": "Ett försök gjordes att flytta en fil till en annan enhet",
        "popupContent": "<div id='DLMtitleBar'><div id='DLMpopupClose' onclick='return DLMHelper.hideInstallerPopup();'></div><div id='DLMlogo'></div><span id='DLMpopupTitle'>Akamai NetSession Interface</span></div><div class='DLMheaderPadding'></div><div id='DLMpopupContainer'>%s</div><div class='DLMheaderPadding'></div>",
        "installMsg": "<div class='DLMinstallMsgHeight'><div>För att genomföra denna nedladdning måste du installera  Akamai NetSession Interface, en nedladdningshanterare som används för att reducera nedladdningstid och förbättra kvalitet. Denna installation bör endast ta några minuter, efter vilket din nedladdning kan återupptas.</div><br /><div>Var god vidta följande steg:</div><br /><ol><li>Ladda ned installationsprogrammet genom att klicka på länken nedan.</li><li>Kör nedladdningsinstalleraren - den kommer att ställa in NetSession Interface.</li><li>När installationen är genomförd kommer detta popup-fönster stängas och nedladdningen återupptas i webbläsaren.</li></ol><br /><div>Klicka här för att börja: <a href='#' onclick='return DLMHelper.downloadInstaller();'>Ladda ned installationsprogrammet</a>.</div><br /><div>Om du har frågor eller vill ha mer information om Akamai NetSession Interface, var god besök vår <a href='http://www.akamai.com/client' target=_blank>hemsida</a>.</div><br /><div><a href='#' onclick='return DLMHelper.setInstallFailure();'>Klicka här</a> om du inte lyckas genomföra installationen.</div></div>",
        "installFailureMsg": "<div class='DLMfailureMsgHeight'><div>Vi beklagar att installationen misslyckades. Var god tag ett ögonblick och delge oss din <a href='http://www.akamai.com/html/misc/akamai_client/dlm_feedback.html' target='_blank'>återkoppling</a> angående denna installationsprocess.</div><br /><br /><div>Klicka på <span style='font-weight: bold; margin: 0;'>OK</span> för att stänga detta popuppfönster och prova en alternativ nedladdningsmetod.<br />Klicka på <span style='font-weight:bold; margin: 0;'>Försök igen</span> för att återgå till föregående skärm och försöka genomföra installationen igen.</div><br /><input type='submit' value='OK' onclick='return DLMHelper.hideInstallerPopup();' /><input type='submit' value='Försök igen' onclick='return DLMHelper.displayInstallerPopup();' style='margin-left: 20px;' /></div>",
        "singleDirectDownloadLink": "Klicka <a href=\"%s\" target=\"_blank\">här</a> för att ladda ned via din webbläsare",
        "bundleDirectDownloadMessage": "Klicka på de individuella fillänkarna för att ladda ned via din webbläsare.",
        "errorPopUpHeader" : "Feldetaljer:",
        "errorTitle": "FEL",
        "showDetailsTitle": "Visa detaljer"
    },
    tr:{
       "startTitle": "Kurulumu başlatmak için \"run (başlat)\" ya da \"open(aç)\"a tıklayın.",
       "relaunchMsgStart": "Kurulum programını görmüyor musunuz? ",
       "relaunchLink": "Tekrar açmayı deneyin.",
       "relaunchMsgEnd": "",
       "title": "%s indiriliyor",
       "autoStart": "Tamamlandığında otomatik olarak aç.",
       "completeTitle": "İndirme işlemi tamamlanmıştır!",
       "completeText": "%s aç",
       "timeLabel": "%skalan süredir.",
       "waiting": "Bekliyor.",
       "paused": "Duraklatıldı.",
       "pausedNotFound": "Dosya bulunamadı!",
       "pausedInsufficientDiskSpace": "Yetersiz disk alanı!",
       "pausedForbidden": "Erişim reddedildi!",
       "pausedDisconnected": "Bağlantı kesildi.",
       "unloadMsg": "Şu anda bir yükleme işlemi sürüyor. Eğer şimdi ayrılırsanız, yükleme işlemi kısa süre içinde duraklayacaktır.",
       "minute": "dakika",
       "minutes": "dakika",
       "second": "saniye",
       "seconds": "saniye",
       "download": "İndir",
       "hourAbbr": "saat",
       "minAbbr": "san.",
       "calcTime": "Zamanı hesaplıyor skalan süredir.",
       "waitStatus": "Bekliyor...",
       "defaultStatus2": "Başlatılıyor...",
       "titleTextProgress": "Toplam işlem durumu %s",
       "titleTextPaused": "Toplam işlem durumu %s DURAKLATILDI",
       "statusProgress": "%s (%s’den %s): %s",
       "percentage": "%s%",
       "cancelledTitle": "%s iptal edildi",
       "cancelledMsg": "İndirme işlemini tekrar başlatın.",
       // New error strings
        "unexpectedHttpResponse": "Beklenmeyen bir HTTP yanıtı alındı",
        "missingRange": "Eksik \"Alan\" başlığı",
        "missingRangeProxy": "Eksik \"Alan\" başlığı. Olası Proxy uyumsuzluğu",
        "zeroContentLength": "Eksik içerik uzunluğu",
        "zeroContentLengthProxy": "Eksik içerik uzunluğu. Olası proxy uyumsuzluğu",
        "invalidFileSize": "Beklenmeyen dosya Boyutu",
        "invalidFileSizeProxy": "Beklenmeyen dosya Boyutu. Olası proxy uyumsuzluğu",
        "invalidRange": "Geçersiz \"İçerik Alanı\" yanıt başlığı",
        "invalidRangeProxy": "Geçersiz \"İçerik Alanı\" yanıt başlığı. Olası proxy uyumsuzluğu",
        "negativeSize": "Geçersiz \"İçerik Alanı\" yanıt başlığı",
        "negativeSizeProxy": "Geçersiz \"İçerik Alanı\" yanıt başlığı. Olası proxy uyumsuzluğu",
        "503Response": "Hizmet geçici olarak kullanılamıyor",
        "unrecognizedResponse": "Yanıt tanınmadı",
        "unrecognizedResponseProxy": "Yanıt tanınmadı. Olası proxy uyumsuzluğu",
        "tooManyRedirects": "Çok fazla HTTP yeniden yönlendirmesi",
        "missingLocationHeader": "Eksik \"Konum\" başlığı",
        "missingLocationHeaderProxy": "Eksik \"Konum\" başlığı. Olası proxy uyumsuzluğu ",
        "invalidLocationHeader": "Geçersiz \"Konum\" başlığı",
        "invalidLocationHeaderProxy": "Geçersiz \"Konum\" başlığı. Olası proxy uyumsuzluğu ",
        "timeOutError": "İstek zaman aşımı",
        "contentVerficationError": "İçerik doğrulama hatası",
        "noRsmd": "İçeriğin doğruluğu saptanamadı",
        "contentInvalid": "Geçersiz içerik",
        "connectivityError": "Bağlantı Hatası",
        "serverUnreachable": "Sunucuya ulaşılamıyor",
        "deletionInProgress": "Silme işlemi sürüyor",
        "diskError": "Disk Hatası",
        "noPermissions": "İzin verilmedi",
        "fileReadOnly": "Salt okuma erişimi için açılan bir dosyaya ya da cihaza yazmaya çalışıldı",
        "tooManyFiles": "Çok fazla açık dosya var",
        "dirNotFound": "Belirtilen dosya veya dizin yok veya bulunamıyor",
        "noSpace": "Cihazda yer kalmadı",
        "crossDeviceError": "Bir dosyayı farklı bir cihaza taşımaya çalışıldı",
        "popupContent": "<div id='DLMtitleBar'><div id='DLMpopupClose' onclick='return DLMHelper.hideInstallerPopup();'></div><div id='DLMlogo'></div><span id='DLMpopupTitle'>Akamai NetSession Interface</span></div><div class='DLMheaderPadding'></div><div id='DLMpopupContainer'>%s</div><div class='DLMheaderPadding'></div>",
        "installMsg": "<div class='DLMinstallMsgHeight'><div>Bu yüklemeyi tamamlamak için, yükleme süresini azaltmak ve kaliteyi artırmak için kullanılan bir yükleme yöneticisi olan Akamai NetSession Interface’i kurmanız gerekiyor. Bu kurulum en fazla beş dakika sürecektir, ardından yüklemeniz başlayabilir.</div><br /><div>Lütfen, aşağıdaki adımları izleyin:</div><br /><ol><li>Aşağıdaki bağlantıya tıklayarak yükleyiciyi karşıdan yükleyin.</li><li>Karşıdan yüklenen yükleyiciyi çalıştırın – bu, NetSession Interface’i kuracaktır.</li><li>Kurulum tamamlandığında, bu açılır pencere kapanacak ve tarayıcı penceresinde karşıdan yükleme başlayacaktır.</li></ol><br /><div>Başlamak için buraya tıklayın: <a href='#' onclick='return DLMHelper.downloadInstaller();'>yükleyiciyi karşıdan yükle</a>.</div><br /><div>Sorularınız varsa veya Akamai NetSession Interface hakkında daha fazla bilgi almak istiyorsanız, lütfen <a href='http://www.akamai.com/client' target=_blank>ana sayfa’</a> mızı ziyaret edin.</div><br /><div>Yüklemeyi tamamlayamıyorsanız, <a href='#' onclick='return DLMHelper.setInstallFailure();'>buraya tıklayın</a>.</div></div>",
        "installFailureMsg": "<div class='DLMfailureMsgHeight'><div>Üzgünüz, yükleme başarısız oldu. Lütfen, bu yükleme işlemiyle ilgili <a href='http://www.akamai.com/html/misc/akamai_client/dlm_feedback.html' target='_blank'>görüşlerinizi</a> paylaşmak için bir iki dakikanızı ayırın.</div><br /><br /><div>Bu açılır pencereyi kapatmak ve alternatif bir yükleme yöntemi denemek için <span style='font-weight: bold; margin: 0;'>TAMAM</span>’a tıklayın.<br />Önceki ekrana dönmek ve yüklemeyi yeniden denemek için <span style='font-weight:bold; margin: 0;'>Yeniden dene’</span> ye tıklayın.</div><br /><input type='submit' value='TAMAM' onclick='return DLMHelper.hideInstallerPopup();' /><input type='submit' value='Yeniden dene' onclick='return DLMHelper.displayInstallerPopup();' style='margin-left: 20px;' /></div>",
        "singleDirectDownloadLink": "Tarayıcınızı kullanarak karşıdan yüklemek için <a href=\"%s\" target=\"_blank\">buraya</a> tıklayın",
        "bundleDirectDownloadMessage": "Tarayıcınızı kullanarak karşıdan yüklemek için ayrı dosya bağlantılarına tıklayın.",
        "errorPopUpHeader" : "Hata Ayrıntıları:",
        "errorTitle": "HATA",
        "showDetailsTitle": "Ayrıntıları Göster"
    },
    "zh-cn": {
        "startTitle": "单击“运行”或“打开”以启动安装程序。",
        "relaunchMsgStart": "看不到安装程序？ ",
        "relaunchLink": "请尝试重新打开它。",
        "relaunchMsgEnd": "",
        "title": "正在下载 %s",
        "autoStart": " 完成时自动打开。",
        "completeTitle": "下载完成！",
        "completeText": "打开 %s",
        "timeLabel": "%s 剩余。",
        "waiting": "正在等待。",
        "paused": "已暂停。",
        "pausedNotFound": "未找到文件！",
        "pausedInsufficientDiskSpace": "磁盘空间不足！",
        "pausedForbidden": "访问被拒绝！",
        "pausedDisconnected": "已从服务器断开连接，正在重试...",
        "unloadMsg": "正在进行下载。如果您现在离开，下载将会暂停。",
        "minute": "分钟",
        "minutes": "分钟",
        "second": "秒",
        "seconds": "秒",
        "download": "下载",
        "hourAbbr": "h",
        "minAbbr": "M",
        "calcTime": "正在计算时间 剩余。",
        // New Bundled DLM strings. Also adds localizable percentage format.
        "waitStatus": "正在等待...",
        "defaultStatus2": "正在初始化...",
        "titleTextProgress": "总进度 %s",
        "titleTextPaused": "总进度 %s 已暂停",
        "statusProgress": "%s（%s，共 %s）：%s",
        "percentage": "%s%",
        "cancelledTitle": "已取消 %s",
        "cancelledMsg": "重新启动下载。",
        // New error strings
        "unexpectedHttpResponse": "接收到一个意外的HTTP响应",
        "missingRange": "缺少‘范围’标头",
        "missingRangeProxy": "缺少‘范围’标头。 代理服务器可能不兼容",
        "zeroContentLength": "缺少内容长度",
        "zeroContentLengthProxy": "缺少内容长度。 代理服务器可能不兼容",
        "invalidFileSize": "意外的文件大小",
        "invalidFileSizeProxy": "意外的文件大小。 代理服务器可能不兼容",
        "invalidRange": "无效的‘内容范围’响应标头",
        "invalidRangeProxy": "无效的‘内容范围’响应标头。 代理服务器可能不兼容",
        "negativeSize": "无效的‘内容范围’响应标头",
        "negativeSizeProxy": "无效的‘内容范围’响应标头。 代理服务器可能不兼容",
        "503Response": "暂时无法提供服务",
        "unrecognizedResponse": "响应未被识别",
        "unrecognizedResponseProxy": "响应未被识别。 代理服务器可能不兼容",
        "tooManyRedirects": "过多HTTP重定向",
        "missingLocationHeader": "缺少‘位置’标头",
        "missingLocationHeaderProxy": "缺少‘位置’标头。 代理服务器可能不兼容",
        "invalidLocationHeader": "无效的‘位置’标头",
        "invalidLocationHeaderProxy": "无效的‘位置’标头。 代理服务器可能不兼容",
        "timeOutError": "请求超时",
        "contentVerficationError": "内容验证失败",
        "noRsmd": "无法确定内容正确性",
        "contentInvalid": "内容无效",
        "connectivityError": "连接错误",
        "serverUnreachable": "无法联系服务器",
        "deletionInProgress": "正在删除",
        "diskError": "磁盘错误",
        "noPermissions": "权限被拒绝",
        "fileReadOnly": "试图写入以只读权限打开的文件或设备",
        "tooManyFiles": "打开的文件过多",
        "dirNotFound": "指定的文件或目录不存在或者无法找到",
        "noSpace": "设备空间不足",
        "crossDeviceError": "试图将文件转移到其他设备",
        "popupContent": "<div id='DLMtitleBar'><div id='DLMpopupClose' onclick='return DLMHelper.hideInstallerPopup();'></div><div id='DLMlogo'></div><span id='DLMpopupTitle'>Akamai NetSession Interface</span></div><div class='DLMheaderPadding'></div><div id='DLMpopupContainer'>%s</div><div class='DLMheaderPadding'></div>",
        "installMsg": "<div class='DLMinstallMsgHeight'><div>如需完成下载，您必须安装Akamai NetSession Interface，它是一种可缩短下载时间并提高下载质量的下载管理器。 安装过程最多只需数分钟，安装完毕后可继续下载。</div><br /><div>请执行以下步骤：</div><br /><ol><li>请单击以下链接，下载安装程序。</li><li>运行已下载的安装程序，该程序将安装NetSession Interface。</li><li>安装完成后，将关闭此弹出菜单并将在浏览器窗口继续完成下载。</li></ol><br /><div>点击此处开始： <a href='#' onclick='return DLMHelper.downloadInstaller();'>下载安装程序</a>.</div><br /><div>如果您有任何问题或者需要了解Akamai NetSession Interface的更多信息，请访问我们的<a href='http://www.akamai.com/client' target=_blank>主页。</a>.</div><br /><div>如果无法完成安装过程，请<a href='#' onclick='return DLMHelper.setInstallFailure();'>单击此处。</a>.</div></div>",
        "installFailureMsg": "<div class='DLMfailureMsgHeight'><div>很抱歉，安装失败。 请花费一点时间提交您对安装过程的<a href='http://www.akamai.com/html/misc/akamai_client/dlm_feedback.html' target='_blank'>反馈。</a>.</div><br /><br /><div>点击<span style='font-weight: bold; margin: 0;'>确定</span>关闭弹出窗口，并尝试其它下载方式。<br />按 <span style='font-weight:bold; margin: 0;'>重试</span> 返回上一个屏幕并尝试重新安装。.</div><br /><input type='submit' value='确定' onclick='return DLMHelper.hideInstallerPopup();' /><input type='submit' value='重试' onclick='return DLMHelper.displayInstallerPopup();' style='margin-left: 20px;' /></div>",
        "singleDirectDownloadLink": "单击 <a href=\"%s\" target=\"_blank\">此处</a>，使用浏览器下载。",
        "bundleDirectDownloadMessage": "单击每个文件的链接，使用浏览器下载。",
        "errorPopUpHeader" : "错误详情:",
        "errorTitle": "出现错误",
        "showDetailsTitle": "显示详情"
    },
    "zh-tw": {
        "startTitle": "按一下「執行」或「開啟」以啟動安裝程式。",
        "relaunchMsgStart": "找不到安裝程式？ ",
        "relaunchLink": "請嘗試重新開啟。",
        "relaunchMsgEnd": "",
        "title": "正在下載 %s",
        "autoStart": "  完成時自動開啟。",
        "completeTitle": "下載完成！",
        "completeText": "開啟 %s",
        "timeLabel": "%s 未完成。",
        "waiting": "正在等待。",
        "paused": "已暫停。",
        "pausedNotFound": "找不到檔案！",
        "pausedInsufficientDiskSpace": "磁碟空間不足！",
        "pausedForbidden": "拒絕存取！",
        "pausedDisconnected": "與伺服器的連線中斷，正在重試...",
        "unloadMsg": "正在進行下載。如果您現在離開，下載將會暫停。",
        "minute": "分鐘",
        "minutes": "分鐘",
        "second": "秒鐘",
        "seconds": "秒鐘",
        "download": "下載",
        "hourAbbr": "時",
        "minAbbr": "分",
        "calcTime": "正在計算時間 未完成。",
        // New Bundled DLM strings. Also adds localizable percentage format.
        "waitStatus": "正在等待...",
        "defaultStatus2": "正在初始化...",
        "titleTextProgress": "總體進度 %s",
        "titleTextPaused": "總體進度 %s 已暫停",
        "statusProgress": "%s (%s/%s)：%s",
        "percentage": "%s%",
        "cancelledTitle": "已取消 %s",
        "cancelledMsg": "重新啟動下載。",
        // New error strings
        "unexpectedHttpResponse": "接收到未預期的HTTP回應",
        "missingRange": "遺失『範圍』標頭",
        "missingRangeProxy": "遺失『範圍』標頭。代理伺服器可能不相容",
        "zeroContentLength": "遺失內容長度",
        "zeroContentLengthProxy": "遺失內容長度。代理伺服器可能不相容",
        "invalidFileSize": "未預期的檔案大小",
        "invalidFileSizeProxy": "未預期的檔案大小。代理伺服器可能不相容",
        "invalidRange": "無效的『內容-範圍』回應標頭",
        "invalidRangeProxy": "無效的『內容-範圍』回應標頭。代理伺服器可能不相容",
        "negativeSize": "無效的『內容-範圍』回應標頭",
        "negativeSizeProxy": "無效的『內容-範圍』回應標頭。代理伺服器可能不相容",
        "503Response": "服務暫時無法使用",
        "unrecognizedResponse": "無法辨識的回應",
        "unrecognizedResponseProxy": "無法辨識的回應。代理伺服器可能不相容",
        "tooManyRedirects": "太多次HTTP重新導向",
        "missingLocationHeader": "遺失『位置』標頭",
        "missingLocationHeaderProxy": "遺失『位置』標頭。代理伺服器可能不相容",
        "invalidLocationHeader": "無效的『位置』標頭",
        "invalidLocationHeaderProxy": "無效的『位置』標頭。代理伺服器可能不相容",
        "timeOutError": "要求逾時",
        "contentVerficationError": "內容驗證失敗",
        "noRsmd": "無法判斷內容之正確性",
        "contentInvalid": "內容無效",
        "connectivityError": "連接錯誤",
        "serverUnreachable": "無法連線伺服器",
        "deletionInProgress": "刪除進行中",
        "diskError": "磁碟錯誤",
        "noPermissions": "使用權限被拒",
        "fileReadOnly": "已嘗試寫入一個開啟為唯讀存取的檔案或是裝置",
        "tooManyFiles": "開啟太多檔案",
        "dirNotFound": "指定的檔案或目錄不存在或找不到",
        "noSpace": "裝置已沒有任何空間",
        "crossDeviceError": "已嘗試移動檔案到不同的裝置",
        "popupContent": "<div id='DLMtitleBar'><div id='DLMpopupClose' onclick='return DLMHelper.hideInstallerPopup();'></div><div id='DLMlogo'></div><span id='DLMpopupTitle'>Akamai NetSession Interface</span></div><div class='DLMheaderPadding'></div><div id='DLMpopupContainer'>%s</div><div class='DLMheaderPadding'></div>",
        "installMsg": "<div class='DLMinstallMsgHeight'><div>為完成下載，您需要安裝 Akamai NetSession Interface，此為用來減少下載時間和增加品質的下載管理員。安裝時間最多只要幾分鐘，安裝完成後即可恢復下載。</div><br /><div>請遵循下列步驟：</div><br /><ol><li>請點選以下連結以下載安裝程式。</li><li>執行已下載的安裝程式－它將會安裝 NetSession Interface。</li><li>當安裝完成時，此彈出視窗將關閉，下載將會在瀏覽器視窗上繼續進行。</li></ol><br /><div>請點選這裡開始下載：<a href='#' onclick='return DLMHelper.downloadInstaller();'>下載安裝程式。</a>.</div><br /><div>若您有任何問題或欲瞭解更多 Akamai NetSession Interface 的相關資訊，請訪問我們的<a href='http://www.akamai.com/client' target=_blank>首頁</a>。.</div><br /><div>若您無法完成安裝，<a href='#' onclick='return DLMHelper.setInstallFailure();'>請點選這裡</a>。.</div></div>",
        "installFailureMsg": "<div class='DLMfailureMsgHeight'><div>我們對於安裝失敗深表歉意。請花一點時間分享您關於此安裝過程的<a href='http://www.akamai.com/html/misc/akamai_client/dlm_feedback.html' target='_blank'>意見</a>。.</div><br /><br /><div>請按<span style='font-weight: bold; margin: 0;'>OK</span> 以關閉此彈出視窗並嘗試其他下載方式。<br />請按<span style='font-weight:bold; margin: 0;'>重試</span>返回前一頁面並嘗試再次重新安裝。</div><br /><input type='submit' value='OK' onclick='return DLMHelper.hideInstallerPopup();' /><input type='submit' value='重試' onclick='return DLMHelper.displayInstallerPopup();' style='margin-left: 20px;' /></div>",
        "singleDirectDownloadLink": "請點選<a href=\"%s\" target=\"_blank\">這裡</a>以使用您的瀏覽器下載。",
        "bundleDirectDownloadMessage": "請點選個別的檔案連結以使用您的瀏覽器下載。",
        "errorPopUpHeader" : "錯誤的詳細資訊:",
        "errorTitle": "錯誤",
        "showDetailsTitle": "顯示詳細資訊"
    }
};

DLMHelper.errorCodes = {
    10: { 
        0:"unexpectedHttpResponse",
        1:"missingRange",
        2:"missingRangeProxy",
        3:"zeroContentLength",
        4:"zeroContentLengthProxy",
        5:"invalidFileSize",
        6:"invalidFileSizeProxy",
        7:"invalidRange",
        8:"invalidRangeProxy",
        9:"negativeSize",
        10:"negativeSizeProxy",
        11:"503Response",
        12:"unrecognizedResponse",
        13:"unrecognizedResponseProxy",
        14:"missingLocationHeader",
        15:"missingLocationHeaderProxy",
        16:"invalidLocationHeader",
        17:"invalidLocationHeaderProxy",
        18:"tooManyRedirects"        
    },
    11: {
        0:"contentVerficationError",
        1:"noRsmd",
        2:"contentInvalid"
    },
    12: {
        0:"connectivityError",
        1:"serverUnreachable",
        2:"timeOutError"
    },
    13: {
        0:"diskError",
        1:"pausedInsufficientDiskSpace",
        2:"noPermissions",
        3:"fileReadOnly",
        4:"tooManyFiles",
        5:"dirNotFound",
        6:"crossDeviceError"
    },
    14: {
        0:"deletionInProgress"
    },
    15: {
        0: "pausedNotFound"
    },
    16: {
        0: "pausedForbidden",
        1: "zeroContentLength"
        // No specific suberror string defined for auth failures and excessive hash blocks, so use only major error
        // 2: "pausedForbidden",
        // 3: "pausedForbidden"
    }
};
// Run the init() function to get everything started.
DLMHelper.init();

