1. // (c) Carbonite, Inc., 2005-2009 All rights reserved
  2. /* Carbonite Service included file /scripts/machinerecord.class.js */
  3. // (c) Carbonite, Inc., 2005-2009 All rights reserved
  4. BaseMachineRecord = function()
  5. {
  6.     // HTML Objects
  7.     this.Name = null;
  8.     this.Number = null;
  9.     this.Description = null;
  10.     this.LastBackupDate = null;
  11.     this.MachineType = null;
  12.     this.Platform = null;
  13.    
  14.     this.HtmlNode = null;
  15.    
  16.     // defining string
  17.     this.definingString = null;
  18.    
  19.     // classes
  20.     this.SELECTCLASS = null;
  21.     this.UNSELECTCLASS = null;
  22.     this.HOVERCLASS = null;
  23.    
  24.     // hover tip position, null will place it automatically
  25.     this.tipX = null;
  26.     this.tipY = null;
  27. }
  28.  
  29. BaseMachineRecord.prototype.parseString = function()
  30. {
  31.     var NVs = this.definingString.split(";");
  32.     var NVindex = 0;
  33.    
  34.     while (NVs[NVindex])
  35.     {
  36.         var NV = NVs[NVindex].split("=");
  37.         this[NV[0]] = NV[1];
  38.         NVindex++;
  39.     }
  40.    
  41.     // default values for those that are not provided
  42.     if ("" == this.MachineType)
  43.         this.MachineType = "desktop";
  44. }
  45.  
  46. BaseMachineRecord.prototype.Select = function(bSelect)
  47. {
  48.     this.HtmlNode.className = (bSelect ? this.SELECTCLASS : this.UNSELECTCLASS) + " " + this.Platform;
  49. }
  50.  
  51. BaseMachineRecord.prototype.Hover = function(bOver)
  52. {
  53.     if (this.HtmlNode.className.indexOf(this.SELECTCLASS) < 0)
  54.         this.HtmlNode.className = (bOver ? this.HOVERCLASS : this.UNSELECTCLASS) + " " + this.Platform;
  55.    
  56.     if (null == this.tipX || null == this.tipY)
  57.     {
  58.         // position the tip so that it shows the description at the bottom of the box
  59.         var machineBox = GetChildWithId(this.HtmlNode, "machineBoxBody")
  60.         if (null != machineBox)
  61.         {
  62.             var mbPos = FindObjectPosition(machineBox);
  63.             this.tipX = mbPos[0] + 20;
  64.             this.tipY = mbPos[1] + machineBox.offsetHeight - 20;
  65.         }
  66.     }
  67.    
  68.     if (bOver)
  69.         ShowTipString(this.Description, this.tipX, this.tipY);
  70.     else
  71.         HideTipString(this.Description);
  72. }
  73.  
  74. function MachineRecordHover()
  75. {
  76.     this.MachineRecord.Hover(true);
  77. }
  78.  
  79. function MachineRecordOut()
  80. {
  81.     this.MachineRecord.Hover(false);
  82. }
  83.  
  84. function MachineRecordClick()
  85. {
  86.     Installation.ChooseComputer(this.MachineRecord);
  87. }
  88.  
  89. MachineRecordBlock = function(str)
  90. {
  91.     // defining string
  92.     this.definingString = str;
  93.     this.parseString();
  94.    
  95.     this.SELECTCLASS = "SelectedMachine";
  96.     this.UNSELECTCLASS = "UnselectedMachine";
  97.     this.HOVERCLASS = "HoverMachine";
  98.    
  99.     this.insertIntoUI();
  100. }
  101.  
  102. MachineRecordBlock.prototype = new BaseMachineRecord;
  103.  
  104. MachineRecordBlock.prototype.insertIntoUI = function()
  105. {
  106.     this.HtmlNode = document.getElementById('crbMachineRecordTemplate').cloneNode(true);
  107.     this.insertValue("Name");
  108.     this.insertValue("Description");
  109.     this.insertValue("LastBackupDate");
  110.    
  111.     GetChildWithId(this.HtmlNode, "machineType").className += " " + this.MachineType;
  112.    
  113.     this.HtmlNode.MachineRecord = this;
  114.     this.HtmlNode.onmouseover = MachineRecordHover;
  115.     this.HtmlNode.onmouseout = MachineRecordOut;
  116.     this.HtmlNode.onclick = MachineRecordClick;
  117.    
  118.     document.getElementById('crbShortMachineList').appendChild(this.HtmlNode);
  119.     this.HtmlNode.style.display = "inline";
  120.    
  121.     this.HtmlNode.className += " " + this.Platform;
  122. }
  123.  
  124. MachineRecordBlock.prototype.insertValue = function(valueName)
  125. {
  126.     var populateNode = GetChildWithId(this.HtmlNode, "machine" + valueName);
  127.     populateNode.innerHTML = this[valueName];
  128. }
  129.  
  130. MachineRecordRow = function(str)
  131. {
  132.     // defining string
  133.     this.definingString = str;
  134.     this.parseString();
  135.    
  136.     this.SELECTCLASS = "SelectedMachineRow";
  137.     this.UNSELECTCLASS = "UnselectedMachineRow";
  138.     this.HOVERCLASS = "HoverMachineRow";
  139.    
  140.     this.insertIntoUI();
  141. }
  142.  
  143. MachineRecordRow.prototype = new BaseMachineRecord;
  144.  
  145. MachineRecordRow.prototype.insertIntoUI = function()
  146. {
  147.     var table = document.getElementById('crbMachineTable');
  148.     var tbody = table.getElementsByTagName('tbody')[0];
  149.    
  150.     this.HtmlNode = document.createElement('tr');
  151.     this.HtmlNode.className = "UnselectedMachineRow";
  152.     var col = document.createElement('td');
  153.     col.className = this.MachineType + "Small";
  154.     var incompatMsg = document.getElementById('crbIncompatiblePlatform').cloneNode(true);
  155.     col.appendChild(incompatMsg);
  156.     this.HtmlNode.appendChild(col);
  157.    
  158.     col = document.createElement('td');
  159.     col.innerText = this.Name;
  160.     this.HtmlNode.appendChild(col);
  161.    
  162.     col = document.createElement('td');
  163.     col.innerText = this.Description;
  164.     this.HtmlNode.appendChild(col);
  165.    
  166.     col = document.createElement('td');
  167.     col.innerText = this.LastBackupDate;
  168.     this.HtmlNode.appendChild(col);
  169.    
  170.     this.HtmlNode.MachineRecord = this;
  171.     this.HtmlNode.onmouseover = MachineRecordHover;
  172.     this.HtmlNode.onmouseout = MachineRecordOut;
  173.     this.HtmlNode.onclick = MachineRecordClick;
  174.    
  175.     this.HtmlNode.className += " " + this.Platform;
  176.    
  177.     tbody.appendChild(this.HtmlNode);
  178. }
  179.  
  180. MachineChosen = function(str)
  181. {
  182.     // defining string
  183.     this.definingString = str;
  184.     this.parseString();
  185.    
  186.     this.insertIntoUI();
  187. }
  188.  
  189. MachineChosen.prototype = new BaseMachineRecord;
  190.  
  191. MachineChosen.prototype.insertIntoUI = function()
  192. {
  193.     this.HtmlNode = document.getElementById('chosenMachineDisplay');
  194.     this.insertValue("Name");
  195.     this.insertValue("Description");
  196.     this.insertValue("LastBackupDate");
  197.    
  198.     GetChildWithId(this.HtmlNode, "machineType").className += " " + this.MachineType;
  199.    
  200.     this.HtmlNode.style.display = "";
  201. }
  202.  
  203. MachineChosen.prototype.insertValue = function(valueName)
  204. {
  205.     var populateNode = GetChildWithId(this.HtmlNode, "machine" + valueName);
  206.     populateNode.innerHTML = this[valueName];
  207. }
  208.  
  209. /* End included file /scripts/machinerecord.class.js */
  210. /* Carbonite Service included file /scripts/table.class.js */
  211. // (c) Carbonite, Inc., 2005-2009 All rights reserved
  212. /* Carbonite Service included file /scripts/draganddrop.js */
  213. // (c) Carbonite, Inc., 2005-2009 All rights reserved
  214. /* Carbonite Service included file /scripts/columninfo.class.js */
  215. // (c) Carbonite, Inc., 2005-2009 All rights reserved
  216. ColumnInfo = function(obj)
  217. {
  218.     this.Column = obj;
  219.  
  220.     this.MinSize = parseInt(this.ColumnStyle().minWidth);
  221.     if (isNaN(this.MinSize))
  222.         this.MinSize = 20;
  223.     this.MaxSize = parseInt(this.ColumnStyle().maxWidth);
  224.     if (isNaN(this.MaxSize))
  225.         this.MaxSize = 1000;
  226.  
  227.     this.RelativeSize = 1;
  228. }
  229.  
  230. ColumnInfo.prototype.ColumnStyle = function()
  231. {
  232.     var colStyle = this.Column.currentStyle ? this.Column.currentStyle : window.getComputedStyle(this.Column, null);
  233.     return colStyle;
  234. }
  235.  
  236. ColumnInfo.prototype.SetWidth = function(width)
  237. {
  238.     width = Math.max(this.MinSize, width);
  239.     width = Math.min(this.MaxSize, width);
  240.     this.Column.style.width = width + 'px';
  241. }
  242.  
  243. ColumnInfo.prototype.GetCurrentWidth = function()
  244. {
  245.     return this.Column.offsetWidth;
  246. }
  247.  
  248. // priovides some backward compatibility; these should be gone when we no longer use the non-htmltable tables
  249. ColumnInfoOld = function(sName)
  250. {
  251.     this.Column = document.getElementById(sName);
  252.     this.Header = document.getElementById(sName + "Header");
  253.     this.MinSize = parseInt(this.Column.currentStyle.minWidth);
  254.     if (isNaN(this.MinSize))
  255.         this.MinSize = 20;
  256.     this.MaxSize = parseInt(this.Column.currentStyle.maxWidth);
  257.    
  258.     if (isNaN(this.MaxSize))
  259.         this.MaxSize = 1000;
  260.     this.RelativeSize = 1;
  261. }
  262.  
  263. ColumnInfoOld.prototype.SetWidth = function(width, headerOffset)
  264. {
  265.     width = Math.max(this.MinSize, width);
  266.     width = Math.min(this.MaxSize, width);
  267.     var cols = document.all.item(this.Column.id);
  268.     for (var col = 0; col < cols.length; col++)
  269.     {
  270.         cols[col].style.width = width + 'px';
  271.     }
  272.     this.Column.style.width = width + 'px';
  273.     this.Header.style.width = (width - headerOffset) + 'px';
  274. }
  275.  
  276. ColumnInfoOld.prototype.GetCurrentWidth = function()
  277. {
  278.     return parseInt(this.Column.currentStyle.width);
  279. }
  280.  
  281. /* End included file /scripts/columninfo.class.js */
  282. /* Carbonite Service included file /scripts/draginfo.class.js */
  283. // (c) Carbonite, Inc., 2005-2009 All rights reserved
  284. DragInfo = function(obj)
  285. {
  286.     this.debug = document.getElementById('DebugDrags');
  287.     this.dodebug('DragInfo created for object' + obj.id);
  288.     this.dragger = obj;
  289.    
  290.     this.init();
  291. }
  292.  
  293. DragInfo.prototype.FindCol = function(headerObj)
  294. {
  295.     this.Columns = new Array();
  296.     this.DragIndex = null;
  297.    
  298.     var tParent = headerObj;
  299.     while (tParent && tParent.nodeName != "TABLE")
  300.         tParent = tParent.parentNode;
  301.    
  302.     // find the column position within the table
  303.     var cols = tParent.getElementsByTagName('TH');
  304.     for (i = 0; i < cols.length && null == this.DragIndex; i++)
  305.     {
  306.         if (cols[i] == headerObj)
  307.             this.DragIndex = i;
  308.     }
  309.    
  310.     var totalToRight = 0;
  311.     for (i = 0; i < cols.length; i++)
  312.     {
  313.         this.dodebug(cols[i].outerHTML);
  314.         var colInfo = new ColumnInfo(cols[i]);
  315.         if (i > this.DragIndex)
  316.             totalToRight += colInfo.GetCurrentWidth();
  317.         this.Columns.push(colInfo);
  318.     }
  319.    
  320.     // final pass through all the columns to the right in order to figure out their relative width
  321.     for (i = this.DragIndex + 1; i < this.Columns.length; i++)
  322.         this.Columns[i].RelativeSize = this.Columns[i].GetCurrentWidth() / totalToRight;
  323. }
  324.  
  325. DragInfo.prototype.init = function()
  326. {
  327.     this.FindCol(this.dragger.parentNode);
  328.    
  329.     this.draggerPos = FindObjectPosition(this.dragger.parentNode);
  330.     this.originalMouse = mouseCoords(event);
  331.     this.mouseOffset = getMouseOffset(this.dragger.parentNode, event);
  332.     this.originalMouse.x -= this.mouseOffset.x;
  333.     this.originalMouse.y -= this.mouseOffset.y;
  334.    
  335.     this.dodebug("X:" + this.originalMouse.x + ", Y:" + this.originalMouse.y);
  336. }
  337.  
  338. DragInfo.prototype.FixColSizes = function(lastIndex, desiredWidth, relativeTotal)
  339. {
  340.     if (lastIndex <= this.DragIndex)
  341.         return;
  342.     // Basically, the idea here is to share out the sizing to the right amongst the columns to the right.
  343.     // The columns will not allow themselves to be set smaller than the minimum or larger than the maximum
  344.     // So, we need to track if we have too much left over in the last column and fix up the rest if necessary
  345.     // Most of the time the recursion is not necessary, and so it should be smooth.
  346.    
  347.     // default relativeTotal to 1
  348.     if (relativeTotal == null)
  349.         relativeTotal = 1;
  350.    
  351.     // First pass, find out how much we need to share
  352.     var newRelTotal = 0, leftover = desiredWidth;
  353.     for (var i = this.DragIndex + 1; i < lastIndex; i++)
  354.     {
  355.         this.Columns[i].SetWidth(Math.round(this.Columns[i].RelativeSize * desiredWidth / relativeTotal));
  356.         newRelTotal += this.Columns[i].RelativeSize;
  357.         leftover -= this.Columns[i].GetCurrentWidth();
  358.     }
  359.     this.Columns[lastIndex].SetWidth(leftover);
  360.     if (this.Columns[lastIndex].GetCurrentWidth() != leftover)
  361.         this.FixColSizes(lastIndex - 1, desiredWidth - this.Columns[i].GetCurrentWidth(), newRelTotal);
  362. }
  363.  
  364. DragInfo.prototype.MoveTo = function(ev)
  365. {
  366.     //var mo = getMouseOffset(this.dragger, event);
  367.     var xMove = ev.clientX - this.mouseOffset.x;
  368.     this.dodebug(xMove);
  369.    
  370.     var movedBy = xMove - this.originalMouse.x;
  371.     this.originalMouse.x = xMove;
  372.     var newLeft = this.Columns[this.DragIndex].GetCurrentWidth() + movedBy;
  373.    
  374.     // Figure out total space left to the right
  375.     var oldRight = 0, maxRight = 0, minRight = 0;
  376.     for (var i = this.DragIndex + 1; i < this.Columns.length; i++)
  377.     {
  378.         oldRight += this.Columns[i].GetCurrentWidth();
  379.         maxRight += this.Columns[i].MaxSize;
  380.         minRight += this.Columns[i].MinSize;
  381.     }
  382.     var newRight = oldRight - movedBy;
  383.    
  384.     //              this.dodebug("oldRight:" + oldRight + ", newRight:" + newRight + ", newLeft:" + newLeft + ", newSum:" + newLeft + newRight + ", oldSum:" + this.Columns[this.DragIndex].GetCurrentWidth() + oldRight);
  385.     // Only change if we're within the allowable limits
  386.     if (newLeft >= this.Columns[this.DragIndex].MinSize &&
  387.     newLeft <= this.Columns[this.DragIndex].MaxSize &&
  388.     newRight <= maxRight &&
  389.     newRight >= minRight)
  390.     {
  391.         this.Columns[this.DragIndex].SetWidth(newLeft);
  392.         this.FixColSizes(this.Columns.length - 1, newRight);
  393.         this.dodebug("LASTLY - movedBy:" + movedBy + ", newLeft:" + newLeft + ", curWidth:" + this.Columns[this.DragIndex].GetCurrentWidth());
  394.     }
  395. }
  396.  
  397. DragInfo.prototype.dodebug = function(msg)
  398. {
  399.     if (this.debug)
  400.         this.debug.value = msg;
  401. }
  402.  
  403. // backward compatibility version - should eventally be replaced by iuseage of tables that use the above
  404. // (c) Carbonite, Inc., 2005-2009 All rights reserved
  405. DragInfoOld = function(obj)
  406. {
  407.     this.debug = document.getElementById('DebugDrags');
  408.     this.dragger = obj;
  409.     this.rightCols = new Array();
  410.     this.init();
  411. }
  412.  
  413. DragInfoOld.prototype.init = function()
  414. {
  415.     var cols = this.dragger.id.split("|");
  416.     this.leftCol = new ColumnInfoOld(cols[0]);
  417.    
  418.     var rCols = cols[1].split(";");
  419.     var totalRight = 0, i = 0;
  420.     for (i = 0; i < rCols.length; i++)
  421.     {
  422.         this.rightCols.push(new ColumnInfoOld(rCols[i]));
  423.         totalRight += this.rightCols[i].GetCurrentWidth();
  424.     }
  425.     for (i = 0; i < rCols.length; i++)
  426.         this.rightCols[i].RelativeSize = this.rightCols[i].GetCurrentWidth() / totalRight;
  427.    
  428.     this.draggerPos = FindObjectPosition(this.dragger);
  429.     this.headerOffset = parseInt(this.dragger.currentStyle.width);
  430.    
  431.     this.originalMouse = mouseCoords(event);
  432.     this.mouseOffset = getMouseOffset(this.dragger, event);
  433.     this.originalMouse.x -= this.mouseOffset.x;
  434.     this.originalMouse.y -= this.mouseOffset.y;
  435.    
  436.     this.dodebug("X:" + this.originalMouse.x + ", Y:" + this.originalMouse.y);
  437. }
  438.  
  439. DragInfoOld.prototype.FixColSizes = function(lastIndex, desiredWidth, relativeTotal)
  440. {
  441.     if (lastIndex < 0)
  442.         return;
  443.     // Basically, the idea here is to share out the sizing to the right amongst the columns to the right.
  444.     // The columns will not allow themselves to be set smaller than the minimum or larger than the maximum
  445.     // So, we need to track if we have too much left over in the last column and fix up the rest if necessary
  446.     // Most of the time the recursion is not necessary, and so it should be smooth.
  447.    
  448.     // default relativeTotal to 1
  449.     if (relativeTotal == null)
  450.         relativeTotal = 1;
  451.    
  452.     // First pass, find out how much we need to share
  453.     var newRelTotal = 0, leftover = desiredWidth;
  454.     for (i = 0; i < lastIndex; i++)
  455.     {
  456.         this.rightCols[i].SetWidth(Math.round(this.rightCols[i].RelativeSize * desiredWidth / relativeTotal), this.headerOffset);
  457.         newRelTotal += this.rightCols[i].RelativeSize;
  458.         leftover -= this.rightCols[i].GetCurrentWidth();
  459.     }
  460.     this.rightCols[lastIndex].SetWidth(leftover, this.headerOffset);
  461.     if (this.rightCols[lastIndex].GetCurrentWidth() != leftover)
  462.         this.FixColSizes(lastIndex - 1, desiredWidth - this.rightCols[i].GetCurrentWidth(), newRelTotal);
  463. }
  464.  
  465. DragInfoOld.prototype.MoveTo = function(ev)
  466. {
  467.     //var mo = getMouseOffset(this.dragger, event);
  468.     var xMove = ev.clientX - this.mouseOffset.x;
  469.    
  470.     var movedBy = xMove - this.originalMouse.x;
  471.     this.originalMouse.x = xMove;
  472.     var newLeft = this.leftCol.GetCurrentWidth() + movedBy;
  473.     // Figure out total space left to the right
  474.     var oldRight = 0, maxRight = 0, minRight = 0, i = 0;
  475.     for (i = 0; i < this.rightCols.length; i++)
  476.     {
  477.         oldRight += this.rightCols[i].GetCurrentWidth();
  478.         maxRight += this.rightCols[i].MaxSize;
  479.         minRight += this.rightCols[i].MinSize;
  480.     }
  481.     var newRight = oldRight - movedBy;
  482.    
  483.     // Only change if we're within the allowable limits
  484.     if (newLeft >= this.leftCol.MinSize && newLeft <= this.leftCol.MaxSize && newRight <= maxRight && newRight >= minRight)
  485.     {
  486.         this.leftCol.SetWidth(newLeft, this.headerOffset);
  487.         this.FixColSizes(this.rightCols.length - 1, newRight);
  488.        
  489.         this.dodebug("movedBy:" + movedBy + ", newRight:" + newRight + ", X:" + ev.clientX + ", xMove:" + xMove);
  490.     }
  491. }
  492.  
  493. DragInfoOld.prototype.dodebug = function(msg)
  494. {
  495.     if (this.debug)
  496.         this.debug.value = msg;
  497. }
  498.  
  499. /* End included file /scripts/draginfo.class.js */
  500. /* Carbonite Service included file /scripts/dragrow.class.js */
  501. // (c) Carbonite, Inc., 2005-2009 All rights reserved
  502. DragRow = function(row, dropAreaId)
  503. {
  504.     this.dropArea = document.getElementById(dropAreaId);
  505.     this.RowAccessor = row;
  506.    
  507.     this.debug = document.getElementById('DebugDrags');
  508.     this.dodebug('DragRow created for object' + this.RowAccessor.GetRow().id);
  509.    
  510.     this.isDroppable = false;
  511.     this.dropOKIndicator = null;
  512.    
  513.     this.dropArea.onmouseup = EndDrag;
  514.     this.lastX = 0;
  515.     this.lastY = 0;
  516.    
  517.     var self = this;
  518.     this.showDropIndicator = function()
  519.     {
  520.         self.showIndicatorTimeout = null;
  521.        
  522.         if (null == self.dropOKIndicator)
  523.         {
  524.             self.dropOKIndicator = document.createElement('div');
  525.             self.dropOKIndicator.innerHTML = self.RowAccessor.GetColumn("Name").innerHTML;
  526.             self.dropOKIndicator.className = "dropNO";
  527.             self.dropOKIndicator.style.position = "absolute";
  528.             document.body.appendChild(self.dropOKIndicator);
  529.             self.UpdateDropIndicator();
  530.         }
  531.     }
  532.    
  533.     this.showIndicatorTimeout = setTimeout(this.showDropIndicator, 100);
  534.     document.body.style.cursor = "hand";
  535. }
  536.  
  537. DragRow.prototype.UpdateDropIndicator = function()
  538. {
  539.     if (this.dropOKIndicator)
  540.     {
  541.         this.dropOKIndicator.style.left = this.lastX + "px";
  542.         this.dropOKIndicator.style.top = this.lastY + "px";
  543.     }
  544. }
  545.  
  546. DragRow.prototype.UpdateCursor = function(ev)
  547. {
  548.     this.testDroppable(ev);
  549.     // indicate that it is movable or show that it is droppable
  550.     if (this.dropOKIndicator)
  551.         this.dropOKIndicator.className = this.isDroppable ? "dropOK" : "dropNO";
  552.     this.UpdateDropIndicator();
  553. }
  554.  
  555. DragRow.prototype.Drop = function()
  556. {
  557.     if (this.showIndicatorTimeout)
  558.         clearTimeout(this.showIndicatorTimeout);
  559.    
  560.     if (this.isDroppable && !IsInCheckList(this.RowAccessor))
  561.         AddToCheckList(this.RowAccessor);
  562.     if (this.dropOKIndicator)
  563.         document.body.removeChild(this.dropOKIndicator);
  564.     this.dropOKIndicator = null;
  565.    
  566.     document.body.style.cursor = "default";
  567. }
  568.  
  569. DragRow.prototype.testDroppable = function(ev)
  570. {
  571.     // test the drop location and if it is somewhere in the target table
  572.     this.lastX = ev.clientX;
  573.     this.lastY = ev.clientY;
  574.    
  575.     if (IsInCheckList(this.RowAccessor))
  576.         this.isDroppable = false;
  577.     else
  578.     {
  579.         // if the location is over the table
  580.         var tpos = FindObjectPosition(this.dropArea);
  581.         this.isDroppable = (this.lastX > tpos[0]) &&
  582.         (this.lastX < (tpos[0] + this.dropArea.offsetWidth)) &&
  583.         (this.lastY > tpos[1]) &&
  584.         (this.lastY < (tpos[1] + this.dropArea.offsetHeight));
  585.     }
  586.    
  587.     this.dodebug(this.isDroppable);
  588. }
  589.  
  590. DragRow.prototype.dodebug = function(msg)
  591. {
  592.     //  if (this.debug)
  593.     //      this.debug.value += msg + " ";
  594.     if (this.debug)
  595.         this.debug.value = msg;
  596. }
  597.  
  598. /* End included file /scripts/dragrow.class.js */
  599.  
  600. /* Carbonite Service included file /scripts/commonfunctions.js */
  601. // (c) Carbonite, Inc., 2005-2009 All rights reserved
  602. // Used in InfoCenter-Alerts.js
  603. //
  604. /* Carbonite Service included file /scripts/string.class.js */
  605. // (c) Carbonite, Inc., 2005-2009 All rights reserved
  606. String.prototype.trim = function ()
  607. {
  608.     return this.replace(/^\s+|\s+$/g, '');
  609.  
  610. // here's a potential alternative
  611. //  var str = this.replace(/^\s*/, "");
  612. //  str = str.replace(/\s*$/, "");
  613.  
  614. //  return str;
  615. }
  616.  
  617. String.prototype.splitOnFirst = function(splitString)
  618. {
  619.     var splitAt = this.indexOf(splitString);
  620.     return [this.substring(0, splitAt), this.substring(splitAt + 1)];
  621. }
  622. /* End included file /scripts/string.class.js */
  623.  
  624. function queryString(name, defaultvalue)
  625. {
  626.     //return the value of the named parameter from the page Url
  627.     query = decodeURI(window.location.search);
  628.     if ((nQueryPos = query.indexOf('?')) != -1)
  629.     {
  630.         //break out the name/value pairs into an array
  631.         arNameValuePairs = query.substring(nQueryPos + 1).split('&');
  632.         //iterate over the array splitting the names and values, stopping when the name is matched (case-insensitively)
  633.         for (n = 0; n < arNameValuePairs.length; n++)
  634.         {
  635.             arNameValuePair = arNameValuePairs[n].split('=');
  636.             if (arNameValuePair[0].toLowerCase() == name.toLowerCase())
  637.                 return arNameValuePair[1];
  638.         }
  639.     }
  640.     return defaultvalue;
  641. }
  642.  
  643. // MessageBox.js
  644. // InfoCenter-Schedule.js
  645. var isIE_ = null;
  646. var isIE6_ = null;
  647. var isIE7_ = null;
  648. function setIEVersionInfo()
  649. {
  650.     var browser = navigator.appName;
  651.     var b_version = navigator.appVersion;
  652.     var version = parseFloat(b_version);
  653.     var MSIETag = b_version.indexOf("MSIE");
  654.     if (MSIETag > -1)
  655.     {
  656.         var EndTag = b_version.indexOf(";", MSIETag);
  657.         version = parseFloat(b_version.substring(MSIETag + 4, EndTag));
  658.     }
  659.    
  660.     isIE_ = browser == "Microsoft Internet Explorer";
  661.     isIE6_ = (isIE_ && version < 7);
  662.     isIE7_ = !isIE6_ && (isIE_ && version < 8);
  663. }
  664.  
  665. function IsIE6()
  666. {
  667.     if (null == isIE6_)
  668.         setIEVersionInfo();
  669.    
  670.     return isIE6_;
  671. }
  672.  
  673. function IsIE7()
  674. {
  675.     if (null == isIE7_)
  676.         setIEVersionInfo();
  677.    
  678.     return isIE7_;
  679. }
  680.  
  681. function IsIE()
  682. {
  683.     if (null == isIE_)
  684.         setIEVersionInfo();
  685.  
  686.     return isIE_;
  687. }
  688.  
  689. function CheckObject(obj, bCheckOn)
  690. {
  691.     if (IsIE6() || IsIE7())
  692.     {
  693.         var attr = document.createAttribute("checked");
  694.         attr.value = "checked";
  695.        
  696.         if (!bCheckOn)
  697.             obj.attributes.removeNamedItem("checked");
  698.         else
  699.             obj.setAttributeNode(attr);
  700.     }
  701.    
  702.     if (!IsIE6())
  703.         obj.checked = bCheckOn;
  704. }
  705.  
  706. // TreeControl.js
  707. // InfoCenter-Schedule.js
  708. function getPageSize()
  709. {
  710.  
  711.     var xScroll, yScroll;
  712.    
  713.     if (window.innerHeight && window.scrollMaxY)
  714.     {
  715.         xScroll = window.innerWidth + window.scrollMaxX;
  716.         yScroll = window.innerHeight + window.scrollMaxY;
  717.     }
  718.     else if (document.body.scrollHeight > document.body.offsetHeight)
  719.     { // all but Explorer Mac
  720.         xScroll = document.body.scrollWidth;
  721.         yScroll = document.body.scrollHeight;
  722.     }
  723.     else
  724.     { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
  725.         xScroll = document.body.offsetWidth;
  726.         yScroll = document.body.offsetHeight;
  727.     }
  728.    
  729.     var windowWidth, windowHeight;
  730.    
  731.     //  console.log(self.innerWidth);
  732.     //  console.log(document.documentElement.clientWidth);
  733.    
  734.     if (self.innerHeight)
  735.     { // all except Explorer
  736.         if (document.documentElement.clientWidth)
  737.         {
  738.             windowWidth = document.documentElement.clientWidth;
  739.         }
  740.         else
  741.         {
  742.             windowWidth = self.innerWidth;
  743.         }
  744.         windowHeight = self.innerHeight;
  745.     }
  746.     else if (document.documentElement && document.documentElement.clientHeight)
  747.     { // Explorer 6 Strict Mode
  748.         windowWidth = document.documentElement.clientWidth;
  749.         windowHeight = document.documentElement.clientHeight;
  750.     }
  751.     else if (document.body)
  752.     { // other Explorers
  753.         windowWidth = document.body.clientWidth;
  754.         windowHeight = document.body.clientHeight;
  755.     }
  756.    
  757.     // for small pages with total height less then height of the viewport
  758.     if (yScroll < windowHeight)
  759.     {
  760.         pageHeight = windowHeight;
  761.     }
  762.     else
  763.     {
  764.         pageHeight = yScroll;
  765.     }
  766.    
  767.     //  console.log("xScroll " + xScroll)
  768.     //  console.log("windowWidth " + windowWidth)
  769.    
  770.     // for small pages with total width less then width of the viewport
  771.     if (xScroll < windowWidth)
  772.     {
  773.         pageWidth = xScroll;
  774.     }
  775.     else
  776.     {
  777.         pageWidth = windowWidth;
  778.     }
  779.     //  console.log("pageWidth " + pageWidth)
  780.    
  781.     arrayPageSize = new Array(pageWidth, pageHeight, windowWidth, windowHeight)
  782.     return arrayPageSize;
  783. }
  784.  
  785. function getAll(obj, theArray)
  786. {
  787.     var children = obj.childNodes;
  788.     if (null == children)
  789.         return;
  790.    
  791.     for (var i = 0; i < children.length; i++)
  792.     {
  793.         if ("#text" != children[i].nodeName)
  794.         {
  795.             theArray.push(children[i]);
  796.             getAll(children[i], theArray);
  797.         }
  798.     }
  799. }
  800.  
  801. function AllChildren(obj)
  802. {
  803.     if (null == obj)
  804.         return null;
  805.    
  806.     if (obj.all)
  807.         return obj.all;
  808.    
  809.     var allArray = new Array();
  810.     getAll(obj, allArray);
  811.    
  812.     return allArray;
  813. }
  814.  
  815. function GetChildWithId(parent, findId)
  816. {
  817.     var children = AllChildren(parent);
  818.    
  819.     var foundChild = null;
  820.     for (var i = 0; i < children.length && !foundChild; i++)
  821.     {
  822.         if (children[i].id == findId)
  823.             foundChild = children[i];
  824.     }
  825.    
  826.     return foundChild;
  827. }
  828.  
  829. function FindObjectPosition(obj, stopObj)
  830. {
  831.     var leftP = 0;
  832.     var topP = 0;
  833.     do
  834.     {
  835.         leftP += obj.offsetLeft;
  836.         topP += obj.offsetTop;
  837.        
  838.         if (stopObj && stopObj == obj)
  839.             break;
  840.     }
  841.     while (obj = obj.offsetParent);
  842.    
  843.     return [leftP, topP];
  844. }
  845.  
  846. function getLeaf(str)
  847. {
  848.     /* Windows will not have forward slash in its path name.
  849.     So check for it first. */
  850.     if (str.indexOf("/") > -1) {
  851.         /* Not a Win32 path. We are in Mac. */
  852.         var arr = str.split("/");
  853.         if (arr.length >= 1) {
  854.             str = arr[arr.length - 1];
  855.         }
  856.     }
  857.     else {
  858.         var arr = str.split("\\");
  859.         if (arr.length >= 1) {
  860.             str = arr[arr.length - 1];
  861.         }
  862.     }
  863.     return str;
  864. }
  865.  
  866. /* C:\Margaret scan functions -- used on Backup tab and in the alert-backup-folders-discovered dialog.  
  867. Note that these are dependent on functions in ServiceInterconnect.js which is not explicitly included here. */
  868. function onchkAllowFolderScan()
  869. {
  870.     serviceCall("/backup-discoverer?cmd=" + (crbBackupDiscoverer.checked ? "enable" : "disable"));
  871. }
  872.  
  873. function onScanNow()
  874. {
  875.     serviceCall("/backup-discoverer?cmd=scan");
  876.  
  877. }
  878.  
  879. function ResizeWindow(windowAttributes, bUseCurrentPosition)
  880. {
  881.     if (typeof(external.Redecorate) != 'undefined')
  882.     {
  883.         var attributes = windowAttributes;
  884.         attributes += (bUseCurrentPosition) ? ";xpos=current;ypos=current;" : "";
  885.         external.Redecorate(attributes);
  886.     }
  887. }
  888.  
  889. // Show/hide the video.  You'll need to call this before displaying any HTML popups on top of the
  890. // video area because Flash always wants to be on top of all HTML.
  891. function showRelaxVideo(bShow)
  892. {
  893.     if (typeof ($f) != 'function') {
  894.         return;
  895.     }
  896.    
  897.     var pl = $f('crbPlayer1');
  898.    
  899.     if (!pl) {
  900.         return;
  901.     }
  902.  
  903.     if (bShow === false)
  904.     {
  905.         pl.style.display = "none";
  906.     }
  907.     else {
  908.         pl.style.display = "block";
  909.     }
  910. }
  911.  
  912. // When the close button on the popup header is clicked, this function gets called
  913. function doPopupCloseAction(elt)
  914. {
  915.     //Walk up the DOM to get the parent DIV with class "InfoCenterPopup"
  916.     function testFunction(el) { return usesClass(el, "InfoCenterPopup"); };
  917.     var parentElt = ancestorNode(elt, testFunction);
  918.     if (undefined == parentElt || null == parentElt) return;
  919.    
  920.     //Find the crbCloseAction element within that div (can't use the ID since there may be multiple popups defined on one page)
  921.     var arrChildren = parentElt.children;
  922.     var closeActionElement = elementByAttribute("class", "crbCloseAction", arrChildren);
  923.    
  924.     //Click the crbCloseAction element
  925.     if(undefined != closeActionElement)
  926.         closeActionElement.click();
  927. }
  928.  
  929. //Format Days Left message
  930. function formatTimeLeft(daysLeft)
  931. {
  932.     var strDay = "DAY";
  933.     var strDays = "DAYS";
  934.     var strYear = "YEAR";
  935.     var strYears = "YEARS";
  936.  
  937.     var formattedTime, elt;
  938.  
  939.     if (null != (elt = top.document.getElementById("crbStrDay")))
  940.     {
  941.         strDay = elt.innerText;
  942.     }
  943.     if (null != (elt = top.document.getElementById("crbStrDays")))
  944.     {
  945.         strDays = elt.innerText;
  946.     }
  947.     if (null != (elt = top.document.getElementById("crbStrYear")))
  948.     {
  949.         strYear = elt.innerText;
  950.     }
  951.     if (null != (elt = top.document.getElementById("crbStrYears")))
  952.     {
  953.         strYears = elt.innerText;
  954.     }
  955.  
  956.     if (Math.floor(daysLeft / 365) == 1)
  957.     {
  958.         formattedTime = 1 + " " + strYear + " " + (daysLeft % 365) + " " + strDays;
  959.     }
  960.     else if ((daysLeft / 365) >= 2)
  961.     {
  962.         formattedTime = Math.floor(daysLeft / 365) + " " + strYears + " " + (daysLeft % 365) + " " + strDays;
  963.     }
  964.     else
  965.     {
  966.         daysLeft = daysLeft % 365;
  967.  
  968.         // 1 day, 2 days, etc.
  969.         var dayLabel = daysLeft == 1 ? strDay : strDays;
  970.  
  971.         formattedTime = daysLeft + " " + dayLabel;
  972.     }
  973.  
  974.     return formattedTime;
  975. }
  976.  
  977. /* End included file /scripts/commonfunctions.js */
  978.  
  979. function mouseCoords(ev)
  980. {
  981.     if (ev.pageX || ev.pageY)
  982.     {
  983.         return {
  984.             x: ev.pageX,
  985.             y: ev.pageY
  986.         };
  987.     }
  988.     return {
  989.         x: ev.clientX + document.body.scrollLeft - document.body.clientLeft,
  990.         y: ev.clientY + document.body.scrollTop - document.body.clientTop
  991.     };
  992. }
  993.  
  994. function getMouseOffset(target, ev)
  995. {
  996.     ev = ev || window.event;
  997.    
  998.     var docPos = FindObjectPosition(target);
  999.     var mousePos = mouseCoords(ev);
  1000.     return {
  1001.         x: mousePos.x - docPos[0],
  1002.         y: mousePos.y - docPos[1]
  1003.     };
  1004. }
  1005.  
  1006. var dragCol = null;
  1007. var dragRow = null;
  1008.  
  1009. // old start drag to support file selector
  1010. function StartDrag(obj)
  1011. {
  1012.     dragRow = null;
  1013.     dragCol = new DragInfoOld(obj);
  1014. }
  1015.  
  1016. function StartColDrag()
  1017. {
  1018.     dragRow = null;
  1019.     dragCol = new DragInfo(this);
  1020. }
  1021.  
  1022. function StartRowDrag()
  1023. {
  1024.     HideLastTip();
  1025.     dragCol = null;
  1026.    
  1027.     dragRow = new DragRow(new RowDataAccess(this, DisplayTable), dragTo);
  1028.     dragRow.UpdateCursor(event);
  1029. }
  1030.  
  1031. function DoDrag()
  1032. {
  1033.     if (dragCol != null)
  1034.     {
  1035.         dragCol.MoveTo(event);
  1036.     }
  1037.    
  1038.     if (dragRow != null)
  1039.     {
  1040.         dragRow.UpdateCursor(event);
  1041.     }
  1042. }
  1043.  
  1044. function EndDrag()
  1045. {
  1046.     dragCol = null;
  1047.     if (dragRow)
  1048.         dragRow.Drop();
  1049.     dragRow = null;
  1050.    
  1051.     document.body.style.cursor = "default";
  1052. }
  1053.  
  1054. var leftCol = null;
  1055. var rightCols = null;
  1056.  
  1057. /* End included file /scripts/draganddrop.js */
  1058.  
  1059. function GetTipRow()
  1060. {
  1061.     var rowObj = event.srcElement;
  1062.     while (rowObj.nodeName.toLowerCase() != 'tr')
  1063.         rowObj = rowObj.parentNode;
  1064.    
  1065.     return rowObj;
  1066. }
  1067.  
  1068. function ShowMyTip()
  1069. {
  1070.     var tipString = GetTipRow().getAttribute("tipstring");
  1071.     ShowTipString(tipString);
  1072. }
  1073.  
  1074. function HideMyTip()
  1075. {
  1076.     var tipString = GetTipRow().getAttribute("tipstring");
  1077.     HideTipString(tipString);
  1078. }
  1079.  
  1080. Table = function(tableNode, onRowAdded, onRowRemoved)
  1081. {
  1082.     this.onRowAdded = (undefined == onRowAdded) ? null : onRowAdded;
  1083.     this.onRowRemoved = (undefined == onRowRemoved) ? null : onRowRemoved;
  1084.    
  1085.     this.table = tableNode;
  1086.     this.tableBody = this.table.getElementsByTagName('tbody')[0];
  1087.     this.columnMaps = new Object();
  1088. }
  1089.  
  1090. Table.prototype.copyProperty = function(srcObj, targetObj, propertyName)
  1091. {
  1092.     var val = srcObj[propertyName];
  1093.     if (null != val && "" != val)
  1094.         targetObj[propertyName] = val;
  1095. }
  1096.  
  1097. Table.prototype.copyAttributes = function(srcObj, targetObj)
  1098. {
  1099.     this.copyProperty(srcObj, targetObj, "className");
  1100.     this.copyProperty(srcObj.style, targetObj.style, "backgroundImage");
  1101.     this.copyProperty(srcObj, targetObj, "onmouseover");
  1102.     this.copyProperty(srcObj, targetObj, "onmouseout");
  1103.     this.copyProperty(srcObj, targetObj, "onmousedown");
  1104.     this.copyProperty(srcObj, targetObj, "onmouseup");
  1105.     this.copyProperty(srcObj, targetObj, "onclick");
  1106.     this.copyProperty(srcObj, targetObj, "id");
  1107.    
  1108.     for (var j = 0; j < srcObj.attributes.length; j++)
  1109.     {
  1110.         switch (srcObj.attributes[j].name)
  1111.         {
  1112.             case "filelastModified":
  1113.             case "tipstring":
  1114.             case "filePath":
  1115.             case "fileVersion":
  1116.             case "filesize":
  1117.             case "purgetime":
  1118.             case "filelastmodified":
  1119.             case "href":
  1120.                 switch (srcObj.attributes[j].value)
  1121.                 {
  1122.                     case "null":
  1123.                     case "":
  1124.                         break;
  1125.                     default:
  1126.                         targetObj.setAttribute(srcObj.attributes[j].name, srcObj.attributes[j].value);
  1127.                         break;
  1128.                 }
  1129.                 break;
  1130.             default:
  1131.                 break;
  1132.         }
  1133.     }
  1134.    
  1135. }
  1136.  
  1137. // This may be a useful general method, but it seems to be only necessary when there appears to be
  1138. // a problem specifically with IE7 adding rows that were part of one table as part of another table.
  1139. // So for now, it's here so that it only included when you need it; but should we find other cases
  1140. // where necessary then we should be able to move it to a general function collection
  1141. Table.prototype.createCopy = function(srcObj)
  1142. {
  1143.     var retObj = null;
  1144.    
  1145.     if ("#text" != srcObj.nodeName)
  1146.     {
  1147.         retObj = document.createElement(srcObj.nodeName);
  1148.         this.copyAttributes(srcObj, retObj);
  1149.        
  1150.         for (var i = 0; i < srcObj.childNodes.length; i++)
  1151.             retObj.appendChild(this.createCopy(srcObj.childNodes[i]));
  1152.     }
  1153.     else
  1154.     {
  1155.         retObj = document.createTextNode(srcObj.nodeValue);
  1156.     }
  1157.    
  1158.     return retObj;
  1159. }
  1160.  
  1161. Table.prototype.appendRow = function(rowObj)
  1162. {
  1163.     /* There is a problem in IE7 where making the append of the child directly does not work, even though it does in IE8
  1164.      Indeed, the same problem occurs if we clone the node. Therefore, we create a "hand-spun" copy of the row, and append that instead. */
  1165.     var rowAdded = rowObj;
  1166.     try
  1167.     {
  1168.         this.tableBody.appendChild(rowObj); // works in IE8 & Safari, just won't in IE7, also tried appending a clone, still won't work (very generic object does not support this method error)
  1169.     }
  1170.     catch (e)
  1171.     {
  1172.         // ignore error, create a "hand-spun" copy to avoid the error
  1173.         rowAdded = this.createCopy(rowObj);
  1174.         this.tableBody.appendChild(rowAdded);
  1175.        
  1176.         // remove the original row from its parent; so that the behaviour is the same
  1177.         rowObj.parentNode.removeChild(rowObj);
  1178.     }
  1179.    
  1180.     // returning the row that is added is important in case we were assuming we'd retain a reference to the actual row in question
  1181.     return rowAdded;
  1182. }
  1183.  
  1184. Table.prototype.AddRow = function(rowObj)
  1185. {
  1186.     var rowAdded = this.appendRow(rowObj);
  1187.    
  1188.     var tipString = rowObj.getAttribute("tipstring");
  1189.     rowObj.onmouseover = ShowMyTip;
  1190.     rowObj.onmouseout = HideMyTip;
  1191.    
  1192.     if (this.onRowAdded)
  1193.         this.onRowAdded(rowObj);
  1194.    
  1195.     return rowAdded;
  1196. }
  1197.  
  1198. Table.prototype.RemoveRow = function(rowObj)
  1199. {
  1200.     this.tableBody.removeChild(rowObj);
  1201.     if (this.onRowRemoved)
  1202.         this.onRowRemoved(rowObj);
  1203. }
  1204.  
  1205. Table.prototype.ClearData = function()
  1206. {
  1207.     var rows = this.tableBody.getElementsByTagName('tr');
  1208.     for (var i = rows.length - 1; i > 0; i--) // don't remove first row - that's the one with the headers
  1209.         this.RemoveRow(rows[i]);
  1210. }
  1211.  
  1212. Table.prototype.ColumnIndexOf = function(id)
  1213. {
  1214.     return this.columnMaps[id];
  1215. }
  1216.  
  1217. Table.prototype.MakeResizable = function()
  1218. {
  1219.     var headers = this.table.getElementsByTagName('TH');
  1220.     var lastResize = false;
  1221.     for (var i = 0; i < headers.length; i++)
  1222.     {
  1223.         if (headers[i].id)
  1224.             this.columnMaps[headers[i].id] = i;
  1225.        
  1226.         if (lastResize)
  1227.         {
  1228.             if (headers[i].className.indexOf('leftBump') < 0)
  1229.                 headers[i].className += ' leftBump';
  1230.         }
  1231.        
  1232.         lastResize = headers[i].className.indexOf('resize') > -1;
  1233.         if (lastResize)
  1234.         {
  1235.             var dragIndicator = document.createElement('span');
  1236.             dragIndicator.className = "draggerIndicator";
  1237.             var dragger = document.createElement('span');
  1238.             dragger.className = "dragger";
  1239.             dragger.onmousedown = StartColDrag;
  1240.             dragger.appendChild(dragIndicator);
  1241.             headers[i].appendChild(dragger);
  1242.         }
  1243.     }
  1244.    
  1245.     // Now add the functions to allow the dragging
  1246.     document.body.onmouseup = function()
  1247.     {
  1248.         EndDrag();
  1249.     }
  1250.     document.body.onmousemove = function()
  1251.     {
  1252.         DoDrag();
  1253.     }
  1254. }
  1255.  
  1256. /* End included file /scripts/table.class.js */
  1257.  
  1258. /* Carbonite Service included file /scripts/serviceinterconnect.js */
  1259. // (c) Carbonite, Inc., 2005-2009 All rights reserved
  1260. /* Carbonite Service included file /scripts/serviceinterconnect.class.js */
  1261. // (c) Carbonite, Inc., 2005-2009 All rights reserved
  1262. /* Carbonite Service SKIPPING already included file /scripts/string.class.js */
  1263.  
  1264. /* Carbonite Service included file /scripts/domhelper.js */
  1265. // (c) Carbonite, Inc., 2005-2009 All rights reserved
  1266.  
  1267. /* Carbonite Service SKIPPING already included file /scripts/commonfunctions.js */
  1268.  
  1269.  
  1270. //shows or removes the element from the flow
  1271. //note: block/inline is not required if you use
  1272. //SPAN for inline, DIV for block
  1273. function showElement(el, show)
  1274. {
  1275.      if (undefined == show)
  1276.           show = true;
  1277.      el.style.display = show ? '' : 'none';
  1278. }
  1279.  
  1280. //use this function when you want the element space
  1281. //to remain, whether it is visible or not
  1282. function visibleElement(el, visible)
  1283. {
  1284.      if (undefined == visible)
  1285.           visible = true;
  1286.      el.style.visibility = visible ? 'visible' : 'hidden';
  1287. }
  1288.  
  1289. function elementsByClass(className, elements)
  1290. {
  1291.     var results = new Array();
  1292.     if (undefined == elements) {
  1293.         elements = document.all;
  1294.     }
  1295.     for (var n = 0; n < elements.length; n++) {
  1296.  
  1297.         if (usesClass(elements[n], className)) {
  1298.             results.push(elements[n]);
  1299.         }
  1300.     }
  1301.  
  1302.     return results;
  1303. }
  1304.  
  1305. /*
  1306.  * return the element(s) having a given attribute/value combination
  1307.  * (either from the whole doc or a set of elements)
  1308.  */
  1309. function elementsByAttribute(attrName, attrValue, elements)
  1310. {
  1311.      var results = new Array();
  1312.      if (undefined == elements)
  1313.           elements = document.all;
  1314.      for (var n = 0; n < elements.length; n++)
  1315.      {
  1316.           var attr = null == elements[n].attributes ? null : elements[n].attributes[attrName];
  1317.           if (null != attr && attr.value == attrValue)
  1318.                 results.push(elements[n]);
  1319.      }
  1320.  
  1321.      return results;
  1322. }
  1323.  
  1324. function elementByAttribute(attrName, attrValue, elements)
  1325. {
  1326.      var results = elementsByAttribute(attrName, attrValue, elements);
  1327.      switch (results.length)
  1328.      {
  1329.           case 1:
  1330.                 return results[0];
  1331.           case 0:
  1332.                 return undefined;
  1333.           default:
  1334.                 return results;
  1335.      }
  1336. }
  1337.  
  1338. function nodeById(root, id)
  1339. {
  1340.      for (var n = 0; n < root.all.length; n++)
  1341.      {
  1342.           if (root.all[n].id == id)
  1343.           {
  1344.                 return root.all[n];
  1345.           }
  1346.      }
  1347.      return null;
  1348. }
  1349.  
  1350. function element(name)
  1351. {
  1352.      return document.getElementById(name);
  1353. }
  1354.  
  1355. function setAttribute(el, attr, value)
  1356. {
  1357.      try
  1358.      {
  1359.           el.setAttribute(attr, value);
  1360.      }
  1361.      catch (e)
  1362.      {
  1363.           logException("DomHelper setAttribute : ", e);
  1364.      }
  1365. }
  1366.  
  1367. function attribute(el, attr)
  1368. {
  1369.      try
  1370.      {
  1371.           var oAttr = el.attributes[attr];
  1372.           return oAttr ? oAttr.value : "";
  1373.      }
  1374.      catch (e)
  1375.      {
  1376.           logException("DomHelper attribute : ", e);
  1377.           return "";
  1378.      }
  1379. }
  1380.  
  1381. function frobClassName(el, remove, add)
  1382. {
  1383.      if (null == el)
  1384.           return;
  1385.      dropClass(el, remove);
  1386.      useClass(el, add);
  1387. }
  1388.  
  1389. /*
  1390.  * remove any of the space-separated classes from the given element's className
  1391.  */
  1392. function dropClass(el, classList)
  1393. {
  1394.      var dropClasses = classList.split(' ');
  1395.      var classes = el.className.split(' ');
  1396.      for (var nDrop = 0; nDrop < dropClasses.length; nDrop++)
  1397.      {
  1398.           for (var nClass = 0; nClass < classes.length; nClass++)
  1399.           {
  1400.                 if (dropClasses[nDrop].toLowerCase() == classes[nClass].toLowerCase())
  1401.                      classes[nClass] = '';
  1402.           }
  1403.      }
  1404.  
  1405.      classes.sort();
  1406.      el.className = classes.join(' ').replace(/  /g, '');
  1407. }
  1408.  
  1409. /*
  1410.  * add the class to the element's classname if not already in the list
  1411.  */
  1412. function useClass(el, className)
  1413. {
  1414.      if (usesClass(el, className))
  1415.           return;
  1416.      var classes = el.className.split(' ');
  1417.      classes.push(className);
  1418.      el.className = classes.join(' ');
  1419. }
  1420.  
  1421. function usesClass(el, className)
  1422. {
  1423.      var classes = el.className.split(' ');
  1424.      for (var n = 0; n < classes.length; n++)
  1425.      {
  1426.           if (className.toLowerCase() == classes[n].toLowerCase())
  1427.                 return true;
  1428.      }
  1429.      return false;
  1430. }
  1431.  
  1432. // Determines if an element uses any of the classes specified in classNames.
  1433. // classNames can be either a space-delimited list of class names, or an array
  1434. // of class names.
  1435. function usesAnyClass(el, classNames)
  1436. {
  1437.     var classNamesArray;
  1438.  
  1439.     if (typeof (classNames) == 'string') {
  1440.         classNamesArray = classNames.split(' ');
  1441.     }
  1442.     else if (classNames instanceof Array) {
  1443.         classNamesArray = classNames;
  1444.     }
  1445.     else {
  1446.         return false;
  1447.     }
  1448.  
  1449.     for (var i = 0; i < classNamesArray.length; i++) {
  1450.         if (usesClass(el, classNamesArray[i])) {
  1451.             return true;
  1452.         }
  1453.     }
  1454.  
  1455.     return false;
  1456. }
  1457.  
  1458. function ancestorNodeById(node, id)
  1459. {
  1460.      while (node)
  1461.      {
  1462.           if (node.id.indexOf(id) == 0)
  1463.                 return node;
  1464.           node = node.parentElement;
  1465.      }
  1466.      return null;
  1467. }
  1468.  
  1469. /* Find an ancestor node that meets the specified test criteria. testFunction must take an element as a parameter */
  1470.  
  1471. function ancestorNode(node, testFunction)
  1472. {
  1473.      while (node)
  1474.      {
  1475.           if (testFunction(node))
  1476.                 return node;
  1477.           node = node.parentElement;
  1478.      }
  1479.      return null;
  1480. }
  1481.  
  1482. // Array of functions that will get called when the DOM is ready.
  1483. var OnDOMReadyNotifications__ = new Array();
  1484.  
  1485. // Registers a function that'll get called when the DOM is ready.  This is currently
  1486. // only implemented for IE.
  1487. //
  1488. // Create a "defer" script element and wait for it to go to the "complete"
  1489. // readyState.  When that happens, call all of the functions that have been
  1490. // registered.
  1491. function onDomReady(func) {
  1492.  
  1493.      if (!IsIE()) {
  1494.           log("onDomReady only implemented for IE");
  1495.           return;
  1496.      }
  1497.  
  1498.      var id = "__crb_dom_ready";
  1499.  
  1500.      var script = document.getElementById(id);
  1501.  
  1502.      if (script == undefined) {
  1503.  
  1504.           document.write("<script id=" + id + " defer src=javascript:void(0)><\/script>");
  1505.  
  1506.           script = document.getElementById(id);
  1507.  
  1508.           script.onreadystatechange = function() {
  1509.                 if (this.readyState == "complete") {
  1510.                      for (var i = 0; i < OnDOMReadyNotifications__.length; i++) {
  1511.                           var f = OnDOMReadyNotifications__[i];
  1512.  
  1513.                           f();
  1514.                      }
  1515.                 }
  1516.           };
  1517.      }
  1518.  
  1519.      OnDOMReadyNotifications__.push(func);
  1520. }
  1521.  
  1522. // For cases where you want to debug what's going on with keyboard focus.  It overwrites all
  1523. // onfocus handlers for all elements in the document.  When an element receives focus,
  1524. // it calls logDetail with the values.
  1525. function hookFocusForDebug() {
  1526.  
  1527.     for (var i = 0; i < document.all.length; i++) {
  1528.         document.all[i].onfocus = function() {
  1529.             var s;
  1530.  
  1531.             if (this.id) {
  1532.                 s = this.id;
  1533.             }
  1534.             else if (this.className && this.className != "") {
  1535.                 s = this.className;
  1536.             }
  1537.             else if (this.href) {
  1538.                 s = this.href;
  1539.             }
  1540.             else if (this.innerHTML) {
  1541.                 s = this.innerHTML;
  1542.             }
  1543.             else if (this.tagName) {
  1544.                 s = this.tagName;
  1545.             }
  1546.             else if (this.document && this.frame && this.history && this.location) {
  1547.                 // this seems to happens sometimes.
  1548.                 s = 'window object (probably)';
  1549.             }
  1550.  
  1551.             logDetail("Focus is on " + s);
  1552.         }
  1553.     }
  1554. }
  1555.  
  1556. /* End included file /scripts/domhelper.js */
  1557. /* Carbonite Service included file /scripts/logging.js */
  1558. // (c) Carbonite, Inc., 2005-2009 All rights reserved
  1559. //Log priorities from LogMsg.h
  1560. var LM_TIMESTAMP = 0;
  1561. var LM_TRACE = 1;
  1562. var LM_DETAIL = 2;
  1563. var LM_STANDARD = 3;
  1564. var LM_STARTUP = 4; //ignored
  1565. var LM_SHUTDOWN = 5; //ignored
  1566. var LM_WARNING = 6;
  1567. var LM_ERROR = 7;
  1568. var LM_FATAL = 8; //ignored
  1569. function trace(text)
  1570. {
  1571.     try
  1572.     {
  1573.         external.Trace(text);
  1574.     }
  1575.     catch (nothing)
  1576.     {
  1577.     }
  1578. }
  1579.  
  1580. var reportErrors = true;
  1581. function log(text, priority)
  1582. {
  1583.     try
  1584.     {
  1585.         if (typeof(external.LogMsg) == "undefined")
  1586.         {
  1587.             if (reportErrors && LM_ERROR == priority)
  1588.                 reportErrors = confirm('LogError:' + text + "\nClick OK to see further errors");
  1589.         }
  1590.         else
  1591.             external.LogMsg(priority == undefined ? LM_STANDARD : parseInt(priority), text);
  1592.     }
  1593.     catch (nothing)
  1594.     {
  1595.     }
  1596. }
  1597.  
  1598. function logTime()
  1599. {
  1600.     log('', LM_TIMESTAMP);
  1601. }
  1602.  
  1603. function logError(text)
  1604. {
  1605.     log(text, LM_ERROR);
  1606. }
  1607.  
  1608. function logWarning(text)
  1609. {
  1610.     log(text, LM_WARNING);
  1611. }
  1612.  
  1613. function logDetail(text)
  1614. {
  1615.     log(text, LM_DETAIL);
  1616. }
  1617.  
  1618. function logTrace(text)
  1619. {
  1620.     log(text, LM_TRACE);
  1621. }
  1622.  
  1623. function logException(text, e)
  1624. {
  1625.     logError(text + ': ' + e.description + ':' + e.number);
  1626. }
  1627.  
  1628.  
  1629. /* End included file /scripts/logging.js */
  1630. /* Carbonite Service included file /js/config.js */
  1631. // (c) Carbonite, Inc., 2005-2011 All rights reserved
  1632.  
  1633. var Config__ = function ()
  1634. {
  1635.     var self = this;
  1636.  
  1637.     // Enable various debugging/diagnostics?
  1638.     //
  1639.     this.isDebug = function ()
  1640.     {
  1641.         return false;
  1642.     }
  1643.  
  1644.     // How many days left before we hide the number of days left?  If the
  1645.     // number of days left in the subscription is more than this value, the
  1646.     // UI elements will be hidden.
  1647.     //
  1648.     this.getHideDaysLeftMessageDays = function ()
  1649.     {
  1650.         // 20 years, which effectively means that it'll always display.
  1651.         //
  1652.         return 20 * 365;
  1653.     }
  1654.  
  1655.     // Number of days left in the subscription before we show the "Renew now"
  1656.     // button.
  1657.     //
  1658.     this.getRenewalDays = function ()
  1659.     {
  1660.         return 60;
  1661.     }
  1662.  
  1663.     // Return true to show the "Support" tab in Info Center.
  1664.     // @todo As it stands, this is not ever used (the code that refs it is
  1665.     // never called.
  1666.     //
  1667.     this.getExternalSupport = function ()
  1668.     {
  1669.         return false;
  1670.     }
  1671.  
  1672.     // Should we hide the purchase-related options (e.g. Buy now, Renew now, sub expires on date).
  1673.     //
  1674.     this.hidePurchaseOptions = function ()
  1675.     {
  1676.         var hidePurchaseOptions = false;
  1677.        
  1678.         purchaseOption = document.getElementById('crbBuyFeature');
  1679.         if (purchaseOption != undefined)
  1680.         {
  1681.             hidePurchaseOptions = (parseInt(purchaseOption.innerText) == 0);
  1682.         }
  1683.        
  1684.         return hidePurchaseOptions;
  1685.     }
  1686.  
  1687.     // Should we use our more advanced number formatting options?
  1688.     //
  1689.     this.useNumberFormatting = function ()
  1690.     {
  1691.         return true;
  1692.     }
  1693.  
  1694.     // What's the thousands separator (e.g. 10,000).
  1695.     //
  1696.     this.thousandsSeparator = function ()
  1697.     {
  1698.         return ",";
  1699.     }
  1700.  
  1701.     // What's the decimal seprator (e.g. 10.03).
  1702.     //
  1703.     this.decimalSeparator = function ()
  1704.     {
  1705.         return ".";
  1706.     }
  1707. }
  1708.  
  1709. var Config = new Config__();
  1710.  
  1711. // When running in debug mode, make sure that there are no duplicate ID values.
  1712. //
  1713. if (Config.isDebug())
  1714. {
  1715.     jQuery(document).ready(function ($) {
  1716.  
  1717.         var counts = {};
  1718.         var elements = document.all;
  1719.  
  1720.         for (var i = 0; i < elements.length; i++)
  1721.         {
  1722.             var element = elements[i];
  1723.            
  1724.             if (element.id != null && element.id.length > 0)
  1725.             {  
  1726.                 if (counts[element.id] == null)
  1727.                     counts[element.id] = 1;
  1728.                 else counts[element.id]++;
  1729.             }
  1730.         }
  1731.  
  1732.         for (var id in counts)
  1733.         {
  1734.             if (id.length > 0 && counts[id] > 1)
  1735.                 alert("duplicate id:  " + id);
  1736.         }
  1737.     });
  1738. }
  1739.  
  1740. /* End included file /js/config.js */
  1741.  
  1742. // Functions for dealing with the fact that there may exist multiple ServiceInterconnect objects
  1743. // on a single HTML page and for dealing with the fact that there may be multiple ServiceConfigItem
  1744. // elements that refer to the same variable.
  1745. //
  1746. var STOPALLINTERCONNECTS = false;
  1747.  
  1748. var __ServiceInterconnectElementCache = function ()
  1749. {
  1750.     var self = this;
  1751.  
  1752.     // For each fact that we receive might need to update multiple elements in
  1753.     // the DOM.  We don't want to go searching through the entire DOM for each
  1754.     // fact we receive...so we store a cache of the name -> elements.  We use
  1755.     // this targetElementsCache_ as a "map".  The key for the map is the name, the value
  1756.     // is and array of DOM elements that have that name.
  1757.     //
  1758.     var targetElementsCache_ = {};
  1759.  
  1760.     // Determines if el has a class of HiddenServiceConfigItem or VisibleServiceConfigItem.
  1761.     //
  1762.     function isServiceConfigItem(el)
  1763.     {
  1764.         var el$ = $(el);
  1765.         return el$.hasClass('HiddenServiceConfigItem') || el$.hasClass('VisibleServiceConfigItem');
  1766.     }
  1767.  
  1768.     // Searches through the DOM for elements where attr=value *and* that
  1769.     // have class="Hidden|VisibleServiceConfigItem".
  1770.     //
  1771.     function getServiceConfigElements(attr, value, targets)
  1772.     {
  1773.         var elements = elementsByAttribute(attr, value);
  1774.  
  1775.         for(var i = 0; i < elements.length; i++)
  1776.         {
  1777.             var el = elements[i];
  1778.  
  1779.             if(isServiceConfigItem(el))
  1780.                 targets.push(el);
  1781.         }
  1782.     }
  1783.  
  1784.     // Sets the value (val) on the target DOM element.  Special
  1785.     // handling for checkbox and input elements.
  1786.     //
  1787.     function setValueInDOM(target, val)
  1788.     {
  1789.         //don't fail since page may not use the returned value
  1790.         if(null == target)
  1791.         {
  1792.         }
  1793.         else if(target.type == "checkbox")
  1794.         {
  1795.             if(val == "0" || val == "1")
  1796.                 target.checked = val == "1";
  1797.         }
  1798.         else if(target.nodeName.toLowerCase() == "input")
  1799.             target.value = val;
  1800.         else
  1801.             target.innerHTML = val;
  1802.     }
  1803.  
  1804.     // Returns the array of DOM ServiceConfigItem elements that have the given id.
  1805.     //
  1806.     // Handles elements of the form:
  1807.     //
  1808.     //  <span data-crbid="crbID" class="VisibleServiceConfigItem"/>
  1809.     //  <span data-crbid="ID" class="VisibleServiceConfigItem"/>
  1810.     //  <span id="crbID" class="VisibleServiceConfigItem"/>
  1811.     //  <span id="ID" class="VisibleServiceConfigItem"/>
  1812.     //
  1813.     // (Note the class can be either VisibleServiceConfigItem or
  1814.     // HiddenServiceConfigItem).
  1815.     //
  1816.     // Uses targetElementsCache_ so it doesn't have to scan through the DOM every time
  1817.     // it's called.  If we've never been asked for 'id' before, then
  1818.     // search through the DOM to see if we can find any elements that
  1819.     // match (and store the result in the targetElementsCache_ for speedy access
  1820.     // next time).
  1821.     //
  1822.     this.getTargetElementsForID = function (id)
  1823.     {
  1824.         id = id.replace(/^crb/, "");
  1825.  
  1826.         var targets = targetElementsCache_[id];
  1827.  
  1828.         if (null == targets)
  1829.         {
  1830.             targets = new Array();
  1831.  
  1832.             getServiceConfigElements('data-crbid', 'crb' + id, targets);
  1833.             getServiceConfigElements('data-crbid', id, targets);
  1834.  
  1835.             var el = document.getElementById('crb' + id);
  1836.  
  1837.             if(null != el && isServiceConfigItem(el))
  1838.                 targets.push(el);
  1839.  
  1840.             el = document.getElementById(id);
  1841.  
  1842.             if(null != el && isServiceConfigItem(el))
  1843.                 targets.push(el);
  1844.  
  1845.             targetElementsCache_[id] = targets;
  1846.         }
  1847.  
  1848.         return targets;
  1849.     }
  1850.  
  1851.     // Stores value in all of the VisibleServiceConfigItem and
  1852.     // HiddenServiceConfigItem DOM elements that have a matching id.
  1853.     //
  1854.     this.putValue = function (id, value)
  1855.     {
  1856.         // It'd be a problem for us if the caller is trying to use us before the
  1857.         // DOM is ready since we rely on it for value storage.
  1858.         //
  1859.         if(!jQuery.isReady && Config.isDebug())
  1860.             alert('ServiceInterconnect being used before DOM isReady');
  1861.  
  1862.         var elements = self.getTargetElementsForID(id);
  1863.  
  1864.         for(var i = 0; i < elements.length; i++)
  1865.         {
  1866.             setValueInDOM(elements[i], value);
  1867.         }
  1868.     }
  1869. }
  1870.  
  1871. var ServiceInterconnectElementCache = new __ServiceInterconnectElementCache();
  1872.  
  1873. ServiceInterconnect = function (args)
  1874. {
  1875.     //Required args: name
  1876.     //Optional args: items (default: all), onPush
  1877.     //top.logTrace("ServiceInterconnect::ServiceInterconnect(" + args.interval + "," + args.uri + ")", false);
  1878.  
  1879.     if(args.name == undefined)
  1880.     {
  1881.         throw "Must specify name!";
  1882.     }
  1883.     if(args.onPush == undefined)
  1884.     {
  1885.         args.onPush = null;
  1886.     }
  1887.     if(args.items == undefined)
  1888.     {
  1889.         args.items = null;
  1890.     }
  1891.  
  1892.     var self = this;
  1893.     this.args = args;
  1894.  
  1895.     this.internalStart = function ()
  1896.     {
  1897.         try
  1898.         {
  1899.             window.external.MonitorServiceState(self.args.name, self.observer, self.args.items);
  1900.         }
  1901.         catch(e)
  1902.         {
  1903.             // don't error in browser; gets in the way of debugging
  1904.         }
  1905.     }
  1906.  
  1907.     this.internalStop = function ()
  1908.     {
  1909.         try
  1910.         {
  1911.             window.external.MonitorServiceState(self.args.name, null, "");
  1912.         }
  1913.         catch(e)
  1914.         {
  1915.             // don't error in browser; gets in the way of debugging
  1916.         }
  1917.     }
  1918.  
  1919.     this.doPush = function (node)
  1920.     {
  1921.         try
  1922.         {
  1923.             if(self.args.onPush)
  1924.             {
  1925.                 self.args.onPush(node);
  1926.             }
  1927.         }
  1928.         catch(e)
  1929.         {
  1930.             // Need to ignore problems when push handlers fail
  1931.             // Usually we have pulled the dom elements out of the document
  1932.             // but the handler still tries to access them
  1933.             if(Config.isDebug())
  1934.             {
  1935.                 alert("Push handler threw exception:  " + e.message);
  1936.             }
  1937.         }
  1938.     }
  1939.  
  1940.     this.observer = function (data)
  1941.     {
  1942.         if(STOPALLINTERCONNECTS)
  1943.             return;
  1944.  
  1945.         // Update all of the targets (elements) for each fact we've been
  1946.         // sent.  Note that there may be multiple elements for each fact.
  1947.         // (Multiple elements may have the same data-crbid attribute.)
  1948.         //
  1949.         var facts = data.split('|');
  1950.         for(n = 0; n < facts.length; n++)
  1951.         {
  1952.             var parts = facts[n].splitOnFirst('=');
  1953.             var name = parts[0];
  1954.             if(name.length < 1)
  1955.                 continue;
  1956.  
  1957.             var val = parts[1];
  1958.  
  1959.             // Update the cache with the new value.
  1960.             //
  1961.             ServiceInterconnectElementCache.putValue(name, val);
  1962.  
  1963.             //now the pushHandler -  if there is one
  1964.             if(self.args.onPush)
  1965.             {
  1966.                 var node = document.createElement("p");
  1967.                 node.id = name;
  1968.                 node.innerHTML = val;
  1969.                 self.doPush(node);
  1970.             }
  1971.         }
  1972.     }
  1973.  
  1974.     return this;
  1975. }
  1976.  
  1977. ServiceInterconnect.prototype.start = function (src)
  1978. {
  1979.     this.InitialPushHandler();
  1980.     setTimeout(this.internalStart, 0);
  1981. }
  1982.  
  1983. ServiceInterconnect.prototype.stop = function (src)
  1984. {
  1985.     setTimeout(this.internalStop, 0);
  1986. }
  1987.  
  1988. ServiceInterconnect.prototype.InitialPushHandler = function()
  1989. {
  1990.     if (this.args.onPush && this.args.items)
  1991.     {
  1992.         var itemList = this.args.items.split(",");
  1993.         for (var i = 0; i < itemList.length; i++)
  1994.         {
  1995.             var nodes = ServiceInterconnectElementCache.getTargetElementsForID (itemList[i]);
  1996.  
  1997.             for (var j = 0; j < nodes.length; j++)
  1998.             {
  1999.                 var node = nodes[j];
  2000.  
  2001.                 var tempNode = document.createElement('p');
  2002.                 tempNode.id = itemList[i];
  2003.  
  2004.                 if (node.type == "checkbox")
  2005.                     tempNode.innerHTML = ((node.value == "on") ? "1" : "0");
  2006.                 else if (node.nodeName.toLowerCase() == "input")
  2007.                     tempNode.innerHTML = node.value;
  2008.                 else
  2009.                     tempNode.innerHTML = node.innerHTML;
  2010.  
  2011.                 this.doPush(tempNode);
  2012.             }
  2013.         }
  2014.     }
  2015. }
  2016.  
  2017. /* End included file /scripts/serviceinterconnect.class.js */
  2018.  
  2019. /* Carbonite Service included file /scripts/traperror.js */
  2020. // (c) Carbonite, Inc., 2005-2009 All rights reserved
  2021. // This message will trap any script errors
  2022. function trapError(message, url, line)
  2023. {
  2024.     // ensure that we eat the error even if the log fails
  2025.     try
  2026.     {
  2027.         logError(url + "(" + line + ") : " + message);
  2028.     }
  2029.     catch (e)
  2030.     {
  2031.     }
  2032.     return true;
  2033. }
  2034.  
  2035. window.onerror = trapError;
  2036.  
  2037.  
  2038. /* End included file /scripts/traperror.js */
  2039. /* Carbonite Service SKIPPING already included file /scripts/logging.js */
  2040.  
  2041.  
  2042. // backup states - from the CarboniteServiceTypes header
  2043. var Backup_State_Undefined = 0;
  2044.  
  2045. var Backup_State_Registration = 10;
  2046. var Backup_State_Stopped = 20;
  2047. var Backup_State_Startup = 25;
  2048. var Backup_State_Sleeping = 30;
  2049. var Backup_State_Starting = 40;
  2050. var Backup_State_Awaiting_Connection = 50;
  2051. var Backup_State_Awaiting_Server = 60;
  2052. var Backup_State_Scanning = 70;
  2053. var Backup_State_Transfering = 80;
  2054. var Backup_State_Finishing = 90;
  2055.  
  2056. // service states - from the CarboniteServiceTypes header
  2057. var Service_State_Undefined = 0;
  2058.  
  2059. //the following states indicate normal actiity
  2060. var Service_State_Normal_First = 1;
  2061. var Service_State_Registration = 2;
  2062. var Service_State_Initial_Backup = 3;
  2063. var Service_State_Restoring = 4;
  2064. var Service_State_Backup_Pending = 5;
  2065. var Service_State_Backing_Up = 6;
  2066. var Service_State_Scanning = 7;
  2067. var Service_State_Idle = 8;
  2068. var Service_State_Normal_Last = 9;
  2069.  
  2070. //the following states all require attention of the user
  2071. var Service_State_Alert_First = 10;
  2072. var Service_State_Alert_No_Service = 11;
  2073. var Service_State_Alert_Disabled = 12;
  2074. var Service_State_Alert_Paused = 13;
  2075. var Service_State_Alert_Retry = 14;
  2076. var Service_State_Alert_Bad_Config = 15;
  2077. var Service_State_Alert_Account_Disabled = 16;
  2078. var Service_State_Alert_Over_Quota = 17;
  2079. var Service_State_Alert_No_Internet = 18;
  2080. var Service_State_Alert_No_Server = 19;
  2081. var Service_State_Alert_Backup_Failed = 20;
  2082. var Service_State_Alert_Subscription_Expired = 21;
  2083. var Service_State_Alert_Backup_Overdue = 22;
  2084. var Service_State_Alert_Operations_Msg = 23;
  2085. var Service_State_Alert_Upgrade_Available = 24;
  2086. var Service_State_Alert_Recover_Mode = 25;
  2087. var Service_State_Alert_MissingVolumes = 26;
  2088. var Service_State_Alert_MissingFiles = 27;
  2089. var Service_State_Alert_Restore_Paused = 28;
  2090. var Service_State_Alert_Account_Over_Quota = 29;
  2091. var Service_State_Alert_MissingNetworkDrive = 30;
  2092. var Service_State_Alert_Last = 31;
  2093.  
  2094. var Service_State_Last = 32;
  2095.  
  2096. var ifrPoster = null;
  2097. function ServicePut(name, value)
  2098. {
  2099.     //not yet - need to refactor first to make the trace function available
  2100.     //logDetail('request to put ' + name + '=' + value);
  2101.    
  2102.     //create posting frame?
  2103.     if (!ifrPoster)
  2104.     {
  2105.         ifrPoster = document.createElement("iframe");
  2106.         ifrPoster.style.visibility = "hidden";
  2107.         ifrPoster.style.border = "0px";
  2108.         ifrPoster.style.height = "0px";
  2109.         ifrPoster.style.width = "0px";
  2110.         body = document.getElementsByTagName("body")[0];
  2111.         body.appendChild(ifrPoster);
  2112.     }
  2113.     ifrPoster.src = "/put-state.htm?" + name + "=" + value;
  2114. }
  2115.  
  2116. function serviceCall(requestURI, resultsHandler)
  2117. {
  2118.     resultsHandler = undefined == resultsHandler ? null : resultsHandler;
  2119.     var dc = new DeferredCall(requestURI, resultsHandler);
  2120. }
  2121.  
  2122. function DeferredCall(uri, resultsHandler)
  2123. {
  2124.     var self = this;
  2125.     self.resultsHandler = resultsHandler;
  2126.    
  2127.     //create a frame to contain the call
  2128.     self.ifrCall = document.createElement("iframe");
  2129.    
  2130.     self.ifrCall.style.visibility = "hidden";
  2131.     self.ifrCall.style.border = "0px";
  2132.     self.ifrCall.style.height = "0px";
  2133.     self.ifrCall.style.width = "0px";
  2134.    
  2135.     self.body = document.getElementsByTagName("body")[0];
  2136.     self.body.appendChild(self.ifrCall);
  2137.    
  2138.     self.onreadystatechange = function()
  2139.     {
  2140.         window.status = self.ifrCall.src + ':' + self.ifrCall.readyState;
  2141.         //wait for interactive on async calls, complete on sync - we need the reply on the latter
  2142.         if ((null != self.resultsHandler && self.ifrCall.readyState == "complete") || (null == self.resultsHandler && self.ifrCall.readyState == "interactive"))
  2143.         {
  2144.             self.ifrCall.onreadystatechange = null;
  2145.             //call the results handler, if there is one
  2146.             if (null != self.resultsHandler)
  2147.             {
  2148.                 self.resultsHandler(self.ifrCall.contentWindow.document.body);
  2149.             }
  2150.             self.body.removeChild(self.ifrCall);
  2151.         }
  2152.     }
  2153.    
  2154.     self.ifrCall.onreadystatechange = self.onreadystatechange;
  2155.     self.ifrCall.src = uri;
  2156. }
  2157.  
  2158.  
  2159. /* End included file /scripts/serviceinterconnect.js */
  2160. /* Carbonite Service included file /js/navigation.js */
  2161. // (c) Carbonite, Inc., 2005-2009 All rights reserved
  2162. /* Carbonite Service SKIPPING already included file /scripts/serviceinterconnect.js */
  2163.  
  2164. /* Carbonite Service SKIPPING already included file /scripts/commonfunctions.js */
  2165.  
  2166. /* Carbonite Service SKIPPING already included file /js/config.js */
  2167.  
  2168.  
  2169. var Navigation__ = function ()
  2170. {
  2171.     var self = this;
  2172.     /* InfoCenter-Nav.js
  2173.     (1) Controls the buttons in the InfoCenter sidebar
  2174.     (2) Controls the display of content in the InfoCenter content IFRAME
  2175.     (3) Opens external links
  2176.     */
  2177.     /* Default parameters for IE windows opened by the InfoCenter */
  2178.     var strDefaultOpenURLParams = "height=600,width=1000,left=0,top=0,scrollbars=yes,location=yes,status=yes";
  2179.  
  2180.     // AccountIsTrial and nExpiryDays are also used from alert.js
  2181.     this.AccountIsTrial = false;
  2182.     this.nExpiryDays = 0;
  2183.  
  2184.     var arrEltsByTabIndex = new Array();
  2185.  
  2186.     function getQueryString()
  2187.     {
  2188.         //return the entire query string
  2189.         var query = decodeURI(window.location.search);
  2190.  
  2191.         if((nQueryPos = query.indexOf('?')) != -1)
  2192.         {
  2193.             return query.substring(nQueryPos + 1);
  2194.         }
  2195.         return undefined;
  2196.     }
  2197.  
  2198.     function autoDecorateURL(strURL)
  2199.     {
  2200.         // protect around COM call to autodecorate the url. We'll fail silently, so that at least the undecorated url gets processed
  2201.         var strDecoratedURL;
  2202.         try
  2203.         {
  2204.             strDecoratedURL = external.DecorateURL(strURL);
  2205.         }
  2206.         catch(err)
  2207.         {
  2208.             try
  2209.             {
  2210.                 external.LogMsg(7/*LM_ERROR*/, "Exception while decorating url; will decorate with any queryString paramters that already exist - description:" + err.description);
  2211.             }
  2212.             catch(err2)
  2213.             {
  2214.             }
  2215.             // we know that the external.DecorateURL could not get called - a real scenario for this is
  2216.             // when we've opened up a local page in a separate browser window (non InfoCenter window).
  2217.             // In that case, there is the real possibility that there are links that use the autodecorate
  2218.             // parameters therein, and so we should redecorate those here
  2219.             strDecoratedURL = appendQueryString(strURL, getQueryString());
  2220.         }
  2221.         return strDecoratedURL;
  2222.     }
  2223.  
  2224.     function autoDecorateParams(params)
  2225.     {
  2226.         var fakeUrl = "?" + params; // in order to avoid automatically adding the ?
  2227.         var decorated = autoDecorateURL(fakeUrl);
  2228.  
  2229.         return decorated.substring(1);
  2230.     }
  2231.  
  2232.     function navigateToURL(url)
  2233.     {
  2234.         // check for typeof(external.NavigateToUrl) does not work on all broswers - throws exception, so the only real way to handle it is to try and catch when a problem
  2235.         try
  2236.         {
  2237.             external.NavigateToUrl(url);
  2238.         }
  2239.         catch(e)
  2240.         {
  2241.             window.open(url, '_blank', strDefaultOpenURLParams);
  2242.         }
  2243.     }
  2244.  
  2245.     /* Lil' helper function to make sure we have the right number of ?s and &s in our query strings*/
  2246.     function appendQueryString(strURL, strQueryString)
  2247.     {
  2248.         var url = strURL;
  2249.         if(undefined != url)
  2250.         {
  2251.             //Check to see whether the URL already has parameters appended to it. If so, use an ampersand instead of a question mark to append additional parameters
  2252.             if(undefined != strQueryString)
  2253.                 url += (strURL.indexOf("?") == -1) ? "?" + strQueryString : "&" + strQueryString;
  2254.  
  2255.         }
  2256.         return url;
  2257.     }
  2258.  
  2259.     function parseURL(strURL, blnSSL)
  2260.     {
  2261.         if(strURL == "")
  2262.         {
  2263.             return undefined;
  2264.         }
  2265.  
  2266.         // If the URL starts with HTTP or is a FILE specification, use it as is
  2267.         if(strURL.substring(0, 4).toLowerCase() == "http" || strURL.substring(0, 5).toLowerCase() == "file:")
  2268.         {
  2269.             return strURL;
  2270.         }
  2271.  
  2272.         else // Prepend the protocol string and download server
  2273.         {
  2274.             var strProtocol = (blnSSL == 1) ? "https://" : "http://";
  2275.             if(strURL.substring(0, 1) != "/")
  2276.             {
  2277.                 strURL = "/" + strURL;
  2278.             }
  2279.  
  2280.             var strServer = getServer();
  2281.             if(strServer != undefined)
  2282.                 return strProtocol + strServer + strURL;
  2283.         }
  2284.  
  2285.         return undefined;
  2286.     }
  2287.  
  2288.     function isStringUndefinedOrEmpty(str)
  2289.     {
  2290.         return str == undefined || str.length == 0;
  2291.     }
  2292.  
  2293.     // Returns the "download server" to use.  The value is taken from the crbDownloadServer
  2294.     // element, if it exists.  If it doesn't exist or has an empty value, we make a check
  2295.     // for crbDefaultDownloadServer.  We don't use crbDefaultDownloadServer in the standard
  2296.     // skin, but it could be specified by a partner.  If none of this yields a server, we'll
  2297.     // fallback to using www.carbonite.com.  That's about the best we can do here.
  2298.     // This fixes WC-2593 (along with all other issues where a download server is needed
  2299.     // before we get one from the service interconnect).
  2300.     function getServer()
  2301.     {
  2302.         var strServer = getServiceVariable("crbDownloadServer");
  2303.  
  2304.         if(isStringUndefinedOrEmpty(strServer))
  2305.         {
  2306.             strServer = getServiceVariable("crbDefaultDownloadServer");
  2307.  
  2308.             if(isStringUndefinedOrEmpty(strServer))
  2309.             {
  2310.                 strServer = "www.carbonite.com";
  2311.             }
  2312.         }
  2313.         return strServer.toLowerCase();
  2314.     }
  2315.  
  2316.     function getServiceVariable(strVarName)
  2317.     {
  2318.         if(null != (elt = top.document.getElementById(strVarName)))
  2319.             return elt.innerHTML;
  2320.  
  2321.         return undefined;
  2322.     }
  2323.  
  2324.     function updateBuyStatus()
  2325.     {
  2326.         var showBuy = false;
  2327.         var showRenew = false;
  2328.         var showDaysLeft = false;
  2329.  
  2330.         if(Config.hidePurchaseOptions() || isNaN(self.AccountIsTrial) || isNaN(self.nExpiryDays))
  2331.         {
  2332.             // Don't display anything.
  2333.             //
  2334.         }
  2335.         else
  2336.         {
  2337.             var bAccountIsTrial = self.AccountIsTrial;
  2338.  
  2339.             if(bAccountIsTrial)
  2340.             {
  2341.                 // For trials, always show the buy button.
  2342.                 //
  2343.                 showBuy = true;
  2344.             }
  2345.             else
  2346.             {
  2347.                 // This is a paid account, hide the Buy button and decide whether to show the Renew button.
  2348.                 //
  2349.                 if(self.nExpiryDays <= Config.getRenewalDays())
  2350.                 {
  2351.                     showRenew = true;
  2352.                 }
  2353.             }
  2354.  
  2355.             // Decide whether to display Days Left message based on number of days left in subscription
  2356.             if(self.nExpiryDays < Config.getHideDaysLeftMessageDays())
  2357.             {
  2358.                 showDaysLeft = true;
  2359.             }
  2360.  
  2361.  
  2362.             if(showDaysLeft)
  2363.             {
  2364.                 var elt;
  2365.  
  2366.                 // Different expiration text for trial vs. paid account.
  2367.                 //
  2368.                 if(null != (elt = document.getElementById('crbTrialTimeLeftMessage')))
  2369.                 {
  2370.                     if(self.nExpiryDays <= 0)
  2371.                     {
  2372.                         elt.style.display = 'none';
  2373.                     }
  2374.                     else
  2375.                     {
  2376.                         elt.style.display = bAccountIsTrial ? 'inline' : 'none';
  2377.                     }
  2378.  
  2379.                 }
  2380.  
  2381.                 if(null != (elt = document.getElementById('crbSubTimeLeftMessage')))
  2382.                 {
  2383.                     if(self.nExpiryDays <= 0)
  2384.                     {
  2385.                         elt.style.display = 'none';
  2386.                     }
  2387.                     else
  2388.                     {
  2389.                         elt.style.display = bAccountIsTrial ? 'none' : 'inline';
  2390.                     }
  2391.  
  2392.                 }
  2393.             }
  2394.         }
  2395.  
  2396.         var elt;
  2397.  
  2398.         if(null != (elt = document.getElementById('crbBuyNow')))
  2399.             elt.style.display = showBuy ? 'block' : 'none';
  2400.  
  2401.         if(null != (elt = document.getElementById('crbRenewNow')))
  2402.             elt.style.display = showRenew ? 'block' : 'none';
  2403.  
  2404.         if(null != (elt = document.getElementById('crbDaysLeftMessage')))
  2405.             elt.style.display = showDaysLeft ? 'block' : 'none';
  2406.     }
  2407.  
  2408.     // publically exposed functions
  2409.  
  2410.  
  2411.     // @todo Is initialise ever used?
  2412.     //
  2413.     this.initialise = function ()
  2414.     {
  2415.         try
  2416.         {
  2417.             var getSupport = document.getElementById("support");
  2418.             var getHelp = document.getElementById("GetHelp");
  2419.  
  2420.             if(Config.getExternalSupport())
  2421.             {
  2422.                 getSupport.style.display = "none";
  2423.                 getHelp.style.display = "inline";
  2424.             }
  2425.             else
  2426.             {
  2427.                 getSupport.style.display = "inline";
  2428.                 getHelp.style.display = "none";
  2429.             }
  2430.         }
  2431.         catch(e)
  2432.         {
  2433.         }
  2434.     }
  2435.  
  2436.     this.openURL = function (strURL, strQueryString, blnSSL)
  2437.     {
  2438.         var baseURL = parseURL(strURL, blnSSL);
  2439.  
  2440.         if(undefined != baseURL)
  2441.         {
  2442.             var url = baseURL;
  2443.             url = appendQueryString(url, strQueryString);
  2444.             url = autoDecorateURL(url);
  2445.  
  2446.             navigateToURL(url);
  2447.         }
  2448.     }
  2449.  
  2450.     /* Open one of the external links that is managed via the ClientUIRedirect table */
  2451.     this.openExternalURL = function (keyword, params, blnSSL)
  2452.     {
  2453.         var urlRedirect = self.getExternalURL(keyword, params);
  2454.         if(undefined != urlRedirect)
  2455.         {
  2456.             self.openURL(urlRedirect, null, blnSSL);
  2457.         }
  2458.         else
  2459.         {
  2460.             logError("openExternalURL(): Couldn't open URL for " + keyword);
  2461.         }
  2462.     }
  2463.  
  2464.     /* Get a fully-specified URL for one of the links that is managed via the ClientUIRedirect table
  2465.     * "keyword" is the value that will be looked up in the ClientUIRedirect table
  2466.     * "params" is a query string to be passed to the destination URL, e.g. name1=value1&name2=value2.  Don't worry about URI-encoding since this function will handle it
  2467.     * "autodecorate" specifies whether we should add the standard parameters (skinid and computeruid). If you are passing the result of this function to openURL, set it to false
  2468.     */
  2469.     this.getExternalURL = function (keyword, params, autodecorate)
  2470.     {
  2471.         if(undefined == params)
  2472.             params = "";
  2473.  
  2474.         /* The redirect URL takes three parameters: a content keyword (where), a URI-encoded query string (querystring)
  2475.         and the computer UID (computeruid) which gets automatically appended by autoDecorateURL */
  2476.         var strRedirectURL = getServiceVariable("crbRedirectURL");
  2477.         if((undefined != strRedirectURL) && (undefined != keyword) && ("" != keyword))
  2478.         {
  2479.             /* Expand to a fully-specified URL from a relative one */
  2480.             var url = parseURL(strRedirectURL);
  2481.  
  2482.             /* Add the standard parameters, skinid and computeruid if the autodecorate parameter is set */
  2483.             if(autodecorate)
  2484.                 url = autoDecorateURL(url);
  2485.  
  2486.             /* Add any additional specified parameters (params) */
  2487.             var strQueryString = "&querystring=" + encodeURIComponent(autoDecorateParams(params));
  2488.             url = appendQueryString(url, "where=" + keyword + strQueryString);
  2489.  
  2490.             return url;
  2491.         }
  2492.         else
  2493.         {
  2494.             if(undefined == strRedirectURL)
  2495.                 logError("getExternalURL(): Couldn't get URL for " + keyword + " because crbRedirectURL is undefined. Check the HTML to ensure that it includes a span with id 'crbRedirectURL'");
  2496.             else
  2497.                 logError("getExternalURL(): Called without specifying a keyword");
  2498.  
  2499.             return undefined;
  2500.         }
  2501.     }
  2502.  
  2503.     /* Go to online account management pages */
  2504.     this.openManage = function ()
  2505.     {
  2506.         var strEmail = getServiceVariable("crbUserEmail");
  2507.         var strQueryString = "";
  2508.         if(strEmail != undefined)
  2509.         {
  2510.             strQueryString = "email=" + strEmail; // params get autodecorated within openExternalUrl
  2511.         }
  2512.         self.openExternalURL('accountmanagement', strQueryString, 1);
  2513.     }
  2514.  
  2515.     /* Change email or password */
  2516.     this.changeAccountInfo = function (param)
  2517.     {
  2518.         var strEmail = getServiceVariable("crbUserEmail");
  2519.  
  2520.         var strQueryString = "edit=" + param;
  2521.         if(strEmail != undefined)
  2522.         {
  2523.             strQueryString += "email=" + strEmail;
  2524.         }
  2525.         self.openExternalURL('changeaccountinfo', strQueryString, 1);
  2526.  
  2527.         //After 2 minutes, log in to update the account info
  2528.         setTimeout("loginNow()", 2 * 60 * 1000);
  2529.  
  2530.     }
  2531.  
  2532.     /* Go to online order pages */
  2533.     this.openOrder = function (sFrom)
  2534.     {
  2535.         /* Set query string parameters */
  2536.         var strQueryString = "from=" + sFrom;
  2537.  
  2538.         if(self.AccountIsTrial != undefined)
  2539.         {
  2540.             strQueryString += "&isTrial=" + self.AccountIsTrial;
  2541.         }
  2542.  
  2543.         self.openExternalURL('purchase', strQueryString, 1);
  2544.     }
  2545.  
  2546.     /* Go to Refer-a-friend signup page */
  2547.     this.openRAF = function ()
  2548.     {
  2549.         var strEmail = getServiceVariable("crbUserEmail");
  2550.         // define a query string even if strEmail is blank, because we want to pass something through
  2551.         // params in order to get decorated values (computerid, skinid, etc.)
  2552.         var strQueryString = "email=" + strEmail;
  2553.         self.openExternalURL('referafriend', strQueryString, 0);
  2554.     }
  2555.  
  2556.     /* Open Live Chat session -- strSource tells us where the chat session was initiated */
  2557.     this.openChat = function (strSource)
  2558.     {
  2559.         var strQueryString = "source=" + strSource;
  2560.         self.openExternalURL('livechat', strQueryString, 0);
  2561.     }
  2562.  
  2563.     this.CommonPushHandler = function (node)
  2564.     {
  2565.         try
  2566.         {
  2567.             if(node.id == "SubscriptionInfo")
  2568.             {
  2569.                 var subInfo = ObjectJSON(node.innerText);
  2570.                 self.nExpiryDays = subInfo.ExpiryDays;
  2571.                 self.AccountIsTrial = subInfo.AccountIsTrial;
  2572.                 updateBuyStatus();
  2573.             }
  2574.         }
  2575.         catch(e)
  2576.         {
  2577.             if(Config.isDebug())
  2578.             {
  2579.                 alert(e.message);
  2580.             }
  2581.         }
  2582.     }
  2583.  
  2584. }
  2585.  
  2586. var Navigation = new Navigation__();
  2587.  
  2588. // global functions used within html pages
  2589. /* Fire an element's click event using the Enter key or Spacebar */
  2590. function fireClick(elt)
  2591. {
  2592.     var key;
  2593.     if (window.event)
  2594.     {
  2595.         key = window.event.keyCode;
  2596.     } //IE only
  2597.     // Fire a click when either the enter key or the spacebar key is pressed
  2598.     if ((key == ENTER) || (key == SPACEBAR))
  2599.     {
  2600.         if (elt != null)
  2601.         { //If we find the button click it
  2602.             elt.click();
  2603.             event.keyCode = 0;
  2604.         }
  2605.     }
  2606. }
  2607.  
  2608. /* Fire a tab event when Down or Right arrow is pressed, and a SHIFT-tab event when Up or Left arrow is pressed */
  2609. function fireTab()
  2610. {
  2611.     var key;
  2612.     var elt = window.event.srcElement;
  2613.     if (window.event)
  2614.     {
  2615.         key = window.event.keyCode;
  2616.     } //IE only
  2617.     // Fire a tab when Down or Right arrow is pressed
  2618.     if ((key == DOWN_ARROW) || (key == RIGHT_ARROW))
  2619.     {
  2620.         if (elt.tabIndex < arrEltsByTabIndex.length + 1)
  2621.             event.keyCode = TAB;
  2622.         else
  2623.             event.keyCode = 0;
  2624.     }
  2625.     else if ((key == UP_ARROW) || (key == LEFT_ARROW))
  2626.     {
  2627.         var prevIndex = elt.tabIndex - 1;
  2628.         if (prevIndex > 0)
  2629.             arrEltsByTabIndex[prevIndex].focus();
  2630.  
  2631.         event.keyCode = 0;
  2632.         event.cancelBubble = true;
  2633.     }
  2634.  
  2635. }
  2636.  
  2637. // Global called by C++ code
  2638. function onEmailSent(vResult)
  2639. {
  2640.     document.getElementById('crbEmailResult').value = vResult;
  2641. }
  2642.  
  2643. /* End included file /js/navigation.js */
  2644. /* Carbonite Service included file /js/schedule.js */
  2645. // (c) Carbonite, Inc., 2005-2009 All rights reserved
  2646. /* Carbonite Service included file /scripts/schedule.class.js */
  2647. // (c) Carbonite, Inc., 2005-2009 All rights reserved
  2648. /* Carbonite Service included file /scripts/box.class.js */
  2649. // (c) Carbonite, Inc., 2005-2009 All rights reserved
  2650. box = function()
  2651. {
  2652.     this.obj;
  2653.     this.GetObject = function()
  2654.     {
  2655.         return this.obj;
  2656.     }
  2657.     this.SetObject = function(ob)
  2658.     {
  2659.         this.obj = ob;
  2660.     }
  2661. }
  2662.  
  2663. /* End included file /scripts/box.class.js */
  2664.  
  2665. /* Carbonite Service SKIPPING already included file /scripts/commonfunctions.js */
  2666.  
  2667. var BACKUP_TYPE = "BackupType";
  2668. var START_HOUR = "StartHour";
  2669. var START_MINUTE = "StartMinute";
  2670. var START_AP = "StartAP";
  2671. var BACKUP_UNTIL = "BackupUntil";
  2672. var FINISH_HOUR = "FinishHour";
  2673. var FINISH_MINUTE = "FinishMinute";
  2674. var FINISH_AP = "FinishAP";
  2675. var ONCE_HOUR = "OnceHour";
  2676. var ONCE_MINUTE = "OnceMinute";
  2677. var ONCE_AP = "OnceAP";
  2678. var SSTART_HOUR = "SStartHour";
  2679. var SSTART_MINUTE = "SStartMinute";
  2680. var SSTART_AP = "SStartAP";
  2681. var SFINISH_HOUR = "SFinishHour";
  2682. var SFINISH_MINUTE = "SFinishMinute";
  2683. var SFINISH_AP = "SFinishAP";
  2684. var DAYS = "Days";
  2685. var NVSEP = ":";
  2686. var SEP = ";";
  2687. var DAYCHOICE = "DayChoice";
  2688. var SPECDAY_SUN = "SpecDaySun";
  2689. var SPECDAY_MON = "SpecDayMon";
  2690. var SPECDAY_TUE = "SpecDayTue";
  2691. var SPECDAY_WED = "SpecDayWed";
  2692. var SPECDAY_THU = "SpecDayThu";
  2693. var SPECDAY_FRI = "SpecDayFri";
  2694. var SPECDAY_SAT = "SpecDaySat";
  2695.  
  2696.  
  2697. var TimeControl = function (timeName, hr, min, processChange)
  2698. {
  2699.     var theHTML = "";
  2700.  
  2701.     hourName = timeName + "Hour";
  2702.     minuteName = timeName + "Minute";
  2703.     apName = timeName + "AP";
  2704.  
  2705.     // 24-hour cloc hour selection
  2706.     var HH = '<select name="' + hourName + '" onchange="' + processChange + '">';
  2707.     for(i = 0; i < 24; i++)
  2708.         HH += '<option value="' + i + '" ' + ((hr == i) ? 'selected="selected"' : '') + '>' + ((i < 10) ? '0' : '') + i + '</option>'
  2709.     HH += '</select>';
  2710.     // normalise the hour value for 12 hour clock
  2711.     ap = (hr > 11) ? "pm" : "am";
  2712.     hr = hr % 12;
  2713.     hr = (hr == 0) ? 12 : hr;
  2714.     var hh = '<select name="' + hourName + '" onchange="' + processChange + '">';
  2715.     for(i = 1; i < 13; i++)
  2716.         hh += '<option value="' + i % 12 + '" ' + ((hr == i) ? 'selected="selected"' : '') + '>' + ((i < 10) ? '0' : '') + i + '</option>'
  2717.     hh += '</select>';
  2718.  
  2719.     var mm = '<select name="' + minuteName + '" onchange="' + processChange + '">';
  2720.     for(i = 0; i < 60; i = i + 5)
  2721.         mm += '<option value="' + i + '" ' + ((min == i) ? 'selected="selected"' : '') + '>' + ((i < 10) ? '0' : '') + i + '</option>';
  2722.     mm += '</select>';
  2723.  
  2724.     var tt = '<input name="' + apName + '" type="radio" value="am" ' + ((ap == 'am') ? 'checked="checked"' : '') + ' onclick="' + processChange + '"/>' + strTimeAM;
  2725.     tt += '<input name="' + apName + '" type="radio" value="pm" ' + ((ap == 'pm') ? 'checked="checked"' : '') + ' onclick="' + processChange + '"/>' + strTimePM;
  2726.  
  2727.     var cPos = 0;
  2728.     var cPrev = "", cThis = "";
  2729.     while(cPos < timeFormat.length)
  2730.     {
  2731.         cThis = timeFormat.charAt(cPos);
  2732.  
  2733.         switch(cThis)
  2734.         {
  2735.             case "H":
  2736.                 if(cPrev != "H")
  2737.                     theHTML += HH;
  2738.                 break;
  2739.             case "h":
  2740.                 if(cPrev != "h")
  2741.                     theHTML += hh;
  2742.                 break;
  2743.             case "m":
  2744.                 if(cPrev != "m")
  2745.                     theHTML += mm;
  2746.                 break;
  2747.             case "t":
  2748.                 if(cPrev != "t")
  2749.                     theHTML += tt;
  2750.                 break;
  2751.             default:
  2752.                 theHTML += cThis;
  2753.                 break;
  2754.         }
  2755.  
  2756.         cPrev = cThis;
  2757.         cPos++;
  2758.     }
  2759.  
  2760.     return theHTML;
  2761. }
  2762.  
  2763. Schedule = function ()
  2764. {
  2765.     this.bUseFinishTime = false;
  2766.     this.StartHour = 0;
  2767.     this.StartMinute = 0;
  2768.     this.FinishHour = 0;
  2769.     this.FinishMinute = 0;
  2770.     this.Days = EveryDay;
  2771.    
  2772.     this.SetStartTime = function (hour, minute, ap)
  2773.     {
  2774.         this.StartHour = hour;
  2775.         this.StartMinute = minute;
  2776.         if(ap)
  2777.         {
  2778.             if(ap == "am")
  2779.             {
  2780.                 if(this.StartHour > 11)
  2781.                     this.StartHour = this.StartHour - 12;
  2782.             }
  2783.             else
  2784.             {
  2785.                 if(this.StartHour < 12)
  2786.                     this.StartHour = this.StartHour + 12;
  2787.             }
  2788.         }
  2789.     }
  2790.  
  2791.     this.SetFinishTime = function (hour, minute, ap)
  2792.     {
  2793.         this.bUseFinishTime = true;
  2794.         this.FinishHour = hour;
  2795.         this.FinishMinute = minute;
  2796.         if(ap)
  2797.         {
  2798.             if(ap == "am")
  2799.             {
  2800.                 if(this.FinishHour > 11)
  2801.                     this.FinishHour = this.FinishHour - 12;
  2802.             }
  2803.             else
  2804.             {
  2805.                 if(this.FinishHour < 12)
  2806.                     this.FinishHour = this.FinishHour + 12;
  2807.             }
  2808.         }
  2809.     }
  2810.  
  2811.     this.Parse = function (strStringDef)
  2812.     {
  2813.         if(strStringDef.length < 1)
  2814.             return;
  2815.  
  2816.         var nFindPair = 0;
  2817.         var NVs, NVPair;
  2818.  
  2819.         NVs = strStringDef.split(";");
  2820.         var i = 0;
  2821.         while(NVs[i])
  2822.         {
  2823.             if(NVs[i].indexOf(":") > -1)
  2824.             {
  2825.                 NVPair = NVs[i].split(":");
  2826.                 strValue = NVPair[1];
  2827.                 switch(NVPair[0])
  2828.                 {
  2829.                     case START_HOUR:
  2830.                         var newHour = parseInt(strValue);
  2831.                         this.StartHour = newHour;
  2832.                         break;
  2833.                     case START_MINUTE:
  2834.                         this.StartMinute = parseInt(strValue);
  2835.                         break;
  2836.                     case BACKUP_UNTIL:
  2837.                         this.bUseFinishTime = (strValue == "TimeUntil");
  2838.                         break;
  2839.                     case FINISH_HOUR:
  2840.                         var newHour = parseInt(strValue);
  2841.                         this.FinishHour = newHour;
  2842.                         this.bUseFinishTime = true;
  2843.                         break;
  2844.                     case FINISH_MINUTE:
  2845.                         this.FinishMinute = parseInt(strValue);
  2846.                         this.bUseFinishTime = true;
  2847.                         break;
  2848.                     case DAYS:
  2849.                         this.Days = strValue;
  2850.                         break;
  2851.                 }
  2852.             }
  2853.  
  2854.             i++;
  2855.         }
  2856.     }
  2857.  
  2858.     this.GetAsString = function ()
  2859.     {
  2860.         var strRet = START_HOUR + NVSEP + this.StartHour + SEP
  2861.                 + START_MINUTE + NVSEP + this.StartMinute + SEP
  2862.                 + BACKUP_UNTIL + NVSEP + (this.bUseFinishTime ? "TimeUntil" : "DoneUntil") + SEP
  2863.                 + DAYS + NVSEP + this.Days + SEP;
  2864.         if (this.bUseFinishTime) {
  2865.             strRet += FINISH_HOUR + NVSEP + this.FinishHour + SEP
  2866.             + FINISH_MINUTE + NVSEP + this.FinishMinute + SEP
  2867.         }
  2868.                
  2869.  
  2870.         return strRet;
  2871.     }
  2872.  
  2873.     this.GetTime = function (hr, mm)
  2874.     {
  2875.         var theTime = "";
  2876.         var hr24 = hr;
  2877.         var hr12 = hr % 12;
  2878.         if(hr12 == 0)
  2879.             hr12 = 12;
  2880.         var tt = ((hr > 11) ? strTimePM : strTimeAM);
  2881.  
  2882.         var cPos = 0;
  2883.         var cPrev = "", cThis = "";
  2884.         while(cPos < timeFormat.length)
  2885.         {
  2886.             cThis = timeFormat.charAt(cPos);
  2887.             cNext = (cPos < timeFormat.length - 1) ? timeFormat.charAt(cPos + 1) : "";
  2888.             switch(cThis)
  2889.             {
  2890.                 case "H":
  2891.                     if(cPrev != "H")
  2892.                         theTime += ((hr24 < 10 && cNext == "H") ? "0" : "") + hr24;
  2893.                     break;
  2894.                 case "h":
  2895.                     if(cPrev != "h")
  2896.                         theTime += ((hr12 < 10 && cNext == "h") ? "0" : "") + hr12;
  2897.                     break;
  2898.                 case "m":
  2899.                     if(cPrev != "m")
  2900.                         theTime += ((mm < 10 && cNext == "m") ? "0" : "") + mm;
  2901.                     break;
  2902.                 case "t":
  2903.                     if(cPrev != "t")
  2904.                         theTime += tt;
  2905.                     break;
  2906.                 default:
  2907.                     theTime += cThis;
  2908.                     break;
  2909.             }
  2910.             cPrev = cThis;
  2911.             cPos++;
  2912.         }
  2913.         return theTime;
  2914.     }
  2915.  
  2916.     this.GetStartTime = function ()
  2917.     {
  2918.         return this.GetTime(this.StartHour, this.StartMinute);
  2919.     }
  2920.  
  2921.     this.GetFinishTime = function ()
  2922.     {
  2923.         return this.GetTime(this.FinishHour, this.FinishMinute);
  2924.     }
  2925.  
  2926.     this.Description = function ()
  2927.     {
  2928.         if(this.Days == EveryDay)
  2929.             str = this.bUseFinishTime ? sdEveryDayTwoTimes : sdEveryDayOneTime;
  2930.         else if(this.Days == Weekdays)
  2931.             str = this.bUseFinishTime ? sdWeekdaysTwoTimes : sdWeekdaysOneTime;
  2932.         else
  2933.             str = this.bUseFinishTime ? sdSpecificDaysTwoTimes : sdSpecificDaysOneTime;
  2934.  
  2935.         str = str.replace("{startTime}", this.GetStartTime());
  2936.         str = str.replace("{finishTime}", this.GetFinishTime());
  2937.         str = str.replace("{listDays}", this.ListDays());
  2938.  
  2939.         return str;
  2940.     }
  2941.  
  2942.     this.ListDays = function ()
  2943.     {
  2944.         if(this.Days == 0)
  2945.             return strDescNoSchedule;
  2946.  
  2947.         strRet = "";
  2948.         if((this.Days & Sun) == Sun)
  2949.             strRet += strSundayShort + ", ";
  2950.         if((this.Days & Mon) == Mon)
  2951.             strRet += strMondayShort + ", ";
  2952.         if((this.Days & Tue) == Tue)
  2953.             strRet += strTuesdayShort + ", ";
  2954.         if((this.Days & Wed) == Wed)
  2955.             strRet += strWednesdayShort + ", ";
  2956.         if((this.Days & Thu) == Thu)
  2957.             strRet += strThursdayShort + ", ";
  2958.         if((this.Days & Fri) == Fri)
  2959.             strRet += strFridayShort + ", ";
  2960.         if((this.Days & Sat) == Sat)
  2961.             strRet += strSaturdayShort + ", ";
  2962.  
  2963.         // drop the ", " at the end of the list
  2964.         return strRet.substring(0, strRet.length - 2);
  2965.     }
  2966.  
  2967.     this.ProcessChange = function (o)
  2968.     {
  2969.         switch(o.name)
  2970.         {
  2971.             case START_HOUR:
  2972.             case SSTART_HOUR:
  2973.             case ONCE_HOUR:
  2974.                 var newHour = parseInt(o.value) + ((!Use24HourClock && this.StartHour > 11 && o.value < 12) ? 12 : 0);
  2975.                 this.StartHour = newHour;
  2976.                 break;
  2977.             case START_MINUTE:
  2978.             case SSTART_MINUTE:
  2979.             case ONCE_MINUTE:
  2980.                 this.StartMinute = parseInt(o.value);
  2981.                 break;
  2982.             case START_AP:
  2983.             case SSTART_AP:
  2984.             case ONCE_AP:
  2985.                 if(o.value == "am")
  2986.                 {
  2987.                     if(this.StartHour > 11)
  2988.                         this.StartHour = this.StartHour - 12;
  2989.                 }
  2990.                 else
  2991.                 {
  2992.                     if(this.StartHour < 12)
  2993.                         this.StartHour = this.StartHour + 12;
  2994.                 }
  2995.                 break;
  2996.             case FINISH_HOUR:
  2997.             case SFINISH_HOUR:
  2998.                 var newHour = parseInt(o.value) + ((!Use24HourClock && this.FinishHour > 11 && o.value < 12) ? 12 : 0);
  2999.                 this.FinishHour = newHour;
  3000.                 this.bUseFinishTime = true;
  3001.                 break;
  3002.             case FINISH_MINUTE:
  3003.             case SFINISH_MINUTE:
  3004.                 this.FinishMinute = parseInt(o.value);
  3005.                 this.bUseFinishTime = true;
  3006.                 break;
  3007.             case FINISH_AP:
  3008.             case SFINISH_AP:
  3009.                 if(o.value == "am")
  3010.                 {
  3011.                     if(this.FinishHour > 11)
  3012.                         this.FinishHour = this.FinishHour - 12;
  3013.                 }
  3014.                 else
  3015.                 {
  3016.                     if(this.FinishHour < 12)
  3017.                         this.FinishHour = this.FinishHour + 12;
  3018.                 }
  3019.                 this.bUseFinishTime = true;
  3020.                 break;
  3021.             case DAYCHOICE:
  3022.                 this.Days = (o.value == "Every") ? EveryDay : ((o.value == "Weekdays") ? Weekdays : 0);
  3023.                 break;
  3024.             case SPECDAY_SUN:
  3025.                 this.Days = o.checked ? this.Days | Sun : this.Days & ~Sun;
  3026.                 break;
  3027.             case SPECDAY_MON:
  3028.                 this.Days = o.checked ? this.Days | Mon : this.Days & ~Mon;
  3029.                 break;
  3030.             case SPECDAY_TUE:
  3031.                 this.Days = o.checked ? this.Days | Tue : this.Days & ~Tue;
  3032.                 break;
  3033.             case SPECDAY_WED:
  3034.                 this.Days = o.checked ? this.Days | Wed : this.Days & ~Wed;
  3035.                 break;
  3036.             case SPECDAY_THU:
  3037.                 this.Days = o.checked ? this.Days | Thu : this.Days & ~Thu;
  3038.                 break;
  3039.             case SPECDAY_FRI:
  3040.                 this.Days = o.checked ? this.Days | Fri : this.Days & ~Fri;
  3041.                 break;
  3042.             case SPECDAY_SAT:
  3043.                 this.Days = o.checked ? this.Days | Sat : this.Days & ~Sat;
  3044.                 break;
  3045.         }
  3046.         ScheduleSettings.UpdateDisplay(o.name, o.value);
  3047.     }
  3048.  
  3049.     this.OutputHTML = function (htmlTemplate)
  3050.     {
  3051.         var StartTime = new box();
  3052.         var FinishTime = new box();
  3053.         var newOne = htmlTemplate; //.cloneNode(true);
  3054.         this.UpdateScheduleControls(newOne, StartTime, FinishTime);
  3055.         if(StartTime.GetObject())
  3056.             StartTime.GetObject().innerHTML = TimeControl("Start", this.StartHour, this.StartMinute, "ScheduleSettings.ProcessSave(this);");
  3057.         if(FinishTime.GetObject())
  3058.             FinishTime.GetObject().innerHTML = TimeControl("Finish", this.FinishHour, this.FinishMinute, "ScheduleSettings.ProcessSave(this);");
  3059.         return newOne;
  3060.     }
  3061.  
  3062.     this.UpdateScheduleControls = function (theNode, StartTime, FinishTime)
  3063.     {
  3064.         var childNode;
  3065.  
  3066.         for(var i = 0; i < theNode.childNodes.length; i++)
  3067.         {
  3068.             childNode = theNode.childNodes[i];
  3069.  
  3070.             this.UpdateSpecificControl(childNode, StartTime, FinishTime);
  3071.  
  3072.             this.UpdateScheduleControls(childNode, StartTime, FinishTime);
  3073.         }
  3074.     }
  3075.  
  3076.     this.UpdateSpecificControl = function (childNode, StartTime, FinishTime)
  3077.     {
  3078.         if(childNode.attributes)
  3079.         {
  3080.             // Feed in the values from the schedule
  3081.             if(childNode.nodeName == "INPUT")
  3082.             {
  3083.                 switch(childNode.attributes["name"].value)
  3084.                 {
  3085.                     case "DayChoice":
  3086.                         switch(childNode.attributes["id"].value)
  3087.                         {
  3088.                             case "Every":
  3089.                                 CheckObject(childNode, this.Days == EveryDay);
  3090.                                 break;
  3091.                             case "Weekdays":
  3092.                                 CheckObject(childNode, this.Days == Weekdays);
  3093.                                 break;
  3094.                             case "Specific":
  3095.                                 CheckObject(childNode, this.Days != EveryDay && this.Days != Weekdays);
  3096.                                 break;
  3097.                         }
  3098.                         break;
  3099.                     case "SpecDaySun":
  3100.                     case "SpecDayMon":
  3101.                     case "SpecDayTue":
  3102.                     case "SpecDayWed":
  3103.                     case "SpecDayThu":
  3104.                     case "SpecDayFri":
  3105.                     case "SpecDaySat":
  3106.                         checkDay = eval(childNode.attributes["name"].value.substring(7));
  3107.                         CheckObject(childNode, ((this.Days & checkDay) == checkDay));
  3108.                         break;
  3109.                 }
  3110.             }
  3111.  
  3112.             if(childNode.attributes["class"])
  3113.             {
  3114.                 var className = childNode.attributes["class"].value;
  3115.                 switch(className)
  3116.                 {
  3117.                     case "crbScheduleStartTime":
  3118.                         StartTime.SetObject(childNode);
  3119.                         break;
  3120.                     case "crbScheduleFinishTime":
  3121.                         FinishTime.SetObject(childNode);
  3122.                         break;
  3123.                 }
  3124.             }
  3125.         }
  3126.     }
  3127.  
  3128.     this.IsEqualTo = function (sched)
  3129.     {
  3130.         var bEqual =
  3131.             (this.bUseFinishTime == sched.bUseFinishTime)
  3132.             && (this.StartHour == sched.StartHour)
  3133.             && (this.StartMinute == sched.StartMinute)
  3134.             && (this.FinishHour == sched.FinishHour)
  3135.             && (this.FinishMinute == sched.FinishMinute)
  3136.             && (this.Days == sched.Days);
  3137.  
  3138.         return bEqual;
  3139.     }
  3140.  
  3141.     this.IsValidTimeWindow = function ()
  3142.     {
  3143.         return !this.bUseFinishTime || !((this.StartHour == this.FinishHour) && (this.StartMinute == this.FinishMinute));
  3144.     }
  3145. }
  3146.  
  3147. /* End included file /scripts/schedule.class.js */
  3148. /* Carbonite Service SKIPPING already included file /scripts/commonfunctions.js */
  3149.  
  3150. /* Carbonite Service SKIPPING already included file /scripts/serviceinterconnect.js */
  3151.  
  3152. /* Carbonite Service included file /scripts/messagebox.js */
  3153. // (c) Carbonite, Inc., 2005-2009 All rights reserved
  3154. /* Carbonite Service SKIPPING already included file /scripts/string.class.js */
  3155.  
  3156. /* Carbonite Service SKIPPING already included file /scripts/commonfunctions.js */
  3157.  
  3158. /* Carbonite Service included file /js/wait.js */
  3159. // (c) Carbonite, Inc., 2005-2009 All rights reserved
  3160. // Useful common scripts for messaging while waiting
  3161.  
  3162. var Wait__ = function ()
  3163. {
  3164.     var self = this;
  3165.  
  3166.     var objOverlay = null;
  3167.     var nestedOverlays = new Array();
  3168.     var popupDiv = null;
  3169.     var orgID = null;
  3170.  
  3171.     function AddPopupDiv(waitDivId, processor)
  3172.     {
  3173.         popupDiv = document.createElement("div");
  3174.         popupDiv.className = "HorizontalCenter";
  3175.         var contentDiv = document.createElement("div");
  3176.         contentDiv.className = "LightBox";
  3177.         popupDiv.appendChild(contentDiv);
  3178.         var pWait = document.getElementById(waitDivId);
  3179.         orgID = waitDivId;
  3180.  
  3181.         if(processor)
  3182.         {
  3183.             // becuase we are processing, we create a clone that we change, rather than changing the original node
  3184.             pWait = pWait.cloneNode(true);
  3185.             orgID = null;
  3186.             pWait.innerHTML = processor(pWait.innerHTML);
  3187.         }
  3188.  
  3189.         contentDiv.appendChild(pWait);
  3190.  
  3191.         document.body.appendChild(popupDiv);
  3192.  
  3193.         pWait.style.display = "";
  3194.         pWait.style.visibility = "visible";
  3195.  
  3196.         var centerPos = $(popupDiv).offset();
  3197.         $(contentDiv).offset(
  3198.         {
  3199.             left: centerPos.left - (contentDiv.offsetWidth / 2),
  3200.             top: centerPos.top - (contentDiv.offsetHeight / 2)
  3201.         }
  3202.         );
  3203.     }
  3204.  
  3205.     function RemovePopupDiv()
  3206.     {
  3207.         if(popupDiv)
  3208.         {
  3209.             if(orgID)
  3210.             {
  3211.                 var orgDiv = document.getElementById(orgID);
  3212.                 orgDiv.parentNode.removeChild(orgDiv);
  3213.                 orgDiv.style.display = "none";
  3214.                 orgDiv.style.visibility = "hidden";
  3215.                 document.body.appendChild(orgDiv);
  3216.             }
  3217.             document.body.removeChild(popupDiv);
  3218.         }
  3219.         popupDiv = null;
  3220.         orgID = null;
  3221.     }
  3222.  
  3223.     function DoWaitOperation()
  3224.     {
  3225.         waitingMethod();
  3226.         self.StopWait();
  3227.     }
  3228.  
  3229.     this.Overlay = function (bShow)
  3230.     {
  3231.         if(bShow)
  3232.         {
  3233.             if(objOverlay)
  3234.             {
  3235.                 nestedOverlays.push(objOverlay);
  3236.             }
  3237.             objOverlay = document.createElement("div");
  3238.             objOverlay.className = "LightBoxBackground";
  3239.             objOverlay.setAttribute("id", "overlay");
  3240.             document.body.appendChild(objOverlay);
  3241.         }
  3242.         else
  3243.         {
  3244.             if(objOverlay)
  3245.                 document.body.removeChild(objOverlay);
  3246.             objOverlay = null;
  3247.             if(nestedOverlays.length > 0)
  3248.                 objOverlay = nestedOverlays.pop();
  3249.         }
  3250.     }
  3251.  
  3252.     this.IsPopped = function ()
  3253.     {
  3254.         return popupDiv != null;
  3255.     }
  3256.  
  3257.     this.AddWaitingDiv = function (waitDivId, processor)
  3258.     {
  3259.         AddPopupDiv(waitDivId, processor);
  3260.         document.body.style.cursor = "wait";
  3261.     }
  3262.  
  3263.     this.RemoveWaitingDiv = function ()
  3264.     {
  3265.         document.body.style.cursor = "default";
  3266.         RemovePopupDiv();
  3267.     }
  3268.  
  3269.     /*
  3270.     Wait - shows message during wait operation (overlaying background with opaque grey)
  3271.     Arguments:
  3272.     messageId - id of the html node to show within the waiting div (required)
  3273.     methodToCall - pointer to method to call (optional; if not provided, caller is responsible for calling StopWait())
  3274.     decorationMethod - method that will preprocess the message to update its contents if necessary
  3275.     */
  3276.     var waitingMethod = null;
  3277.     this.DoWait = function (messageId, methodToCall, decorationMethod)
  3278.     {
  3279.         self.Overlay(true);
  3280.         self.AddWaitingDiv(messageId, decorationMethod);
  3281.  
  3282.         if(methodToCall)
  3283.         {
  3284.             // let us know what the method to call is
  3285.             waitingMethod = methodToCall;
  3286.             //var fnCall = "DoWaitOperation('" + methodToCall + "')";
  3287.             setTimeout(DoWaitOperation, 0);
  3288.         }
  3289.     }
  3290.  
  3291.     this.StopWait = function ()
  3292.     {
  3293.         waitingMethod = null;
  3294.         self.RemoveWaitingDiv();
  3295.         self.Overlay(false);
  3296.     }
  3297.  
  3298.     this.Popup = function (messageId, decorationMethod)
  3299.     {
  3300.         self.Overlay(true);
  3301.         AddPopupDiv(messageId, decorationMethod);
  3302.     }
  3303.  
  3304.     this.StopPopup = function ()
  3305.     {
  3306.         RemovePopupDiv();
  3307.         self.Overlay(false);
  3308.     }
  3309.  
  3310. }
  3311.  
  3312. var Wait = new Wait__();
  3313.  
  3314. /* End included file /js/wait.js */
  3315.  
  3316. var msgBoxArgs = {};
  3317.  
  3318. BUTTON_OK = 0x01;
  3319. BUTTON_CANCEL = 0x02;
  3320. BUTTON_YES = 0x04;
  3321. BUTTON_NO = 0x08;
  3322. BUTTONS_OKCANCEL = BUTTON_OK | BUTTON_CANCEL;
  3323. BUTTONS_YESNO = BUTTON_YES | BUTTON_NO;
  3324. BUTTONS_YESNOCANCEL = BUTTON_YES | BUTTON_NO | BUTTON_CANCEL;
  3325.  
  3326. ID_YES = 'IdYes';
  3327. ID_NO = 'IdNo';
  3328. ID_OK = 'IdOK';
  3329. ID_CANCEL = 'IdCancel';
  3330.  
  3331. ICON_NONE = 1;
  3332. ICON_INFO = 2;
  3333. ICON_WARNING = 3;
  3334.  
  3335. MESSAGEBOX_ERROR_NOELEMENT = -1;
  3336.  
  3337. function HtmlMessageBoxFromUrl(url)
  3338. {
  3339.     // grey out the area of the main window
  3340.     Wait.Overlay(true);
  3341.     var retval = external.AlertFromUrl(url);
  3342.     Wait.Overlay(false);
  3343.  
  3344.     return retval;
  3345. }
  3346.  
  3347. function HtmlMessageBox2(id, buttonSpec)
  3348. {
  3349.     if (typeof (external.Alert) == "undefined")
  3350.         return (BUTTON_OK == HtmlMessageBox(id, buttonSpec) ? ID_OK : ID_CANCEL);
  3351.        
  3352.     var theNode = document.getElementById(id);
  3353.     if (!theNode)
  3354.         return MESSAGEBOX_ERROR_NOELEMENT;
  3355.  
  3356.     switch (buttonSpec) {
  3357.         case BUTTON_OK: buttonSpec = ID_OK; break;
  3358.         case BUTTON_CANCEL: buttonSpec = ID_CANCEL; break;
  3359.         case BUTTON_YES: buttonSpec = ID_YES; break;
  3360.         case BUTTON_NO: buttonSpec = ID_NO; break;
  3361.         case BUTTONS_OKCANCEL: buttonSpec = ID_CANCEL + '*_default*SecondaryButton|' + ID_OK; break;
  3362.         case BUTTONS_YESNO: buttonSpec = ID_NO + '*_default*SecondaryButton|' + ID_YES; break;
  3363.         case BUTTONS_YESNOCANCEL: buttonSpec = buttonSpec = ID_CANCEL + '*_default*SecondaryButton|' + ID_NO + '*_default*SecondaryButton|' + ID_YES; break;
  3364.     }
  3365.     //the node style indicates the size of the messagebox with dialogHeight and dialogWidth
  3366.     //the captions for the buttons need not be stated for common buttons (see HTMLMessageBox2.html)
  3367.     //otherwise, the button spec is sent as id1*caption1|id2*caption2|...|idN*captionN
  3368.  
  3369.     // grey out the area of the main window
  3370.     Wait.Overlay(true);
  3371.     var retval = external.Alert("", theNode.outerHTML, buttonSpec);
  3372.     Wait.Overlay(false);
  3373.  
  3374.     return retval;
  3375. }
  3376.  
  3377. /*
  3378.     The opts parameters is a javascript Object used to pass in
  3379.     a variable set of optional settings.
  3380.    
  3381.     Usage:
  3382.    
  3383.         var options = new Object();
  3384.         options.idOkButtonText = "crbConfirmUnfreezeOkButton";
  3385.         options.idCancelButtonText = "crbConfirmUnfreezeCancelButton";
  3386.         options.iconType = ICON_NONE;
  3387.         if (HtmlMessageBox('crbConfirmUnfreeze', BUTTONS_OKCANCEL, options) == BUTTON_OK)
  3388.         {
  3389.             ...do stuff...
  3390.         }
  3391.  
  3392.     Option properties:
  3393.    
  3394.         - idOkButtonText: the id of an element that contains the replacement text
  3395.           for the OK button.
  3396.         - idCancelButtonText: ... Cancel button.
  3397.         - idYesButtonText: ... Yes button.
  3398.         - idNoButtonText: ... No button.
  3399.         - iconType: sets or turns off the message box icon (default is an info icon).
  3400.           Use one of the ICON_x constants (see top of this file).
  3401.    
  3402. */
  3403. function HtmlMessageBox(id, buttonTypes, opts)
  3404. {
  3405.     var theNode = document.getElementById(id);
  3406.     if (!theNode)
  3407.         return MESSAGEBOX_ERROR_NOELEMENT;
  3408.    
  3409.     // Our call to MessageBox / MessageBoxStyle needs an options param,
  3410.     // too. So we'll just use the one that caller passed to us, if any,
  3411.     // creating a new one only if necessary.
  3412.     if (opts == null)
  3413.         opts = new Object();
  3414.     opts.Message = theNode.innerHTML;
  3415.     opts.Buttons = buttonTypes;
  3416.    
  3417.     // process optional opts settings
  3418.     if (opts.idOkButtonText)
  3419.         opts.OkButtonText = ReadButtonText(opts.idOkButtonText);
  3420.     if (opts.idCancelButtonText)
  3421.         opts.CancelButtonText = ReadButtonText(opts.idCancelButtonText);
  3422.     if (opts.idYesButtonText)
  3423.         opts.YesButtonText = ReadButtonText(opts.idYesButtonText);
  3424.     if (opts.idNoButtonText)
  3425.         opts.NoButtonText = ReadButtonText(opts.idNoButtonText);
  3426.  
  3427.     var sStyle = theNode.style;
  3428.     var retVal;
  3429.     if (sStyle)
  3430.     {
  3431.         theNode.removeAttribute("title");
  3432.         retVal = MessageBoxStyle(opts, sStyle);
  3433.     }
  3434.     else
  3435.         retVal = MessageBox(opts);
  3436.    
  3437.     return retVal;
  3438. }
  3439.  
  3440. function ParseStyle(sStyle, d, w)
  3441. {
  3442.     var buffer = 50;
  3443.  
  3444.     var dialogHeight = -1;
  3445.     var dialogWidth = -1;
  3446.     var dialogTop = -1;
  3447.     var dialogLeft = -1;
  3448.    
  3449.     var styleString = (sStyle.cssText!=null)?sStyle.cssText:sStyle;
  3450.     var nvPairs = styleString.split(";");
  3451.     var newStyle = "";
  3452.     for(var i=0; i<nvPairs.length; i++)
  3453.     {
  3454.         if(nvPairs[i].length>0)
  3455.         {
  3456.             var stylePair = nvPairs[i].split(":");
  3457.             switch(stylePair[0].trim().toLowerCase())
  3458.             {
  3459.             // if we've been provided dialog attributes
  3460.             case "dialogheight":
  3461.             case "dialogtop":
  3462.             case "dialogleft":
  3463.             case "dialogwidth":
  3464.                 eval(stylePair[0] + " = parseInt('" + stylePair[1] + "')");
  3465.                 break;
  3466.            
  3467.             // Check for things that hide these items; we want to force them to be visible for the message box
  3468.             case "visibility":
  3469.                 if (stylePair[1].trim().toLowerCase() != "hidden")
  3470.                     newStyle += stylePair[0] + ":" + stylePair[1] + ";";
  3471.                 break;
  3472.             case "display":
  3473.                 if (stylePair[1].trim().toLowerCase() != "none")
  3474.                     newStyle += stylePair[0] + ":" + stylePair[1] + ";";
  3475.                 break;
  3476.                
  3477.             // by default, pass the style on through
  3478.             default:
  3479.                 newStyle += stylePair[0] + ":" + stylePair[1] + ";";
  3480.                 break;
  3481.             }
  3482.         }
  3483.     }
  3484.    
  3485.     // If a height has been specified, adjust it (add 40) for IE6.
  3486.     if (dialogHeight > 0 && IsIE6())
  3487.         dialogHeight += 40;
  3488.    
  3489.     // Use default sizes if not supplied
  3490.     if (dialogHeight < 0)
  3491.         dialogHeight = d.body.clientHeight - buffer * 2;
  3492.     if (dialogWidth < 0)
  3493.         dialogWidth = d.body.clientWidth - buffer * 2;
  3494.    
  3495.     // Minimum height that IE allows is 100px, minimum width 250px - if the passed in values are smaller, the dialog will not be centered
  3496.     if (dialogHeight < 100)
  3497.         dialogHeight = 100;
  3498.     if (dialogWidth < 250)
  3499.         dialogWidth = 250;
  3500.    
  3501.     // center the dialog with respect to the screen, unless top and/or left have been provided to force it elsewhere
  3502.     if (dialogLeft < 0)
  3503.         dialogLeft = w.screenLeft + (d.body.clientWidth - dialogWidth) / 2;
  3504.     if (dialogTop < 0)
  3505.         dialogTop = w.screenTop + (d.body.clientHeight - dialogHeight) / 2;
  3506.    
  3507.     newStyle += "dialogHeight: " + dialogHeight + "px;dialogWidth: " + dialogWidth + "px;dialogTop: " + dialogTop + "px;dialogLeft:" + dialogLeft + " px;";
  3508.    
  3509.     return newStyle;
  3510. }
  3511.  
  3512. function MessageBox(vArgs)
  3513. {
  3514.     return MessageBoxStyle(vArgs, "");
  3515. }
  3516.  
  3517. function MessageBoxStyle(vArgs, style)
  3518. {
  3519.     var d = top ? top.document : document;
  3520.     var w = top ? top.window : window;
  3521.  
  3522.     Wait.Overlay(true);
  3523.     var retVal = window.showModalDialog("MessageBox.htm", vArgs, "center: no;status: no;unadorned: yes;" + ParseStyle(style, d, w));
  3524.     Wait.Overlay(false);   
  3525.     return retVal;
  3526. }
  3527.  
  3528. function WriteMessage()
  3529. {
  3530.     if (msgBoxArgs.Message)
  3531.         document.write(msgBoxArgs.Message);
  3532. }
  3533.  
  3534. function AppendButtonTags(currButtonType, sButtonName, buttonPanel)
  3535. {
  3536.     var button = document.getElementById(sButtonName);
  3537.     var i = 0;
  3538.     var buttonContent;
  3539.     var isOverrideText = IsOverrideButtonText(currButtonType);
  3540.     while (buttonContent = button.childNodes[i])
  3541.     {
  3542.         var newNode = buttonContent.cloneNode(true);
  3543.         if (isOverrideText)
  3544.             ReplaceCurrentButtonText(currButtonType, newNode);
  3545.         buttonPanel.appendChild(newNode);
  3546.         i++;
  3547.     }
  3548. }
  3549.  
  3550. function WriteButtons()
  3551. {
  3552.     var buttonPanel = document.getElementById("crbMessageBoxButtons");
  3553.     if (msgBoxArgs.Buttons & BUTTON_CANCEL)
  3554.         AppendButtonTags(BUTTON_CANCEL, "crbMsgBoxCancel", buttonPanel);
  3555.     // Add the OK button if msgBoxArgs.Buttons is null.  This happens
  3556.     // when loaded from the Skin extended menu in CarboniteUI.
  3557.     if (!msgBoxArgs.Buttons || (msgBoxArgs.Buttons & BUTTON_OK))
  3558.         AppendButtonTags(BUTTON_OK, "crbMsgBoxOK", buttonPanel);
  3559.     if (msgBoxArgs.Buttons & BUTTON_NO)
  3560.         AppendButtonTags(BUTTON_NO, "crbMsgBoxNo", buttonPanel);
  3561.     if (msgBoxArgs.Buttons & BUTTON_YES)
  3562.         AppendButtonTags(BUTTON_YES, "crbMsgBoxYes", buttonPanel);
  3563. }
  3564.  
  3565. function ReturnResult(result)
  3566. {
  3567.     returnValue = result;
  3568.     window.close();
  3569. }
  3570.  
  3571. function ReadButtonText(id)
  3572. {
  3573.     var theNode = document.getElementById(id);
  3574.     if (!theNode)
  3575.         return null;
  3576.     return theNode.innerHTML;
  3577. }
  3578.  
  3579. function IsOverrideButtonText(currButtonType)
  3580. {
  3581.     if ( (currButtonType == BUTTON_OK && msgBoxArgs.OkButtonText)
  3582.          || (currButtonType == BUTTON_CANCEL && msgBoxArgs.CancelButtonText)
  3583.          || (currButtonType == BUTTON_YES && msgBoxArgs.YesButtonText)
  3584.          || (currButtonType == BUTTON_NO && msgBoxArgs.NoButtonText))
  3585.     {
  3586.         return true;
  3587.     }
  3588.     return false;
  3589. }
  3590.  
  3591. function ReplaceCurrentButtonText(currButtonType, newNode)
  3592. {
  3593.     var res = newNode.getElementsByTagName('a');
  3594.     if (res == null || res.length == 0)
  3595.         return;
  3596.     if (currButtonType == BUTTON_OK)
  3597.         res[0].innerHTML = msgBoxArgs.OkButtonText;
  3598.     if (currButtonType == BUTTON_CANCEL)
  3599.         res[0].innerHTML = msgBoxArgs.CancelButtonText;
  3600.     if (currButtonType == BUTTON_YES)
  3601.         res[0].innerHTML = msgBoxArgs.YesButtonText;
  3602.     if (currButtonType == BUTTON_NO)
  3603.         res[0].innerHTML = msgBoxArgs.NoButtonText;    
  3604. }
  3605.  
  3606. function FinalizeDocument()
  3607. {
  3608.     // change or remove message box's "info" icon
  3609.     if (msgBoxArgs.iconType)
  3610.     {
  3611.         var n = document.getElementById("crbMsgBoxText");
  3612.         if (n != null)
  3613.         {
  3614.             if (msgBoxArgs.iconType == ICON_WARNING)
  3615.                 n.style.backgroundImage = "url(../images/alert.png)";
  3616.             else if (msgBoxArgs.iconType == ICON_NONE)
  3617.             {
  3618.                 n.style.backgroundImage = "none";
  3619.                 n.style.paddingLeft = "0";
  3620.                
  3621.             }
  3622.         }
  3623.     }
  3624. }
  3625.  
  3626. // Utility message box functions
  3627. /* Takes the ID of the span containing the dialog box text; pops a confirmation dialog */
  3628. function crbConfirm2(id)
  3629. {
  3630.     return ID_OK == (buttonSelected = HtmlMessageBox2(id, BUTTONS_OKCANCEL));
  3631. }
  3632.  
  3633. /* Takes the ID of the span containing the dialog box text; pops an alert dialog */
  3634. function crbAlert(id)
  3635. {
  3636.     HtmlMessageBox2(id, BUTTON_OK);
  3637. }
  3638.  
  3639. function crbConfirmYN2(id)
  3640. {
  3641.     var buttonSelected;
  3642.     return ID_YES == (buttonSelected = HtmlMessageBox2(id, BUTTONS_YESNO));
  3643. }
  3644. /* End included file /scripts/messagebox.js */
  3645.  
  3646. function formatTime(hour, minute, iso) {
  3647.   var printMinute = minute;
  3648.   if (minute < 10) printMinute = '0' + minute;
  3649.  
  3650.   if (iso) {
  3651.     var printHour = hour
  3652.     if (printHour < 10) printHour = '0' + hour;
  3653.     return printHour + ':' + printMinute;
  3654.   } else {
  3655.     var printHour = hour % 12;
  3656.     if (printHour == 0) printHour = 12;
  3657.     var half = (hour < 12) ? 'am' : 'pm';
  3658.     return printHour + ':' + printMinute + half;
  3659.   }
  3660. }
  3661.  
  3662. function parseTime(text) {
  3663.   var match = match = /(\d+)\s*[:\-\.,]\s*(\d+)\s*(am|pm)?/i.exec(text);
  3664.   if (match && match.length >= 3) {
  3665.     var hour = Number(match[1]);
  3666.     var minute = Number(match[2])
  3667.     if (hour == 12 && match[3]) hour -= 12;
  3668.     if (match[3] && match[3].toLowerCase() == 'pm') hour += 12;
  3669.     return {
  3670.       hour: hour,
  3671.       minute: minute
  3672.     };
  3673.   } else {
  3674.     return null;
  3675.   }
  3676. }
  3677.  
  3678. var MIScheduleSettings__ = function () {
  3679.   var CONTINUOUS = 0;
  3680.   var ONCE_PER_DAY = 1;
  3681.   var EXCLUDE_HOURS = 2;
  3682.  
  3683.   this.PutMISchedule = function () {
  3684.     // Schedule types
  3685.     var scheduleInfo = {
  3686.       "ScheduleType": CONTINUOUS,
  3687.       "StartHour": 0,
  3688.       "StartMinute": 0,
  3689.       "EndHour": 0,
  3690.       "EndMinute": 0
  3691.     };
  3692.     if ($("#MIdaily").is(":checked")) {
  3693.       scheduleInfo.ScheduleType = ONCE_PER_DAY;
  3694.       var startTime = parseTime($('#MIbackup_start').val());
  3695.       if (startTime) {
  3696.         scheduleInfo.StartHour = startTime.hour;
  3697.         scheduleInfo.StartMinute = startTime.minute;
  3698.       }
  3699.     } else if ($("#MIexcludeHours").is(":checked")) {
  3700.       scheduleInfo.ScheduleType = EXCLUDE_HOURS;
  3701.       var startTime = parseTime($('#MIexclude_start').val());
  3702.       if (startTime) {
  3703.         scheduleInfo.StartHour = startTime.hour;
  3704.         scheduleInfo.StartMinute = startTime.minute;
  3705.       }
  3706.       var endTime = parseTime($('#MIexclude_end').val());
  3707.       if (endTime) {
  3708.         scheduleInfo.EndHour = endTime.hour;
  3709.         scheduleInfo.EndMinute = endTime.minute;
  3710.       }
  3711.     }
  3712.  
  3713.     this.UpdateTimeFields(scheduleInfo.ScheduleType, scheduleInfo.StartHour, scheduleInfo.StartMinute, scheduleInfo.EndHour, scheduleInfo.EndMinute);
  3714.  
  3715.     var scheduleJSON = $.toJSON(scheduleInfo);
  3716.     $.ajax({
  3717.       url: "/put-MIschedule.htm",
  3718.       data: "nocache=1&schedule=" + scheduleJSON
  3719.     });
  3720.   }
  3721.  
  3722.   this.initMISchedule = function () {
  3723.     var data = $.parseJSON($("#crbMIScheduleInfo").html());
  3724.  
  3725.     // Init defaults for daily backup and exclude range backup
  3726.     // Daily backup will default to midnight
  3727.     var defaultDailyBackupTime = formatTime(0, 0, Use24HourClock);
  3728.     $('#MIbackup_start').val(defaultDailyBackupTime);
  3729.     $('#MIbackup_start_text').text(defaultDailyBackupTime);
  3730.  
  3731.     // Exclude range backup will default to the current time + 2 hours
  3732.     var defaultExcludeStartTime = new Date();
  3733.     var defaultExcludeStartHour = defaultExcludeStartTime.getHours();
  3734.     var defaultExcludeStartMin = defaultExcludeStartTime.getMinutes() < 15 ? 0 : 30;
  3735.     var defaultExcludeEndTime = new Date();
  3736.     var defaultExcludeEndHour = (defaultExcludeEndTime.getHours() + 2) % 24;
  3737.     var defaultExcludeEndMinute = defaultExcludeEndTime.getMinutes() < 15 ? 0 : 30;
  3738.     var defaultExcludeStartTimeText = formatTime(defaultExcludeStartHour, defaultExcludeStartMin, Use24HourClock);
  3739.     var defaultExcludeEndTimeText = formatTime(defaultExcludeEndHour, defaultExcludeEndMinute, Use24HourClock);
  3740.     $('#MIexclude_start').val(defaultExcludeStartTimeText);
  3741.     $('#MIexclude_start_text').text(defaultExcludeStartTimeText);
  3742.     $('#MIexclude_end').val(defaultExcludeEndTimeText);
  3743.     $('#MIexclude_end_text').text(defaultExcludeEndTimeText);
  3744.  
  3745.     // Now load the schedule according to the data in crbMIScheduleInfo
  3746.     if (data.ScheduleType == CONTINUOUS) {
  3747.       $('#MIcontinuously').click();
  3748.     } else if (data.ScheduleType == ONCE_PER_DAY) {
  3749.       $('#MIdaily').click();
  3750.       var startTime = formatTime(data.StartHour, data.StartMinute, Use24HourClock);
  3751.       $('#MIbackup_start').val(startTime);
  3752.       $('#MIbackup_start_text').text(startTime);
  3753.     } else if (data.ScheduleType == EXCLUDE_HOURS) {
  3754.       $('#MIexcludeHours').click();
  3755.       var startTime = formatTime(data.StartHour, data.StartMinute, Use24HourClock);
  3756.       var endTime = formatTime(data.EndHour, data.EndMinute, Use24HourClock);
  3757.       $('#MIexclude_start').val(startTime);
  3758.       $('#MIexclude_start_text').text(startTime);
  3759.       $('#MIexclude_end').val(endTime);
  3760.       $('#MIexclude_end_text').text(endTime);
  3761.     }
  3762.   }
  3763.  
  3764.   this.UpdateTimeFields = function (scheduleType, startHour, startMinute, endHour, endMinute) {
  3765.     var startTime = formatTime(startHour, startMinute, Use24HourClock);
  3766.     var endTime = formatTime(endHour, endMinute, Use24HourClock);
  3767.     if (scheduleType == ONCE_PER_DAY) {
  3768.       $('#MIbackup_start_text').text(startTime);
  3769.     } else if (scheduleType == EXCLUDE_HOURS) {
  3770.       $('#MIexclude_start_text').text(startTime);
  3771.       $('#MIexclude_end_text').text(endTime);
  3772.     }
  3773.   }
  3774. }
  3775.  
  3776. var ScheduleSettings__ = function ()
  3777. {
  3778.     function E$(id)
  3779.     {
  3780.         return document.getElementById(id);
  3781.     }
  3782.  
  3783.     var self = this;
  3784.  
  3785.     this.Schedules = new Object;
  3786.     var scheduleNum;
  3787.     var schedule;
  3788.     var ifrPoster = null;
  3789.     var needsCommit = false;
  3790.  
  3791.     NO_SCHEDULE = 0;
  3792.     SINGLE_SCHEDULE = 1;
  3793.     MULTIPLE_SCHEDULE = 2;
  3794.     var scheduleType = NO_SCHEDULE;
  3795.  
  3796.     Sun = 0x01;
  3797.     Mon = 0x02;
  3798.     Tue = 0x04;
  3799.     Wed = 0x08;
  3800.     Thu = 0x10;
  3801.     Fri = 0x20;
  3802.     Sat = 0x40;
  3803.     EveryDay = Sun | Mon | Tue | Wed | Thu | Fri | Sat;
  3804.     Weekdays = Mon | Tue | Wed | Thu | Fri;
  3805.  
  3806.     localNav = false;
  3807.  
  3808.     /* Silence javascript errors */
  3809.     window.onerror = parent.trapError;
  3810.  
  3811.     function DefaultSchedule()
  3812.     {
  3813.         return self.Schedules[0] ? self.Schedules[0] : schedule;
  3814.     }
  3815.  
  3816.  
  3817.     function ShowHideTimeControl(sName, bShow)
  3818.     {
  3819.         var hourName = sName + "Hour";
  3820.         var minuteName = sName + "Minute";
  3821.  
  3822.         var dropdown = E$(hourName);
  3823.         dropdown.style.display = bShow ? "" : "none";
  3824.  
  3825.         dropdown = E$(minuteName);
  3826.         dropdown.style.display = bShow ? "" : "none";
  3827.  
  3828.     }
  3829.  
  3830.     function HideTimeControl(sName, timeout)
  3831.     {
  3832.         // delay before executing the hide so that this operation blends with the other effects
  3833.         setTimeout('ShowHideTimeControl("' + sName + '", false)', timeout);
  3834.     }
  3835.  
  3836.     function ShowTimeControl(sName, timeout)
  3837.     {
  3838.         // delay before executing the hide so that this operation blends with the other effects
  3839.         setTimeout('ShowHideTimeControl("' + sName + '", true)', timeout);
  3840.     }
  3841.  
  3842.     this.AdvancedScheduling = function ()
  3843.     {
  3844.         var border = 10;
  3845.  
  3846.         var over = E$('overlay');
  3847.         // stretch overlay to fill page and fade in
  3848.         var arrayPageSize = getPageSize();
  3849.         over.style.position = "absolute";
  3850.         over.style.width = arrayPageSize[0];
  3851.         over.style.height = arrayPageSize[1];
  3852.         over.style.top = 0;
  3853.         over.style.left = 0;
  3854.         over.style.display = "";
  3855.  
  3856.         var as = E$("AdvancedSchedule");
  3857.         RefreshAdvancedScheduleList();
  3858.         as.style.position = "absolute";
  3859.         as.style.width = arrayPageSize[0] - border * 2;
  3860.         as.style.height = 0; // style appears to be determining height
  3861.         as.style.top = border;
  3862.         as.style.left = border;
  3863.         as.style.display = "";
  3864.  
  3865.         // if we have no advanced rules, then open the entry screen for the first one anyway
  3866.         if(!self.Schedules[0])
  3867.             self.AddNewSchedule();
  3868.     }
  3869.  
  3870.     this.SimpleScheduling = function ()
  3871.     {
  3872.         schedule = DefaultSchedule() ? DefaultSchedule() : new Schedule();
  3873.         E$('AdvancedSchedule').style.display = "none";
  3874.         E$('overlay').style.display = "none";
  3875.     }
  3876.  
  3877.     this.AddNewSchedule = function ()
  3878.     {
  3879.         var nTotal = 0;
  3880.         while(self.Schedules[nTotal])
  3881.             nTotal++;
  3882.         self.EditSchedule(nTotal);
  3883.     }
  3884.  
  3885.     this.EditSchedule = function (num)
  3886.     {
  3887.         var as = E$("AdvancedSchedule");
  3888.         var es = E$("EditSchedule");
  3889.  
  3890.         es.style.position = as.style.position;
  3891.         es.style.width = as.style.width;
  3892.         es.style.height = as.style.height;
  3893.         es.style.top = as.style.top;
  3894.         es.style.left = as.style.left;
  3895.         GetEditSchedule(num);
  3896.         as.style.display = "none";
  3897.         es.style.display = "";
  3898.     }
  3899.  
  3900.     this.StopEdit = function ()
  3901.     {
  3902.         schedule = self.Schedules[0] ? self.Schedules[0] : new Schedule();
  3903.         scheduleNum = -1;
  3904.         RefreshAdvancedScheduleList();
  3905.         if(self.Schedules[0])
  3906.         {
  3907.             E$('EditSchedule').style.display = "none";
  3908.             E$('AdvancedSchedule').style.display = "";
  3909.         }
  3910.         else
  3911.         {
  3912.             // go all the way back to the main schedule screen
  3913.             E$('EditSchedule').style.display = "none";
  3914.             E$('AdvancedSchedule').style.display = "none";
  3915.             E$('overlay').style.display = "none";
  3916.         }
  3917.     }
  3918.  
  3919.     function GetEditSchedule(num)
  3920.     {
  3921.         // create temporary copy of schedule in placeholder
  3922.         scheduleNum = num;
  3923.         schedule = new Schedule();
  3924.         if(self.Schedules[scheduleNum])
  3925.             schedule.Parse(self.Schedules[scheduleNum].GetAsString());
  3926.  
  3927.         var editSchedule = schedule.OutputHTML(E$("ScheduleDetails"));
  3928.         var sg = E$("ScheduleGetter");
  3929.         // clean any children present - this one will need to be the only one
  3930.         while(sg.childNodes[0])
  3931.         {
  3932.             sg.removeChild(sg.childNodes[0])
  3933.         };
  3934.         sg.appendChild(editSchedule);
  3935.     }
  3936.  
  3937.     function AddOrChangeSchedule(sched, num)
  3938.     {
  3939.         var i = 0;
  3940.         var bIsUnique = true;
  3941.         while(self.Schedules[i] && bIsUnique)
  3942.         {
  3943.             bIsUnique = !self.Schedules[i].IsEqualTo(sched);
  3944.             i++;
  3945.         }
  3946.  
  3947.         if(bIsUnique)
  3948.             self.Schedules[num] = sched;
  3949.  
  3950.         return bIsUnique;
  3951.     }
  3952.  
  3953.     function SaveEditSchedule()
  3954.     {
  3955.         schedule.bUseFinishTime = true;
  3956.         var bAdded = AddOrChangeSchedule(schedule, scheduleNum);
  3957.  
  3958.         if(bAdded)
  3959.         {
  3960.             scheduleType = MULTIPLE_SCHEDULE;
  3961.             E$("Advanced").checked = true;
  3962.             self.ShowApplyButton();
  3963.             self.StopEdit();
  3964.         }
  3965.  
  3966.         return bAdded;
  3967.     }
  3968.  
  3969.     this.DeleteSchedule = function (iNum)
  3970.     {
  3971.         var i = 0;
  3972.         while(self.Schedules[i])
  3973.         {
  3974.             if(i > iNum)
  3975.                 self.Schedules[i - 1] = self.Schedules[i];
  3976.             i++;
  3977.         }
  3978.         self.Schedules[i - 1] = null;
  3979.         if(!self.Schedules[0])
  3980.         {
  3981.             scheduleType = NO_SCHEDULE;
  3982.             E$("continuously").checked = true;
  3983.         }
  3984.         self.ShowApplyButton();
  3985.         RefreshAdvancedScheduleList();
  3986.     }
  3987.  
  3988.     function PutScheduleInfo(str, onsavedfunc)
  3989.     {
  3990.         var req;
  3991.  
  3992.         try
  3993.         {
  3994.             req = new ActiveXObject("Msxml2.XMLHTTP");
  3995.         } catch(e)
  3996.         {
  3997.             req = new ActiveXObject("Microsoft.XMLHTTP");
  3998.         }
  3999.  
  4000.         // nocache=1 is so existing installations don't have an issue
  4001.         // with previously cacheable content (The http server used to
  4002.         // say that /put-schedule.htm was cacheable.  That was fixed,
  4003.         // but we want to make sure that any content left over from
  4004.         // previous builds doesn't get used.)
  4005.         var url = "/put-schedule.htm?nocache=1&" + str;
  4006.  
  4007.         req.onreadystatechange = function ()
  4008.         {
  4009.             // When the load is complete, call the save function.
  4010.             if((typeof (onsavedfunc) == 'function') && (req.readyState == 4))
  4011.             {
  4012.                 onsavedfunc();
  4013.             }
  4014.         }
  4015.  
  4016.         req.open("GET", url, false);
  4017.         req.send("");
  4018.     }
  4019.  
  4020.     function ApplyScheduleChanges(onsavedfunc)
  4021.     {
  4022.         // Prevent the user from saving if they have chosen Advanced with no scedules
  4023.         if(scheduleType & 0x02 && !self.Schedules[0])
  4024.         {
  4025.             HtmlMessageBox2("crbEmptyAdvanced", BUTTON_OK);
  4026.             return;
  4027.         }
  4028.  
  4029.         // Update top-level choice
  4030.         if(!schedule)
  4031.         {
  4032.             schedule = DefaultSchedule() ? DefaultSchedule() : new Schedule();
  4033.         }
  4034.            
  4035.         scheduleType &= ~0x04;
  4036.         if(((scheduleType & 0x02) == 0x00))
  4037.             schedule.Days = EveryDay;
  4038.         if(!self.Schedules[0] && scheduleType != NO_SCHEDULE)
  4039.             self.Schedules[0] = schedule;
  4040.         //GetPoster().src="/put-state.htm?" + BACKUP_TYPE + "=" + scheduleType;
  4041.  
  4042.         updateTimeFields(schedule);
  4043.  
  4044.         // Now save off all the schedules (even if we're not using them right now)
  4045.         var allScheds = "UpdateAll=1&" + BACKUP_TYPE + "=" + scheduleType;
  4046.  
  4047.         // Only append schedule hours if the type is not continuous (i.e. NO_SCHEDULE).
  4048.         if (scheduleType != NO_SCHEDULE)
  4049.         {
  4050.             var i = 0;
  4051.             while(self.Schedules[i])
  4052.             {
  4053.                 allScheds += "&Schedule" + i + "=" + self.Schedules[i].GetAsString();
  4054.                 i++;
  4055.             }
  4056.         }
  4057.         PutScheduleInfo(allScheds, onsavedfunc);
  4058.  
  4059.         needsCommit = false;
  4060.     }
  4061.  
  4062.     this.ShowApplyButton = function ()
  4063.     {
  4064.         needsCommit = true;
  4065.         //      var as = E$("ApplyScheduleChanges");
  4066.         //      var ac = E$("CancelScheduleChanges");
  4067.         //      if(as.style.display == "none")
  4068.         //          as.style.display = "";
  4069.         //      if(ac.style.display == "none")
  4070.         //          ac.style.display = "";
  4071.     }
  4072.  
  4073.     this.SetChoice = function (o)
  4074.     {
  4075.         // Simply store changed values for submission
  4076.         scheduleType = o.value;
  4077.  
  4078.         // update the time to reflect the selection
  4079.         switch(o.id)
  4080.         {
  4081.             case "continuously":
  4082.             case "crbScheduleDefaultRadioButton":
  4083.                 DefaultSchedule().bUseFinishTime = false;
  4084.                 break;
  4085.             case "daily":
  4086.                 var timeSelected = parseTime($('#backup_start').val());
  4087.                 if(timeSelected)
  4088.                 {
  4089.                     DefaultSchedule().SetStartTime(
  4090.                         timeSelected.hour,
  4091.                         timeSelected.minute
  4092.                     );
  4093.                 }
  4094.                 DefaultSchedule().bUseFinishTime = false;
  4095.                 break;
  4096.             case "excludeHours":
  4097.                 var excludeStart = parseTime($('#exclude_start').val());
  4098.                 if(excludeStart)
  4099.                 {
  4100.                     DefaultSchedule().SetFinishTime(
  4101.                         excludeStart.hour,
  4102.                         excludeStart.minute
  4103.                     );
  4104.                 }
  4105.                 var excludeEnd = parseTime($('#exclude_end').val());
  4106.                 if(excludeEnd)
  4107.                 {
  4108.                     DefaultSchedule().SetStartTime(
  4109.                         excludeEnd.hour,
  4110.                         excludeEnd.minute
  4111.                     );
  4112.                 }
  4113.                 DefaultSchedule().bUseFinishTime = true;
  4114.                 break;
  4115.             default:
  4116.                 break;
  4117.         }
  4118.  
  4119.         self.ShowApplyButton();
  4120.     }
  4121.  
  4122.     function RefreshAdvancedScheduleList()
  4123.     {
  4124.         var listTopNode = E$("listTopNode");
  4125.         var strInner;
  4126.         var i = 0;
  4127.         if(!self.Schedules[0])
  4128.             strInner = strNoSchedRules;
  4129.         else
  4130.         {
  4131.             strInner = strSchedRules;
  4132.             strInner += "<table class='scheduletable'>";
  4133.             while(self.Schedules[i])
  4134.             {
  4135.                 var schedEditLink = "<tr><td><a onmousedown='localNav=true;' href='javascript:ScheduleSettings.EditSchedule(" + i + ")'><span class='Bullet'>" + strBullet + "</span>" + self.Schedules[i].Description() + "</a></td><td>&nbsp;<a class='addToolTip' onmousedown='localNav=true;' href='javascript:ScheduleSettings.DeleteSchedule(" + i + ")'><font size='-2'>" + strDeleteSchedule + "</font></a></td></tr>";
  4136.                 strInner += schedEditLink;
  4137.                 i++;
  4138.             }
  4139.             strInner += "</table>";
  4140.         }
  4141.  
  4142.         listTopNode.innerHTML = strInner;
  4143.     }
  4144.  
  4145.     this.UpdateDisplay = function (sName, sValue)
  4146.     {
  4147.         switch(sName)
  4148.         {
  4149.             case DAYCHOICE:
  4150.                 E$(SPECDAY_SUN).checked = schedule.Days & Sun;
  4151.                 E$(SPECDAY_MON).checked = schedule.Days & Mon;
  4152.                 E$(SPECDAY_TUE).checked = schedule.Days & Tue;
  4153.                 E$(SPECDAY_WED).checked = schedule.Days & Wed;
  4154.                 E$(SPECDAY_THU).checked = schedule.Days & Thu;
  4155.                 E$(SPECDAY_FRI).checked = schedule.Days & Fri;
  4156.                 E$(SPECDAY_SAT).checked = schedule.Days & Sat;
  4157.                 break;
  4158.             case SPECDAY_SUN:
  4159.             case SPECDAY_MON:
  4160.             case SPECDAY_TUE:
  4161.             case SPECDAY_WED:
  4162.             case SPECDAY_THU:
  4163.             case SPECDAY_FRI:
  4164.             case SPECDAY_SAT:
  4165.                 if(schedule.Days == EveryDay)
  4166.                     E$("Every").checked = true;
  4167.                 else if(schedule.Days == Weekdays)
  4168.                     E$("Weekdays").checked = true;
  4169.                 else
  4170.                     E$("Specific").checked = true;
  4171.                 break;
  4172.             case SSTART_HOUR:
  4173.             case SSTART_MINUTE:
  4174.             case SSTART_AP:
  4175.             case SFINISH_HOUR:
  4176.             case SFINISH_MINUTE:
  4177.             case SFINISH_AP:
  4178.                 E$("excludeHours").checked = true;
  4179.                 self.SetChoice(E$("excludeHours"));
  4180.                 scheduleType = SINGLE_SCHEDULE;
  4181.                 break;
  4182.             case ONCE_HOUR:
  4183.             case ONCE_MINUTE:
  4184.             case ONCE_AP:
  4185.                 E$("daily").checked = true;
  4186.                 self.SetChoice(E$("daily"));
  4187.                 scheduleType = SINGLE_SCHEDULE | 0x04;
  4188.                 break;
  4189.             case BACKUP_TYPE:
  4190.                 switch(scheduleType)
  4191.                 {
  4192.                     case NO_SCHEDULE:
  4193.                         E$("continuously").checked = true;
  4194.                         break;
  4195.                     case SINGLE_SCHEDULE:
  4196.                         E$(DefaultSchedule().bUseFinishTime ? "excludeHours" : "daily").checked = true;
  4197.                         break;
  4198.                     case MULTIPLE_SCHEDULE:
  4199.                         E$("Advanced").checked = true;
  4200.                         break;
  4201.                 }
  4202.                 break;
  4203.         }
  4204.     }
  4205.  
  4206.     this.ProcessSave = function (o)
  4207.     {
  4208.         schedule.ProcessChange(o);
  4209.     }
  4210.  
  4211.     this.InitSimpleSchedule = function ()
  4212.     {
  4213.         schedule = DefaultSchedule() ? DefaultSchedule() : new Schedule();
  4214.  
  4215.         if(E$("crbAllowAdvancedSchedule") && eval(E$("crbAllowAdvancedSchedule").innerText))
  4216.             $('#crbAdvancedSchedule').show();
  4217.        
  4218.         if (scheduleType == SINGLE_SCHEDULE) {
  4219.             if (schedule.bUseFinishTime) {
  4220.                 $("#excludeHours").closest("li").click();
  4221.                 $("#excludeHours").attr("checked", true);
  4222.             } else {
  4223.                 $("#daily").closest("li").click();
  4224.                 $("#daily").attr("checked", true);
  4225.             }
  4226.         } else if (scheduleType == MULTIPLE_SCHEDULE) {
  4227.             $("#Advanced").closest("li").click();
  4228.             $("#Advanced").attr("checked", true);
  4229.         } else {
  4230.             $("#continuously").closest("li").click();
  4231.             $("#continuously").attr("checked", true);
  4232.         }
  4233.  
  4234.         // now set the values in the controls
  4235.         updateTimeFields(schedule);
  4236.     }
  4237.  
  4238.     function updateTimeFields(sched)
  4239.     {
  4240.         var defaultDailyBackupTime = formatTime(0, 0, Use24HourClock);
  4241.         $('#backup_start').val(defaultDailyBackupTime);
  4242.         $('#backup_start_text').text(defaultDailyBackupTime);
  4243.         var defaultExcludeStartTime = new Date();
  4244.         var defaultExcludeStartHour = defaultExcludeStartTime.getHours();
  4245.         var defaultExcludeStartMin = defaultExcludeStartTime.getMinutes() < 15 ? 0 : 30;
  4246.         var defaultExcludeEndTime = new Date();
  4247.         var defaultExcludeEndHour = (defaultExcludeEndTime.getHours() + 2) % 24;
  4248.         var defaultExcludeEndMinute = defaultExcludeEndTime.getMinutes() < 15 ? 0 : 30;
  4249.         var defaultExcludeStartTimeText = formatTime(defaultExcludeStartHour, defaultExcludeStartMin, Use24HourClock);
  4250.         var defaultExcludeEndTimeText = formatTime(defaultExcludeEndHour, defaultExcludeEndMinute, Use24HourClock);
  4251.         $('#exclude_start').val(defaultExcludeStartTimeText);
  4252.         $('#exclude_start_text').text(defaultExcludeStartTimeText);
  4253.         $('#exclude_end').val(defaultExcludeEndTimeText);
  4254.         $('#exclude_end_text').text(defaultExcludeEndTimeText);
  4255.        
  4256.         if(scheduleType == SINGLE_SCHEDULE)
  4257.         {
  4258.             if (schedule.bUseFinishTime) {
  4259.                 $('#exclude_start').val(formatTime(sched.FinishHour, sched.FinishMinute, Use24HourClock));
  4260.                 $('#exclude_start_text').text(formatTime(sched.FinishHour, sched.FinishMinute, Use24HourClock));
  4261.                 $('#exclude_end').val(formatTime(sched.StartHour, sched.StartMinute, Use24HourClock));
  4262.                 $('#exclude_end_text').text(formatTime(sched.StartHour, sched.StartMinute, Use24HourClock));
  4263.             } else {
  4264.                 $('#backup_start').val(formatTime(sched.StartHour, sched.StartMinute, Use24HourClock));
  4265.                 $('#backup_start_text').text(formatTime(sched.StartHour, sched.StartMinute, Use24HourClock));
  4266.             }
  4267.         }
  4268.     }
  4269.  
  4270.     function checkUnsaved()
  4271.     {
  4272.         if(!localNav && needsCommit && BUTTON_YES == HtmlMessageBox2("crbUnsavedSchedule", BUTTONS_YESNO))
  4273.             ApplyScheduleChanges();
  4274.         localNav = false;
  4275.     }
  4276.  
  4277.     function ValidityTest()
  4278.     {
  4279.         var bValid = schedule.IsValidTimeWindow();
  4280.         var bNoDays = schedule.Days == 0;
  4281.         if(!bValid || bNoDays)
  4282.         {
  4283.             HtmlMessageBox2(bNoDays ? "crbNoDaysChosen" : "crbInvalidTimeSpan", BUTTON_OK);
  4284.             needsCommit = false;
  4285.         }
  4286.         return bValid && !bNoDays;
  4287.     }
  4288.  
  4289.     this.SaveEdit = function ()
  4290.     {
  4291.         if(ValidityTest() && !SaveEditSchedule())
  4292.             HtmlMessageBox2("crbDuplicateSchedule", BUTTON_OK);
  4293.     }
  4294.  
  4295.     this.ApplyChanges = function (onsavedfunc)
  4296.     {
  4297.         if(scheduleType != SINGLE_SCHEDULE || ValidityTest())
  4298.             ApplyScheduleChanges(onsavedfunc);
  4299.     }
  4300.  
  4301.     this.SetCurrentSchedule = function (schedValue)
  4302.     {
  4303.         schedule = schedValue;
  4304.     }
  4305.  
  4306.     this.SetCurrentScheduleType = function (typeValue)
  4307.     {
  4308.         scheduleType = typeValue;
  4309.     }
  4310.  
  4311.     this.GetCurrentSchedule = function ()
  4312.     {
  4313.         return schedule;
  4314.     }
  4315. }
  4316.  
  4317. var ScheduleSettings = new ScheduleSettings__();
  4318. var MIScheduleSettings = new MIScheduleSettings__();
  4319. /* End included file /js/schedule.js */
  4320.  
  4321. // defines openOrderWithVerification
  4322. /* Carbonite Service included file /js/alert.js */
  4323. // (c) Carbonite, Inc., 2005-2009 All rights reserved
  4324. /* Carbonite Service included file /scripts/progressmeter.class.js */
  4325. // (c) Carbonite, Inc., 2005-2009 All rights reserved
  4326.  
  4327. var DEFAULT_INCREMENT_PAUSE = 25;
  4328.  
  4329. ProgressMeter = function(barObj, valueField, initialPause)
  4330. {
  4331.     this.bar = barObj;
  4332.     this.target = (null != barObj) ? barObj.firstChild : null;
  4333.     this.maxWidth = this.bar.offsetWidth - 2; // track the maximum width, so that we do not bump it up by more than this
  4334.     this.valueField = valueField;
  4335.    
  4336.     this.newWidth = 0;
  4337.     this.pctDone = 0;
  4338.     this.incrementPause = null;
  4339.     this.SetIncrementInterval(initialPause);
  4340.    
  4341.     var self = this;
  4342.     this.IncrementProgress = function()
  4343.     {
  4344.         if (self.target && self.target.offsetWidth < self.newWidth)
  4345.         {
  4346.             self.target.style.width = (self.target.offsetWidth < self.maxWidth) ? self.target.offsetWidth + 1 : self.maxWidth;
  4347.            
  4348.             if (self.target.offsetWidth < self.newWidth)
  4349.                 setTimeout(self.IncrementProgress, self.incrementPause);
  4350.         }
  4351.        
  4352.         self.UpdateValueField();
  4353.     }
  4354. }
  4355.  
  4356. ProgressMeter.prototype.UpdateValueField = function()
  4357. {
  4358.     if (this.valueField) {
  4359.         var visiblePercentage = (Math.round((this.target.offsetWidth * 100) / this.maxWidth));
  4360.         if (visiblePercentage >= 100 && this.pctDone < 100) {
  4361.             visiblePercentage = 99.99; // it's so close to being done, but not quite there
  4362.         }
  4363.         if (this.target.offsetWidth < this.newWidth) {
  4364.             this.valueField.innerText = visiblePercentage + "%";
  4365.         }
  4366.         else {
  4367.             // Something is wrong with the indicator, but let's at least
  4368.             // make the number look correct.
  4369.             this.valueField.innerText = this.pctDone + "%";
  4370.         }
  4371.     }
  4372. }
  4373.  
  4374. ProgressMeter.prototype.SetProgressMeter = function(pctDone)
  4375. {
  4376.     // quick return if we're already reflecting this value
  4377.     if (this.pctDone == pctDone)
  4378.         return;
  4379.    
  4380.     if (this.target && this.bar)
  4381.     {
  4382.         var prevPctDone = this.pctDone;
  4383.         this.pctDone = (pctDone > 100) ? 100 : ((pctDone < 0) ? 0 : pctDone);
  4384.         var isDownshift = prevPctDone > this.pctDone;
  4385.        
  4386.         // Ensure that the target and the bar are visible
  4387.         this.bar.style.display = "";
  4388.         this.target.style.display = "";
  4389.        
  4390.         // if we had't yet reached the previous limit, bump up and decrease the pause
  4391.         if (this.target.offsetWidth < this.newWidth)
  4392.         {
  4393.             this.target.style.width = this.newWidth;
  4394.             this.incrementPause -= parseInt(this.incrementPause / 10);
  4395.         }
  4396.         else if (this.newWidth > 0)
  4397.             this.incrementPause += parseInt(this.incrementPause / 10);
  4398.        
  4399.         this.newWidth = parseInt(this.maxWidth * (this.pctDone / 100));
  4400.         if (this.pctDone == 100 || isDownshift)
  4401.         {
  4402.             this.target.style.width = this.newWidth;
  4403.             this.UpdateValueField();
  4404.         }
  4405.         else
  4406.             this.IncrementProgress();
  4407.     }
  4408. }
  4409.  
  4410. ProgressMeter.prototype.SetIncrementInterval = function(newIncrement)
  4411. {
  4412.     this.incrementPause = (null != newIncrement) ? newIncrement : DEFAULT_INCREMENT_PAUSE;
  4413. }
  4414.  
  4415. ////////
  4416.  
  4417. ProgressMercuryMeter = function(barObj, valueField, initialValue, initialPause)
  4418. {
  4419.     this.initialized = false;
  4420.     this.bar = barObj;
  4421.     // There are two children. The first one draws the border and the
  4422.     // second one draws the mercury.
  4423.     var mercuryBorder = (null != barObj) ? barObj.firstChild : null;
  4424.     var progressMercury = (null != barObj) ? barObj.lastChild : null;
  4425.     var leftImg = null;
  4426.     var centerImg = null;
  4427.     var rightImg = null;
  4428.     var leftWidth = 0;
  4429.     var centerWidth = 0;
  4430.     var rightWidth = 0;
  4431.     if (progressMercury != null && (mercuryBorder != progressMercury)) {
  4432.         var borderImgs = mercuryBorder.getElementsByTagName("IMG");
  4433.         var mercuryImgs = progressMercury.getElementsByTagName("IMG");
  4434.         if ((3 == borderImgs.length) && (3 == mercuryImgs.length)) {
  4435.             // Assume hight is same for all the three image elements.
  4436.             leftWidth = borderImgs[0].width;
  4437.             centerWidth = borderImgs[1].width;
  4438.             rightWidth = borderImgs[2].width;
  4439.             leftImg = mercuryImgs[0];
  4440.             centerImg = mercuryImgs[1];
  4441.             rightImg = mercuryImgs[2];
  4442.             // We are just starting so set the width of all the three
  4443.             // images to 0 width.
  4444.             leftImg.style.width = 0 + "px";
  4445.             centerImg.style.width = 0 + "px";
  4446.             rightImg.style.width = 0 + "px";
  4447.             leftImg.style.height = borderImgs[0].height;
  4448.             centerImg.style.height = borderImgs[1].height;
  4449.             rightImg.style.height = borderImgs[2].height;
  4450.         }
  4451.         else {
  4452.             progressMercury = null;
  4453.         }
  4454.     }
  4455.     this.leftWidth = leftWidth;
  4456.     this.centerWidth = centerWidth;
  4457.     this.rightWidth = rightWidth;
  4458.  
  4459.     this.leftImg = leftImg;
  4460.     this.centerImg = centerImg;
  4461.     this.rightImg = rightImg;
  4462.     this.progressMercury = progressMercury;
  4463.     // Track the maximum width, so that we do not bump it up by more than this.
  4464.     this.maxWidth = (null != this.bar) ? this.bar.offsetWidth : 0;
  4465.     this.valueField = valueField;
  4466.     this.newWidth = 0;
  4467.     this.pctDone = 0;
  4468.     this.incrementPause = null;
  4469.     this.SetIncrementInterval(initialPause);
  4470.     var self = this;
  4471.     this.IncrementProgress = function()
  4472.     {
  4473.         if (!self.hasImages()) {
  4474.             return;
  4475.         }
  4476.         var offsetWidth = self.getOffsetWidth();
  4477.         if (offsetWidth <= self.newWidth) {
  4478.             var currWidth = (offsetWidth < self.maxWidth) ? offsetWidth + 1 : self.maxWidth;
  4479.             self.distributeWidth(currWidth, self);
  4480.             if (offsetWidth < self.newWidth) {
  4481.                 setTimeout(self.IncrementProgress, self.incrementPause);
  4482.             }
  4483.         }
  4484.  
  4485.         self.UpdateValueField();
  4486.     }
  4487.  
  4488.     if (initialValue === undefined || isNaN(initialValue)) {
  4489.         initialValue = 0;
  4490.     }
  4491.     this.SetProgressMeter(initialValue, true);
  4492.     this.initialized = true;
  4493. }
  4494.  
  4495. ProgressMercuryMeter.prototype.hasImages = function()
  4496. {
  4497.     return (null != this.progressMercury);
  4498. }
  4499.  
  4500. ProgressMercuryMeter.prototype.getOffsetWidth = function()
  4501. {
  4502.     var width = 0;
  4503.     if (this.hasImages()) {
  4504.         width = this.leftImg.width + this.centerImg.width + this.rightImg.width;
  4505.     }
  4506.     return width;
  4507. }
  4508.  
  4509. ProgressMercuryMeter.prototype.UpdateValueField = function()
  4510. {
  4511.     if (this.valueField) {
  4512.         var visiblePercentage = (Math.round((this.getOffsetWidth() * 100) / this.maxWidth));
  4513.         if (visiblePercentage >= 100 && this.pctDone < 100) {
  4514.             // It's so close to being done, but not quite there.
  4515.             visiblePercentage = 99.99;
  4516.         }
  4517.         if (this.getOffsetWidth() < this.newWidth) {
  4518.             this.valueField.innerText = visiblePercentage + "%";
  4519.         }
  4520.         else {
  4521.             // Something is wrong with the indicator, but let's at least
  4522.             // make the number look correct.
  4523.             this.valueField.innerText = this.pctDone + "%";
  4524.         }
  4525.     }
  4526. }
  4527.  
  4528. ProgressMercuryMeter.prototype.distributeWidth = function(width, self)
  4529. {
  4530.     var leftImg = self.leftImg
  4531.     var centerImg = self.centerImg
  4532.     var rightImg = self.rightImg
  4533.     // Distribute this width to the three images.
  4534.     if (width <= self.leftWidth) {
  4535.         leftImg.style.width = Math.max(width, 0) + "px";
  4536.         centerImg.style.width = "0px";
  4537.         rightImg.style.width = "0px";
  4538.     }
  4539.     else if (width <= self.leftWidth + self.rightWidth) {
  4540.         leftImg.style.width = self.leftWidth;
  4541.         centerImg.style.width = "0px";
  4542.         rightImg.style.width = (width - self.leftWidth) + "px";
  4543.     }
  4544.     else {
  4545.         var edgeWidth = self.leftWidth + self.rightWidth;
  4546.         leftImg.style.width = self.leftWidth;
  4547.         centerImg.style.width = Math.min((width - edgeWidth), self.centerWidth) + "px";
  4548.         rightImg.style.width = self.rightWidth;
  4549.     }
  4550. }
  4551.  
  4552. ProgressMercuryMeter.prototype.SetProgressMeter = function(pctDone, force)
  4553. {
  4554.     // quick return if we're already reflecting this value
  4555.     if (this.initialized && this.pctDone == pctDone) {
  4556.         return;
  4557.     }
  4558.  
  4559.     if (!force) {
  4560.         // If the last value is <= 0 then force anyway.
  4561.         force = this.pctDone <= 0;
  4562.     }
  4563.  
  4564.     if (this.hasImages() && this.bar) {
  4565.         var prevPctDone = this.pctDone;
  4566.         this.pctDone = (pctDone > 100) ? 100 : ((pctDone < 0) ? 0 : pctDone);
  4567.         var isDownshift = prevPctDone > this.pctDone;
  4568.         // Ensure that the target and the bar are visible.
  4569.         this.bar.style.display = "";
  4570.         this.progressMercury.style.display = "";
  4571.         // If we had't yet reached the previous limit, bump up and decrease
  4572.         // the pause.
  4573.         if (this.getOffsetWidth() < this.newWidth) {
  4574.             this.distributeWidth(this.newWidth, this);
  4575.             this.incrementPause -= parseInt(this.incrementPause / 10);
  4576.         }
  4577.         else if (this.newWidth > 0) {
  4578.             this.incrementPause += parseInt(this.incrementPause / 10);
  4579.         }
  4580.         this.newWidth = parseInt(this.maxWidth * (this.pctDone / 100));
  4581.         if (force || this.pctDone == 100 || isDownshift) {
  4582.             this.distributeWidth(this.newWidth, this);
  4583.             this.UpdateValueField();
  4584.         }
  4585.         else {
  4586.             this.IncrementProgress();
  4587.         }
  4588.     }
  4589. }
  4590.  
  4591. ProgressMercuryMeter.prototype.SetIncrementInterval = function(newIncrement)
  4592. {
  4593.     this.incrementPause = (null != newIncrement) ? newIncrement : DEFAULT_INCREMENT_PAUSE;
  4594. }
  4595.  
  4596.  
  4597.  
  4598.  
  4599.  
  4600.  
  4601.  
  4602. /* End included file /scripts/progressmeter.class.js */
  4603. /* Carbonite Service SKIPPING already included file /scripts/serviceinterconnect.js */
  4604.  
  4605. /* Carbonite Service SKIPPING already included file /scripts/commonfunctions.js */
  4606.  
  4607. /* Carbonite Service SKIPPING already included file /scripts/messagebox.js */
  4608.  
  4609. /* Carbonite Service included file /scripts/numberformat.js */
  4610. // (c) Carbonite, Inc., 2005-2009 All rights reserved
  4611. /* Carbonite Service SKIPPING already included file /js/config.js */
  4612.  
  4613.  
  4614. /* If comma-formatting is turned on, format the display of the input element */
  4615. function crbFormatNumber(eltName)
  4616. {
  4617.     if (Config.useNumberFormatting())
  4618.     {
  4619.         if (null != (elt = document.getElementById(eltName)))
  4620.             elt.innerHTML = new NumberFormat(elt.innerHTML).toFormatted();
  4621.     }
  4622. }
  4623.  
  4624. function jqFormatNumber(jQueryObj)
  4625. {
  4626.     if(Config.useNumberFormatting())
  4627.     {
  4628.         var existingValue = jQueryObj.html();
  4629.         jQueryObj.html(new NumberFormat(existingValue).toFormatted());
  4630.     }
  4631. }
  4632.  
  4633. function NumberFormat(num, inputDecimal)
  4634. {
  4635.     this.VERSION = 'Number Format v1.5.4';
  4636.     this.COMMA = Config.thousandsSeparator();
  4637.     this.PERIOD = Config.decimalSeparator();
  4638.     this.DASH = '-';
  4639.     this.LEFT_PAREN = '(';
  4640.     this.RIGHT_PAREN = ')';
  4641.     this.LEFT_OUTSIDE = 0;
  4642.     this.LEFT_INSIDE = 1;
  4643.     this.RIGHT_INSIDE = 2;
  4644.     this.RIGHT_OUTSIDE = 3;
  4645.     this.LEFT_DASH = 0;
  4646.     this.RIGHT_DASH = 1;
  4647.     this.PARENTHESIS = 2;
  4648.     this.NO_ROUNDING = -1
  4649.     this.num;
  4650.     this.numOriginal;
  4651.     this.hasSeparators = false;
  4652.     this.separatorValue;
  4653.     this.inputDecimalValue;
  4654.     this.decimalValue;
  4655.     this.negativeFormat;
  4656.     this.negativeRed;
  4657.     this.hasCurrency;
  4658.     this.currencyPosition;
  4659.     this.currencyValue;
  4660.     this.places;
  4661.     this.roundToPlaces;
  4662.     this.truncate;
  4663.     this.setNumber = setNumberNF;
  4664.     this.toUnformatted = toUnformattedNF;
  4665.     this.setInputDecimal = setInputDecimalNF;
  4666.     this.setSeparators = setSeparatorsNF;
  4667.     this.setCommas = setCommasNF;
  4668.     this.setNegativeFormat = setNegativeFormatNF;
  4669.     this.setNegativeRed = setNegativeRedNF;
  4670.     this.setCurrency = setCurrencyNF;
  4671.     this.setCurrencyPrefix = setCurrencyPrefixNF;
  4672.     this.setCurrencyValue = setCurrencyValueNF;
  4673.     this.setCurrencyPosition = setCurrencyPositionNF;
  4674.     this.setPlaces = setPlacesNF;
  4675.     this.toFormatted = toFormattedNF;
  4676.     this.toPercentage = toPercentageNF;
  4677.     this.getOriginal = getOriginalNF;
  4678.     this.moveDecimalRight = moveDecimalRightNF;
  4679.     this.moveDecimalLeft = moveDecimalLeftNF;
  4680.     this.getRounded = getRoundedNF;
  4681.     this.preserveZeros = preserveZerosNF;
  4682.     this.justNumber = justNumberNF;
  4683.     this.expandExponential = expandExponentialNF;
  4684.     this.getZeros = getZerosNF;
  4685.     this.moveDecimalAsString = moveDecimalAsStringNF;
  4686.     this.moveDecimal = moveDecimalNF;
  4687.     this.addSeparators = addSeparatorsNF;
  4688.    
  4689.     if (inputDecimal == null)
  4690.     {
  4691.         this.setNumber(num, this.PERIOD);
  4692.     }
  4693.     else
  4694.     {
  4695.         this.setNumber(num, inputDecimal);
  4696.     }
  4697.    
  4698.     this.setCommas(true);
  4699.     this.setNegativeFormat(this.LEFT_DASH);
  4700.     this.setNegativeRed(false);
  4701.     this.setCurrency(false);
  4702.     this.setCurrencyPrefix('$');
  4703.     this.setPlaces(0);
  4704. }
  4705.  
  4706. function setInputDecimalNF(val)
  4707. {
  4708.     this.inputDecimalValue = val;
  4709. }
  4710.  
  4711. function setNumberNF(num, inputDecimal)
  4712. {
  4713.     if (inputDecimal != null)
  4714.     {
  4715.         this.setInputDecimal(inputDecimal);
  4716.     }
  4717.     this.numOriginal = num;
  4718.     this.num = this.justNumber(num);
  4719. }
  4720.  
  4721. function toUnformattedNF()
  4722. {
  4723.     return (this.num);
  4724. }
  4725.  
  4726. function getOriginalNF()
  4727. {
  4728.     return (this.numOriginal);
  4729. }
  4730.  
  4731. function setNegativeFormatNF(format)
  4732. {
  4733.     this.negativeFormat = format;
  4734. }
  4735.  
  4736. function setNegativeRedNF(isRed)
  4737. {
  4738.     this.negativeRed = isRed;
  4739. }
  4740.  
  4741. function setSeparatorsNF(isC, separator, decimal)
  4742. {
  4743.     this.hasSeparators = isC;
  4744.     if (separator == null)
  4745.         separator = this.COMMA;
  4746.     if (decimal == null)
  4747.         decimal = this.PERIOD;
  4748.     if (separator == decimal)
  4749.     {
  4750.         this.decimalValue = (decimal == this.PERIOD) ? this.COMMA : this.PERIOD;
  4751.     }
  4752.     else
  4753.     {
  4754.         this.decimalValue = decimal;
  4755.     }
  4756.     this.separatorValue = separator;
  4757. }
  4758.  
  4759. function setCommasNF(isC)
  4760. {
  4761.     this.setSeparators(isC, this.COMMA, this.PERIOD);
  4762. }
  4763.  
  4764. function setCurrencyNF(isC)
  4765. {
  4766.     this.hasCurrency = isC;
  4767. }
  4768.  
  4769. function setCurrencyValueNF(val)
  4770. {
  4771.     this.currencyValue = val;
  4772. }
  4773.  
  4774. function setCurrencyPrefixNF(cp)
  4775. {
  4776.     this.setCurrencyValue(cp);
  4777.     this.setCurrencyPosition(this.LEFT_OUTSIDE);
  4778. }
  4779.  
  4780. function setCurrencyPositionNF(cp)
  4781. {
  4782.     this.currencyPosition = cp;
  4783. }
  4784.  
  4785. function setPlacesNF(p, tr)
  4786. {
  4787.     this.roundToPlaces = !(p == this.NO_ROUNDING);
  4788.     this.truncate = (tr != null && tr);
  4789.     this.places = (p < 0) ? 0 : p;
  4790. }
  4791.  
  4792. function addSeparatorsNF(nStr, inD, outD, sep)
  4793. {
  4794.     nStr += '';
  4795.     var dpos = nStr.indexOf(inD);
  4796.     var nStrEnd = '';
  4797.     if (dpos != -1)
  4798.     {
  4799.         nStrEnd = outD + nStr.substring(dpos + 1, nStr.length);
  4800.         nStr = nStr.substring(0, dpos);
  4801.     }
  4802.     var rgx = /(\d+)(\d{3})/;
  4803.     while (rgx.test(nStr))
  4804.     {
  4805.         nStr = nStr.replace(rgx, '$1' + sep + '$2');
  4806.     }
  4807.     return nStr + nStrEnd;
  4808. }
  4809.  
  4810. function toFormattedNF()
  4811. {
  4812.     var pos;
  4813.     var nNum = this.num;
  4814.     var nStr;
  4815.     var splitString = new Array(2);
  4816.     if (this.roundToPlaces)
  4817.     {
  4818.         nNum = this.getRounded(nNum);
  4819.         nStr = this.preserveZeros(Math.abs(nNum));
  4820.     }
  4821.     else
  4822.     {
  4823.         nStr = this.expandExponential(Math.abs(nNum));
  4824.     }
  4825.     if (this.hasSeparators)
  4826.     {
  4827.         nStr = this.addSeparators(nStr, this.PERIOD, this.decimalValue, this.separatorValue);
  4828.     }
  4829.     else
  4830.     {
  4831.         nStr = nStr.replace(new RegExp('\\' + this.PERIOD), this.decimalValue);
  4832.     }
  4833.    
  4834.     var c0 = '';
  4835.     var n0 = '';
  4836.     var c1 = '';
  4837.     var n1 = '';
  4838.     var n2 = '';
  4839.     var c2 = '';
  4840.     var n3 = '';
  4841.     var c3 = '';
  4842.     var negSignL = (this.negativeFormat == this.PARENTHESIS) ? this.LEFT_PAREN : this.DASH;
  4843.     var negSignR = (this.negativeFormat == this.PARENTHESIS) ? this.RIGHT_PAREN : this.DASH;
  4844.     if (this.currencyPosition == this.LEFT_OUTSIDE)
  4845.     {
  4846.         if (nNum < 0)
  4847.         {
  4848.             if (this.negativeFormat == this.LEFT_DASH || this.negativeFormat == this.PARENTHESIS)
  4849.                 n1 = negSignL;
  4850.             if (this.negativeFormat == this.RIGHT_DASH || this.negativeFormat == this.PARENTHESIS)
  4851.                 n2 = negSignR;
  4852.         }
  4853.         if (this.hasCurrency)
  4854.             c0 = this.currencyValue;
  4855.     }
  4856.     else if (this.currencyPosition == this.LEFT_INSIDE)
  4857.     {
  4858.         if (nNum < 0)
  4859.         {
  4860.             if (this.negativeFormat == this.LEFT_DASH || this.negativeFormat == this.PARENTHESIS)
  4861.                 n0 = negSignL;
  4862.             if (this.negativeFormat == this.RIGHT_DASH || this.negativeFormat == this.PARENTHESIS)
  4863.                 n3 = negSignR;
  4864.         }
  4865.         if (this.hasCurrency)
  4866.             c1 = this.currencyValue;
  4867.     }
  4868.     else if (this.currencyPosition == this.RIGHT_INSIDE)
  4869.     {
  4870.         if (nNum < 0)
  4871.         {
  4872.             if (this.negativeFormat == this.LEFT_DASH || this.negativeFormat == this.PARENTHESIS)
  4873.                 n0 = negSignL;
  4874.             if (this.negativeFormat == this.RIGHT_DASH || this.negativeFormat == this.PARENTHESIS)
  4875.                 n3 = negSignR;
  4876.         }
  4877.         if (this.hasCurrency)
  4878.             c2 = this.currencyValue;
  4879.     }
  4880.     else if (this.currencyPosition == this.RIGHT_OUTSIDE)
  4881.     {
  4882.         if (nNum < 0)
  4883.         {
  4884.             if (this.negativeFormat == this.LEFT_DASH || this.negativeFormat == this.PARENTHESIS)
  4885.                 n1 = negSignL;
  4886.             if (this.negativeFormat == this.RIGHT_DASH || this.negativeFormat == this.PARENTHESIS)
  4887.                 n2 = negSignR;
  4888.         }
  4889.         if (this.hasCurrency)
  4890.             c3 = this.currencyValue;
  4891.     }
  4892.     nStr = c0 + n0 + c1 + n1 + nStr + n2 + c2 + n3 + c3;
  4893.     if (this.negativeRed && nNum < 0)
  4894.     {
  4895.         nStr = '<font color="red">' + nStr + '</font>';
  4896.     }
  4897.     return (nStr);
  4898. }
  4899.  
  4900. function toPercentageNF()
  4901. {
  4902.     nNum = this.num * 100;
  4903.     nNum = this.getRounded(nNum);
  4904.     return nNum + '%';
  4905. }
  4906.  
  4907. function getZerosNF(places)
  4908. {
  4909.     var extraZ = '';
  4910.     var i;
  4911.     for (i = 0; i < places; i++)
  4912.     {
  4913.         extraZ += '0';
  4914.     }
  4915.     return extraZ;
  4916. }
  4917.  
  4918. function expandExponentialNF(origVal)
  4919. {
  4920.     if (isNaN(origVal))
  4921.         return origVal;
  4922.     var newVal = parseFloat(origVal) + '';
  4923.     var eLoc = newVal.toLowerCase().indexOf('e');
  4924.     if (eLoc != -1)
  4925.     {
  4926.         var plusLoc = newVal.toLowerCase().indexOf('+');
  4927.         var negLoc = newVal.toLowerCase().indexOf('-', eLoc);
  4928.         var justNumber = newVal.substring(0, eLoc);
  4929.         if (negLoc != -1)
  4930.         {
  4931.             var places = newVal.substring(negLoc + 1, newVal.length);
  4932.             justNumber = this.moveDecimalAsString(justNumber, true, parseInt(places));
  4933.         }
  4934.         else
  4935.         {
  4936.             if (plusLoc == -1)
  4937.                 plusLoc = eLoc;
  4938.             var places = newVal.substring(plusLoc + 1, newVal.length);
  4939.             justNumber = this.moveDecimalAsString(justNumber, false, parseInt(places));
  4940.         }
  4941.         newVal = justNumber;
  4942.     }
  4943.     return newVal;
  4944. }
  4945.  
  4946. function moveDecimalRightNF(val, places)
  4947. {
  4948.     var newVal = '';
  4949.     if (places == null)
  4950.         newVal = this.moveDecimal(val, false);
  4951.     else
  4952.         newVal = this.moveDecimal(val, false, places);
  4953.    
  4954.     return newVal;
  4955. }
  4956.  
  4957. function moveDecimalLeftNF(val, places)
  4958. {
  4959.     var newVal = '';
  4960.     if (places == null)
  4961.         newVal = this.moveDecimal(val, true);
  4962.     else
  4963.         newVal = this.moveDecimal(val, true, places);
  4964.    
  4965.     return newVal;
  4966. }
  4967.  
  4968. function moveDecimalAsStringNF(val, left, places)
  4969. {
  4970.     var spaces = (arguments.length < 3) ? this.places : places;
  4971.     if (spaces <= 0)
  4972.         return val;
  4973.     var newVal = val + '';
  4974.     var extraZ = this.getZeros(spaces);
  4975.     var re1 = new RegExp('([0-9.]+)');
  4976.     if (left)
  4977.     {
  4978.         newVal = newVal.replace(re1, extraZ + '$1');
  4979.         var re2 = new RegExp('(-?)([0-9]*)([0-9]{' + spaces + '})(\\.?)');
  4980.         newVal = newVal.replace(re2, '$1$2.$3');
  4981.     }
  4982.     else
  4983.     {
  4984.         var reArray = re1.exec(newVal);
  4985.         if (reArray != null)
  4986.         {
  4987.             newVal = newVal.substring(0, reArray.index) + reArray[1] + extraZ + newVal.substring(reArray.index + reArray[0].length);
  4988.         }
  4989.         var re2 = new RegExp('(-?)([0-9]*)(\\.?)([0-9]{' + spaces + '})');
  4990.         newVal = newVal.replace(re2, '$1$2$4.');
  4991.     }
  4992.     newVal = newVal.replace(/\.$/, '');
  4993.     return newVal;
  4994. }
  4995.  
  4996. function moveDecimalNF(val, left, places)
  4997. {
  4998.     var newVal = '';
  4999.     if (places == null)
  5000.         newVal = this.moveDecimalAsString(val, left);
  5001.     else
  5002.         newVal = this.moveDecimalAsString(val, left, places);
  5003.    
  5004.     return parseFloat(newVal);
  5005. }
  5006.  
  5007. function getRoundedNF(val)
  5008. {
  5009.     val = this.moveDecimalRight(val);
  5010.     if (this.truncate)
  5011.         val = val >= 0 ? Math.floor(val) : Math.ceil(val);
  5012.     else
  5013.         val = Math.round(val);
  5014.    
  5015.     val = this.moveDecimalLeft(val);
  5016.     return val;
  5017. }
  5018.  
  5019. function preserveZerosNF(val)
  5020. {
  5021.     var i;
  5022.     val = this.expandExponential(val);
  5023.     if (this.places <= 0)
  5024.         return val;
  5025.     var decimalPos = val.indexOf('.');
  5026.     if (decimalPos == -1)
  5027.     {
  5028.         val += '.';
  5029.         for (i = 0; i < this.places; i++)
  5030.         {
  5031.             val += '0';
  5032.         }
  5033.     }
  5034.     else
  5035.     {
  5036.         var actualDecimals = (val.length - 1) - decimalPos;
  5037.         var difference = this.places - actualDecimals;
  5038.         for (i = 0; i < difference; i++)
  5039.         {
  5040.             val += '0';
  5041.         }
  5042.     }
  5043.     return val;
  5044. }
  5045.  
  5046. function justNumberNF(val)
  5047. {
  5048.     newVal = val + '';
  5049.     var isPercentage = false;
  5050.     if (newVal.indexOf('%') != -1)
  5051.     {
  5052.         newVal = newVal.replace(/\%/g, '');
  5053.         isPercentage = true;
  5054.     }
  5055.    
  5056.     var re = new RegExp('[^\\' + this.inputDecimalValue + '\\d\\-\\+\\(\\)eE]', 'g');
  5057.     newVal = newVal.replace(re, '');
  5058.     var tempRe = new RegExp('[' + this.inputDecimalValue + ']', 'g');
  5059.     var treArray = tempRe.exec(newVal);
  5060.     if (treArray != null)
  5061.     {
  5062.         var tempRight = newVal.substring(treArray.index + treArray[0].length);
  5063.         newVal = newVal.substring(0, treArray.index) + this.PERIOD + tempRight.replace(tempRe, '');
  5064.     }
  5065.     if (newVal.charAt(newVal.length - 1) == this.DASH)
  5066.     {
  5067.         newVal = newVal.substring(0, newVal.length - 1);
  5068.         newVal = '-' + newVal;
  5069.     }
  5070.     else if (newVal.charAt(0) == this.LEFT_PAREN && newVal.charAt(newVal.length - 1) == this.RIGHT_PAREN)
  5071.     {
  5072.         newVal = newVal.substring(1, newVal.length - 1);
  5073.         newVal = '-' + newVal;
  5074.     }
  5075.     newVal = parseFloat(newVal);
  5076.     if (!isFinite(newVal))
  5077.     {
  5078.         newVal = 0;
  5079.     }
  5080.     if (isPercentage)
  5081.     {
  5082.         newVal = this.moveDecimalLeft(newVal, 2);
  5083.     }
  5084.     return newVal;
  5085. }
  5086.  
  5087. /* End included file /scripts/numberformat.js */
  5088. /* Carbonite Service included file /scripts/objectjson.js */
  5089. // (c) Carbonite, Inc., 2005-2011 All rights reserved
  5090. // Convert JSON string contents to a real object
  5091. function ObjectJSON(sJSON)
  5092. {
  5093.     // try catch handling to work around a bug in IE9 - trim does not remove a final
  5094.     // control character within the string, but it does in other IE flavours
  5095.     try
  5096.     {
  5097.         eval('var jObj = ' + sJSON + ';');
  5098.     }
  5099.     catch(e)
  5100.     {
  5101.         eval('var jObj = ' + sJSON.substring(0, sJSON.length - 1) + ';');
  5102.     }
  5103.     return jObj;
  5104. }
  5105.  
  5106. function FormatDate(timeAmount)
  5107. {
  5108.     if (timeAmount == null) return null;
  5109.  
  5110.     var date = new Date(timeAmount);
  5111.     return date.toLocaleDateString() + " " + date.toLocaleTimeString();
  5112. }
  5113.  
  5114. /* ObjectWrapperBase
  5115.  
  5116.     If JSON does not always include all fields for an object, it is up to the consumer to assume null if not present
  5117.     This leads to a lot of client code that tests whether all items in the path are present:
  5118.     e.g.
  5119.  
  5120.         if(obj.A && obj.A.x && obj.A.x.P)
  5121.             m = obj.A.x.P;
  5122.  
  5123.     ObjectWrapperBase allows one to predeclare member names, and have them prefilled with null
  5124.     so as to avoid constant checking of existence.
  5125.  
  5126.             m = objWrap.P; // will be null if any of the items above are null
  5127. */
  5128. ObjectWrapperBase = function()
  5129. {
  5130.     this.baseObj = null;
  5131. }
  5132.  
  5133. ObjectWrapperBase.prototype.setObject = function (obj, doMapAllProperties)
  5134. {
  5135.     // default to map all properties - pass "false" to doMap in order to specify map if desired
  5136.     if (null == doMapAllProperties) doMapAllProperties = true;
  5137.  
  5138.     this.baseObj = obj;
  5139.  
  5140.     if (doMapAllProperties)
  5141.         this.mapAllProperties();
  5142. }
  5143.  
  5144. // Find the child within the underlying object, or return null if child path is invalid
  5145. ObjectWrapperBase.prototype.FindChild = function (objPath)
  5146. {
  5147.     if (null == this.baseObj) return null;
  5148.  
  5149.     var objCheck = objPath.split('.');
  5150.     var objName = "this.baseObj";
  5151.     var ok = null;
  5152.  
  5153.     for (var i = 0; i < objCheck.length; i++)
  5154.     {
  5155.         objName += "." + objCheck[i];
  5156.         try
  5157.         {
  5158.             ok = eval(objName);
  5159.         }
  5160.         catch (e)
  5161.         {
  5162.             ok = null;
  5163.         }
  5164.  
  5165.         if (null == ok) return null;
  5166.     }
  5167.  
  5168.     return ok;
  5169. }
  5170.  
  5171. // call FindChild for to map properies in the underlying object and the exposed object
  5172. ObjectWrapperBase.prototype.mapProperties = function (mapArray)
  5173. {
  5174.     for (var i = 0; i < mapArray.length; ++i)
  5175.     {
  5176.         var wrappedName = (mapArray[i].length < 2) ? mapArray[i][0] : mapArray[i][1];
  5177.         eval("this." + mapArray[i][0] + " = this.FindChild('" + wrappedName + "');");
  5178.     }
  5179. }
  5180.  
  5181. ObjectWrapperBase.prototype.mapAllProperties = function ()
  5182. {
  5183.     // maps all the properites that it can find in the underlying object
  5184.     for (prop in this.baseObj)
  5185.     {
  5186.         eval("this." + prop + " = this.baseObj." + prop);
  5187.     }
  5188. }
  5189.  
  5190. ObjectWrapperBase.prototype.getDateTimeFormat = function (timeObj)
  5191. {
  5192.     if (null == timeObj)
  5193.         return '';
  5194.  
  5195.     var useOffset = 0;// (new Date()).getTimezoneOffset() - timeObj.utcOffsetInMin; // it seems like we should be using this offset, but it is actually unused (source: Nathan @ Rebit)
  5196.  
  5197.     return FormatDate(1000 * (parseFloat(timeObj.time) - useOffset * 60));
  5198. }
  5199.  
  5200. /* End included file /scripts/objectjson.js */
  5201.  
  5202. // need for AccountIsTrial, nExpiryDays, openOrder
  5203. /* Carbonite Service SKIPPING already included file /js/navigation.js */
  5204.  
  5205.  
  5206. // need for drawing the line to simulate the window size when viewed
  5207. // from within the debugger.
  5208. /* Carbonite Service included file /js/displayinfo.js */
  5209.  
  5210. function getDisplayInfoValue(displayInfo, fieldName)
  5211. {
  5212.     var re = new RegExp(fieldName + ": *([0-9]+)");
  5213.  
  5214.     var matches = displayInfo.match(re);
  5215.  
  5216.     if (matches == null || matches.length < 2) {
  5217.         return null;
  5218.     }
  5219.  
  5220.     return matches[1];
  5221. }
  5222.  
  5223. if (typeof(jQuery) != "undefined" && typeof(external.LogMsg) == "undefined") {
  5224.     jQuery(document).ready(function ($) {
  5225.         var displayInfo = document.getElementById('crbDisplayInfo').content;
  5226.  
  5227.         var width = getDisplayInfoValue(displayInfo, "width");
  5228.         var height = getDisplayInfoValue(displayInfo, "height");
  5229.  
  5230.         if (width && height) {
  5231.  
  5232.             var div = document.createElement('div');
  5233.  
  5234.             div.style.top = 0;
  5235.             div.style.left = 0;
  5236.             div.style.height = height + "px";
  5237.             div.style.width = width + "px";
  5238.             div.style.borderWidth = "1px";
  5239.             div.style.borderStyle = "solid";
  5240.             div.style.borderColor = "black";
  5241.             div.style.position = "absolute";
  5242.             div.style.zIndex = -1;
  5243.  
  5244.             document.body.appendChild(div);
  5245.         }
  5246.     });
  5247. }
  5248.  
  5249.  
  5250. /* End included file /js/displayinfo.js */
  5251.  
  5252. // global functions
  5253.  
  5254. // used elsewhere (Installation.js, PrivateKey.js, RestoreWizard.js)
  5255. /* Takes an element ID; clicks the element */
  5256. function crbClick(id)
  5257. {
  5258.     if (null != (elt = document.getElementById(id)))
  5259.         elt.click();
  5260.  
  5261.     //If the element is not in this document, try the top document (e.g., for clickable elements in InfoCenter-Status.htm)
  5262.     else if (null != (elt = top.document.getElementById(id)))
  5263.         elt.click();
  5264. }
  5265.  
  5266. // where used?
  5267. function selectDefaultBackupSet(blnClose)
  5268. {
  5269.     if (crbConfirm("strSelectedDefaultBackup"))
  5270.     {
  5271.         crbClick("crbSelectDefaultBackupSet");
  5272.         if (blnClose)
  5273.         {
  5274.             crbClick("crbClose");
  5275.         }
  5276.     }
  5277. }
  5278.  
  5279. // where used?
  5280. function selectManualBackupSet(blnClose)
  5281. {
  5282.     if (crbConfirm("strSelectedManualBackup"))
  5283.     {
  5284.         crbClick("crbSelectManualBackupSet");
  5285.         if (blnClose)
  5286.         {
  5287.             crbClick("crbClose");
  5288.         }
  5289.     }
  5290. }
  5291.  
  5292.  
  5293. // scoping of Alerts functionality
  5294. var __Alert = function ()
  5295. {
  5296.     var self = this;
  5297.  
  5298.     var nIntervalId;
  5299.     var nCountdown = 30;
  5300.  
  5301.     var strDays = "days";
  5302.     var strHours = "h";
  5303.     var strMinutes = "m";
  5304.     var fnCheckPurchase = null;
  5305.     var nPurchaseTimeout = null;
  5306.     var nPurchaseTimeoutMs = 30000; // Timeout and check for a purchase after 30 seconds
  5307.     var nBackedUpCount = -1;
  5308.     var progressMercury = null;
  5309.     var nRestorePendingCount = 0;
  5310.  
  5311.     var interconnect;
  5312.     this.startInterconnect = function ()
  5313.     {
  5314.         interconnect = new ServiceInterconnect(
  5315.         {
  5316.             name: "InfoCenter-Alerts.js" + (new Date()).getTime(),
  5317.             items: "DownloadServer,HomeServer1,UserEmail,RecoverMode,PausedMinutes,RestorePendingCount," +
  5318.                         "RestoredCount,RestoreErrorCount,BackedUpCount,BackedUpSize,SubscriptionInfo," +
  5319.                         "Quota,TotalBackupSize,QuotaUsagePct,OverQuotaSize,BackupDiscoverer",
  5320.             onPush: self.pushHandler
  5321.         });
  5322.         interconnect.start();
  5323.     }
  5324.  
  5325.     function updatePurchaseStatus()
  5326.     {
  5327.         if(nPurchaseTimeout)
  5328.         {
  5329.             clearTimeout(nPurchaseTimeout);
  5330.             nPurchaseTimeout = null;
  5331.             logTrace("SubscriptionInfo updated, calling CheckPurchase function:" + fnCheckPurchase);
  5332.             if(fnCheckPurchase)
  5333.                 fnCheckPurchase();
  5334.         }
  5335.     }
  5336.  
  5337.     this.pushHandler = function (node)
  5338.     {
  5339.         try
  5340.         {
  5341.             //Update common InfoCenter operations first
  5342.             if(Navigation.CommonPushHandler)
  5343.             {
  5344.                 Navigation.CommonPushHandler(node);
  5345.             }
  5346.  
  5347.             switch(node.id)
  5348.             {
  5349.                 case "QuotaUsagePct":
  5350.                     var widthPercent = node.innerHTML;
  5351.                     var pctComplete = parseInt(widthPercent, 10);
  5352.  
  5353.                     if(null == progressMercury)
  5354.                     {
  5355.                         var quotaMeterElement = document.getElementById("crbQuotaMeter");
  5356.                         if(quotaMeterElement != null)
  5357.                         {
  5358.                             progressMercury = new ProgressMercuryMeter(quotaMeterElement.parentElement, document.getElementById("crbQuotaUsagePct"), pctComplete);
  5359.                         }
  5360.                     }
  5361.                     else
  5362.                     {
  5363.                         progressMercury.SetProgressMeter(pctComplete);
  5364.                     }
  5365.  
  5366.                     break;
  5367.  
  5368.                 case "SubscriptionInfo":
  5369.                     var subInfo = ObjectJSON(node.innerText);
  5370.                     Navigation.nExpiryDays = subInfo.ExpiryDays;
  5371.                     Navigation.AccountIsTrial = subInfo.AccountIsTrial;
  5372.                     updatePurchaseStatus();
  5373.                     break;
  5374.  
  5375.                 case "PausedMinutes":
  5376.                     updatePausedTime();
  5377.                     break;
  5378.  
  5379.                 case "RecoverMode":
  5380.                     if(null != (target = document.getElementById("crbExitRecoverModeMessage")))
  5381.                     {
  5382.                         target.style.display = (node.innerHTML == 1) ? "block" : "none";
  5383.                     }
  5384.                     if(null != (target = document.getElementById("crbRestoreDoneButton")))
  5385.                     {
  5386.                         target.style.display = (node.innerHTML == 1) ? "none" : "block";
  5387.                     }
  5388.                     break;
  5389.  
  5390.                 case "RestoreErrorCount":
  5391.                     /* Show a warning on alert-restore-finished.htm if there are restore errors */
  5392.                     if(null != (target = document.getElementById("crbRestoreErrorWarning")))
  5393.                         target.style.display = (node.innerHTML > 0) ? "block" : "none";
  5394.  
  5395.                     /* Show the restore error count if there are restore errors */
  5396.                     if(null != (target = document.getElementById("liRestoreErrors")))
  5397.                         target.style.display = (node.innerHTML == 0) ? "none" : "block";
  5398.  
  5399.                     break;
  5400.  
  5401.                 case "BackupDiscoverer":
  5402.                     //the value is a bitfield of (msb-lsb) scanning|enabled
  5403.                     var nField = parseInt(node.innerHTML);
  5404.                     var bEnabled = 1 == (nField & 1);
  5405.                     var bScanning = 2 == (nField & 2);
  5406.                     //Use a function that deals with the strange behavior of IE6 and IE7 checkboxes to set checked value
  5407.                     CheckObject(crbBackupDiscoverer, bEnabled);
  5408.                     break;
  5409.  
  5410.                 case "RestorePendingCount":
  5411.                     nRestorePendingCount = parseFloat(node.innerHTML);
  5412.                     setViewRestoreStatusLinks();
  5413.                     // Note: deliberate fallthrough here to set crbRestorePendingCount
  5414.                 case "RestoredCount":
  5415.                 case "BackedUpCount":
  5416.                     //Set variable values, e.g. nBackedupCount
  5417.                     /*var varName = "n" + node.id;
  5418.                     eval(varName + "= parseFloat(node.innerHTML);");
  5419.                     trace(varName + " = " + eval(varName));
  5420.                     */
  5421.                     //Set hidden spans with unformatted values
  5422.                     if(null != (elt = document.getElementById("crb" + node.id + "Unformatted")))
  5423.                         elt.innerHTML = node.innerHTML;
  5424.  
  5425.                     crbFormatNumber("crb" + node.id); // Comma-format file counts
  5426.                     break;
  5427.             }
  5428.         }
  5429.         catch(e)
  5430.         {
  5431.         }
  5432.     }
  5433.  
  5434.     function setViewRestoreStatusLinks()
  5435.     {
  5436.         // View status li on alert-recover-mode.htm
  5437.         var viewStatusListItem = $("#alert-recover-mode-restore-status-li")
  5438.         if (viewStatusListItem.length > 0)  // If we can find this link
  5439.         {
  5440.             viewStatusListItem.toggle(nRestorePendingCount > 0);
  5441.         }
  5442.     }
  5443.  
  5444.     function countdown()
  5445.     {
  5446.         document.getElementById('crbCountdown').innerHTML = nCountdown;
  5447.         if(nCountdown-- == 0)
  5448.         {
  5449.             window.clearInterval(nIntervalId);
  5450.             crbClick('crbShutdown');
  5451.         }
  5452.     }
  5453.  
  5454.     this.getShutdownReason = function ()
  5455.     {
  5456.         //what's the reason for wanting to delay the shutdown?
  5457.         var sdReasonDiv = document.getElementById(queryString('delayreason'));
  5458.         if(sdReasonDiv)
  5459.             sdReasonDiv.style.display = "block";
  5460.  
  5461.         //start a timer to countdown from 30 seconds and autoclick the shutdown button on timeout
  5462.         nIntervalId = window.setInterval(countdown, 1000);
  5463.     }
  5464.  
  5465.     this.alertUpgradeOnLoad = function ()
  5466.     {
  5467.         var bIsAdmin = eval(document.getElementById("crbIsAdminUser").innerText);
  5468.         var showMessage = bIsAdmin ? "AdminInstallUpdate" : "NeedAdminUpdate";
  5469.         var showButton = bIsAdmin ? "crbUpgradeButton" : "crbOKButton";
  5470.         document.getElementById(showMessage).style.display = "";
  5471.         document.getElementById(showButton).style.display = "";
  5472.     }
  5473.  
  5474.     this.onLoadMissingFiles = function ()
  5475.     {
  5476.         //given data=file-count|missing-since|purge-in;...
  5477.         //but, we'll sum up the file counts and present just one line of information
  5478.         //using the time till the first file is purged
  5479.         var body = document.body.innerHTML;
  5480.         var qsdata = queryString('data');
  5481.  
  5482.         if(qsdata == undefined)
  5483.             return;
  5484.  
  5485.         var buckets = qsdata.split(';');
  5486.         var n = 0;
  5487.         var fileCount = 0;
  5488.         var missingSince = null;
  5489.         var purgeIn = null;
  5490.         for(var bucket in buckets)
  5491.         {
  5492.             if(buckets[bucket] == '')
  5493.                 continue;
  5494.  
  5495.             var bucketInfo = buckets[bucket].split('|');
  5496.  
  5497.             fileCount += parseInt(bucketInfo[0], 10);
  5498.             if(null == missingSince)
  5499.             {
  5500.                 missingSince = bucketInfo[1];
  5501.                 purgeIn = bucketInfo[2];
  5502.             }
  5503.         }
  5504.  
  5505.         var summary = divSummary.innerHTML.replace(/{filecount}/g, fileCount)
  5506.         summary = summary.replace(/{since}/g, missingSince);
  5507.         summary = summary.replace(/{purge}/g, purgeIn);
  5508.         divSummary.innerHTML = summary;
  5509.     }
  5510.  
  5511.     /******** Check for a purchase *******/
  5512.  
  5513.     this.openOrderWithVerification = function (source, fnSuccess, fnFailure)
  5514.     {
  5515.         // Open the order page
  5516.         Navigation.openOrder(source);
  5517.  
  5518.         // For some languages, the purchase check is not required.
  5519.         var pDoPurchaseCheck = top.document.getElementById("crbDoPurchaseCheck");
  5520.         var intDoPurchaseCheck = (pDoPurchaseCheck && pDoPurchaseCheck.innerHTML) ? parseInt(pDoPurchaseCheck.innerHTML) : 1;
  5521.  
  5522.         if(intDoPurchaseCheck == 1)
  5523.         {
  5524.             // Ask the user to click "OK" when they've purchased so we can go log in
  5525.             if(crbConfirm2("crbConfirmPurchase"))
  5526.             {
  5527.                 Wait.DoWait('lbPleaseWait');
  5528.                 checkPurchaseWithTimeout(fnSuccess, fnFailure, nPurchaseTimeoutMs);
  5529.             }
  5530.         }
  5531.         else
  5532.         {
  5533.             // No purchase check -- just call the success function
  5534.             if(fnSuccess)
  5535.                 fnSuccess();
  5536.         }
  5537.     }
  5538.  
  5539.     function checkPurchaseWithTimeout(fnSuccess, fnFailure, t)
  5540.     {
  5541.         logTrace("Calling checkPurchaseWithTimeout with success function: " + fnSuccess + " and failure function: " + fnFailure);
  5542.  
  5543.         // If you're a trial account or an expired paid account, we need to log in and check to see if you've paid
  5544.         if(Navigation.AccountIsTrial || (Navigation.nExpiryDays <= 0))
  5545.         {
  5546.             //make the infocenter tell the service to do a purchase check
  5547.             $('#crbCheckPurchase').click();
  5548.  
  5549.             //wake back up in t milliseconds to see if the purchase happened like the user said it did
  5550.             fnCheckPurchase = function () { Alert.checkPurchase(fnSuccess, fnFailure); };
  5551.             nPurchaseTimeout = setTimeout(fnCheckPurchase, t);
  5552.         }
  5553.         // Otherwise we just say thanks
  5554.         else
  5555.         {
  5556.             purchaseSuccessful(fnSuccess);
  5557.         }
  5558.     }
  5559.  
  5560.     // Takes two functions: what to do if the purchase is successful, and what to do if it fails;
  5561.     // functions can be null if there is no action to take
  5562.     this.checkPurchase = function (fnSuccess, fnFailure)
  5563.     {
  5564.         logTrace("Inside checkPurchase: AccountIsTrial = " + Navigation.AccountIsTrial + " and nExpiryDays = " + Navigation.nExpiryDays);
  5565.         if(Navigation.AccountIsTrial || (Navigation.nExpiryDays <= 0))
  5566.         {
  5567.             logTrace("Inside checkPurchase: No purchase detected.");
  5568.  
  5569.             // If the user clicks OK to try again, check purchase status again
  5570.             if(crbConfirm2("crbNotBoughtYet"))
  5571.             {
  5572.                 checkPurchaseWithTimeout(fnSuccess, fnFailure, nPurchaseTimeoutMs);
  5573.             }
  5574.             else
  5575.             {
  5576.                 purchaseFailure(fnFailure);
  5577.             }
  5578.         }
  5579.         else
  5580.         {
  5581.             logTrace("Inside checkPurchase: Purchase detected.");
  5582.             purchaseSuccessful(fnSuccess);
  5583.         }
  5584.  
  5585.     }
  5586.  
  5587.     function purchaseSuccessful(fnSuccess)
  5588.     {
  5589.         Wait.StopWait();
  5590.         clearTimeout(nPurchaseTimeout);
  5591.         nPurchaseTimeout = null;
  5592.         crbAlert("crbPurchaseSuccessful");
  5593.         if(fnSuccess)
  5594.             fnSuccess();
  5595.     }
  5596.  
  5597.     function purchaseFailure(fnFailure)
  5598.     {
  5599.         Wait.StopWait();
  5600.         clearTimeout(nPurchaseTimeout);
  5601.         nPurchaseTimeout = null;
  5602.         if(fnFailure)
  5603.             fnFailure();
  5604.     }
  5605.  
  5606.     // Converts crbPausedMinutes.innerText into a user-understandable duration
  5607.     // (e.g. "5 hours, 32 seconds") and stores the result in the crbPausedTime
  5608.     // element.
  5609.     //
  5610.     this.updatePausedTime = function ()
  5611.     {
  5612.         var source;
  5613.  
  5614.         if(null == (source = document.getElementById("crbPausedMinutes")))
  5615.             return;
  5616.  
  5617.         var target;
  5618.  
  5619.         if(null == (target = document.getElementById("crbPausedTime")))
  5620.             return;
  5621.  
  5622.         var pausedMins = source.innerHTML;
  5623.         var nDays = Math.floor(pausedMins / 60 / 24);
  5624.         var nHours = Math.floor(pausedMins / 60);
  5625.         var nMins = pausedMins % 60;
  5626.  
  5627.         // Localize the time labels (days, hours, minutes)
  5628.         if(null != (elt = document.getElementById("crbStrDays")))
  5629.         {
  5630.             strDays = elt.innerHTML;
  5631.         }
  5632.         if(null != (elt = document.getElementById("crbStrHours")))
  5633.         {
  5634.             strHours = elt.innerHTML;
  5635.         }
  5636.         if(null != (elt = document.getElementById("crbStrMinutes")))
  5637.         {
  5638.             strMinutes = elt.innerHTML;
  5639.         }
  5640.         if(null != (elt = document.getElementById("crbStrDay")))
  5641.         {
  5642.             strDay = elt.innerHTML;
  5643.         }
  5644.         if(null != (elt = document.getElementById("crbStrHour")))
  5645.         {
  5646.             strHour = elt.innerHTML;
  5647.         }
  5648.         if(null != (elt = document.getElementById("crbStrMinute")))
  5649.         {
  5650.             strMinute = elt.innerHTML;
  5651.         }
  5652.  
  5653.         var sFormattedPause = '';
  5654.         if(nDays > 0)
  5655.         {
  5656.             sFormattedPause = nDays + ' ' + (nDays == 1 ? strDay : strDays);
  5657.         }
  5658.         //don't show hours/minutes if days are set - too much detail
  5659.         else
  5660.         {
  5661.             if(nHours > 0)
  5662.             {
  5663.                 sFormattedPause += nHours + " " + (nHours == 1 ? strHour : strHours);
  5664.             }
  5665.             if(nMins > 0)
  5666.             {
  5667.                 if(sFormattedPause != '')
  5668.                     sFormattedPause += ', ';
  5669.                 sFormattedPause += nMins + ' ' + (nMins == 1 ? strMinute : strMinutes);
  5670.             }
  5671.         }
  5672.         target.innerHTML = sFormattedPause;
  5673.     }
  5674. }
  5675.  
  5676. // the global Alert object to isolate operations within the about namespace
  5677. var Alert = new __Alert();
  5678.  
  5679. // Start the interconnect when ready
  5680. jQuery(document).ready(
  5681.     function ()
  5682.     {
  5683.         Alert.startInterconnect();
  5684.     }
  5685. );
  5686.  
  5687. /* End included file /js/alert.js */
  5688. /* Carbonite Service SKIPPING already included file /scripts/draganddrop.js */
  5689.  
  5690. /* Carbonite Service included file /scripts/privatekey.js */
  5691. // (c) Carbonite, Inc., 2005-2009 All rights reserved
  5692. // Need for crbAlert
  5693. /* Carbonite Service SKIPPING already included file /scripts/messagebox.js */
  5694.  
  5695.  
  5696. // need for crbClick
  5697. /* Carbonite Service SKIPPING already included file /js/alert.js */
  5698.  
  5699.  
  5700. function onImportBodyLoad()
  5701. {
  5702.     //expect to be given a hint
  5703.     crbPKHint.innerText = queryString('hint');
  5704. }
  5705.  
  5706. function setPrivateKeyBehavior()
  5707. {
  5708.     if (!document.getElementById("crbManageKey").checked)
  5709.     {
  5710.         if (crbConfirm2("crbConfirmManageKey"))
  5711.         {
  5712.             /* Launch dialog box to solicit passphrase and hint */
  5713.             //window.location.href="registration-private-key-export.htm";
  5714.                 Installation.onPhase("SaveKey");
  5715.             return;
  5716.         }
  5717.         else
  5718.             crbAlert("crbCancelManageKey");
  5719.     }
  5720.     crbClick("crbCancelManageKey");
  5721. }
  5722.  
  5723. var keyManagementDelegate__ = {
  5724.  
  5725.     onPKExported: function() {
  5726.     },
  5727.  
  5728.     onPKManagementChange: function() {
  5729.     },
  5730.  
  5731.     onPKError: function() {
  5732.  
  5733.     }
  5734. };
  5735.  
  5736. function onPKExport(res)
  5737. {
  5738.     if (res == 0)
  5739.     {
  5740.         keyManagementDelegate__.onPKExported();
  5741.     }
  5742.     else if (res != "canx")
  5743.     {
  5744.         crbAlert("crbKeyExportFailed");
  5745.  
  5746.         keyManagementDelegate__.onPKError();
  5747.     }
  5748. }
  5749.  
  5750. function onPKImport(res)
  5751. {
  5752.     if (res == 0)
  5753.         crbClick("crbPKDone");
  5754.     else
  5755.         crbAlert("crbKeyImportFailed");
  5756. }
  5757.  
  5758. function onPKManagementChange(res)
  5759. {
  5760.     if (res == 0)
  5761.     {
  5762.         crbAlert("crbKeyManagedByServer");
  5763.  
  5764.         keyManagementDelegate__.onPKManagementChange();
  5765.     }
  5766.     else
  5767.     {
  5768.         crbAlert("crbKeyReturnFailed");
  5769.  
  5770.         keyManagementDelegate__.onPKError();
  5771.     }
  5772.  
  5773.     return;
  5774. }
  5775.  
  5776. function onPKUnderstood()
  5777. {
  5778.     element("crbPKExportButton").disabled = false == element("chkPKUnderstood").checked || false == checkPassword();
  5779. }
  5780.  
  5781. //retain the message id on failure
  5782. var sPasswordFailureMsgId = "";
  5783. function isPasswordValid(password)
  5784. {
  5785.     sPasswordFailureMsgId = "";
  5786.     if (0 == password.length)
  5787.         return true;
  5788.  
  5789.     if (password.length < 6)
  5790.     {
  5791.         sPasswordFailureMsgId = "crbPasswordTooShort";
  5792.         return false;
  5793.     }
  5794.  
  5795.     var invalidChars = document.getElementById("crbInvalidPasswordChars").innerText;
  5796.     var regexInvalid = new RegExp(invalidChars);
  5797.     if (password.match(regexInvalid))
  5798.     {
  5799.         sPasswordFailureMsgId = "crbInvalidCharacter";
  5800.         return false;
  5801.     }
  5802.  
  5803.     return true;
  5804. }
  5805.  
  5806. var count = 0;
  5807.  
  5808. function getPasswordValue()
  5809. {
  5810.     var passwordElement = element("crbPKPassword");
  5811.  
  5812.     if (passwordElement.type != "password")
  5813.     {
  5814.         if (count++ == 0)
  5815.             debugger;
  5816.  
  5817.         return "";
  5818.     }
  5819.  
  5820.     return passwordElement.value;
  5821. }
  5822.  
  5823. function getConfirmValue()
  5824. {
  5825.     var confirmElement = element("crbPKConfirmPassword");
  5826.  
  5827.     if (confirmElement.type != "password")
  5828.     {
  5829.         return "";
  5830.     }
  5831.  
  5832.     return confirmElement.value;
  5833. }
  5834.  
  5835. function isPasswordConfirmed()
  5836. {
  5837.     if (getPasswordValue() != getConfirmValue())
  5838.     {
  5839.         sPasswordFailureMsgId = "crbNoPasswordMatch";
  5840.         return false;
  5841.     }
  5842.  
  5843.     return true;
  5844. }
  5845.  
  5846. function checkPassword()
  5847. {
  5848.     //user understands what they're doing?
  5849.     if (false == element("chkPKUnderstood").checked)
  5850.     {
  5851.         crbAlert("crbNotUnderstood");
  5852.         return false;
  5853.     }
  5854.  
  5855.     if (isPasswordValid(getPasswordValue()) && isPasswordConfirmed())
  5856.         return true;
  5857.  
  5858.     return false;
  5859. }
  5860.  
  5861. function onPKPasswordChange(async)
  5862. {
  5863.     var sPassword = getPasswordValue();
  5864.     var bPasswordIsBlank = ("" == sPassword);
  5865.     var bPasswordIsValid = isPasswordValid(sPassword);
  5866.     var bConfirmed = false;
  5867.     if (bPasswordIsValid)
  5868.         bConfirmed = isPasswordConfirmed();
  5869.  
  5870.     //enable the save button?
  5871.     onPKUnderstood();
  5872.    
  5873.     //good password -- but don't show the checkmark if the password is blank
  5874.     visibleElement(element("PKPasswordGood"), (bPasswordIsValid && !bPasswordIsBlank));
  5875.  
  5876.     //confirmed password?
  5877.     visibleElement(element("PKPasswordConfirmed"), bPasswordIsValid && "" != sPassword && bConfirmed);
  5878.  
  5879.     //hint?
  5880.     visibleElement(element("PKHintGood"), element("crbPKHint").value != "");
  5881.  
  5882.     divPKError.innerHTML = "" == sPasswordFailureMsgId ? "&nbsp;" : element(sPasswordFailureMsgId).innerHTML;
  5883. }
  5884.  
  5885. // Starts a timer that will enable/disable the Save button and fill any error/status information the
  5886. // user might need to know about.
  5887. function startPKPasswordTimer()
  5888. {
  5889.     var nPKPasswordMonitor = setInterval("onPKPasswordChange(true)", 500);
  5890. }
  5891.  
  5892. /* End included file /scripts/privatekey.js */
  5893. /* Carbonite Service included file /scripts/tooltips.js */
  5894. // (c) Carbonite, Inc., 2005-2009 All rights reserved
  5895. var lastTipId;
  5896. var showTip;
  5897.  
  5898. function ShowTipString(s, x, y)
  5899. {
  5900.     var tipId = s + "tip";
  5901.     // destroy the current one if it is different to this one.
  5902.     if (lastTipId != tipId)
  5903.     {
  5904.         DestroyTipId(lastTipId);
  5905.         lastTipId = tipId;
  5906.     }
  5907.    
  5908.     if (showTip)
  5909.         clearTimeout(showTip);
  5910.    
  5911.     if (x == null || y == null)
  5912.     {
  5913.         showTip = setTimeout("ShowTipString('" + s + "', " + ((x == null) ? event.clientX : x) + ", " + ((y == null) ? event.clientY : y) + ");", 300);
  5914.         return;
  5915.     }
  5916.    
  5917.     var tipDiv = document.getElementById(tipId);
  5918.     if (!tipDiv && s.length > 0)
  5919.     {
  5920.         tipDiv = document.createElement("div");
  5921.         tipDiv.id = tipId;
  5922.         tipDiv.className = "pathTip";
  5923.         tipDiv.style.left = x - 20;
  5924.         tipDiv.style.top = y + 15;
  5925.         tipDiv.innerHTML = unescape(s);
  5926.         document.body.appendChild(tipDiv);
  5927.        
  5928.         // Now adjust the position if hidden off to the right
  5929.         var tipRight = FindObjectPosition(tipDiv)[0] + tipDiv.offsetWidth;
  5930.         if (document.body.clientWidth < tipRight)
  5931.             tipDiv.style.left = x - 20 - (tipRight - document.body.clientWidth);
  5932.     }
  5933. }
  5934.  
  5935. function HideTipString(s)
  5936. {
  5937.     var tipId = s + "tip";
  5938.     DestroyTipId(tipId);
  5939. }
  5940.  
  5941. function DestroyTipId(tipId)
  5942. {
  5943.     var tipDiv = document.getElementById(tipId);
  5944.     if (tipDiv)
  5945.         document.body.removeChild(tipDiv);
  5946.     if (lastTipId == tipId)
  5947.         lastTipId = null;
  5948.     if (showTip)
  5949.         clearTimeout(showTip);
  5950. }
  5951.  
  5952. function ShowTip(obj)
  5953. {
  5954.     ShowTipString(obj.innerHTML);
  5955. }
  5956.  
  5957. function HideTip(obj)
  5958. {
  5959.     HideTipString(obj.innerHTML);
  5960. }
  5961.  
  5962. function HideLastTip()
  5963. {
  5964.     DestroyTipId(lastTipId);
  5965. }
  5966.  
  5967. function ShowTipID(id)
  5968. {
  5969.     if (document.getElementById(id))
  5970.         ShowTip(document.getElementById(id));
  5971. }
  5972.  
  5973. function HideTipID(id)
  5974. {
  5975.     if (document.getElementById(id))
  5976.         HideTip(document.getElementById(id));
  5977. }
  5978.  
  5979. function AddTips()
  5980. {
  5981.     // Go through the whole document and find all attributes tipId="xxx"
  5982.     var attr, oldScript;
  5983.     var childArray = document.all; //getElementsByTagName("*"); // ideally, we could use an xpath expression to query the DOM- unfortunately, this is only supported in Mozilla Firefox for now...
  5984.     for (var i = 0; i < childArray.length; i++)
  5985.     {
  5986.         attr = childArray[i].attributes ? childArray[i].getAttribute("tipId") : null;
  5987.         if (null != attr)
  5988.         {
  5989.             oldScript = childArray[i].onmouseover;
  5990.             if (oldScript)
  5991.                 childArray[i].onmouseover = function()
  5992.                 {
  5993.                     eval(oldScript + " ");
  5994.                     ShowTipID(this.getAttribute("tipId"));
  5995.                 }
  5996.             else
  5997.                 childArray[i].onmouseover = function()
  5998.                 {
  5999.                     ShowTipID(this.getAttribute("tipId"));
  6000.                 }
  6001.                
  6002.             oldScript = childArray[i].onmouseout;
  6003.             if (oldScript)
  6004.                 childArray[i].onmouseout = function()
  6005.                 {
  6006.                     eval(oldScript + " ");
  6007.                     HideTipID(this.getAttribute("tipId"));
  6008.                 }
  6009.             else
  6010.                 childArray[i].onmouseout = function()
  6011.                 {
  6012.                     HideTipID(this.getAttribute("tipId"));
  6013.                 }
  6014.                
  6015.         }
  6016.     }
  6017. }
  6018.  
  6019. /* End included file /scripts/tooltips.js */
  6020. /* Carbonite Service included file /scripts/computerdescription.js */
  6021. // (c) Carbonite, Inc., 2005-2009 All rights reserved
  6022. /* Carbonite Service SKIPPING already included file /js/wait.js */
  6023.  
  6024.  
  6025. var ComputerDescription__ = function ()
  6026. {
  6027.     var self = this;
  6028.  
  6029.     var selectedMachineType = '';
  6030.  
  6031.     // Set default machine type to 'desktop'.  Also set focus to the edit field.
  6032.     this.InitMachineDescriptions = function ()
  6033.     {
  6034.         inferSelectedMachineType();
  6035.  
  6036.         if(selectedMachineType.length == 0)
  6037.         {
  6038.             PopulateMachineDescriptionsImpl("", "desktop");
  6039.         }
  6040.  
  6041.         $('#crbMachineDescription').focus();
  6042.     }
  6043.  
  6044.     function PopulateMachineDescriptionsImpl(desc, type)
  6045.     {
  6046.         if(desc != null && desc.length > 0)
  6047.             $('#crbMachineDescription').val(desc);
  6048.         if(type != null && type.length > 0)
  6049.             $('#crbMachineType' + type).click();
  6050.     }
  6051.  
  6052.     this.PopulateMachineDescriptions = function (descInfo)
  6053.     {
  6054.         var splitAt = descInfo.lastIndexOf(";");
  6055.         if(splitAt == 0)
  6056.             return; // don't populate from empty
  6057.         var desc = descInfo.substr(0, splitAt);
  6058.         var type = descInfo.substr(splitAt + 1);
  6059.  
  6060.         PopulateMachineDescriptionsImpl(desc, type);
  6061.     }
  6062.  
  6063.     function inferSelectedMachineType()
  6064.     {
  6065.         if(selectedMachineType.length == 0)
  6066.         {
  6067.             var typeArray = new Array("desktop", "laptop", "server");
  6068.             for(var i = 0; i < typeArray.length; i++)
  6069.             {
  6070.                 if($('#crbMachineType' + typeArray[i]).hasClass("SelectedMachine"))
  6071.                 {
  6072.                     selectedMachineType = typeArray[i];
  6073.                     break;
  6074.                 }
  6075.             }
  6076.         }
  6077.     }
  6078.  
  6079.     this.SetDescription = function (silent)
  6080.     {
  6081.         inferSelectedMachineType();
  6082.  
  6083.         var desc = $('#crbMachineDescription').val();
  6084.  
  6085.         var validChoice = desc.length > 0;
  6086.         if(validChoice)
  6087.         {
  6088.             $('#crbMachineTypeString').val(selectedMachineType);
  6089.             $('#crbFormattedMachineDescription').val(desc + ";" + selectedMachineType);
  6090.             $('#crbDescriptionMade').click();
  6091.         }
  6092.         else if (!silent)
  6093.         {
  6094.             HtmlMessageBox2('crbPleaseSupplyDescription', BUTTON_OK);              
  6095.         }
  6096.  
  6097.         return validChoice;
  6098.     }
  6099.  
  6100.     this.ChangeMachineDescription = function ()
  6101.     {
  6102.         Wait.Popup("crbChangeDescription");
  6103.         $('#crbOKMachineDescription').focus();
  6104.     }
  6105.  
  6106.     this.SetMachineDescription = function (silent)
  6107.     {
  6108.         if(self.SetDescription(silent))
  6109.         {
  6110.             var desc = $('#crbMachineDescription').val();
  6111.  
  6112.             $('#crbViewTypeDescription').text(desc);
  6113.             $('#crbViewTypeDescription').attr("title", desc);
  6114.             $('#computerTypeIcon').removeClass('laptop desktop server');
  6115.             $('#computerTypeIcon').addClass($('#crbMachineTypeString').val());
  6116.  
  6117.             Wait.StopPopup();
  6118.         }
  6119.     }
  6120.  
  6121.     var tabbedMachineType = null;
  6122.     this.HoverMachineType = function (mt)
  6123.     {
  6124.         if(tabbedMachineType == null)
  6125.             HighlightMachineType(mt, true);
  6126.     }
  6127.  
  6128.     this.OutMachineType = function (mt)
  6129.     {
  6130.         if(tabbedMachineType == null)
  6131.             HighlightMachineType(mt, false);
  6132.     }
  6133.  
  6134.     function HighlightMachineType(mt, highlightOn)
  6135.     {
  6136.         if(mt.className.indexOf("SelectedMachine") < 0) {
  6137.             if (highlightOn) {
  6138.                 $(mt).addClass("HoverMachine");
  6139.             }
  6140.             else {
  6141.                 $(mt).removeClass("HoverMachine");
  6142.             }
  6143.         }
  6144.     }
  6145.  
  6146.     this.SelectMachineType = function (mt)
  6147.     {
  6148.         self.ReleaseMachineTypeFocus();
  6149.  
  6150.         // They've clicked on it, blur it to remove the ugly dotted box
  6151.         mt.blur();
  6152.         ChooseMachineType(mt);
  6153.     }
  6154.  
  6155.     function ChooseMachineType(mt)
  6156.     {
  6157.         selectedMachineType = mt.id.substring(14);
  6158.         $('#crbMachineTypedesktop, #crbMachineTypelaptop, #crbMachineTypeserver').removeClass("SelectedMachine");
  6159.         $(mt).addClass('SelectedMachine');
  6160.     }
  6161.  
  6162.     /* Keyboard values */
  6163.     var TAB = 9;
  6164.     var ENTER = 13;
  6165.     var SHIFT = 16;
  6166.     var SPACEBAR = 32;
  6167.     var LEFT_ARROW = 37;
  6168.     var UP_ARROW = 38;
  6169.     var RIGHT_ARROW = 39;
  6170.     var DOWN_ARROW = 40;
  6171.  
  6172.     this.SetMachineTypeFocus = function (mt)
  6173.     {
  6174.         tabbedMachineType = mt;
  6175.         HighlightMachineType(mt, true);
  6176.     }
  6177.  
  6178.     this.ReleaseMachineTypeFocus = function ()
  6179.     {
  6180.         if(tabbedMachineType)
  6181.             HighlightMachineType(tabbedMachineType, false);
  6182.  
  6183.         tabbedMachineType = null;
  6184.     }
  6185.  
  6186.     this.MachineChosenTest = function (mt)
  6187.     {
  6188.         var key = window.event.keyCode;
  6189.         if(key == ENTER)
  6190.             ChooseMachineType(mt);
  6191.     }
  6192. }
  6193.  
  6194. var ComputerDescription = new ComputerDescription__();
  6195.  
  6196. // Called from InfoCenter
  6197. function PopulateMachineDescriptions(descInfo)
  6198. {
  6199.     ComputerDescription.PopulateMachineDescriptions(descInfo);
  6200. }
  6201.  
  6202. /* End included file /scripts/computerdescription.js */
  6203. /* Carbonite Service SKIPPING already included file /js/wait.js */
  6204.  
  6205. /* Carbonite Service included file /scripts/infocenter-tooltips.js */
  6206. // (c) Carbonite, Inc., 2005-2009 All rights reserved
  6207. var imagePath = "/images/tooltiparrow.gif";
  6208.  
  6209. function addtip()
  6210. {
  6211.     var thealinks = document.getElementsByTagName("a");
  6212.     if (!thealinks)
  6213.     {
  6214.         return;
  6215.     }
  6216.    
  6217.     for (var x = 0; x != thealinks.length; x++)
  6218.     {
  6219.    
  6220.         if (thealinks[x].className == "addToolTip")
  6221.         {
  6222.             thealinks[x].setAttribute("tooltiptext", thealinks[x].title);
  6223.             thealinks[x].removeAttribute("title");
  6224.            
  6225.             var openBrace;
  6226.             var closeBrace;
  6227.            
  6228.             // scripts within tags are wrapped inside function anonymous(){HERE} - we strip them and add the complete call - adding the space forces the conversion to a string of the embedded function
  6229.             if (thealinks[x].onmouseover)
  6230.             {
  6231.                 var sMouseOver = thealinks[x].onmouseover + " ";
  6232.                 openBrace = sMouseOver.indexOf('{');
  6233.                 closeBrace = sMouseOver.lastIndexOf('}');
  6234.                 sMouseOver = sMouseOver.substr(openBrace, closeBrace);
  6235.                
  6236.                 thealinks[x].onmouseover = function gomouseover()
  6237.                 {
  6238.                     eval(sMouseOver);
  6239.                     ddrivetip(this.getAttribute("tooltiptext"));
  6240.                 };
  6241.             }
  6242.             else
  6243.                 thealinks[x].onmouseover = function gomouseover()
  6244.                 {
  6245.                     ddrivetip(this.getAttribute("tooltiptext"));
  6246.                 };
  6247.            
  6248.             if (thealinks[x].onmouseout)
  6249.             {
  6250.                 var sMouseOut = thealinks[x].onmouseout + " ";
  6251.                 openBrace = sMouseOut.indexOf('{');
  6252.                 closeBrace = sMouseOut.lastIndexOf('}');
  6253.                 sMouseOut = sMouseOut.substr(openBrace, closeBrace);
  6254.                 thealinks[x].onmouseout = function gomouseout()
  6255.                 {
  6256.                     eval(sMouseOut);
  6257.                     hideddrivetip();
  6258.                 };
  6259.             }
  6260.             else
  6261.                 thealinks[x].onmouseout = function gomouseout()
  6262.                 {
  6263.                     hideddrivetip();
  6264.                 };
  6265.         }
  6266.        
  6267.     }
  6268. }
  6269.  
  6270. var offsetfromcursorX = -7; //Customize x offset of tooltip
  6271. var offsetfromcursorY = 20; //Customize y offset of tooltip
  6272. var offsetdivfrompointerX = 13; //Customize x offset of tooltip DIV relative to pointer image
  6273. var offsetdivfrompointerY = 13; //Customize y offset of tooltip DIV relative to pointer image. Tip: Set it to (height_of_pointer_image-1).
  6274. document.write('<div id="theToolTip" class="ToolTip"></div>'); //write out tooltip DIV
  6275. document.write('<img id="ToolTipPointer" class="ToolTipPointer" src="' + imagePath + '">'); //write out pointer image
  6276. var ie = document.all;
  6277. var ns6 = document.getElementById && !document.all;
  6278. var enabletip = false;
  6279. var enableTips = true;
  6280.  
  6281. if (ie || ns6)
  6282. {
  6283.     var tipobj = document.all ? document.all["theToolTip"] : document.getElementById ? document.getElementById("theToolTip") : "";
  6284. }
  6285.  
  6286. var pointerobj = document.all ? document.all["ToolTipPointer"] : document.getElementById ? document.getElementById("ToolTipPointer") : "";
  6287.  
  6288.  
  6289. function ietruebody()
  6290. {
  6291.     return (document.compatMode && document.compatMode != "BackCompat") ? document.documentElement : document.body;
  6292. }
  6293.  
  6294.  
  6295. function ddrivetip(thetext, thewidth, thecolor)
  6296. {
  6297.     if (enableTips && (ns6 || ie))
  6298.     {
  6299.         if (typeof thewidth !== "undefined")
  6300.         {
  6301.             tipobj.style.width = thewidth + "px";
  6302.         }
  6303.         if (typeof thecolor !== "undefined" && thecolor !== "")
  6304.         {
  6305.             tipobj.style.backgroundColor = thecolor;
  6306.         }
  6307.         tipobj.innerHTML = thetext;
  6308.         enabletip = true;
  6309.         return false;
  6310.     }
  6311. }
  6312.  
  6313.  
  6314. function positiontip(e)
  6315. {
  6316.     if (enabletip)
  6317.     {
  6318.         var nondefaultpos = false;
  6319.         var curX = (ns6) ? e.pageX : event.clientX + ietruebody().scrollLeft;
  6320.         var curY = (ns6) ? e.pageY : event.clientY + ietruebody().scrollTop;
  6321.        
  6322.         //Find out how close the mouse is to the corner of the window
  6323.         var winwidth = ie && !window.opera ? ietruebody().clientWidth : window.innerWidth - 20;
  6324.         var winheight = ie && !window.opera ? ietruebody().clientHeight : window.innerHeight - 20;
  6325.        
  6326.         var rightedge = ie && !window.opera ? winwidth - event.clientX - offsetfromcursorX : winwidth - e.clientX - offsetfromcursorX;
  6327.         var bottomedge = ie && !window.opera ? winheight - event.clientY - offsetfromcursorY : winheight - e.clientY - offsetfromcursorY;
  6328.        
  6329.         var leftedge = (offsetfromcursorX < 0) ? offsetfromcursorX * (-1) : -1000;
  6330.        
  6331.         //if the horizontal distance isn't enough to accomodate the width of the context menu
  6332.         if (rightedge < tipobj.offsetWidth)
  6333.         {
  6334.             //move the horizontal position of the menu to the left by it's width - 25 px
  6335.             tipobj.style.left = curX - tipobj.offsetWidth + 25 + "px";
  6336.            
  6337.             //Place the pointer graphic
  6338.             pointerobj.style.top = curY + offsetfromcursorY + "px";
  6339.             pointerobj.style.left = curX + offsetfromcursorX - 10 + "px";
  6340.         }
  6341.         else if (curX < leftedge)
  6342.         {
  6343.             tipobj.style.left = "5px";
  6344.         }
  6345.         else
  6346.         {
  6347.             //position the horizontal position of the menu where the mouse is positioned
  6348.             tipobj.style.left = curX + offsetfromcursorX - offsetdivfrompointerX + "px";
  6349.             pointerobj.style.left = curX + offsetfromcursorX + "px";
  6350.         }
  6351.        
  6352.         //same concept with the vertical position
  6353.         if (bottomedge < tipobj.offsetHeight)
  6354.         {
  6355.             tipobj.style.top = curY - tipobj.offsetHeight - offsetfromcursorY + "px";
  6356.             nondefaultpos = true;
  6357.         }
  6358.         else
  6359.         {
  6360.             tipobj.style.top = curY + offsetfromcursorY + offsetdivfrompointerY + "px";
  6361.             pointerobj.style.top = curY + offsetfromcursorY + "px";
  6362.         }
  6363.        
  6364.         nondefaultpos |= AdjustWidth(tipobj, winwidth, winheight);
  6365.         nondefaultpos |= AdjustHeight(tipobj, winwidth, winheight);
  6366.        
  6367.         tipobj.style.visibility = "visible";
  6368.        
  6369.         if (!nondefaultpos)
  6370.         {
  6371.             pointerobj.style.visibility = "visible";
  6372.         }
  6373.         else
  6374.         {
  6375.             pointerobj.style.visibility = "hidden";
  6376.         }
  6377.     }
  6378. }
  6379.  
  6380. function hideddrivetip()
  6381. {
  6382.     if (ns6 || ie)
  6383.     {
  6384.         enabletip = false;
  6385.         tipobj.style.visibility = "hidden";
  6386.         pointerobj.style.visibility = "hidden";
  6387.         tipobj.style.left = "-1000px";
  6388.         tipobj.style.backgroundColor = '';
  6389.         tipobj.style.width = '';
  6390.     }
  6391. }
  6392.  
  6393. function AdjustWidth(tipobj, winwidth, winheight)
  6394. {
  6395.     // If you alter this method, make the equivalent changes to AdjustHeight
  6396.     var nondefaultpos = false;
  6397.    
  6398.     // if it goes over the top adjust the width, but not more than available
  6399.     while (getTop(tipobj) < 0 &&
  6400.     getWidth(tipobj) < (winwidth - 10))
  6401.     {
  6402.         var bottom = getBottom(tipobj);
  6403.         var increaseTo = getWidth(tipobj) * 1.1;
  6404.         tipobj.style.width = (increaseTo < (winwidth - 10)) ? increaseTo : (winwidth - 10); // object will autoadjust height
  6405.         tipobj.style.top = bottom - getHeight(tipobj); // set the bottom relative to the new height
  6406.         tipobj.style.bottom = bottom; // set the bottom relative to the new height
  6407.     }
  6408.    
  6409.     // if it goes over the bottom adjust the width, but not more than available
  6410.     while (getBottom(tipobj) > (winheight - 5) &&
  6411.     getWidth(tipobj) < (winwidth - 10))
  6412.     {
  6413.         var top = getTop(tipobj);
  6414.         var increaseTo = getWidth(tipobj) * 1.1;
  6415.         tipobj.style.width = (increaseTo < (winwidth - 10)) ? increaseTo : (winwidth - 10); // object will autoadjust height
  6416.         tipobj.style.top = top;
  6417.         tipobj.style.bottom = top + getHeight(tipobj);
  6418.     }
  6419.    
  6420.     // prevent this from moving horizontally out of bounds
  6421.     var overRight = getRight(tipobj) - (winwidth - 5);
  6422.     if (overRight > 0)
  6423.     {
  6424.         tipobj.style.left = getLeft(tipobj) - overRight;
  6425.         tipobj.style.right = winwidth - 5;
  6426.         nondefaultpos = true;
  6427.     }
  6428.    
  6429.     var overLeft = 5 - getLeft(tipobj);
  6430.     if (overLeft > 0)
  6431.     {
  6432.         tipobj.style.left = 5;
  6433.         nondefaultpos = true;
  6434.     }
  6435.    
  6436.     return nondefaultpos;
  6437. }
  6438.  
  6439. function AdjustHeight(tipobj, winwidth, winheight)
  6440. {
  6441.     // If you alter this method, make the equivalent changes to AdjustWidth
  6442.     var nondefaultpos = false;
  6443.    
  6444.     // if it goes over the left adjust the height
  6445.     while (getLeft(tipobj) < 0 &&
  6446.     getHeight(tipobj) < (winheight - 10))
  6447.     {
  6448.         var right = getRight(tipobj);
  6449.         var increaseTo = getHeight(tipobj) * 1.1;
  6450.         tipobj.style.height = (increaseTo < (winheight - 10)) ? increaseTo : (winheight - 10); // object will autoadjust width
  6451.         tipobj.style.right = right;
  6452.         tipobj.style.left = right - getWidth(tipobj);
  6453.     }
  6454.    
  6455.     // if it goes over the right adjust the height
  6456.     while (parseInt(tipobj.style.right) > (winwidth - 5) && tipobj.offsetHeight < (winheight - 10))
  6457.     {
  6458.         var left = parseInt(tipobj.style.left);
  6459.         var increaseTo = tipobj.offsetHeight * 1.1;
  6460.         tipobj.style.height = (increaseTo < (winheight - 10)) ? increaseTo : (winheight - 10); // object will autoadjust width
  6461.         tipobj.style.left = left;
  6462.         tipobj.style.left = left + getWidth(tipobj);
  6463.     }
  6464.    
  6465.     // prevent this from moving vertically out of bounds
  6466.     var overBottom = getBottom(tipobj) - (winheight - 5);
  6467.     if (overBottom > 0)
  6468.     {
  6469.         tipobj.style.bottom = winheight - 5;
  6470.         nondefaultpos = true;
  6471.     }
  6472.    
  6473.     var overTop = 5 - getTop(tipobj);
  6474.     if (overTop > 0)
  6475.     {
  6476.         tipobj.style.top = 5;
  6477.         nondefaultpos = true;
  6478.     }
  6479.    
  6480.     return nondefaultpos;
  6481. }
  6482.  
  6483. function _getActual(obj, sToGet)
  6484. {
  6485.     var actual = eval("parseInt(obj.style." + sToGet + ")");
  6486.     if (isNaN(actual))
  6487.         actual = eval("obj.offset" + sToGet.substr(0, 1).toUpperCase() + sToGet.substr(1));
  6488.    
  6489.     return actual;
  6490. }
  6491.  
  6492. function getTop(obj)
  6493. {
  6494.     return _getActual(obj, "top");
  6495. }
  6496.  
  6497. function getLeft(obj)
  6498. {
  6499.     return _getActual(obj, "left");
  6500. }
  6501.  
  6502. function getWidth(obj)
  6503. {
  6504.     return _getActual(obj, "width");
  6505. }
  6506.  
  6507. function getHeight(obj)
  6508. {
  6509.     return _getActual(obj, "height");
  6510. }
  6511.  
  6512. function getBottom(obj)
  6513. {
  6514.     return getTop(obj) + getHeight(obj);
  6515. }
  6516.  
  6517. function getRight(obj)
  6518. {
  6519.     return getLeft(obj) + getWidth(obj);
  6520. }
  6521.  
  6522. document.onmousemove = positiontip;
  6523. addtip();
  6524.  
  6525. /* End included file /scripts/infocenter-tooltips.js */
  6526. /* Carbonite Service included file /js/schedule.js */
  6527. // (c) Carbonite, Inc., 2005-2009 All rights reserved
  6528. /* Carbonite Service included file /scripts/schedule.class.js */
  6529. // (c) Carbonite, Inc., 2005-2009 All rights reserved
  6530. /* Carbonite Service included file /scripts/box.class.js */
  6531. // (c) Carbonite, Inc., 2005-2009 All rights reserved
  6532. box = function()
  6533. {
  6534.     this.obj;
  6535.     this.GetObject = function()
  6536.     {
  6537.         return this.obj;
  6538.     }
  6539.     this.SetObject = function(ob)
  6540.     {
  6541.         this.obj = ob;
  6542.     }
  6543. }
  6544.  
  6545. /* End included file /scripts/box.class.js */
  6546.  
  6547. /* Carbonite Service SKIPPING already included file /scripts/commonfunctions.js */
  6548.  
  6549. var BACKUP_TYPE = "BackupType";
  6550. var START_HOUR = "StartHour";
  6551. var START_MINUTE = "StartMinute";
  6552. var START_AP = "StartAP";
  6553. var BACKUP_UNTIL = "BackupUntil";
  6554. var FINISH_HOUR = "FinishHour";
  6555. var FINISH_MINUTE = "FinishMinute";
  6556. var FINISH_AP = "FinishAP";
  6557. var ONCE_HOUR = "OnceHour";
  6558. var ONCE_MINUTE = "OnceMinute";
  6559. var ONCE_AP = "OnceAP";
  6560. var SSTART_HOUR = "SStartHour";
  6561. var SSTART_MINUTE = "SStartMinute";
  6562. var SSTART_AP = "SStartAP";
  6563. var SFINISH_HOUR = "SFinishHour";
  6564. var SFINISH_MINUTE = "SFinishMinute";
  6565. var SFINISH_AP = "SFinishAP";
  6566. var DAYS = "Days";
  6567. var NVSEP = ":";
  6568. var SEP = ";";
  6569. var DAYCHOICE = "DayChoice";
  6570. var SPECDAY_SUN = "SpecDaySun";
  6571. var SPECDAY_MON = "SpecDayMon";
  6572. var SPECDAY_TUE = "SpecDayTue";
  6573. var SPECDAY_WED = "SpecDayWed";
  6574. var SPECDAY_THU = "SpecDayThu";
  6575. var SPECDAY_FRI = "SpecDayFri";
  6576. var SPECDAY_SAT = "SpecDaySat";
  6577.  
  6578.  
  6579. var TimeControl = function (timeName, hr, min, processChange)
  6580. {
  6581.     var theHTML = "";
  6582.  
  6583.     hourName = timeName + "Hour";
  6584.     minuteName = timeName + "Minute";
  6585.     apName = timeName + "AP";
  6586.  
  6587.     // 24-hour cloc hour selection
  6588.     var HH = '<select name="' + hourName + '" onchange="' + processChange + '">';
  6589.     for(i = 0; i < 24; i++)
  6590.         HH += '<option value="' + i + '" ' + ((hr == i) ? 'selected="selected"' : '') + '>' + ((i < 10) ? '0' : '') + i + '</option>'
  6591.     HH += '</select>';
  6592.     // normalise the hour value for 12 hour clock
  6593.     ap = (hr > 11) ? "pm" : "am";
  6594.     hr = hr % 12;
  6595.     hr = (hr == 0) ? 12 : hr;
  6596.     var hh = '<select name="' + hourName + '" onchange="' + processChange + '">';
  6597.     for(i = 1; i < 13; i++)
  6598.         hh += '<option value="' + i % 12 + '" ' + ((hr == i) ? 'selected="selected"' : '') + '>' + ((i < 10) ? '0' : '') + i + '</option>'
  6599.     hh += '</select>';
  6600.  
  6601.     var mm = '<select name="' + minuteName + '" onchange="' + processChange + '">';
  6602.     for(i = 0; i < 60; i = i + 5)
  6603.         mm += '<option value="' + i + '" ' + ((min == i) ? 'selected="selected"' : '') + '>' + ((i < 10) ? '0' : '') + i + '</option>';
  6604.     mm += '</select>';
  6605.  
  6606.     var tt = '<input name="' + apName + '" type="radio" value="am" ' + ((ap == 'am') ? 'checked="checked"' : '') + ' onclick="' + processChange + '"/>' + strTimeAM;
  6607.     tt += '<input name="' + apName + '" type="radio" value="pm" ' + ((ap == 'pm') ? 'checked="checked"' : '') + ' onclick="' + processChange + '"/>' + strTimePM;
  6608.  
  6609.     var cPos = 0;
  6610.     var cPrev = "", cThis = "";
  6611.     while(cPos < timeFormat.length)
  6612.     {
  6613.         cThis = timeFormat.charAt(cPos);
  6614.  
  6615.         switch(cThis)
  6616.         {
  6617.             case "H":
  6618.                 if(cPrev != "H")
  6619.                     theHTML += HH;
  6620.                 break;
  6621.             case "h":
  6622.                 if(cPrev != "h")
  6623.                     theHTML += hh;
  6624.                 break;
  6625.             case "m":
  6626.                 if(cPrev != "m")
  6627.                     theHTML += mm;
  6628.                 break;
  6629.             case "t":
  6630.                 if(cPrev != "t")
  6631.                     theHTML += tt;
  6632.                 break;
  6633.             default:
  6634.                 theHTML += cThis;
  6635.                 break;
  6636.         }
  6637.  
  6638.         cPrev = cThis;
  6639.         cPos++;
  6640.     }
  6641.  
  6642.     return theHTML;
  6643. }
  6644.  
  6645. Schedule = function ()
  6646. {
  6647.     this.bUseFinishTime = false;
  6648.     this.StartHour = 0;
  6649.     this.StartMinute = 0;
  6650.     this.FinishHour = 0;
  6651.     this.FinishMinute = 0;
  6652.     this.Days = EveryDay;
  6653.    
  6654.     this.SetStartTime = function (hour, minute, ap)
  6655.     {
  6656.         this.StartHour = hour;
  6657.         this.StartMinute = minute;
  6658.         if(ap)
  6659.         {
  6660.             if(ap == "am")
  6661.             {
  6662.                 if(this.StartHour > 11)
  6663.                     this.StartHour = this.StartHour - 12;
  6664.             }
  6665.             else
  6666.             {
  6667.                 if(this.StartHour < 12)
  6668.                     this.StartHour = this.StartHour + 12;
  6669.             }
  6670.         }
  6671.     }
  6672.  
  6673.     this.SetFinishTime = function (hour, minute, ap)
  6674.     {
  6675.         this.bUseFinishTime = true;
  6676.         this.FinishHour = hour;
  6677.         this.FinishMinute = minute;
  6678.         if(ap)
  6679.         {
  6680.             if(ap == "am")
  6681.             {
  6682.                 if(this.FinishHour > 11)
  6683.                     this.FinishHour = this.FinishHour - 12;
  6684.             }
  6685.             else
  6686.             {
  6687.                 if(this.FinishHour < 12)
  6688.                     this.FinishHour = this.FinishHour + 12;
  6689.             }
  6690.         }
  6691.     }
  6692.  
  6693.     this.Parse = function (strStringDef)
  6694.     {
  6695.         if(strStringDef.length < 1)
  6696.             return;
  6697.  
  6698.         var nFindPair = 0;
  6699.         var NVs, NVPair;
  6700.  
  6701.         NVs = strStringDef.split(";");
  6702.         var i = 0;
  6703.         while(NVs[i])
  6704.         {
  6705.             if(NVs[i].indexOf(":") > -1)
  6706.             {
  6707.                 NVPair = NVs[i].split(":");
  6708.                 strValue = NVPair[1];
  6709.                 switch(NVPair[0])
  6710.                 {
  6711.                     case START_HOUR:
  6712.                         var newHour = parseInt(strValue);
  6713.                         this.StartHour = newHour;
  6714.                         break;
  6715.                     case START_MINUTE:
  6716.                         this.StartMinute = parseInt(strValue);
  6717.                         break;
  6718.                     case BACKUP_UNTIL:
  6719.                         this.bUseFinishTime = (strValue == "TimeUntil");
  6720.                         break;
  6721.                     case FINISH_HOUR:
  6722.                         var newHour = parseInt(strValue);
  6723.                         this.FinishHour = newHour;
  6724.                         this.bUseFinishTime = true;
  6725.                         break;
  6726.                     case FINISH_MINUTE:
  6727.                         this.FinishMinute = parseInt(strValue);
  6728.                         this.bUseFinishTime = true;
  6729.                         break;
  6730.                     case DAYS:
  6731.                         this.Days = strValue;
  6732.                         break;
  6733.                 }
  6734.             }
  6735.  
  6736.             i++;
  6737.         }
  6738.     }
  6739.  
  6740.     this.GetAsString = function ()
  6741.     {
  6742.         var strRet = START_HOUR + NVSEP + this.StartHour + SEP
  6743.                 + START_MINUTE + NVSEP + this.StartMinute + SEP
  6744.                 + BACKUP_UNTIL + NVSEP + (this.bUseFinishTime ? "TimeUntil" : "DoneUntil") + SEP
  6745.                 + DAYS + NVSEP + this.Days + SEP;
  6746.         if (this.bUseFinishTime) {
  6747.             strRet += FINISH_HOUR + NVSEP + this.FinishHour + SEP
  6748.             + FINISH_MINUTE + NVSEP + this.FinishMinute + SEP
  6749.         }
  6750.                
  6751.  
  6752.         return strRet;
  6753.     }
  6754.  
  6755.     this.GetTime = function (hr, mm)
  6756.     {
  6757.         var theTime = "";
  6758.         var hr24 = hr;
  6759.         var hr12 = hr % 12;
  6760.         if(hr12 == 0)
  6761.             hr12 = 12;
  6762.         var tt = ((hr > 11) ? strTimePM : strTimeAM);
  6763.  
  6764.         var cPos = 0;
  6765.         var cPrev = "", cThis = "";
  6766.         while(cPos < timeFormat.length)
  6767.         {
  6768.             cThis = timeFormat.charAt(cPos);
  6769.             cNext = (cPos < timeFormat.length - 1) ? timeFormat.charAt(cPos + 1) : "";
  6770.             switch(cThis)
  6771.             {
  6772.                 case "H":
  6773.                     if(cPrev != "H")
  6774.                         theTime += ((hr24 < 10 && cNext == "H") ? "0" : "") + hr24;
  6775.                     break;
  6776.                 case "h":
  6777.                     if(cPrev != "h")
  6778.                         theTime += ((hr12 < 10 && cNext == "h") ? "0" : "") + hr12;
  6779.                     break;
  6780.                 case "m":
  6781.                     if(cPrev != "m")
  6782.                         theTime += ((mm < 10 && cNext == "m") ? "0" : "") + mm;
  6783.                     break;
  6784.                 case "t":
  6785.                     if(cPrev != "t")
  6786.                         theTime += tt;
  6787.                     break;
  6788.                 default:
  6789.                     theTime += cThis;
  6790.                     break;
  6791.             }
  6792.             cPrev = cThis;
  6793.             cPos++;
  6794.         }
  6795.         return theTime;
  6796.     }
  6797.  
  6798.     this.GetStartTime = function ()
  6799.     {
  6800.         return this.GetTime(this.StartHour, this.StartMinute);
  6801.     }
  6802.  
  6803.     this.GetFinishTime = function ()
  6804.     {
  6805.         return this.GetTime(this.FinishHour, this.FinishMinute);
  6806.     }
  6807.  
  6808.     this.Description = function ()
  6809.     {
  6810.         if(this.Days == EveryDay)
  6811.             str = this.bUseFinishTime ? sdEveryDayTwoTimes : sdEveryDayOneTime;
  6812.         else if(this.Days == Weekdays)
  6813.             str = this.bUseFinishTime ? sdWeekdaysTwoTimes : sdWeekdaysOneTime;
  6814.         else
  6815.             str = this.bUseFinishTime ? sdSpecificDaysTwoTimes : sdSpecificDaysOneTime;
  6816.  
  6817.         str = str.replace("{startTime}", this.GetStartTime());
  6818.         str = str.replace("{finishTime}", this.GetFinishTime());
  6819.         str = str.replace("{listDays}", this.ListDays());
  6820.  
  6821.         return str;
  6822.     }
  6823.  
  6824.     this.ListDays = function ()
  6825.     {
  6826.         if(this.Days == 0)
  6827.             return strDescNoSchedule;
  6828.  
  6829.         strRet = "";
  6830.         if((this.Days & Sun) == Sun)
  6831.             strRet += strSundayShort + ", ";
  6832.         if((this.Days & Mon) == Mon)
  6833.             strRet += strMondayShort + ", ";
  6834.         if((this.Days & Tue) == Tue)
  6835.             strRet += strTuesdayShort + ", ";
  6836.         if((this.Days & Wed) == Wed)
  6837.             strRet += strWednesdayShort + ", ";
  6838.         if((this.Days & Thu) == Thu)
  6839.             strRet += strThursdayShort + ", ";
  6840.         if((this.Days & Fri) == Fri)
  6841.             strRet += strFridayShort + ", ";
  6842.         if((this.Days & Sat) == Sat)
  6843.             strRet += strSaturdayShort + ", ";
  6844.  
  6845.         // drop the ", " at the end of the list
  6846.         return strRet.substring(0, strRet.length - 2);
  6847.     }
  6848.  
  6849.     this.ProcessChange = function (o)
  6850.     {
  6851.         switch(o.name)
  6852.         {
  6853.             case START_HOUR:
  6854.             case SSTART_HOUR:
  6855.             case ONCE_HOUR:
  6856.                 var newHour = parseInt(o.value) + ((!Use24HourClock && this.StartHour > 11 && o.value < 12) ? 12 : 0);
  6857.                 this.StartHour = newHour;
  6858.                 break;
  6859.             case START_MINUTE:
  6860.             case SSTART_MINUTE:
  6861.             case ONCE_MINUTE:
  6862.                 this.StartMinute = parseInt(o.value);
  6863.                 break;
  6864.             case START_AP:
  6865.             case SSTART_AP:
  6866.             case ONCE_AP:
  6867.                 if(o.value == "am")
  6868.                 {
  6869.                     if(this.StartHour > 11)
  6870.                         this.StartHour = this.StartHour - 12;
  6871.                 }
  6872.                 else
  6873.                 {
  6874.                     if(this.StartHour < 12)
  6875.                         this.StartHour = this.StartHour + 12;
  6876.                 }
  6877.                 break;
  6878.             case FINISH_HOUR:
  6879.             case SFINISH_HOUR:
  6880.                 var newHour = parseInt(o.value) + ((!Use24HourClock && this.FinishHour > 11 && o.value < 12) ? 12 : 0);
  6881.                 this.FinishHour = newHour;
  6882.                 this.bUseFinishTime = true;
  6883.                 break;
  6884.             case FINISH_MINUTE:
  6885.             case SFINISH_MINUTE:
  6886.                 this.FinishMinute = parseInt(o.value);
  6887.                 this.bUseFinishTime = true;
  6888.                 break;
  6889.             case FINISH_AP:
  6890.             case SFINISH_AP:
  6891.                 if(o.value == "am")
  6892.                 {
  6893.                     if(this.FinishHour > 11)
  6894.                         this.FinishHour = this.FinishHour - 12;
  6895.                 }
  6896.                 else
  6897.                 {
  6898.                     if(this.FinishHour < 12)
  6899.                         this.FinishHour = this.FinishHour + 12;
  6900.                 }
  6901.                 this.bUseFinishTime = true;
  6902.                 break;
  6903.             case DAYCHOICE:
  6904.                 this.Days = (o.value == "Every") ? EveryDay : ((o.value == "Weekdays") ? Weekdays : 0);
  6905.                 break;
  6906.             case SPECDAY_SUN:
  6907.                 this.Days = o.checked ? this.Days | Sun : this.Days & ~Sun;
  6908.                 break;
  6909.             case SPECDAY_MON:
  6910.                 this.Days = o.checked ? this.Days | Mon : this.Days & ~Mon;
  6911.                 break;
  6912.             case SPECDAY_TUE:
  6913.                 this.Days = o.checked ? this.Days | Tue : this.Days & ~Tue;
  6914.                 break;
  6915.             case SPECDAY_WED:
  6916.                 this.Days = o.checked ? this.Days | Wed : this.Days & ~Wed;
  6917.                 break;
  6918.             case SPECDAY_THU:
  6919.                 this.Days = o.checked ? this.Days | Thu : this.Days & ~Thu;
  6920.                 break;
  6921.             case SPECDAY_FRI:
  6922.                 this.Days = o.checked ? this.Days | Fri : this.Days & ~Fri;
  6923.                 break;
  6924.             case SPECDAY_SAT:
  6925.                 this.Days = o.checked ? this.Days | Sat : this.Days & ~Sat;
  6926.                 break;
  6927.         }
  6928.         ScheduleSettings.UpdateDisplay(o.name, o.value);
  6929.     }
  6930.  
  6931.     this.OutputHTML = function (htmlTemplate)
  6932.     {
  6933.         var StartTime = new box();
  6934.         var FinishTime = new box();
  6935.         var newOne = htmlTemplate; //.cloneNode(true);
  6936.         this.UpdateScheduleControls(newOne, StartTime, FinishTime);
  6937.         if(StartTime.GetObject())
  6938.             StartTime.GetObject().innerHTML = TimeControl("Start", this.StartHour, this.StartMinute, "ScheduleSettings.ProcessSave(this);");
  6939.         if(FinishTime.GetObject())
  6940.             FinishTime.GetObject().innerHTML = TimeControl("Finish", this.FinishHour, this.FinishMinute, "ScheduleSettings.ProcessSave(this);");
  6941.         return newOne;
  6942.     }
  6943.  
  6944.     this.UpdateScheduleControls = function (theNode, StartTime, FinishTime)
  6945.     {
  6946.         var childNode;
  6947.  
  6948.         for(var i = 0; i < theNode.childNodes.length; i++)
  6949.         {
  6950.             childNode = theNode.childNodes[i];
  6951.  
  6952.             this.UpdateSpecificControl(childNode, StartTime, FinishTime);
  6953.  
  6954.             this.UpdateScheduleControls(childNode, StartTime, FinishTime);
  6955.         }
  6956.     }
  6957.  
  6958.     this.UpdateSpecificControl = function (childNode, StartTime, FinishTime)
  6959.     {
  6960.         if(childNode.attributes)
  6961.         {
  6962.             // Feed in the values from the schedule
  6963.             if(childNode.nodeName == "INPUT")
  6964.             {
  6965.                 switch(childNode.attributes["name"].value)
  6966.                 {
  6967.                     case "DayChoice":
  6968.                         switch(childNode.attributes["id"].value)
  6969.                         {
  6970.                             case "Every":
  6971.                                 CheckObject(childNode, this.Days == EveryDay);
  6972.                                 break;
  6973.                             case "Weekdays":
  6974.                                 CheckObject(childNode, this.Days == Weekdays);
  6975.                                 break;
  6976.                             case "Specific":
  6977.                                 CheckObject(childNode, this.Days != EveryDay && this.Days != Weekdays);
  6978.                                 break;
  6979.                         }
  6980.                         break;
  6981.                     case "SpecDaySun":
  6982.                     case "SpecDayMon":
  6983.                     case "SpecDayTue":
  6984.                     case "SpecDayWed":
  6985.                     case "SpecDayThu":
  6986.                     case "SpecDayFri":
  6987.                     case "SpecDaySat":
  6988.                         checkDay = eval(childNode.attributes["name"].value.substring(7));
  6989.                         CheckObject(childNode, ((this.Days & checkDay) == checkDay));
  6990.                         break;
  6991.                 }
  6992.             }
  6993.  
  6994.             if(childNode.attributes["class"])
  6995.             {
  6996.                 var className = childNode.attributes["class"].value;
  6997.                 switch(className)
  6998.                 {
  6999.                     case "crbScheduleStartTime":
  7000.                         StartTime.SetObject(childNode);
  7001.                         break;
  7002.                     case "crbScheduleFinishTime":
  7003.                         FinishTime.SetObject(childNode);
  7004.                         break;
  7005.                 }
  7006.             }
  7007.         }
  7008.     }
  7009.  
  7010.     this.IsEqualTo = function (sched)
  7011.     {
  7012.         var bEqual =
  7013.             (this.bUseFinishTime == sched.bUseFinishTime)
  7014.             && (this.StartHour == sched.StartHour)
  7015.             && (this.StartMinute == sched.StartMinute)
  7016.             && (this.FinishHour == sched.FinishHour)
  7017.             && (this.FinishMinute == sched.FinishMinute)
  7018.             && (this.Days == sched.Days);
  7019.  
  7020.         return bEqual;
  7021.     }
  7022.  
  7023.     this.IsValidTimeWindow = function ()
  7024.     {
  7025.         return !this.bUseFinishTime || !((this.StartHour == this.FinishHour) && (this.StartMinute == this.FinishMinute));
  7026.     }
  7027. }
  7028.  
  7029. /* End included file /scripts/schedule.class.js */
  7030. /* Carbonite Service SKIPPING already included file /scripts/commonfunctions.js */
  7031.  
  7032. /* Carbonite Service SKIPPING already included file /scripts/serviceinterconnect.js */
  7033.  
  7034. /* Carbonite Service included file /scripts/messagebox.js */
  7035. // (c) Carbonite, Inc., 2005-2009 All rights reserved
  7036. /* Carbonite Service SKIPPING already included file /scripts/string.class.js */
  7037.  
  7038. /* Carbonite Service SKIPPING already included file /scripts/commonfunctions.js */
  7039.  
  7040. /* Carbonite Service included file /js/wait.js */
  7041. // (c) Carbonite, Inc., 2005-2009 All rights reserved
  7042. // Useful common scripts for messaging while waiting
  7043.  
  7044. var Wait__ = function ()
  7045. {
  7046.     var self = this;
  7047.  
  7048.     var objOverlay = null;
  7049.     var nestedOverlays = new Array();
  7050.     var popupDiv = null;
  7051.     var orgID = null;
  7052.  
  7053.     function AddPopupDiv(waitDivId, processor)
  7054.     {
  7055.         popupDiv = document.createElement("div");
  7056.         popupDiv.className = "HorizontalCenter";
  7057.         var contentDiv = document.createElement("div");
  7058.         contentDiv.className = "LightBox";
  7059.         popupDiv.appendChild(contentDiv);
  7060.         var pWait = document.getElementById(waitDivId);
  7061.         orgID = waitDivId;
  7062.  
  7063.         if(processor)
  7064.         {
  7065.             // becuase we are processing, we create a clone that we change, rather than changing the original node
  7066.             pWait = pWait.cloneNode(true);
  7067.             orgID = null;
  7068.             pWait.innerHTML = processor(pWait.innerHTML);
  7069.         }
  7070.  
  7071.         contentDiv.appendChild(pWait);
  7072.  
  7073.         document.body.appendChild(popupDiv);
  7074.  
  7075.         pWait.style.display = "";
  7076.         pWait.style.visibility = "visible";
  7077.  
  7078.         var centerPos = $(popupDiv).offset();
  7079.         $(contentDiv).offset(
  7080.         {
  7081.             left: centerPos.left - (contentDiv.offsetWidth / 2),
  7082.             top: centerPos.top - (contentDiv.offsetHeight / 2)
  7083.         }
  7084.         );
  7085.     }
  7086.  
  7087.     function RemovePopupDiv()
  7088.     {
  7089.         if(popupDiv)
  7090.         {
  7091.             if(orgID)
  7092.             {
  7093.                 var orgDiv = document.getElementById(orgID);
  7094.                 orgDiv.parentNode.removeChild(orgDiv);
  7095.                 orgDiv.style.display = "none";
  7096.                 orgDiv.style.visibility = "hidden";
  7097.                 document.body.appendChild(orgDiv);
  7098.             }
  7099.             document.body.removeChild(popupDiv);
  7100.         }
  7101.         popupDiv = null;
  7102.         orgID = null;
  7103.     }
  7104.  
  7105.     function DoWaitOperation()
  7106.     {
  7107.         waitingMethod();
  7108.         self.StopWait();
  7109.     }
  7110.  
  7111.     this.Overlay = function (bShow)
  7112.     {
  7113.         if(bShow)
  7114.         {
  7115.             if(objOverlay)
  7116.             {
  7117.                 nestedOverlays.push(objOverlay);
  7118.             }
  7119.             objOverlay = document.createElement("div");
  7120.             objOverlay.className = "LightBoxBackground";
  7121.             objOverlay.setAttribute("id", "overlay");
  7122.             document.body.appendChild(objOverlay);
  7123.         }
  7124.         else
  7125.         {
  7126.             if(objOverlay)
  7127.                 document.body.removeChild(objOverlay);
  7128.             objOverlay = null;
  7129.             if(nestedOverlays.length > 0)
  7130.                 objOverlay = nestedOverlays.pop();
  7131.         }
  7132.     }
  7133.  
  7134.     this.IsPopped = function ()
  7135.     {
  7136.         return popupDiv != null;
  7137.     }
  7138.  
  7139.     this.AddWaitingDiv = function (waitDivId, processor)
  7140.     {
  7141.         AddPopupDiv(waitDivId, processor);
  7142.         document.body.style.cursor = "wait";
  7143.     }
  7144.  
  7145.     this.RemoveWaitingDiv = function ()
  7146.     {
  7147.         document.body.style.cursor = "default";
  7148.         RemovePopupDiv();
  7149.     }
  7150.  
  7151.     /*
  7152.     Wait - shows message during wait operation (overlaying background with opaque grey)
  7153.     Arguments:
  7154.     messageId - id of the html node to show within the waiting div (required)
  7155.     methodToCall - pointer to method to call (optional; if not provided, caller is responsible for calling StopWait())
  7156.     decorationMethod - method that will preprocess the message to update its contents if necessary
  7157.     */
  7158.     var waitingMethod = null;
  7159.     this.DoWait = function (messageId, methodToCall, decorationMethod)
  7160.     {
  7161.         self.Overlay(true);
  7162.         self.AddWaitingDiv(messageId, decorationMethod);
  7163.  
  7164.         if(methodToCall)
  7165.         {
  7166.             // let us know what the method to call is
  7167.             waitingMethod = methodToCall;
  7168.             //var fnCall = "DoWaitOperation('" + methodToCall + "')";
  7169.             setTimeout(DoWaitOperation, 0);
  7170.         }
  7171.     }
  7172.  
  7173.     this.StopWait = function ()
  7174.     {
  7175.         waitingMethod = null;
  7176.         self.RemoveWaitingDiv();
  7177.         self.Overlay(false);
  7178.     }
  7179.  
  7180.     this.Popup = function (messageId, decorationMethod)
  7181.     {
  7182.         self.Overlay(true);
  7183.         AddPopupDiv(messageId, decorationMethod);
  7184.     }
  7185.  
  7186.     this.StopPopup = function ()
  7187.     {
  7188.         RemovePopupDiv();
  7189.         self.Overlay(false);
  7190.     }
  7191.  
  7192. }
  7193.  
  7194. var Wait = new Wait__();
  7195.  
  7196. /* End included file /js/wait.js */
  7197.  
  7198. var msgBoxArgs = {};
  7199.  
  7200. BUTTON_OK = 0x01;
  7201. BUTTON_CANCEL = 0x02;
  7202. BUTTON_YES = 0x04;
  7203. BUTTON_NO = 0x08;
  7204. BUTTONS_OKCANCEL = BUTTON_OK | BUTTON_CANCEL;
  7205. BUTTONS_YESNO = BUTTON_YES | BUTTON_NO;
  7206. BUTTONS_YESNOCANCEL = BUTTON_YES | BUTTON_NO | BUTTON_CANCEL;
  7207.  
  7208. ID_YES = 'IdYes';
  7209. ID_NO = 'IdNo';
  7210. ID_OK = 'IdOK';
  7211. ID_CANCEL = 'IdCancel';
  7212.  
  7213. ICON_NONE = 1;
  7214. ICON_INFO = 2;
  7215. ICON_WARNING = 3;
  7216.  
  7217. MESSAGEBOX_ERROR_NOELEMENT = -1;
  7218.  
  7219. function HtmlMessageBoxFromUrl(url)
  7220. {
  7221.     // grey out the area of the main window
  7222.     Wait.Overlay(true);
  7223.     var retval = external.AlertFromUrl(url);
  7224.     Wait.Overlay(false);
  7225.  
  7226.     return retval;
  7227. }
  7228.  
  7229. function HtmlMessageBox2(id, buttonSpec)
  7230. {
  7231.     if (typeof (external.Alert) == "undefined")
  7232.         return (BUTTON_OK == HtmlMessageBox(id, buttonSpec) ? ID_OK : ID_CANCEL);
  7233.        
  7234.     var theNode = document.getElementById(id);
  7235.     if (!theNode)
  7236.         return MESSAGEBOX_ERROR_NOELEMENT;
  7237.  
  7238.     switch (buttonSpec) {
  7239.         case BUTTON_OK: buttonSpec = ID_OK; break;
  7240.         case BUTTON_CANCEL: buttonSpec = ID_CANCEL; break;
  7241.         case BUTTON_YES: buttonSpec = ID_YES; break;
  7242.         case BUTTON_NO: buttonSpec = ID_NO; break;
  7243.         case BUTTONS_OKCANCEL: buttonSpec = ID_CANCEL + '*_default*SecondaryButton|' + ID_OK; break;
  7244.         case BUTTONS_YESNO: buttonSpec = ID_NO + '*_default*SecondaryButton|' + ID_YES; break;
  7245.         case BUTTONS_YESNOCANCEL: buttonSpec = buttonSpec = ID_CANCEL + '*_default*SecondaryButton|' + ID_NO + '*_default*SecondaryButton|' + ID_YES; break;
  7246.     }
  7247.     //the node style indicates the size of the messagebox with dialogHeight and dialogWidth
  7248.     //the captions for the buttons need not be stated for common buttons (see HTMLMessageBox2.html)
  7249.     //otherwise, the button spec is sent as id1*caption1|id2*caption2|...|idN*captionN
  7250.  
  7251.     // grey out the area of the main window
  7252.     Wait.Overlay(true);
  7253.     var retval = external.Alert("", theNode.outerHTML, buttonSpec);
  7254.     Wait.Overlay(false);
  7255.  
  7256.     return retval;
  7257. }
  7258.  
  7259. /*
  7260.     The opts parameters is a javascript Object used to pass in
  7261.     a variable set of optional settings.
  7262.    
  7263.     Usage:
  7264.    
  7265.         var options = new Object();
  7266.         options.idOkButtonText = "crbConfirmUnfreezeOkButton";
  7267.         options.idCancelButtonText = "crbConfirmUnfreezeCancelButton";
  7268.         options.iconType = ICON_NONE;
  7269.         if (HtmlMessageBox('crbConfirmUnfreeze', BUTTONS_OKCANCEL, options) == BUTTON_OK)
  7270.         {
  7271.             ...do stuff...
  7272.         }
  7273.  
  7274.     Option properties:
  7275.    
  7276.         - idOkButtonText: the id of an element that contains the replacement text
  7277.           for the OK button.
  7278.         - idCancelButtonText: ... Cancel button.
  7279.         - idYesButtonText: ... Yes button.
  7280.         - idNoButtonText: ... No button.
  7281.         - iconType: sets or turns off the message box icon (default is an info icon).
  7282.           Use one of the ICON_x constants (see top of this file).
  7283.    
  7284. */
  7285. function HtmlMessageBox(id, buttonTypes, opts)
  7286. {
  7287.     var theNode = document.getElementById(id);
  7288.     if (!theNode)
  7289.         return MESSAGEBOX_ERROR_NOELEMENT;
  7290.    
  7291.     // Our call to MessageBox / MessageBoxStyle needs an options param,
  7292.     // too. So we'll just use the one that caller passed to us, if any,
  7293.     // creating a new one only if necessary.
  7294.     if (opts == null)
  7295.         opts = new Object();
  7296.     opts.Message = theNode.innerHTML;
  7297.     opts.Buttons = buttonTypes;
  7298.    
  7299.     // process optional opts settings
  7300.     if (opts.idOkButtonText)
  7301.         opts.OkButtonText = ReadButtonText(opts.idOkButtonText);
  7302.     if (opts.idCancelButtonText)
  7303.         opts.CancelButtonText = ReadButtonText(opts.idCancelButtonText);
  7304.     if (opts.idYesButtonText)
  7305.         opts.YesButtonText = ReadButtonText(opts.idYesButtonText);
  7306.     if (opts.idNoButtonText)
  7307.         opts.NoButtonText = ReadButtonText(opts.idNoButtonText);
  7308.  
  7309.     var sStyle = theNode.style;
  7310.     var retVal;
  7311.     if (sStyle)
  7312.     {
  7313.         theNode.removeAttribute("title");
  7314.         retVal = MessageBoxStyle(opts, sStyle);
  7315.     }
  7316.     else
  7317.         retVal = MessageBox(opts);
  7318.    
  7319.     return retVal;
  7320. }
  7321.  
  7322. function ParseStyle(sStyle, d, w)
  7323. {
  7324.     var buffer = 50;
  7325.  
  7326.     var dialogHeight = -1;
  7327.     var dialogWidth = -1;
  7328.     var dialogTop = -1;
  7329.     var dialogLeft = -1;
  7330.    
  7331.     var styleString = (sStyle.cssText!=null)?sStyle.cssText:sStyle;
  7332.     var nvPairs = styleString.split(";");
  7333.     var newStyle = "";
  7334.     for(var i=0; i<nvPairs.length; i++)
  7335.     {
  7336.         if(nvPairs[i].length>0)
  7337.         {
  7338.             var stylePair = nvPairs[i].split(":");
  7339.             switch(stylePair[0].trim().toLowerCase())
  7340.             {
  7341.             // if we've been provided dialog attributes
  7342.             case "dialogheight":
  7343.             case "dialogtop":
  7344.             case "dialogleft":
  7345.             case "dialogwidth":
  7346.                 eval(stylePair[0] + " = parseInt('" + stylePair[1] + "')");
  7347.                 break;
  7348.            
  7349.             // Check for things that hide these items; we want to force them to be visible for the message box
  7350.             case "visibility":
  7351.                 if (stylePair[1].trim().toLowerCase() != "hidden")
  7352.                     newStyle += stylePair[0] + ":" + stylePair[1] + ";";
  7353.                 break;
  7354.             case "display":
  7355.                 if (stylePair[1].trim().toLowerCase() != "none")
  7356.                     newStyle += stylePair[0] + ":" + stylePair[1] + ";";
  7357.                 break;
  7358.                
  7359.             // by default, pass the style on through
  7360.             default:
  7361.                 newStyle += stylePair[0] + ":" + stylePair[1] + ";";
  7362.                 break;
  7363.             }
  7364.         }
  7365.     }
  7366.    
  7367.     // If a height has been specified, adjust it (add 40) for IE6.
  7368.     if (dialogHeight > 0 && IsIE6())
  7369.         dialogHeight += 40;
  7370.    
  7371.     // Use default sizes if not supplied
  7372.     if (dialogHeight < 0)
  7373.         dialogHeight = d.body.clientHeight - buffer * 2;
  7374.     if (dialogWidth < 0)
  7375.         dialogWidth = d.body.clientWidth - buffer * 2;
  7376.    
  7377.     // Minimum height that IE allows is 100px, minimum width 250px - if the passed in values are smaller, the dialog will not be centered
  7378.     if (dialogHeight < 100)
  7379.         dialogHeight = 100;
  7380.     if (dialogWidth < 250)
  7381.         dialogWidth = 250;
  7382.    
  7383.     // center the dialog with respect to the screen, unless top and/or left have been provided to force it elsewhere
  7384.     if (dialogLeft < 0)
  7385.         dialogLeft = w.screenLeft + (d.body.clientWidth - dialogWidth) / 2;
  7386.     if (dialogTop < 0)
  7387.         dialogTop = w.screenTop + (d.body.clientHeight - dialogHeight) / 2;
  7388.    
  7389.     newStyle += "dialogHeight: " + dialogHeight + "px;dialogWidth: " + dialogWidth + "px;dialogTop: " + dialogTop + "px;dialogLeft:" + dialogLeft + " px;";
  7390.    
  7391.     return newStyle;
  7392. }
  7393.  
  7394. function MessageBox(vArgs)
  7395. {
  7396.     return MessageBoxStyle(vArgs, "");
  7397. }
  7398.  
  7399. function MessageBoxStyle(vArgs, style)
  7400. {
  7401.     var d = top ? top.document : document;
  7402.     var w = top ? top.window : window;
  7403.  
  7404.     Wait.Overlay(true);
  7405.     var retVal = window.showModalDialog("MessageBox.htm", vArgs, "center: no;status: no;unadorned: yes;" + ParseStyle(style, d, w));
  7406.     Wait.Overlay(false);   
  7407.     return retVal;
  7408. }
  7409.  
  7410. function WriteMessage()
  7411. {
  7412.     if (msgBoxArgs.Message)
  7413.         document.write(msgBoxArgs.Message);
  7414. }
  7415.  
  7416. function AppendButtonTags(currButtonType, sButtonName, buttonPanel)
  7417. {
  7418.     var button = document.getElementById(sButtonName);
  7419.     var i = 0;
  7420.     var buttonContent;
  7421.     var isOverrideText = IsOverrideButtonText(currButtonType);
  7422.     while (buttonContent = button.childNodes[i])
  7423.     {
  7424.         var newNode = buttonContent.cloneNode(true);
  7425.         if (isOverrideText)
  7426.             ReplaceCurrentButtonText(currButtonType, newNode);
  7427.         buttonPanel.appendChild(newNode);
  7428.         i++;
  7429.     }
  7430. }
  7431.  
  7432. function WriteButtons()
  7433. {
  7434.     var buttonPanel = document.getElementById("crbMessageBoxButtons");
  7435.     if (msgBoxArgs.Buttons & BUTTON_CANCEL)
  7436.         AppendButtonTags(BUTTON_CANCEL, "crbMsgBoxCancel", buttonPanel);
  7437.     // Add the OK button if msgBoxArgs.Buttons is null.  This happens
  7438.     // when loaded from the Skin extended menu in CarboniteUI.
  7439.     if (!msgBoxArgs.Buttons || (msgBoxArgs.Buttons & BUTTON_OK))
  7440.         AppendButtonTags(BUTTON_OK, "crbMsgBoxOK", buttonPanel);
  7441.     if (msgBoxArgs.Buttons & BUTTON_NO)
  7442.         AppendButtonTags(BUTTON_NO, "crbMsgBoxNo", buttonPanel);
  7443.     if (msgBoxArgs.Buttons & BUTTON_YES)
  7444.         AppendButtonTags(BUTTON_YES, "crbMsgBoxYes", buttonPanel);
  7445. }
  7446.  
  7447. function ReturnResult(result)
  7448. {
  7449.     returnValue = result;
  7450.     window.close();
  7451. }
  7452.  
  7453. function ReadButtonText(id)
  7454. {
  7455.     var theNode = document.getElementById(id);
  7456.     if (!theNode)
  7457.         return null;
  7458.     return theNode.innerHTML;
  7459. }
  7460.  
  7461. function IsOverrideButtonText(currButtonType)
  7462. {
  7463.     if ( (currButtonType == BUTTON_OK && msgBoxArgs.OkButtonText)
  7464.          || (currButtonType == BUTTON_CANCEL && msgBoxArgs.CancelButtonText)
  7465.          || (currButtonType == BUTTON_YES && msgBoxArgs.YesButtonText)
  7466.          || (currButtonType == BUTTON_NO && msgBoxArgs.NoButtonText))
  7467.     {
  7468.         return true;
  7469.     }
  7470.     return false;
  7471. }
  7472.  
  7473. function ReplaceCurrentButtonText(currButtonType, newNode)
  7474. {
  7475.     var res = newNode.getElementsByTagName('a');
  7476.     if (res == null || res.length == 0)
  7477.         return;
  7478.     if (currButtonType == BUTTON_OK)
  7479.         res[0].innerHTML = msgBoxArgs.OkButtonText;
  7480.     if (currButtonType == BUTTON_CANCEL)
  7481.         res[0].innerHTML = msgBoxArgs.CancelButtonText;
  7482.     if (currButtonType == BUTTON_YES)
  7483.         res[0].innerHTML = msgBoxArgs.YesButtonText;
  7484.     if (currButtonType == BUTTON_NO)
  7485.         res[0].innerHTML = msgBoxArgs.NoButtonText;    
  7486. }
  7487.  
  7488. function FinalizeDocument()
  7489. {
  7490.     // change or remove message box's "info" icon
  7491.     if (msgBoxArgs.iconType)
  7492.     {
  7493.         var n = document.getElementById("crbMsgBoxText");
  7494.         if (n != null)
  7495.         {
  7496.             if (msgBoxArgs.iconType == ICON_WARNING)
  7497.                 n.style.backgroundImage = "url(../images/alert.png)";
  7498.             else if (msgBoxArgs.iconType == ICON_NONE)
  7499.             {
  7500.                 n.style.backgroundImage = "none";
  7501.                 n.style.paddingLeft = "0";
  7502.                
  7503.             }
  7504.         }
  7505.     }
  7506. }
  7507.  
  7508. // Utility message box functions
  7509. /* Takes the ID of the span containing the dialog box text; pops a confirmation dialog */
  7510. function crbConfirm2(id)
  7511. {
  7512.     return ID_OK == (buttonSelected = HtmlMessageBox2(id, BUTTONS_OKCANCEL));
  7513. }
  7514.  
  7515. /* Takes the ID of the span containing the dialog box text; pops an alert dialog */
  7516. function crbAlert(id)
  7517. {
  7518.     HtmlMessageBox2(id, BUTTON_OK);
  7519. }
  7520.  
  7521. function crbConfirmYN2(id)
  7522. {
  7523.     var buttonSelected;
  7524.     return ID_YES == (buttonSelected = HtmlMessageBox2(id, BUTTONS_YESNO));
  7525. }
  7526. /* End included file /scripts/messagebox.js */
  7527.  
  7528. function formatTime(hour, minute, iso) {
  7529.   var printMinute = minute;
  7530.   if (minute < 10) printMinute = '0' + minute;
  7531.  
  7532.   if (iso) {
  7533.     var printHour = hour
  7534.     if (printHour < 10) printHour = '0' + hour;
  7535.     return printHour + ':' + printMinute;
  7536.   } else {
  7537.     var printHour = hour % 12;
  7538.     if (printHour == 0) printHour = 12;
  7539.     var half = (hour < 12) ? 'am' : 'pm';
  7540.     return printHour + ':' + printMinute + half;
  7541.   }
  7542. }
  7543.  
  7544. function parseTime(text) {
  7545.   var match = match = /(\d+)\s*[:\-\.,]\s*(\d+)\s*(am|pm)?/i.exec(text);
  7546.   if (match && match.length >= 3) {
  7547.     var hour = Number(match[1]);
  7548.     var minute = Number(match[2])
  7549.     if (hour == 12 && match[3]) hour -= 12;
  7550.     if (match[3] && match[3].toLowerCase() == 'pm') hour += 12;
  7551.     return {
  7552.       hour: hour,
  7553.       minute: minute
  7554.     };
  7555.   } else {
  7556.     return null;
  7557.   }
  7558. }
  7559.  
  7560. var MIScheduleSettings__ = function () {
  7561.   var CONTINUOUS = 0;
  7562.   var ONCE_PER_DAY = 1;
  7563.   var EXCLUDE_HOURS = 2;
  7564.  
  7565.   this.PutMISchedule = function () {
  7566.     // Schedule types
  7567.     var scheduleInfo = {
  7568.       "ScheduleType": CONTINUOUS,
  7569.       "StartHour": 0,
  7570.       "StartMinute": 0,
  7571.       "EndHour": 0,
  7572.       "EndMinute": 0
  7573.     };
  7574.     if ($("#MIdaily").is(":checked")) {
  7575.       scheduleInfo.ScheduleType = ONCE_PER_DAY;
  7576.       var startTime = parseTime($('#MIbackup_start').val());
  7577.       if (startTime) {
  7578.         scheduleInfo.StartHour = startTime.hour;
  7579.         scheduleInfo.StartMinute = startTime.minute;
  7580.       }
  7581.     } else if ($("#MIexcludeHours").is(":checked")) {
  7582.       scheduleInfo.ScheduleType = EXCLUDE_HOURS;
  7583.       var startTime = parseTime($('#MIexclude_start').val());
  7584.       if (startTime) {
  7585.         scheduleInfo.StartHour = startTime.hour;
  7586.         scheduleInfo.StartMinute = startTime.minute;
  7587.       }
  7588.       var endTime = parseTime($('#MIexclude_end').val());
  7589.       if (endTime) {
  7590.         scheduleInfo.EndHour = endTime.hour;
  7591.         scheduleInfo.EndMinute = endTime.minute;
  7592.       }
  7593.     }
  7594.  
  7595.     this.UpdateTimeFields(scheduleInfo.ScheduleType, scheduleInfo.StartHour, scheduleInfo.StartMinute, scheduleInfo.EndHour, scheduleInfo.EndMinute);
  7596.  
  7597.     var scheduleJSON = $.toJSON(scheduleInfo);
  7598.     $.ajax({
  7599.       url: "/put-MIschedule.htm",
  7600.       data: "nocache=1&schedule=" + scheduleJSON
  7601.     });
  7602.   }
  7603.  
  7604.   this.initMISchedule = function () {
  7605.     var data = $.parseJSON($("#crbMIScheduleInfo").html());
  7606.  
  7607.     // Init defaults for daily backup and exclude range backup
  7608.     // Daily backup will default to midnight
  7609.     var defaultDailyBackupTime = formatTime(0, 0, Use24HourClock);
  7610.     $('#MIbackup_start').val(defaultDailyBackupTime);
  7611.     $('#MIbackup_start_text').text(defaultDailyBackupTime);
  7612.  
  7613.     // Exclude range backup will default to the current time + 2 hours
  7614.     var defaultExcludeStartTime = new Date();
  7615.     var defaultExcludeStartHour = defaultExcludeStartTime.getHours();
  7616.     var defaultExcludeStartMin = defaultExcludeStartTime.getMinutes() < 15 ? 0 : 30;
  7617.     var defaultExcludeEndTime = new Date();
  7618.     var defaultExcludeEndHour = (defaultExcludeEndTime.getHours() + 2) % 24;
  7619.     var defaultExcludeEndMinute = defaultExcludeEndTime.getMinutes() < 15 ? 0 : 30;
  7620.     var defaultExcludeStartTimeText = formatTime(defaultExcludeStartHour, defaultExcludeStartMin, Use24HourClock);
  7621.     var defaultExcludeEndTimeText = formatTime(defaultExcludeEndHour, defaultExcludeEndMinute, Use24HourClock);
  7622.     $('#MIexclude_start').val(defaultExcludeStartTimeText);
  7623.     $('#MIexclude_start_text').text(defaultExcludeStartTimeText);
  7624.     $('#MIexclude_end').val(defaultExcludeEndTimeText);
  7625.     $('#MIexclude_end_text').text(defaultExcludeEndTimeText);
  7626.  
  7627.     // Now load the schedule according to the data in crbMIScheduleInfo
  7628.     if (data.ScheduleType == CONTINUOUS) {
  7629.       $('#MIcontinuously').click();
  7630.     } else if (data.ScheduleType == ONCE_PER_DAY) {
  7631.       $('#MIdaily').click();
  7632.       var startTime = formatTime(data.StartHour, data.StartMinute, Use24HourClock);
  7633.       $('#MIbackup_start').val(startTime);
  7634.       $('#MIbackup_start_text').text(startTime);
  7635.     } else if (data.ScheduleType == EXCLUDE_HOURS) {
  7636.       $('#MIexcludeHours').click();
  7637.       var startTime = formatTime(data.StartHour, data.StartMinute, Use24HourClock);
  7638.       var endTime = formatTime(data.EndHour, data.EndMinute, Use24HourClock);
  7639.       $('#MIexclude_start').val(startTime);
  7640.       $('#MIexclude_start_text').text(startTime);
  7641.       $('#MIexclude_end').val(endTime);
  7642.       $('#MIexclude_end_text').text(endTime);
  7643.     }
  7644.   }
  7645.  
  7646.   this.UpdateTimeFields = function (scheduleType, startHour, startMinute, endHour, endMinute) {
  7647.     var startTime = formatTime(startHour, startMinute, Use24HourClock);
  7648.     var endTime = formatTime(endHour, endMinute, Use24HourClock);
  7649.     if (scheduleType == ONCE_PER_DAY) {
  7650.       $('#MIbackup_start_text').text(startTime);
  7651.     } else if (scheduleType == EXCLUDE_HOURS) {
  7652.       $('#MIexclude_start_text').text(startTime);
  7653.       $('#MIexclude_end_text').text(endTime);
  7654.     }
  7655.   }
  7656. }
  7657.  
  7658. var ScheduleSettings__ = function ()
  7659. {
  7660.     function E$(id)
  7661.     {
  7662.         return document.getElementById(id);
  7663.     }
  7664.  
  7665.     var self = this;
  7666.  
  7667.     this.Schedules = new Object;
  7668.     var scheduleNum;
  7669.     var schedule;
  7670.     var ifrPoster = null;
  7671.     var needsCommit = false;
  7672.  
  7673.     NO_SCHEDULE = 0;
  7674.     SINGLE_SCHEDULE = 1;
  7675.     MULTIPLE_SCHEDULE = 2;
  7676.     var scheduleType = NO_SCHEDULE;
  7677.  
  7678.     Sun = 0x01;
  7679.     Mon = 0x02;
  7680.     Tue = 0x04;
  7681.     Wed = 0x08;
  7682.     Thu = 0x10;
  7683.     Fri = 0x20;
  7684.     Sat = 0x40;
  7685.     EveryDay = Sun | Mon | Tue | Wed | Thu | Fri | Sat;
  7686.     Weekdays = Mon | Tue | Wed | Thu | Fri;
  7687.  
  7688.     localNav = false;
  7689.  
  7690.     /* Silence javascript errors */
  7691.     window.onerror = parent.trapError;
  7692.  
  7693.     function DefaultSchedule()
  7694.     {
  7695.         return self.Schedules[0] ? self.Schedules[0] : schedule;
  7696.     }
  7697.  
  7698.  
  7699.     function ShowHideTimeControl(sName, bShow)
  7700.     {
  7701.         var hourName = sName + "Hour";
  7702.         var minuteName = sName + "Minute";
  7703.  
  7704.         var dropdown = E$(hourName);
  7705.         dropdown.style.display = bShow ? "" : "none";
  7706.  
  7707.         dropdown = E$(minuteName);
  7708.         dropdown.style.display = bShow ? "" : "none";
  7709.  
  7710.     }
  7711.  
  7712.     function HideTimeControl(sName, timeout)
  7713.     {
  7714.         // delay before executing the hide so that this operation blends with the other effects
  7715.         setTimeout('ShowHideTimeControl("' + sName + '", false)', timeout);
  7716.     }
  7717.  
  7718.     function ShowTimeControl(sName, timeout)
  7719.     {
  7720.         // delay before executing the hide so that this operation blends with the other effects
  7721.         setTimeout('ShowHideTimeControl("' + sName + '", true)', timeout);
  7722.     }
  7723.  
  7724.     this.AdvancedScheduling = function ()
  7725.     {
  7726.         var border = 10;
  7727.  
  7728.         var over = E$('overlay');
  7729.         // stretch overlay to fill page and fade in
  7730.         var arrayPageSize = getPageSize();
  7731.         over.style.position = "absolute";
  7732.         over.style.width = arrayPageSize[0];
  7733.         over.style.height = arrayPageSize[1];
  7734.         over.style.top = 0;
  7735.         over.style.left = 0;
  7736.         over.style.display = "";
  7737.  
  7738.         var as = E$("AdvancedSchedule");
  7739.         RefreshAdvancedScheduleList();
  7740.         as.style.position = "absolute";
  7741.         as.style.width = arrayPageSize[0] - border * 2;
  7742.         as.style.height = 0; // style appears to be determining height
  7743.         as.style.top = border;
  7744.         as.style.left = border;
  7745.         as.style.display = "";
  7746.  
  7747.         // if we have no advanced rules, then open the entry screen for the first one anyway
  7748.         if(!self.Schedules[0])
  7749.             self.AddNewSchedule();
  7750.     }
  7751.  
  7752.     this.SimpleScheduling = function ()
  7753.     {
  7754.         schedule = DefaultSchedule() ? DefaultSchedule() : new Schedule();
  7755.         E$('AdvancedSchedule').style.display = "none";
  7756.         E$('overlay').style.display = "none";
  7757.     }
  7758.  
  7759.     this.AddNewSchedule = function ()
  7760.     {
  7761.         var nTotal = 0;
  7762.         while(self.Schedules[nTotal])
  7763.             nTotal++;
  7764.         self.EditSchedule(nTotal);
  7765.     }
  7766.  
  7767.     this.EditSchedule = function (num)
  7768.     {
  7769.         var as = E$("AdvancedSchedule");
  7770.         var es = E$("EditSchedule");
  7771.  
  7772.         es.style.position = as.style.position;
  7773.         es.style.width = as.style.width;
  7774.         es.style.height = as.style.height;
  7775.         es.style.top = as.style.top;
  7776.         es.style.left = as.style.left;
  7777.         GetEditSchedule(num);
  7778.         as.style.display = "none";
  7779.         es.style.display = "";
  7780.     }
  7781.  
  7782.     this.StopEdit = function ()
  7783.     {
  7784.         schedule = self.Schedules[0] ? self.Schedules[0] : new Schedule();
  7785.         scheduleNum = -1;
  7786.         RefreshAdvancedScheduleList();
  7787.         if(self.Schedules[0])
  7788.         {
  7789.             E$('EditSchedule').style.display = "none";
  7790.             E$('AdvancedSchedule').style.display = "";
  7791.         }
  7792.         else
  7793.         {
  7794.             // go all the way back to the main schedule screen
  7795.             E$('EditSchedule').style.display = "none";
  7796.             E$('AdvancedSchedule').style.display = "none";
  7797.             E$('overlay').style.display = "none";
  7798.         }
  7799.     }
  7800.  
  7801.     function GetEditSchedule(num)
  7802.     {
  7803.         // create temporary copy of schedule in placeholder
  7804.         scheduleNum = num;
  7805.         schedule = new Schedule();
  7806.         if(self.Schedules[scheduleNum])
  7807.             schedule.Parse(self.Schedules[scheduleNum].GetAsString());
  7808.  
  7809.         var editSchedule = schedule.OutputHTML(E$("ScheduleDetails"));
  7810.         var sg = E$("ScheduleGetter");
  7811.         // clean any children present - this one will need to be the only one
  7812.         while(sg.childNodes[0])
  7813.         {
  7814.             sg.removeChild(sg.childNodes[0])
  7815.         };
  7816.         sg.appendChild(editSchedule);
  7817.     }
  7818.  
  7819.     function AddOrChangeSchedule(sched, num)
  7820.     {
  7821.         var i = 0;
  7822.         var bIsUnique = true;
  7823.         while(self.Schedules[i] && bIsUnique)
  7824.         {
  7825.             bIsUnique = !self.Schedules[i].IsEqualTo(sched);
  7826.             i++;
  7827.         }
  7828.  
  7829.         if(bIsUnique)
  7830.             self.Schedules[num] = sched;
  7831.  
  7832.         return bIsUnique;
  7833.     }
  7834.  
  7835.     function SaveEditSchedule()
  7836.     {
  7837.         schedule.bUseFinishTime = true;
  7838.         var bAdded = AddOrChangeSchedule(schedule, scheduleNum);
  7839.  
  7840.         if(bAdded)
  7841.         {
  7842.             scheduleType = MULTIPLE_SCHEDULE;
  7843.             E$("Advanced").checked = true;
  7844.             self.ShowApplyButton();
  7845.             self.StopEdit();
  7846.         }
  7847.  
  7848.         return bAdded;
  7849.     }
  7850.  
  7851.     this.DeleteSchedule = function (iNum)
  7852.     {
  7853.         var i = 0;
  7854.         while(self.Schedules[i])
  7855.         {
  7856.             if(i > iNum)
  7857.                 self.Schedules[i - 1] = self.Schedules[i];
  7858.             i++;
  7859.         }
  7860.         self.Schedules[i - 1] = null;
  7861.         if(!self.Schedules[0])
  7862.         {
  7863.             scheduleType = NO_SCHEDULE;
  7864.             E$("continuously").checked = true;
  7865.         }
  7866.         self.ShowApplyButton();
  7867.         RefreshAdvancedScheduleList();
  7868.     }
  7869.  
  7870.     function PutScheduleInfo(str, onsavedfunc)
  7871.     {
  7872.         var req;
  7873.  
  7874.         try
  7875.         {
  7876.             req = new ActiveXObject("Msxml2.XMLHTTP");
  7877.         } catch(e)
  7878.         {
  7879.             req = new ActiveXObject("Microsoft.XMLHTTP");
  7880.         }
  7881.  
  7882.         // nocache=1 is so existing installations don't have an issue
  7883.         // with previously cacheable content (The http server used to
  7884.         // say that /put-schedule.htm was cacheable.  That was fixed,
  7885.         // but we want to make sure that any content left over from
  7886.         // previous builds doesn't get used.)
  7887.         var url = "/put-schedule.htm?nocache=1&" + str;
  7888.  
  7889.         req.onreadystatechange = function ()
  7890.         {
  7891.             // When the load is complete, call the save function.
  7892.             if((typeof (onsavedfunc) == 'function') && (req.readyState == 4))
  7893.             {
  7894.                 onsavedfunc();
  7895.             }
  7896.         }
  7897.  
  7898.         req.open("GET", url, false);
  7899.         req.send("");
  7900.     }
  7901.  
  7902.     function ApplyScheduleChanges(onsavedfunc)
  7903.     {
  7904.         // Prevent the user from saving if they have chosen Advanced with no scedules
  7905.         if(scheduleType & 0x02 && !self.Schedules[0])
  7906.         {
  7907.             HtmlMessageBox2("crbEmptyAdvanced", BUTTON_OK);
  7908.             return;
  7909.         }
  7910.  
  7911.         // Update top-level choice
  7912.         if(!schedule)
  7913.         {
  7914.             schedule = DefaultSchedule() ? DefaultSchedule() : new Schedule();
  7915.         }
  7916.            
  7917.         scheduleType &= ~0x04;
  7918.         if(((scheduleType & 0x02) == 0x00))
  7919.             schedule.Days = EveryDay;
  7920.         if(!self.Schedules[0] && scheduleType != NO_SCHEDULE)
  7921.             self.Schedules[0] = schedule;
  7922.         //GetPoster().src="/put-state.htm?" + BACKUP_TYPE + "=" + scheduleType;
  7923.  
  7924.         updateTimeFields(schedule);
  7925.  
  7926.         // Now save off all the schedules (even if we're not using them right now)
  7927.         var allScheds = "UpdateAll=1&" + BACKUP_TYPE + "=" + scheduleType;
  7928.  
  7929.         // Only append schedule hours if the type is not continuous (i.e. NO_SCHEDULE).
  7930.         if (scheduleType != NO_SCHEDULE)
  7931.         {
  7932.             var i = 0;
  7933.             while(self.Schedules[i])
  7934.             {
  7935.                 allScheds += "&Schedule" + i + "=" + self.Schedules[i].GetAsString();
  7936.                 i++;
  7937.             }
  7938.         }
  7939.         PutScheduleInfo(allScheds, onsavedfunc);
  7940.  
  7941.         needsCommit = false;
  7942.     }
  7943.  
  7944.     this.ShowApplyButton = function ()
  7945.     {
  7946.         needsCommit = true;
  7947.         //      var as = E$("ApplyScheduleChanges");
  7948.         //      var ac = E$("CancelScheduleChanges");
  7949.         //      if(as.style.display == "none")
  7950.         //          as.style.display = "";
  7951.         //      if(ac.style.display == "none")
  7952.         //          ac.style.display = "";
  7953.     }
  7954.  
  7955.     this.SetChoice = function (o)
  7956.     {
  7957.         // Simply store changed values for submission
  7958.         scheduleType = o.value;
  7959.  
  7960.         // update the time to reflect the selection
  7961.         switch(o.id)
  7962.         {
  7963.             case "continuously":
  7964.             case "crbScheduleDefaultRadioButton":
  7965.                 DefaultSchedule().bUseFinishTime = false;
  7966.                 break;
  7967.             case "daily":
  7968.                 var timeSelected = parseTime($('#backup_start').val());
  7969.                 if(timeSelected)
  7970.                 {
  7971.                     DefaultSchedule().SetStartTime(
  7972.                         timeSelected.hour,
  7973.                         timeSelected.minute
  7974.                     );
  7975.                 }
  7976.                 DefaultSchedule().bUseFinishTime = false;
  7977.                 break;
  7978.             case "excludeHours":
  7979.                 var excludeStart = parseTime($('#exclude_start').val());
  7980.                 if(excludeStart)
  7981.                 {
  7982.                     DefaultSchedule().SetFinishTime(
  7983.                         excludeStart.hour,
  7984.                         excludeStart.minute
  7985.                     );
  7986.                 }
  7987.                 var excludeEnd = parseTime($('#exclude_end').val());
  7988.                 if(excludeEnd)
  7989.                 {
  7990.                     DefaultSchedule().SetStartTime(
  7991.                         excludeEnd.hour,
  7992.                         excludeEnd.minute
  7993.                     );
  7994.                 }
  7995.                 DefaultSchedule().bUseFinishTime = true;
  7996.                 break;
  7997.             default:
  7998.                 break;
  7999.         }
  8000.  
  8001.         self.ShowApplyButton();
  8002.     }
  8003.  
  8004.     function RefreshAdvancedScheduleList()
  8005.     {
  8006.         var listTopNode = E$("listTopNode");
  8007.         var strInner;
  8008.         var i = 0;
  8009.         if(!self.Schedules[0])
  8010.             strInner = strNoSchedRules;
  8011.         else
  8012.         {
  8013.             strInner = strSchedRules;
  8014.             strInner += "<table class='scheduletable'>";
  8015.             while(self.Schedules[i])
  8016.             {
  8017.                 var schedEditLink = "<tr><td><a onmousedown='localNav=true;' href='javascript:ScheduleSettings.EditSchedule(" + i + ")'><span class='Bullet'>" + strBullet + "</span>" + self.Schedules[i].Description() + "</a></td><td>&nbsp;<a class='addToolTip' onmousedown='localNav=true;' href='javascript:ScheduleSettings.DeleteSchedule(" + i + ")'><font size='-2'>" + strDeleteSchedule + "</font></a></td></tr>";
  8018.                 strInner += schedEditLink;
  8019.                 i++;
  8020.             }
  8021.             strInner += "</table>";
  8022.         }
  8023.  
  8024.         listTopNode.innerHTML = strInner;
  8025.     }
  8026.  
  8027.     this.UpdateDisplay = function (sName, sValue)
  8028.     {
  8029.         switch(sName)
  8030.         {
  8031.             case DAYCHOICE:
  8032.                 E$(SPECDAY_SUN).checked = schedule.Days & Sun;
  8033.                 E$(SPECDAY_MON).checked = schedule.Days & Mon;
  8034.                 E$(SPECDAY_TUE).checked = schedule.Days & Tue;
  8035.                 E$(SPECDAY_WED).checked = schedule.Days & Wed;
  8036.                 E$(SPECDAY_THU).checked = schedule.Days & Thu;
  8037.                 E$(SPECDAY_FRI).checked = schedule.Days & Fri;
  8038.                 E$(SPECDAY_SAT).checked = schedule.Days & Sat;
  8039.                 break;
  8040.             case SPECDAY_SUN:
  8041.             case SPECDAY_MON:
  8042.             case SPECDAY_TUE:
  8043.             case SPECDAY_WED:
  8044.             case SPECDAY_THU:
  8045.             case SPECDAY_FRI:
  8046.             case SPECDAY_SAT:
  8047.                 if(schedule.Days == EveryDay)
  8048.                     E$("Every").checked = true;
  8049.                 else if(schedule.Days == Weekdays)
  8050.                     E$("Weekdays").checked = true;
  8051.                 else
  8052.                     E$("Specific").checked = true;
  8053.                 break;
  8054.             case SSTART_HOUR:
  8055.             case SSTART_MINUTE:
  8056.             case SSTART_AP:
  8057.             case SFINISH_HOUR:
  8058.             case SFINISH_MINUTE:
  8059.             case SFINISH_AP:
  8060.                 E$("excludeHours").checked = true;
  8061.                 self.SetChoice(E$("excludeHours"));
  8062.                 scheduleType = SINGLE_SCHEDULE;
  8063.                 break;
  8064.             case ONCE_HOUR:
  8065.             case ONCE_MINUTE:
  8066.             case ONCE_AP:
  8067.                 E$("daily").checked = true;
  8068.                 self.SetChoice(E$("daily"));
  8069.                 scheduleType = SINGLE_SCHEDULE | 0x04;
  8070.                 break;
  8071.             case BACKUP_TYPE:
  8072.                 switch(scheduleType)
  8073.                 {
  8074.                     case NO_SCHEDULE:
  8075.                         E$("continuously").checked = true;
  8076.                         break;
  8077.                     case SINGLE_SCHEDULE:
  8078.                         E$(DefaultSchedule().bUseFinishTime ? "excludeHours" : "daily").checked = true;
  8079.                         break;
  8080.                     case MULTIPLE_SCHEDULE:
  8081.                         E$("Advanced").checked = true;
  8082.                         break;
  8083.                 }
  8084.                 break;
  8085.         }
  8086.     }
  8087.  
  8088.     this.ProcessSave = function (o)
  8089.     {
  8090.         schedule.ProcessChange(o);
  8091.     }
  8092.  
  8093.     this.InitSimpleSchedule = function ()
  8094.     {
  8095.         schedule = DefaultSchedule() ? DefaultSchedule() : new Schedule();
  8096.  
  8097.         if(E$("crbAllowAdvancedSchedule") && eval(E$("crbAllowAdvancedSchedule").innerText))
  8098.             $('#crbAdvancedSchedule').show();
  8099.        
  8100.         if (scheduleType == SINGLE_SCHEDULE) {
  8101.             if (schedule.bUseFinishTime) {
  8102.                 $("#excludeHours").closest("li").click();
  8103.                 $("#excludeHours").attr("checked", true);
  8104.             } else {
  8105.                 $("#daily").closest("li").click();
  8106.                 $("#daily").attr("checked", true);
  8107.             }
  8108.         } else if (scheduleType == MULTIPLE_SCHEDULE) {
  8109.             $("#Advanced").closest("li").click();
  8110.             $("#Advanced").attr("checked", true);
  8111.         } else {
  8112.             $("#continuously").closest("li").click();
  8113.             $("#continuously").attr("checked", true);
  8114.         }
  8115.  
  8116.         // now set the values in the controls
  8117.         updateTimeFields(schedule);
  8118.     }
  8119.  
  8120.     function updateTimeFields(sched)
  8121.     {
  8122.         var defaultDailyBackupTime = formatTime(0, 0, Use24HourClock);
  8123.         $('#backup_start').val(defaultDailyBackupTime);
  8124.         $('#backup_start_text').text(defaultDailyBackupTime);
  8125.         var defaultExcludeStartTime = new Date();
  8126.         var defaultExcludeStartHour = defaultExcludeStartTime.getHours();
  8127.         var defaultExcludeStartMin = defaultExcludeStartTime.getMinutes() < 15 ? 0 : 30;
  8128.         var defaultExcludeEndTime = new Date();
  8129.         var defaultExcludeEndHour = (defaultExcludeEndTime.getHours() + 2) % 24;
  8130.         var defaultExcludeEndMinute = defaultExcludeEndTime.getMinutes() < 15 ? 0 : 30;
  8131.         var defaultExcludeStartTimeText = formatTime(defaultExcludeStartHour, defaultExcludeStartMin, Use24HourClock);
  8132.         var defaultExcludeEndTimeText = formatTime(defaultExcludeEndHour, defaultExcludeEndMinute, Use24HourClock);
  8133.         $('#exclude_start').val(defaultExcludeStartTimeText);
  8134.         $('#exclude_start_text').text(defaultExcludeStartTimeText);
  8135.         $('#exclude_end').val(defaultExcludeEndTimeText);
  8136.         $('#exclude_end_text').text(defaultExcludeEndTimeText);
  8137.        
  8138.         if(scheduleType == SINGLE_SCHEDULE)
  8139.         {
  8140.             if (schedule.bUseFinishTime) {
  8141.                 $('#exclude_start').val(formatTime(sched.FinishHour, sched.FinishMinute, Use24HourClock));
  8142.                 $('#exclude_start_text').text(formatTime(sched.FinishHour, sched.FinishMinute, Use24HourClock));
  8143.                 $('#exclude_end').val(formatTime(sched.StartHour, sched.StartMinute, Use24HourClock));
  8144.                 $('#exclude_end_text').text(formatTime(sched.StartHour, sched.StartMinute, Use24HourClock));
  8145.             } else {
  8146.                 $('#backup_start').val(formatTime(sched.StartHour, sched.StartMinute, Use24HourClock));
  8147.                 $('#backup_start_text').text(formatTime(sched.StartHour, sched.StartMinute, Use24HourClock));
  8148.             }
  8149.         }
  8150.     }
  8151.  
  8152.     function checkUnsaved()
  8153.     {
  8154.         if(!localNav && needsCommit && BUTTON_YES == HtmlMessageBox2("crbUnsavedSchedule", BUTTONS_YESNO))
  8155.             ApplyScheduleChanges();
  8156.         localNav = false;
  8157.     }
  8158.  
  8159.     function ValidityTest()
  8160.     {
  8161.         var bValid = schedule.IsValidTimeWindow();
  8162.         var bNoDays = schedule.Days == 0;
  8163.         if(!bValid || bNoDays)
  8164.         {
  8165.             HtmlMessageBox2(bNoDays ? "crbNoDaysChosen" : "crbInvalidTimeSpan", BUTTON_OK);
  8166.             needsCommit = false;
  8167.         }
  8168.         return bValid && !bNoDays;
  8169.     }
  8170.  
  8171.     this.SaveEdit = function ()
  8172.     {
  8173.         if(ValidityTest() && !SaveEditSchedule())
  8174.             HtmlMessageBox2("crbDuplicateSchedule", BUTTON_OK);
  8175.     }
  8176.  
  8177.     this.ApplyChanges = function (onsavedfunc)
  8178.     {
  8179.         if(scheduleType != SINGLE_SCHEDULE || ValidityTest())
  8180.             ApplyScheduleChanges(onsavedfunc);
  8181.     }
  8182.  
  8183.     this.SetCurrentSchedule = function (schedValue)
  8184.     {
  8185.         schedule = schedValue;
  8186.     }
  8187.  
  8188.     this.SetCurrentScheduleType = function (typeValue)
  8189.     {
  8190.         scheduleType = typeValue;
  8191.     }
  8192.  
  8193.     this.GetCurrentSchedule = function ()
  8194.     {
  8195.         return schedule;
  8196.     }
  8197. }
  8198.  
  8199. var ScheduleSettings = new ScheduleSettings__();
  8200. var MIScheduleSettings = new MIScheduleSettings__();
  8201. /* End included file /js/schedule.js */
  8202.  
  8203. var Installation__ = function ()
  8204. {
  8205.     var self = this;
  8206.  
  8207.     var bTest = false;
  8208.     var nBackupState = -1;
  8209.     var nServiceState = -1;
  8210.     var nQuotaUsagePct = -1;
  8211.     var sPhase = "";
  8212.     var nPhaseIndex = 0;
  8213.     var tmrScanningTimeout = 0;
  8214.     var sCurrentWindowSize = "";
  8215.  
  8216.     var interconnect;
  8217.     function startInterconnect()
  8218.     {
  8219.         interconnect = new ServiceInterconnect(
  8220.         {
  8221.             "items": "all",
  8222.             "onPush": installation_pushHandler,
  8223.             "name": "Installation.js"
  8224.         });
  8225.         interconnect.start();
  8226.     }
  8227.  
  8228.     var nTestTimer = 0;
  8229.     var nTestPhase = 0;
  8230.  
  8231.     function testPhases()
  8232.     {
  8233.         //run through all phases
  8234.         var elPhase = document.getElementById('phases').childNodes.item(nTestPhase);
  8235.  
  8236.         if(elPhase.id && elPhase.id.length > 8)
  8237.             self.onPhase(elPhase.id.substring(8));
  8238.  
  8239.         if(++nTestPhase == document.getElementById('phases').childNodes.length)
  8240.             clearInterval(nTestTimer);
  8241.         else
  8242.         {
  8243.             clearInterval(nTestTimer);
  8244.             nTestTimer = setInterval(testPhases, 500);
  8245.         }
  8246.     }
  8247.  
  8248.     this.InstallInit = function ()
  8249.     {
  8250.         logTrace('Installation.js::body_onload');
  8251.  
  8252.         //start an interval timer for validating passwords
  8253.         //this runs all the time that we're in the installation phase
  8254.         //(it'd be better to switch it on only when the manual encryption panel is visible)
  8255.         startPKPasswordTimer();
  8256.  
  8257.         //show normally hidden controls?
  8258.         if(queryString('test'))
  8259.         {
  8260.             logTrace('installation.js::body_onload test mode on');
  8261.             bTest = queryString('test') == '1';
  8262.             if(bTest)
  8263.             {
  8264.                 for(i = 0; i < document.all.length; i++)
  8265.                 {
  8266.                     try
  8267.                     {
  8268.                         if(document.all.item(i).className == "develop")
  8269.                             document.all.item(i).style.display = "inline";
  8270.                     }
  8271.                     catch(e)
  8272.                     {
  8273.                     }
  8274.                 }
  8275.             }
  8276.         }
  8277.  
  8278.         var ds = queryString('server', '');
  8279.  
  8280.         if(ds != '')
  8281.         {
  8282.             crbDownloadServer.innerText = queryString('server', '');
  8283.         }
  8284.  
  8285.         if(queryString('phase'))
  8286.         {
  8287.             // run through all phases?
  8288.             if(queryString('phase') == 'all')
  8289.                 nTestTimer = setInterval(testPhases, 10);
  8290.             else
  8291.                 self.onPhase(queryString('phase'));
  8292.         }
  8293.  
  8294.         startInterconnect();
  8295.  
  8296.         // Add mouseover tooltips
  8297.         addtip();
  8298.     }
  8299.  
  8300.     this.onPhase = function (phase, supportBack)
  8301.     {
  8302.         try
  8303.         {
  8304.             if (phase != 0 &&
  8305.                 phase != 10 &&
  8306.                 phase != 20 &&
  8307.                 phase != 23 &&
  8308.                 phase != 25 &&
  8309.                 phase != 40 &&
  8310.                 phase != 45 &&
  8311.                 phase != 50 &&
  8312.                 phase != 60)
  8313.                 self.postCoreMetric(phase);
  8314.            
  8315.             if(typeof supportBack == 'undefined')
  8316.                 supportBack = false;
  8317.  
  8318.             var prevPhase = sPhase;
  8319.  
  8320.             logTrace('phase change to ' + phase);
  8321.             sPhase = phase;
  8322.             var divPhase = document.getElementById('crbPhase' + phase);
  8323.             if(divPhase == null)
  8324.             {
  8325.                 logError('element crbPhase' + phase + ' does not exist');
  8326.                 return;
  8327.             }
  8328.  
  8329.             nPhaseIndex = divPhase.getAttribute('Index');
  8330.  
  8331.             //the control, title, and body are optionally under the phase div using class="control|title|body"
  8332.             var elControl = null;
  8333.             var elTitle = document.getElementById('l_str' + sPhase + 'Title');
  8334.             var elBody = divPhase;
  8335.             var strWindowAttributes = "";
  8336.  
  8337.             if(elTitle == null)
  8338.                 elTitle = document.getElementById('crbTitleDefault');
  8339.  
  8340.             for(i = 0; i < divPhase.children.length; i++)
  8341.             {
  8342.                 var el = divPhase.childNodes.item(i);
  8343.                 if(el.className == undefined)
  8344.                     continue;
  8345.                 switch(el.className.toLowerCase())
  8346.                 {
  8347.                     case "phasewindowsize":
  8348.                         var elWindowSize = null;
  8349.                         for(var j = 0; j < el.children.length; j++)
  8350.                         {
  8351.                             /* There should only be one child element, but check its name just in case */
  8352.                             if("WindowAttributes" == el.childNodes.item(i).name)
  8353.                             {
  8354.                                 elWindowSize = el.childNodes.item(i);
  8355.                                 break;
  8356.                             }
  8357.                             else { continue; }
  8358.                         }
  8359.  
  8360.                         if(null != elWindowSize)
  8361.                         {
  8362.                             strWindowAttributes = elWindowSize.innerText;
  8363.                             /* Only resize the window if we need to, since resizing snaps it back to center */
  8364.                             if(sCurrentWindowSize != strWindowAttributes)
  8365.                             {
  8366.                                 /* Resize but keep the current window position */
  8367.                                 ResizeWindow(strWindowAttributes, true);
  8368.                                 /* Store the current window size for the next phase */
  8369.                                 sCurrentWindowSize = strWindowAttributes;
  8370.                             }
  8371.                         }
  8372.                         break;
  8373.                     case "phasecontrol":
  8374.                         elControl = el;
  8375.                         break;
  8376.                     case "phasebody":
  8377.                         elBody = el;
  8378.                         break;
  8379.                 }
  8380.             }
  8381.  
  8382.             var elStatus = document.getElementById('crbStatus');
  8383.  
  8384.             // Remember the current phase in order to support the "Back" operation.
  8385.             var currentBody = elementByAttribute('class', 'PhaseBody', elStatus.childNodes);
  8386.  
  8387.             if(currentBody && currentBody.crbOriginalParent)
  8388.             {
  8389.                 // Add back to the original parent in order to support back operation.
  8390.                 currentBody.crbOriginalParent.appendChild(currentBody);
  8391.             }
  8392.             else if(supportBack)
  8393.             {
  8394.                 logError('Unable to transition from ' + prevPhase + ' to ' + phase + ': Unable to configure for back operation');
  8395.                 return;
  8396.             }
  8397.  
  8398.             //set main html for this phase
  8399.             // Use appendChild instead of copying the innerHTML to make the tooltips work
  8400.             elStatus.innerHTML = "";
  8401.             elBody.crbOriginalParent = divPhase;
  8402.             elStatus.appendChild(elBody);
  8403.  
  8404.             elBody.style.visibility = "visible";
  8405.  
  8406.             if(supportBack)
  8407.             {
  8408.                 elControl.setAttribute("back", prevPhase);
  8409.             }
  8410.  
  8411.             //show optional controls
  8412.             showOptional(elControl, "back", crbBackButton);
  8413.             showOptional(elControl, "next", crbNextButton);
  8414.             showOptional(elControl, "accept", crbAcceptButton);
  8415.             showOptional(elControl, "cancel", crbCancelButton);
  8416.             showOptional(elControl, "done", crbDoneButton);
  8417.             showOptional(elControl, "load", crbLoadButton);
  8418.             showOptional(elControl, "progress", installProgress);
  8419.  
  8420.             // If the current phase has a positive index, show the navigation breadcrumbs
  8421.             (nPhaseIndex > -1) ? showCrumbs() : hideCrumbs();
  8422.  
  8423.             // if this is the scanning phase, set a 3 minute timeout so we don't get stuck
  8424.             if(phase.toLowerCase() == 'scanning')
  8425.             {
  8426.                 tmrScanningTimeout = setTimeout("checkScan(true)", 3 * 60 * 1000);
  8427.                 logTrace('set scanning timeout id=' + tmrScanningTimeout);
  8428.             }
  8429.             else if(tmrScanningTimeout)
  8430.             {
  8431.                 clearTimeout(tmrScanningTimeout);
  8432.                 logTrace('cleared scanning timeout id=' + tmrScanningTimeout);
  8433.                 tmrScanningTimeout = 0;
  8434.             }
  8435.  
  8436.             // run any phase initialization script that is registered.
  8437.             if(elControl)
  8438.             {
  8439.                 // Execute the onphase JavaScript.  This will only get executed the first
  8440.                 // time the phase is entered (not if the user does a Back followed
  8441.                 // by a next).
  8442.                 var wasPhaseInitialized = elControl.getAttribute('crbWasPhaseInitialized');
  8443.  
  8444.                 if(wasPhaseInitialized !== true)
  8445.                 {
  8446.                     var initPhaseJS = elControl.getAttribute('onphase');
  8447.  
  8448.                     if(initPhaseJS)
  8449.                     {
  8450.                         eval(initPhaseJS);
  8451.                     }
  8452.  
  8453.                     elControl.setAttribute('crbWasPhaseInitialized', true);
  8454.                 }
  8455.  
  8456.                 // onshowphase contains JavaScript that will always get
  8457.                 // executed when a phase is entered (regardless of whether
  8458.                 // it's been executed before).
  8459.                 var showPhaseJS = elControl.getAttribute('onshow');
  8460.  
  8461.                 if(showPhaseJS)
  8462.                 {
  8463.                     eval(showPhaseJS);
  8464.                 }
  8465.  
  8466.                 // Show the proper nav progress indicator in the upper right.
  8467.                 //
  8468.                 var navNumber = elControl.getAttribute('nav');
  8469.  
  8470.                 $('.NavImage').hide();
  8471.  
  8472.                 if(navNumber)
  8473.                 {
  8474.                     $('#crbNavImage' + navNumber).show();
  8475.                 }
  8476.             }
  8477.  
  8478.             // Remove the focus from the next and previous buttons.
  8479.             blurButtonElements(crbBackButton);
  8480.             blurButtonElements(crbNextButton);
  8481.         }
  8482.         catch(e)
  8483.         {
  8484.             logError("exception in phase " + phase + " : " + e.description);
  8485.         }
  8486.     }
  8487.  
  8488.     // Find all of the anchor tags within the specified element (el) and call their blur
  8489.     // methods.
  8490.     function blurButtonElements(el)
  8491.     {
  8492.         var els = el.getElementsByTagName('a');
  8493.  
  8494.         if(els)
  8495.         {
  8496.             for(var i = 0; i < els.length; i++)
  8497.             {
  8498.                 els[i].blur();
  8499.             }
  8500.         }
  8501.     }
  8502.  
  8503.     function showOptional(elIn, attrName, elOut)
  8504.     {
  8505.         try
  8506.         {
  8507.             //display it?
  8508.             var attr = elIn.attributes.getNamedItem(attrName);
  8509.             elOut.style.display = attr == null || attr.value == "" ? "none" : "";
  8510.             switch(attrName.toLowerCase())
  8511.             {
  8512.                 case "back":
  8513.                 case "next":
  8514.                 case "accept":
  8515.                     elOut.setAttribute("destination", attr == null ? "" : attr.value);
  8516.                     break;
  8517.                 case "cancel":
  8518.                     elOut.setAttribute("function", attr == null ? "" : attr.value);
  8519.                     break;
  8520.                 case "progress":
  8521.                     if(null != attr && "" != attr.value)
  8522.                     {
  8523.                         $('#installProgress').progressbar({ value: parseFloat(attr.value) });
  8524.                     }
  8525.                     break;
  8526.             }
  8527.         }
  8528.         catch(e)
  8529.         {
  8530.             elOut.style.display = "none";
  8531.         }
  8532.     }
  8533.  
  8534.     this.onNext = function (sDestination)
  8535.     {
  8536.         //if the destination contains parens, it's a function, so evaluate it. Otherwise it's a phase
  8537.         if(sDestination.indexOf('(') == -1)
  8538.             self.onPhase(sDestination);
  8539.         else
  8540.             eval(sDestination);
  8541.     }
  8542.  
  8543.     this.onCancel = function (sFunction)
  8544.     {
  8545.         //if the destination contains parens, it's a function, so evaluate it. Otherwise it's a phase
  8546.         eval(sFunction);
  8547.     }
  8548.  
  8549.     this.onPKImportCancel = function ()
  8550.     {
  8551.         event.cancelBubble = true;
  8552.         if(crbConfirm2('crbCancelPKImport'))
  8553.         {
  8554.             crbClick('crbCancelledPKImport');
  8555.         }
  8556.     }
  8557.  
  8558.     function showCrumbs()
  8559.     {
  8560.         //we count the children on the phases div and use the child number of the current phase to set the breadcrumb trail
  8561.         crumbs = document.getElementById('phases').attributes.getNamedItem('count').value;
  8562.  
  8563.         //if there are too many crumbs, delete some
  8564.         while(divCrumbTrail.childNodes.length > crumbs)
  8565.         {
  8566.             divCrumbTrail.removeChild(divCrumbTrail.children(0));
  8567.         }
  8568.  
  8569.         //if there aren't enough crumbs, make some more
  8570.         while(divCrumbTrail.childNodes.length < crumbs)
  8571.         {
  8572.             divCrumbTrail.appendChild(divCrumbTrail.children(0).cloneNode());
  8573.         }
  8574.  
  8575.         //change all but the selected crumb to unselected
  8576.         for(i = 0; i < divCrumbTrail.childNodes.length; i++)
  8577.         {
  8578.             divCrumbTrail.childNodes.item(i).className = i == nPhaseIndex ? "CrumbSelected" : "crumb";
  8579.         }
  8580.  
  8581.         //Show the breadcrumb trail div
  8582.         divCrumbTrail.style.visibility = "visible";
  8583.  
  8584.     }
  8585.  
  8586.     function hideCrumbs()
  8587.     {
  8588.         divCrumbTrail.style.visibility = "hidden";
  8589.     }
  8590.  
  8591.     function installation_pushHandler(node)
  8592.     {
  8593.         try
  8594.         {
  8595.             Alert.pushHandler(node);
  8596.  
  8597.             switch(node.id.toLowerCase())
  8598.             {
  8599.                 case "backupstate":
  8600.                     nBackupState = node.innerHTML;
  8601.                     monitorScan(false);
  8602.                     break;
  8603.                 case "quotausagepct":
  8604.                     nQuotaUsagePct = node.innerHTML;
  8605.                     monitorScan(false);
  8606.                     break;
  8607.                 case "totalbackupsize":
  8608.                     crbTotalBackupSize2.innerHTML = node.innerHTML;
  8609.                     break;
  8610.                 case "userholdskey":
  8611.                     //the encryption auto and manual panels show different content based on whether the user is
  8612.                     //managing the private key
  8613.                     var bIsUserManaged = "1" == node.innerHTML;
  8614.  
  8615.                     // TODO:  Handle case where server doesn't allow user to manage key.
  8616.                     /*
  8617.                     //if the panel slider is in the wrong position then change it
  8618.                     if(undefined != crbEncryptionKeyPanel.onOffSwitch && crbEncryptionKeyPanel.onOffSwitch.isOn() ^ bIsUserManaged)
  8619.                     crbEncryptionKeyPanel.onOffSwitch.setOn(bIsUserManaged);
  8620.                     */
  8621.  
  8622.                     /* TODO:  Is this required?
  8623.                     //blurb
  8624.                     showElement(divPKUserManagedBlurb, bIsUserManaged);
  8625.                     showElement(divPKUserUnmanagedBlurb, !bIsUserManaged);
  8626.                     */
  8627.                     //buttons
  8628.                     showElement(crbPKManageAtServer, bIsUserManaged);
  8629.                     showElement(crbPKExport, !bIsUserManaged);
  8630.  
  8631.                     //hide password entry controls
  8632.                     showElement(frmPrivateKeyPassword, !bIsUserManaged);
  8633.  
  8634.                     //show the 'I understand about managing my own key' checkbox and text?
  8635.                     showElement(divPKUnderstood, !bIsUserManaged);
  8636.  
  8637.                     break;
  8638.             }
  8639.         }
  8640.         catch(e)
  8641.         {
  8642.             logError("Exception in installation_pushHandler processing " + node.id + " : " + e.description);
  8643.         }
  8644.     }
  8645.  
  8646.     var nCheckScanTimer = 0;
  8647.     function monitorScan()
  8648.     {
  8649.         /*
  8650.         used when showing the Scanning panel to switch to another panel when the scan has finished
  8651.         displays the Scanned panel if the resulting backup is overquota, or the scope panel otherwise
  8652.         there's some 'bounce' in the service state that can mean it appears to stop scanning then starts again
  8653.         to counter this, we'll wait 5 seconds after a reported stop, and only react if the state is still idle
  8654.         */
  8655.         if(sPhase.toLowerCase() != "scanning")
  8656.             return;
  8657.  
  8658.         logTrace('monitorScan with bs=' + nBackupState + ' and quota=' + nQuotaUsagePct);
  8659.         //don't check until we have the state and the quota pct
  8660.         if(nBackupState != Backup_State_Undefined && nQuotaUsagePct != -1)
  8661.         {
  8662.             //cancel existing timer, and start a new one
  8663.             if(nCheckScanTimer != 0)
  8664.                 clearTimeout(nCheckScanTimer);
  8665.             nCheckScanTimer = setTimeout("checkScan(false)", 5000);
  8666.         }
  8667.     }
  8668.  
  8669.     function checkScan(bScanningTimedOut)
  8670.     {
  8671.         logTrace('checkScan(' + bScanningTimedOut + ') with bs=' + nBackupState + ', quotapct=' + nQuotaUsagePct);
  8672.         if(sPhase.toLowerCase() == "scanning" && (bScanningTimedOut || nBackupState != Backup_State_Scanning))
  8673.             self.onPhase(nQuotaUsagePct > 100 ? "Scanned" : "Scope");
  8674.         nCheckScanTimer = 0;
  8675.     }
  8676.  
  8677.     function triggerScopeClickInUI(shouldIncludeDefaultBackup)
  8678.     {
  8679.         var scopeButton$ = null;
  8680.  
  8681.         if(shouldIncludeDefaultBackup)
  8682.             scopeButton$ = $('#crbScopeSome');
  8683.         else
  8684.             scopeButton$ = $('#crbScopeNone');
  8685.  
  8686.         setTimeout(
  8687.             function ()
  8688.             {
  8689.                 scopeButton$.click();
  8690.             },
  8691.         0);
  8692.     }
  8693.  
  8694.     var nBuyNow = 0;
  8695.     this.onScannedChosen = function (el)
  8696.     {
  8697.         nBuyNow = el.value;
  8698.         crbNextButton.style.display = "block";
  8699.         crbNextButton.setAttribute("destination", "Installation.onScannedNext()");
  8700.         triggerScopeClickInUI(nBuyNow == 1);
  8701.  
  8702.         //stop the current event
  8703.         event.cancelBubble = true;
  8704.     }
  8705.  
  8706.     var sSavedComment;
  8707.     var blnShowedUpsell = false;
  8708.  
  8709.     this.onScannedNext = function ()
  8710.     {
  8711.         //we're either going to take the user to the buy page, or reduce the backup set to zero
  8712.         //if they're buying, we want to raise a dialog which they 'ok' when they've bought. Then we'll check they bought.
  8713.         //if they're managing their own backup, we'll confirm their choice, remove documents and settings from the backup set
  8714.         if(nBuyNow == 1)
  8715.         {
  8716.             //if they said they'd buy, did they?
  8717.             Alert.openOrderWithVerification("ic-QuotaLimitedInstall", "Installation.onPhase('Review')", "Wait.StopWait()");
  8718.         }
  8719.         else
  8720.         {
  8721.             //they said they want to manually backup, so tell the service to remove 'documents and settings' from the backup set
  8722.  
  8723.             //Check to see whether to display an upsell message
  8724.             if(showUpsellMessage() && !blnShowedUpsell)
  8725.             {
  8726.                 Wait.Popup('lbUpsell');
  8727.                 blnShowedUpsell = true;
  8728.             }
  8729.             else
  8730.             {
  8731.                 self.selectQuotaLimitedPlan();
  8732.             }
  8733.         }
  8734.  
  8735.     }
  8736.  
  8737.     this.selectUnlimitedPlan = function ()
  8738.     {
  8739.         try
  8740.         {
  8741.             var elt = document.getElementById('crbBuyNow');
  8742.             elt.checked = true;
  8743.             self.onScannedChosen(elt);
  8744.             Wait.StopPopup();
  8745.             self.onScannedNext();
  8746.         }
  8747.         catch(e)
  8748.         {
  8749.             alert(e.description);
  8750.         }
  8751.     }
  8752.  
  8753.     this.selectQuotaLimitedPlan = function ()
  8754.     {
  8755.         Wait.StopPopup();
  8756.         crbScopeNone.click();
  8757.         self.onPhase("Review");
  8758.     }
  8759.  
  8760.     // Check to see whether we should show an upsell message when the user selects the quota-limited product
  8761.     function showUpsellMessage()
  8762.     {
  8763.         try
  8764.         {
  8765.             return document.getElementById('crbShowUpsellMessage').innerText == "1";
  8766.         }
  8767.         catch(e)
  8768.         {
  8769.         }
  8770.  
  8771.         return false;
  8772.     }
  8773.  
  8774.     this.onScopeNext = function ()
  8775.     {  
  8776.         var bSupportBack = true;
  8777.  
  8778.         //the user either chose to backup documents and settings or select files manually
  8779.         //we instruct the service what to backup (or not backup) then got to Review
  8780.         if($('#crbInstallPhaseScopeAutoRadioButton').attr('checked'))
  8781.         {
  8782.             // Explicitly trigger the scope click so that we always include the default backup
  8783.             // when Automatic mode is selected.  This is needed in case the user previously
  8784.             // selected Advanced -> Start with nothing in your online backup, but then clicked
  8785.             // the Back button to change the scope to Automatic instead.
  8786.             triggerScopeClickInUI(true)
  8787.             self.onPhase("Review", bSupportBack);
  8788.         }
  8789.         else
  8790.         {
  8791.             self.onPhase("What", bSupportBack);
  8792.         }
  8793.     }
  8794.  
  8795.     this.onWhatNext = function ()
  8796.     {
  8797.         triggerScopeClickInUI($('#crbInstallPhaseWhatDefaultRadioButton').attr('checked'))
  8798.         self.onPhase("Schedule", true /*bSupportBack*/);
  8799.     }
  8800.  
  8801.     this.finalizeBackupSchedule = function ()
  8802.     {
  8803.         ScheduleSettings.ApplyChanges();
  8804.     }
  8805.  
  8806.     this.onScheduleNext = function ()
  8807.     {
  8808.         ScheduleSettings.SimpleScheduling();
  8809.  
  8810.         // Get all the schedule state.
  8811.         //
  8812.         if($('#crbScheduleDefaultRadioButton').attr('checked'))
  8813.         {
  8814.             ScheduleSettings.SetChoice(document.getElementById('crbScheduleDefaultRadioButton'));
  8815.         }
  8816.         else if($('#crbScheduleManualRadioButton').attr('checked'))
  8817.         {
  8818.             if($('#daily').attr('checked'))
  8819.             {
  8820.                 ScheduleSettings.SetChoice(document.getElementById('daily'));
  8821.             }
  8822.             else if($('#excludeHours').attr('checked'))
  8823.             {
  8824.                 ScheduleSettings.SetChoice(document.getElementById('excludeHours'));
  8825.             }
  8826.             else
  8827.             {
  8828.                 var closeFunc = function ()
  8829.                 {
  8830.                     $(this).dialog("close");
  8831.                 }
  8832.  
  8833.                 $("#crbInvalidSchedule").dialog({
  8834.                     show: true,
  8835.                     modal: true,
  8836.                     width: 400,
  8837.                     buttons: { "Close window": closeFunc }
  8838.                 });
  8839.  
  8840.                 return;
  8841.             }
  8842.         }
  8843.  
  8844.         var showEncryption = eval($('.l_ShowEncryption').text());
  8845.         self.onPhase(showEncryption ? "Encryption" : "Review", true /*bSupportBack*/);
  8846.     }
  8847.  
  8848.     this.onEncryptionNext = function ()
  8849.     {
  8850.         self.onPhase("Review", true /*bSupportBack*/);
  8851.     }
  8852.  
  8853.     this.onReviewNext = function ()
  8854.     {
  8855.         self.onPhase("ManualBackup", false /*bSupportBack*/);
  8856.     }
  8857.  
  8858.     // Called by the "Advanced setup options" button in PhaseExportKey - MRJ... Can't find this
  8859.     function togglePKOption()
  8860.     {
  8861.         try
  8862.         {
  8863.             var advOptions = document.getElementById("crbAdvancedBackupOptions");
  8864.             var pkOption = document.getElementById("crbPKOption");
  8865.             advOptions.style.display = (advOptions.style.display == "none") ? "block" : "none";
  8866.             pkOption.style.display = (pkOption.style.display == "none") ? "block" : "none";
  8867.         }
  8868.         catch(e)
  8869.         {
  8870.  
  8871.         }
  8872.     }
  8873.  
  8874.     var MachineList = new Array();
  8875.     this.populateMachineList = function (sMachineList)
  8876.     {
  8877.         // trim any trailing | character so that the split length is correct
  8878.         if(sMachineList.substring(sMachineList.length - 1) == "|")
  8879.             sMachineList = sMachineList.substring(0, sMachineList.length - 1);
  8880.  
  8881.         // Find the value for how many machine cause the table to show vs. the simpler list
  8882.         var useTableAfterField = document.getElementById('useTableAfter');
  8883.         var useTableAfter = 6;
  8884.         if(null != useTableAfterField)
  8885.             useTableAfter = parseInt(useTableAfterField.innerText);
  8886.         if(isNaN(useTableAfter))
  8887.             useTableAfter = 6;
  8888.  
  8889.         var Computers = sMachineList.split("|");
  8890.         var compindex = 0;
  8891.  
  8892.         var MachineRecord = Computers.length > useTableAfter ? MachineRecordRow : MachineRecordBlock;
  8893.  
  8894.         if(Computers.length > useTableAfter)
  8895.         {
  8896.             document.getElementById('crbShortMachineList').style.display = "none";
  8897.             document.getElementById('crbLongMachineList').style.display = "";
  8898.             (new Table(document.getElementById('crbMachineTable'))).MakeResizable();
  8899.         }
  8900.  
  8901.         while(Computers[compindex])
  8902.         {
  8903.             var mr = new MachineRecord(Computers[compindex]);
  8904.             MachineList.push(mr);
  8905.             compindex++;
  8906.         }
  8907.  
  8908.         var machineCount = document.getElementById('crbMachineCount');
  8909.         if(machineCount)
  8910.             machineCount.innerText = MachineList.length;
  8911.     }
  8912.  
  8913.     function IsSupportedPlatform(MachineRecord)
  8914.     {
  8915.         var isSupported = false;
  8916.         var platforms = document.getElementById('crbPlatforms').innerText.split(";");
  8917.  
  8918.         for(var i = 0; i < platforms.length; i++)
  8919.         {
  8920.             isSupported = (platforms[i] == MachineRecord.Platform);
  8921.             if(isSupported)
  8922.                 break;
  8923.         }
  8924.  
  8925.         return isSupported;
  8926.     }
  8927.  
  8928.     this.ChooseComputer = function (MachineRecord)
  8929.     {
  8930.         // First check that this is okay to select
  8931.         if(!IsSupportedPlatform(MachineRecord))
  8932.             return;
  8933.  
  8934.         // Select this machine, unselect others
  8935.         for(var i = 0; i < MachineList.length; i++)
  8936.             MachineList[i].Select(MachineList[i].Number == MachineRecord.Number);
  8937.  
  8938.         // inform the document of the chosen machine
  8939.         var machineChosen = document.getElementById('crbMachineChosen');
  8940.         machineChosen.setAttribute("chosenMachine", MachineRecord.definingString);
  8941.  
  8942.         crbNextButton.style.display = "block";
  8943.         crbNextButton.setAttribute("destination", "document.getElementById('crbMachineChoice').click();");
  8944.  
  8945.     }
  8946.    
  8947.     /// Posts a page view data type to a CoreMetrics server.
  8948.     /// Used for tracking installer progress.
  8949.     /// Attr1 = Reserved
  8950.     /// Attr2 = Computer Number
  8951.     /// Attr3 = Client Version
  8952.     this.postCoreMetric = function (pageId)
  8953.     {
  8954.         var dt = new Date();
  8955.         var st = dt.getTime();
  8956.         var ciProd = "90382861";
  8957.         var pageCatId = "CLIENT/INSTALLER2"
  8958.         var computerUID = top.document.getElementById('crbComputerNumber').innerHTML;
  8959.         var cjuid = "1";
  8960.         var cjuidPadding = "1"
  8961.  
  8962.         if (0 == computerUID.length) {
  8963.             computerUID = st;
  8964.         }
  8965.  
  8966.         if ("DONE" == pageId) {
  8967.             cjuid = "7"
  8968.             cjuidPadding = "7"
  8969.         }
  8970.  
  8971.         for (var i = 1; i < (23 - computerUID.length); ++i) {
  8972.             cjuid = cjuid + cjuidPadding;
  8973.         }
  8974.         cjuid = cjuid + computerUID;
  8975.         var cjsid = "1";
  8976.         for (var i = 1; i < (10 - computerUID.length); ++i) {
  8977.             cjsid = cjsid + "0";
  8978.         }
  8979.         cjsid = cjsid + computerUID;
  8980.        
  8981.         var url = "http%3A///localhost%3A668/html/Installation.htm";
  8982.        
  8983.         var imgRoot = "http://data.";
  8984.         var img = "coremetrics.com/eluminate?tid=1&vn1=4.1.1&vn2=mobile&ec=UTF-8&cjen=1" +
  8985.         "&ci=" + ciProd +
  8986.         "&st=" + st +
  8987.         "&cg=" + pageCatId +
  8988.         "&pi=ClientInstallerPhase/" + pageId +  
  8989.         "&ul=" + url +
  8990.         "&cjuid=" + cjuid +
  8991.         "&cjsid=" + cjsid +
  8992.         "&cjvf=1";
  8993.        
  8994.         var imgProd = imgRoot + img;
  8995.        
  8996.         var imgFull = $('<img src="' + imgProd + '" />')
  8997.         $("#phases").append(imgFull)
  8998.     }
  8999.    
  9000. }
  9001. var Installation = new Installation__();
  9002.  
  9003. function onPKHint(hint)
  9004. {
  9005.     document.getElementById('crbPKInputHint').innerHTML = hint;
  9006. }
  9007.  
  9008. // This gets called from InstallFinalizer.cpp
  9009. function setExportPrivateKeyAllowed(allowed)
  9010. {
  9011.     $('.l_ShowEncryption').text(allowed ? 'true' : 'false');
  9012. }
  9013.  
  9014. function PopulateMachineList(sMachineList)
  9015. {
  9016.     Installation.populateMachineList(sMachineList);
  9017. }
  9018.  
  9019. function ShowRestoreDecorations()
  9020. {
  9021. }
  9022.  
  9023. function onPhase(x)
  9024. {
  9025.     Installation.onPhase(x);
  9026. }
  9027.  
  9028. var MoreLessHelper__ = function(moreSelector, lessSelector) {
  9029.  
  9030.     var moreSelector_ = moreSelector;
  9031.     var lessSelector_ = lessSelector;
  9032.  
  9033.     this.showMore = function() {
  9034.         if (moreSelector_) {
  9035.             $(moreSelector_).show();
  9036.         }
  9037.  
  9038.         if (lessSelector_) {
  9039.             $(lessSelector_).hide();
  9040.         }
  9041.  
  9042.         forceHeightChange();
  9043.     }
  9044.  
  9045.     this.showLess = function() {
  9046.         if (moreSelector_) {
  9047.             $(moreSelector_).hide();
  9048.         }
  9049.  
  9050.         if (lessSelector_) {
  9051.             $(lessSelector_).show();
  9052.         }
  9053.  
  9054.         forceHeightChange();
  9055.     }
  9056.  
  9057.     function forceHeightChange() {
  9058.         var jq = $('.NeedsResizeHack');
  9059.  
  9060.         jq.css('height', '1px');
  9061.         jq.css('height', 'auto');
  9062.     }
  9063. }
  9064.  
  9065. // Called by install finalizer. Conveys schedule options to system.
  9066. function FinishSchedule()
  9067. {
  9068.     Installation.finalizeBackupSchedule();
  9069. }