<commit_before>/* HPK Namespace. */
var HPK = {};

/* ===== GotoBox ===== */

/* Creates a new GotoBox object. */
HPK.GotoBox = function(presentation) {
  var that = this;
  this._element = $("<input type='text' id='goto-box'>")
    .keypress(function(event) {
      switch (event.keyCode) {
        case 13: // Enter
          presentation.gotoSlide($(this).val() - 1);
          that.hide();
          break;
        case 27: // ESC
          that.hide();
          break;
      }
      event.stopPropagation();
    });
  $("body").append(this._element);
}

HPK.GotoBox.prototype = {
  /* Shows, clears and focuses the goto box. */
  show: function() {
    this._element.val("").show().focus();
  },

  /* Hides the goto box. */
  hide: function() {
    this._element.hide();
  }
}

/* ===== CurrentSlideCounter ===== */

/* Creates a new CurrentSlideCounter object. */
HPK.CurrentSlideCounter = function() {
  this._element = $("
");
  $("body").append(this._element);
}

HPK.CurrentSlideCounter.prototype = {
  /* Updates the current slide counter. */
  update: function(currentSlideIndex) {
    this._element.text(currentSlideIndex + 1);
  }
}

/* ===== Navigation ===== */

/* Creates a new Navigation object. */
HPK.Navigation = function(presentation) {
  this._visible = false;
  var that = this;
  this._element = $("
")
    .append($("")
      .click(function(event) {
        presentation.gotoPrevSlide();
        event.stopPropagation();
      })
    )
    .append($("")
      .click(function(event) {
        alert("TODO")
      })
    )
    .append($("")
      .click(function(event) {
        presentation.gotoNextSlide();
        event.stopPropagation();
      })
    )
    .mouseover(function() {
      that.clearHideTimer();
    })
    .mouseout(function() {
      that.touch();
    })
    .mousemove(function(event) {
      event.stopPropagation();
    });
  $("body").append(this._element);
  this._hideTimer = null;
}

HPK.Navigation.prototype = {

  /* Is the navigation visible? */
  isVisible: function() {
    return this._visible;
  },

  /* Clears the current hiding timer. */
  clearHideTimer: function() {
    if (this._hideTimer) {
      clearTimeout(this._hideTimer);
      this._hideTimer = null;
    }
  },

  /* Clears the current hiding timer and creates a new one. */
  touch: function() {
    this.clearHideTimer();
    var that = this;
    this._hideTimer = setTimeout(function() {
      that.hide();
    }, 5000);
  },

  /* Shows the navigation. */
  show: function() {
    this._visible = true;
    this._element.css("opacity", "0").show().fadeTo("normal", 0.8);
    this.touch();
  },

  /* Hides the navigation. */
  hide: function() {
    this.clearHideTimer();
    this._element.fadeOut("normal");
    this._visible = false;
  }
}

/* ===== Presentation ===== */

/* Creates a new Presentation object and injects the presentation mode toggle
   element into the HTML. */
HPK.Presentation = function() {
  this._slides = $("div.presentation div.slide");
  this._currentSlideIndex = null;
  this._presenting = false;
  this._screenStyleLinks = $("link[rel=stylesheet][media=screen]");
  this._projectionStyleLinks = $("link[rel=stylesheet][media=projection]");

  this._createRunPresentationLink();

  this.currentSlideCounter = new HPK.CurrentSlideCounter;
  this.gotoBox = new HPK.GotoBox(this);
  this.navigation = new HPK.Navigation();
}

HPK.Presentation.prototype = {
  /* Creates the link that enables user to run the presentation. */
  _createRunPresentationLink: function() {
    var that = this;
    $("body").append($("")
      .text(HPK.localizationStrings["runPresentation"])
      .click(function(event) {
        that.beginPresentation();

        /* The following line makes sure that the $(document.click(...) handler
           we setup in the "beginPresentation" will not catch the event. */
        event.stopPropagation();
      })
    );
  },

  /* Returns current slide as jQuery object. */
  _currentSlide: function() {
    return this._slides.slice(this._currentSlideIndex, this._currentSlideIndex + 1);
  },

  /* Are we presenting now? */
  isPresenting: function() {
    return this._presenting;
  },

  /* Begins the presentation. */
  beginPresentation: function() {
    if (this._presenting) { return; }
    if (this._slides.length == 0) { return; }

    this._slides.slice(1).hide();
    this._currentSlideIndex = 0;
    this.currentSlideCounter.update(this._currentSlideIndex);

    this._screenStyleLinks.attr("media", "projection")
    this._projectionStyleLinks.attr("media", "screen");
    /* WebKit does not reflect all changes and needs a little help. */
    if ($.browser.safari) { // Detects Google Chrome too.
      this._screenStyleLinks.attr("disabled", "disabled");
      this._projectionStyleLinks.removeAttr("disabled");
    }

    var that = this;

    $(document).mousemove(function(event) {
      if (event.pageY >= 0.8 * $(document).height()) {
        if (!that.navigation.isVisible()) {
          that.navigation.show();
        } else {
          that.navigation.touch();
        }
      } else {
        if (that.navigation.isVisible()) {
          that.navigation.hide();
        }
      }
    });

    $(document).click(function(event) {
      switch (event.which) {
        case 1: // Left button
          that.gotoNextSlideOrEndPresentation();
          return false;
        case 3: // Right button
          that.gotoPrevSlideOrEndPresentation();
          return false;
      }
    });

    $(document).keypress(function(event) {
      switch (event.which) {
        case 13:  // Enter
        case 32:  // Space
        case 110: // "n"
          that.gotoNextSlideOrEndPresentation();
          return false;

        case 8:   // Backspace
        case 112: // "p"
          that.gotoPrevSlideOrEndPresentation();
          return false;

        case 103: // "g"
          that.gotoBox.show();
          return false;

        case 0:
          switch (event.keyCode) {
            case 34: // Page Down
            case 39: // Right Arrow
            case 40: // Down Arrow
              that.gotoNextSlideOrEndPresentation();
              return false;

            case 33: // Page Up
            case 37: // Left Arrow
            case 38: // Up Arrow
              that.gotoPrevSlideOrEndPresentation();
              return false;

            case 27: // ESC
              that.endPresentation();
              return false;
          }
      }
    });

    this._presenting = true;
  },

  /* Ends the presentation. */
  endPresentation: function() {
    if (!this._presenting) { return; }

    this._slides.show();
    this._currentSlideIndex = null;
    this.gotoBox.hide();

    this._screenStyleLinks.attr("media", "screen");
    this._projectionStyleLinks.attr("media", "projection");
    /* WebKit does not reflect all changes and needs a little help. */
    if ($.browser.safari) { // Detects Google Chrome too.
      this._screenStyleLinks.removeAttr("disabled");
      this._projectionStyleLinks.attr("disabled", "disabled");
    }

    $(document).unbind("mousemove", this._documentMousemove);
    $(document).unbind("click", this._documentClick);
    $(document).unbind("keypress", this._documentKeypress);

    this._presenting = false;
  },

  /* Are we on the last slide? */
  isOnFirstSlide: function() {
    return this._presenting
      && this._currentSlideIndex == 0;
  },

  /* Are we on the last slide? */
  isOnLastSlide: function() {
    return this._presenting
      && this._currentSlideIndex == this._slides.length - 1;
  },

  /* If presenting, moves to the slide with specified index (if there is any). */
  gotoSlide: function(slideIndex) {
    if (this._presenting && slideIndex >= 0 && slideIndex < this._slides.length) {
      this._currentSlide().hide();
      this._currentSlideIndex = slideIndex;
      this._currentSlide().show();
      this.currentSlideCounter.update(this._currentSlideIndex);
    }
  },

  /* If presenting, moves to the next slide (if there is any). */
  gotoNextSlide: function() {
    this.gotoSlide(this._currentSlideIndex + 1);
  },

  /* If presenting, moves to the previous slide (if there is any). */
  gotoPrevSlide: function() {
    this.gotoSlide(this._currentSlideIndex - 1);
  },

  /* If presenting, moves to the next slide (if there is any) or ends the
     presentation. */
  gotoNextSlideOrEndPresentation: function() {
    if (this._presenting) {
      if (!this.isOnLastSlide()) {
        this.gotoNextSlide();
      } else {
        this.endPresentation();
      }
    }
  },

  /* If presenting, moves to the previous slide (if there is any) or ends the
     presentation. */
  gotoPrevSlideOrEndPresentation: function() {
    if (this._presenting) {
      if (!this.isOnFirstSlide()) {
        this.gotoPrevSlide();
      } else {
        this.endPresentation();
      }
    }
  }
}

/* ===== Let's roll... ===== */

$(document).ready(function() {
  /* Opera has its own presentation capabilities, we do not have to help it.
     See http://www.opera.com/browser/tutorials/operashow/. */
  if ($.browser.opera) { return; }

  HPK.presentation = new HPK.Presentation();

  /* These variables will be closed over by the resize handler bellow, so they
     will behave like static variables from its point of view. */
  var oldWindowWidth = $(window).width();
  var oldWindowHeight = $(window).height();

  $(window).bind("resize", function() {
    var windowWidth = $(window).width();
    var windowHeight = $(window).height();

    /* This is obviously an optimization, but we do it mainly because IE
       triggers the resize handler much more often than it should, which
       results to switching from and to the presentation again in certain
       situations (such as clicking the "Run presentation" link or at the
       end of the presentation). */
    if (windowWidth == oldWindowWidth && windowHeight == oldWindowHeight) {
      return;
    }

    /* In IE, the window height is actually larger than the screen height
       in the fullscreen mode, but it does not count scrollbar width into
       the window width. Firefox has a small bar at the top even in the
       fullscreen mode. As a result, fullscreen mode detection must be a bit
       tolerant. Browser world is a mess... */
    var isFullscreen = screen.width - windowWidth <= 20
      && screen.height - windowHeight <= 10;

    if (!HPK.presentation.isPresenting() && isFullscreen) {
      HPK.presentation.beginPresentation();
    } else if (HPK.presentation.isPresenting() && !isFullscreen) {
      HPK.presentation.endPresentation();
    }

    oldWindowWidth = windowWidth;
    oldWindowHeight = windowHeight;
  });

  var matches = document.location.hash.match(/^#slide-(\d+)$/);
  if (matches) {
    HPK.presentation.beginPresentation();
    HPK.presentation.gotoSlide(parseInt(matches[1]) - 1);
  }
});

<commit_msg>Made some Presentation properties private.<commit_after>/* HPK Namespace. */
var HPK = {};

/* ===== GotoBox ===== */

/* Creates a new GotoBox object. */
HPK.GotoBox = function(presentation) {
  var that = this;
  this._element = $("<input type='text' id='goto-box'>")
    .keypress(function(event) {
      switch (event.keyCode) {
        case 13: // Enter
          presentation.gotoSlide($(this).val() - 1);
          that.hide();
          break;
        case 27: // ESC
          that.hide();
          break;
      }
      event.stopPropagation();
    });
  $("body").append(this._element);
}

HPK.GotoBox.prototype = {
  /* Shows, clears and focuses the goto box. */
  show: function() {
    this._element.val("").show().focus();
  },

  /* Hides the goto box. */
  hide: function() {
    this._element.hide();
  }
}

/* ===== CurrentSlideCounter ===== */

/* Creates a new CurrentSlideCounter object. */
HPK.CurrentSlideCounter = function() {
  this._element = $("
");
  $("body").append(this._element);
}

HPK.CurrentSlideCounter.prototype = {
  /* Updates the current slide counter. */
  update: function(currentSlideIndex) {
    this._element.text(currentSlideIndex + 1);
  }
}

/* ===== Navigation ===== */

/* Creates a new Navigation object. */
HPK.Navigation = function(presentation) {
  this._visible = false;
  var that = this;
  this._element = $("
")
    .append($("")
      .click(function(event) {
        presentation.gotoPrevSlide();
        event.stopPropagation();
      })
    )
    .append($("")
      .click(function(event) {
        alert("TODO")
      })
    )
    .append($("")
      .click(function(event) {
        presentation.gotoNextSlide();
        event.stopPropagation();
      })
    )
    .mouseover(function() {
      that.clearHideTimer();
    })
    .mouseout(function() {
      that.touch();
    })
    .mousemove(function(event) {
      event.stopPropagation();
    });
  $("body").append(this._element);
  this._hideTimer = null;
}

HPK.Navigation.prototype = {

  /* Is the navigation visible? */
  isVisible: function() {
    return this._visible;
  },

  /* Clears the current hiding timer. */
  clearHideTimer: function() {
    if (this._hideTimer) {
      clearTimeout(this._hideTimer);
      this._hideTimer = null;
    }
  },

  /* Clears the current hiding timer and creates a new one. */
  touch: function() {
    this.clearHideTimer();
    var that = this;
    this._hideTimer = setTimeout(function() {
      that.hide();
    }, 5000);
  },

  /* Shows the navigation. */
  show: function() {
    this._visible = true;
    this._element.css("opacity", "0").show().fadeTo("normal", 0.8);
    this.touch();
  },

  /* Hides the navigation. */
  hide: function() {
    this.clearHideTimer();
    this._element.fadeOut("normal");
    this._visible = false;
  }
}

/* ===== Presentation ===== */

/* Creates a new Presentation object and injects the presentation mode toggle
   element into the HTML. */
HPK.Presentation = function() {
  this._slides = $("div.presentation div.slide");
  this._currentSlideIndex = null;
  this._presenting = false;
  this._screenStyleLinks = $("link[rel=stylesheet][media=screen]");
  this._projectionStyleLinks = $("link[rel=stylesheet][media=projection]");

  this._createRunPresentationLink();

  this._currentSlideCounter = new HPK.CurrentSlideCounter;
  this._gotoBox = new HPK.GotoBox(this);
  this._navigation = new HPK.Navigation();
}

HPK.Presentation.prototype = {
  /* Creates the link that enables user to run the presentation. */
  _createRunPresentationLink: function() {
    var that = this;
    $("body").append($("")
      .text(HPK.localizationStrings["runPresentation"])
      .click(function(event) {
        that.beginPresentation();

        /* The following line makes sure that the $(document.click(...) handler
           we setup in the "beginPresentation" will not catch the event. */
        event.stopPropagation();
      })
    );
  },

  /* Returns current slide as jQuery object. */
  _currentSlide: function() {
    return this._slides.slice(this._currentSlideIndex, this._currentSlideIndex + 1);
  },

  /* Are we presenting now? */
  isPresenting: function() {
    return this._presenting;
  },

  /* Begins the presentation. */
  beginPresentation: function() {
    if (this._presenting) { return; }
    if (this._slides.length == 0) { return; }

    this._slides.slice(1).hide();
    this._currentSlideIndex = 0;
    this._currentSlideCounter.update(this._currentSlideIndex);

    this._screenStyleLinks.attr("media", "projection")
    this._projectionStyleLinks.attr("media", "screen");
    /* WebKit does not reflect all changes and needs a little help. */
    if ($.browser.safari) { // Detects Google Chrome too.
      this._screenStyleLinks.attr("disabled", "disabled");
      this._projectionStyleLinks.removeAttr("disabled");
    }

    var that = this;

    $(document).mousemove(function(event) {
      if (event.pageY >= 0.8 * $(document).height()) {
        if (!that._navigation.isVisible()) {
          that._navigation.show();
        } else {
          that._navigation.touch();
        }
      } else {
        if (that._navigation.isVisible()) {
          that._navigation.hide();
        }
      }
    });

    $(document).click(function(event) {
      switch (event.which) {
        case 1: // Left button
          that.gotoNextSlideOrEndPresentation();
          return false;
        case 3: // Right button
          that.gotoPrevSlideOrEndPresentation();
          return false;
      }
    });

    $(document).keypress(function(event) {
      switch (event.which) {
        case 13:  // Enter
        case 32:  // Space
        case 110: // "n"
          that.gotoNextSlideOrEndPresentation();
          return false;

        case 8:   // Backspace
        case 112: // "p"
          that.gotoPrevSlideOrEndPresentation();
          return false;

        case 103: // "g"
          that._gotoBox.show();
          return false;

        case 0:
          switch (event.keyCode) {
            case 34: // Page Down
            case 39: // Right Arrow
            case 40: // Down Arrow
              that.gotoNextSlideOrEndPresentation();
              return false;

            case 33: // Page Up
            case 37: // Left Arrow
            case 38: // Up Arrow
              that.gotoPrevSlideOrEndPresentation();
              return false;

            case 27: // ESC
              that.endPresentation();
              return false;
          }
      }
    });

    this._presenting = true;
  },

  /* Ends the presentation. */
  endPresentation: function() {
    if (!this._presenting) { return; }

    this._slides.show();
    this._currentSlideIndex = null;
    this._gotoBox.hide();

    this._screenStyleLinks.attr("media", "screen");
    this._projectionStyleLinks.attr("media", "projection");
    /* WebKit does not reflect all changes and needs a little help. */
    if ($.browser.safari) { // Detects Google Chrome too.
      this._screenStyleLinks.removeAttr("disabled");
      this._projectionStyleLinks.attr("disabled", "disabled");
    }

    $(document).unbind("mousemove", this._documentMousemove);
    $(document).unbind("click", this._documentClick);
    $(document).unbind("keypress", this._documentKeypress);

    this._presenting = false;
  },

  /* Are we on the last slide? */
  isOnFirstSlide: function() {
    return this._presenting
      && this._currentSlideIndex == 0;
  },

  /* Are we on the last slide? */
  isOnLastSlide: function() {
    return this._presenting
      && this._currentSlideIndex == this._slides.length - 1;
  },

  /* If presenting, moves to the slide with specified index (if there is any). */
  gotoSlide: function(slideIndex) {
    if (this._presenting && slideIndex >= 0 && slideIndex < this._slides.length) {
      this._currentSlide().hide();
      this._currentSlideIndex = slideIndex;
      this._currentSlide().show();
      this._currentSlideCounter.update(this._currentSlideIndex);
    }
  },

  /* If presenting, moves to the next slide (if there is any). */
  gotoNextSlide: function() {
    this.gotoSlide(this._currentSlideIndex + 1);
  },

  /* If presenting, moves to the previous slide (if there is any). */
  gotoPrevSlide: function() {
    this.gotoSlide(this._currentSlideIndex - 1);
  },

  /* If presenting, moves to the next slide (if there is any) or ends the
     presentation. */
  gotoNextSlideOrEndPresentation: function() {
    if (this._presenting) {
      if (!this.isOnLastSlide()) {
        this.gotoNextSlide();
      } else {
        this.endPresentation();
      }
    }
  },

  /* If presenting, moves to the previous slide (if there is any) or ends the
     presentation. */
  gotoPrevSlideOrEndPresentation: function() {
    if (this._presenting) {
      if (!this.isOnFirstSlide()) {
        this.gotoPrevSlide();
      } else {
        this.endPresentation();
      }
    }
  }
}

/* ===== Let's roll... ===== */

$(document).ready(function() {
  /* Opera has its own presentation capabilities, we do not have to help it.
     See http://www.opera.com/browser/tutorials/operashow/. */
  if ($.browser.opera) { return; }

  HPK.presentation = new HPK.Presentation();

  /* These variables will be closed over by the resize handler bellow, so they
     will behave like static variables from its point of view. */
  var oldWindowWidth = $(window).width();
  var oldWindowHeight = $(window).height();

  $(window).bind("resize", function() {
    var windowWidth = $(window).width();
    var windowHeight = $(window).height();

    /* This is obviously an optimization, but we do it mainly because IE
       triggers the resize handler much more often than it should, which
       results to switching from and to the presentation again in certain
       situations (such as clicking the "Run presentation" link or at the
       end of the presentation). */
    if (windowWidth == oldWindowWidth && windowHeight == oldWindowHeight) {
      return;
    }

    /* In IE, the window height is actually larger than the screen height
       in the fullscreen mode, but it does not count scrollbar width into
       the window width. Firefox has a small bar at the top even in the
       fullscreen mode. As a result, fullscreen mode detection must be a bit
       tolerant. Browser world is a mess... */
    var isFullscreen = screen.width - windowWidth <= 20
      && screen.height - windowHeight <= 10;

    if (!HPK.presentation.isPresenting() && isFullscreen) {
      HPK.presentation.beginPresentation();
    } else if (HPK.presentation.isPresenting() && !isFullscreen) {
      HPK.presentation.endPresentation();
    }

    oldWindowWidth = windowWidth;
    oldWindowHeight = windowHeight;
  });

  var matches = document.location.hash.match(/^#slide-(\d+)$/);
  if (matches) {
    HPK.presentation.beginPresentation();
    HPK.presentation.gotoSlide(parseInt(matches[1]) - 1);
  }
});

<|endoftext|>


<commit_before>module.exports = function Printer(){
    this.colors = require('colors');

    this.STAGED = "STAGED";
    this.NOT_STAGED = "NOT_STAGED";
    this.UNTRACKED = "UNTRACKED";
    this.margin = "                 ";
    this.smallMargin = "          ";
    this.maxLineLength = 80;

    this.colors.setTheme({
      silly: 'rainbow',
      input: 'grey',
      verbose: 'cyan',
      prompt: 'grey',
      good: 'green',
      staged: 'green',
      data: 'grey',
      help: 'cyan',
      important: 'yellow',
      debug: 'blue',
      important: 'blue',
      change: 'red',
      RED: 'red',
      error: 'red',
      name: 'red',
      title: 'green',
      arg: 'white'
    });

    this.statusStringIsClean = function(strings, str) {
        return strings.length >= 2 &&(strings[0].indexOf("On branch") != -1 && (strings[1].indexOf("nothing to commit") != -1 || (strings.length>=3 && strings[2].indexOf("nothing to commit") != -1)));
    };

    this.E = function(str) {
        console.log(str.error);
    };

    this.I = function(str) {
        console.log(str.important);
    };

    this.logo = function(path) {
        var fs = require('fs');
        var logo = fs.readFileSync(path).toString();
        this.printLinesWithPrefix("\t\t", logo);
    };

    this.description = function(issueID, fields) {
        var issuetype = fields.issuetype ? fields.issuetype.name || "" : "typeless";
        var status = fields.status ? fields.status.name || "" : "without any status";
        var assignee = fields.assignee ? fields.assignee.displayName || "" : "no one";
        var summary = fields.summary || "";
        this._description(issueID, summary, fields.description || "",
            status, issuetype, assignee);
    };

    this._description = function(key, summary, description, status, issuetype, assignee) {
        description = this.truncateLines(description);
        console.log(("\t|  " + key + ": " + summary).title);
        // console.log("\t| ".title, "Status:".title, status, "\tType:".title, issuetype, "\tAssignee:".title,  assignee);
        this.hr("\t|");
        console.log("\t| ", "A", ("'"+issuetype+"'").verbose, "issue that is", ("'"+status+"'").verbose, "assigned to", ("'"+assignee+"'").verbose + ".");
        this.hr("\t|");
        this.printLinesWithPrefix("\t| ", description);
    };

    this.comments = function(data) {
        var self = this;
        console.log("\t### COMMENTS ###".title);
        data = JSON.parse(data);
        if(data.comments){
            var comments = data.comments;
            for(var i=0; i<comments.length; i++) {
                var c = comments[i];
                var author =c.author.displayName;
                console.log("\t#".verbose);
                console.log("\t#".verbose, "author: ", author.name, "\t created: ", c.created.verbose, "\tupdated: "+c.updated.verbose);
                var body = self.truncateLines(c.body);
                self.printLinesWithPrefix("\t#   ", body);
            }
        }else {
            console.log("No comments");
        }
    };

    this.truncateLines = function(str) {
        var max = this.maxLineLength;
        var truncated = "";
        var strings = str.split("\n");
        for(var i =0; i<strings.length; i++) {
            var s = strings[i];
            if(s.length > max) {
                var words = s.split(" ");
                var line = "\n";

                for(var j = 0; j<words.length; j++) {
                   line += " "+words[j];
                   var next = line + (j<words.length-1 ? " " + words[j+1] : "");
                   if(next.length >= max){
                        truncated += line;
                        line = "\n";
                   }
                }
                truncated += line === "\n" ? "" : line;
            } else {
                truncated += "\n" + s;
            }
        }
        return truncated;
    };

    this.printLinesWithPrefix = function(margin, str) {
        var strings = str.split("\n");
        for(var i =0; i<strings.length; i++) {
            console.log((margin + strings[i]).verbose);
        }
    };

    this.print = function(str) {
        var strings = str.split("\n");
        if(this.statusStringIsClean(strings, str)){
            console.log((" ~ "+strings[0]+ " CLEAN ~").good);
        } else {
            for(var i =0; i<strings.length; i++) {
                this.pf(strings[i], i);
            }
        }
    };

    this.printCmd = function(c) {
        var ARG = c.arg;
        while(ARG.length < 15) {
            ARG = ARG + " ";
        }
        ARG = ARG + " > ";

        console.log("\t" + ARG.arg + c.name.help);
    };

    this.printBranch = function(currentBranch) {
        process.stdout.write(this.smallMargin);
        console.log("On branch:".verbose, currentBranch);
    };

    this.pf = function(str, lineNumber){
        if(str.length==0)
            return;

        var margin = str.indexOf("On branch") != -1 ? this.smallMargin : this.margin;
        if(!this.hide(str)) {
            process.stdout.write(margin);
        }

        this.notStaged(str);
        this.untracked(str);
        this.isStaged(str);
        if(!this.hide(str)){
            if(this.isGood(str, lineNumber)) {
                console.log(str.good);
            } else if(this.isVerbose(str, lineNumber)) {
                console.log(str.verbose);
            } else if(this.isChange(str, lineNumber)) {
                console.log(str.change);
            } else if(this.isImportant(str, lineNumber)) {
                  console.log(str.important);
            } else if(this.isALineItem(str, lineNumber) || this.state == this.UNTRACKED) {
                if(this.state == this.STAGED)
                    console.log(str.staged.staged);
                else if(this.state == this.NOT_STAGED)
                    console.log(str.change);
                else if(this.state == this.UNTRACKED)
                    console.log(str.change);
                else
                    console.log(str);

            } else {
                console.log(str);
            }
        }
    };

    this.isGood = function(str, lineNumber) {
        return str.indexOf("Your branch is up-to-date") != -1 || str.indexOf("nothing to commit, working directory clean") != -1;
    };

    this.isALineItem = function(str, lineNumber) {
        return str.indexOf("modified:") != -1 || str.indexOf("new file:") != -1 || str.indexOf("deleted") != -1;
    };

    this.isVerbose = function(str, lineNumber) {
        return str.indexOf("On branch") != -1;
    };

    this.isImportant = function(str, lineNumber) {
        return this.notStaged(str) || this.untracked(str) || this.isStaged(str);
    };

    this.isStaged = function(str) {
        var b = str.indexOf("Changes to be committed:") != -1;
        if(b)
            this.state = this.STAGED;
        return b;
    };

    this.notStaged = function(str) {
        var b = str.indexOf("Changes not staged for commit:") != -1 || str.indexOf("Unstaged changes after reset:") != -1;
        if(b)
            this.state = this.NOT_STAGED;
        return b;
    };

    this.untracked = function(str){
        var b = str.indexOf("Untracked files:") != -1;
        if(b)
            this.state = this.UNTRACKED;
        return b;
    };

    this.isChange = function(str, lineNumber) {
        return false;
    };

    this.hide = function(str, lineNumber) {
        return str.indexOf("(use \"git ") != -1;
    };

    this.hr = function(prefix) {
        prefix = prefix || "";
        console.log(prefix + "----------------------------------------------------------------------------------");
    };

    return this;
}

<commit_msg>[develop] quick commit.<commit_after>module.exports = function Printer(){
    this.colors = require('colors');

    this.STAGED = "STAGED";
    this.NOT_STAGED = "NOT_STAGED";
    this.UNTRACKED = "UNTRACKED";
    this.margin = "                 ";
    this.smallMargin = "          ";
    this.maxLineLength = 80;

    this.colors.setTheme({
      silly: 'rainbow',
      input: 'grey',
      verbose: 'cyan',
      prompt: 'grey',
      good: 'green',
      staged: 'green',
      data: 'grey',
      help: 'cyan',
      important: 'yellow',
      debug: 'blue',
      important: 'blue',
      change: 'red',
      RED: 'red',
      error: 'red',
      name: 'red',
      logo: 'green',
      title: 'green',
      arg: 'white'
    });

    this.statusStringIsClean = function(strings, str) {
        return strings.length >= 2 &&(strings[0].indexOf("On branch") != -1 && (strings[1].indexOf("nothing to commit") != -1 || (strings.length>=3 && strings[2].indexOf("nothing to commit") != -1)));
    };

    this.E = function(str) {
        console.log(str.error);
    };

    this.I = function(str) {
        console.log(str.important);
    };

    this.logo = function(path) {
        var fs = require('fs');
        var logo = fs.readFileSync(path).toString();
        this.printLinesWithPrefix("\t\t", logo, 'logo');
    };

    this.description = function(issueID, fields) {
        var issuetype = fields.issuetype ? fields.issuetype.name || "" : "typeless";
        var status = fields.status ? fields.status.name || "" : "without any status";
        var assignee = fields.assignee ? fields.assignee.displayName || "" : "no one";
        var summary = fields.summary || "";
        this._description(issueID, summary, fields.description || "",
            status, issuetype, assignee);
    };

    this._description = function(key, summary, description, status, issuetype, assignee) {
        description = this.truncateLines(description);
        console.log(("\t|  " + key + ": " + summary).title);
        // console.log("\t| ".title, "Status:".title, status, "\tType:".title, issuetype, "\tAssignee:".title,  assignee);
        this.hr("\t|");
        console.log("\t| ", "A", ("'"+issuetype+"'").verbose, "issue that is", ("'"+status+"'").verbose, "assigned to", ("'"+assignee+"'").verbose + ".");
        this.hr("\t|");
        this.printLinesWithPrefix("\t| ", description);
    };

    this.comments = function(data) {
        var self = this;
        console.log("\t### COMMENTS ###".title);
        data = JSON.parse(data);
        if(data.comments){
            var comments = data.comments;
            for(var i=0; i<comments.length; i++) {
                var c = comments[i];
                var author =c.author.displayName;
                console.log("\t#".verbose);
                console.log("\t#".verbose, "author: ", author.name, "\t created: ", c.created.verbose, "\tupdated: "+c.updated.verbose);
                var body = self.truncateLines(c.body);
                self.printLinesWithPrefix("\t#   ", body);
            }
        }else {
            console.log("No comments");
        }
    };

    this.truncateLines = function(str) {
        var max = this.maxLineLength;
        var truncated = "";
        var strings = str.split("\n");
        for(var i =0; i<strings.length; i++) {
            var s = strings[i];
            if(s.length > max) {
                var words = s.split(" ");
                var line = "\n";

                for(var j = 0; j<words.length; j++) {
                   line += " "+words[j];
                   var next = line + (j<words.length-1 ? " " + words[j+1] : "");
                   if(next.length >= max){
                        truncated += line;
                        line = "\n";
                   }
                }
                truncated += line === "\n" ? "" : line;
            } else {
                truncated += "\n" + s;
            }
        }
        return truncated;
    };

    this.printLinesWithPrefix = function(margin, str, style) {
        var strings = str.split("\n");
        for(var i =0; i<strings.length; i++) {
            console.log((margin + strings[i])[style || 'verbose']);
        }
    };

    this.print = function(str) {
        var strings = str.split("\n");
        if(this.statusStringIsClean(strings, str)){
            console.log((" ~ "+strings[0]+ " CLEAN ~").good);
        } else {
            for(var i =0; i<strings.length; i++) {
                this.pf(strings[i], i);
            }
        }
    };

    this.printCmd = function(c) {
        var ARG = c.arg;
        while(ARG.length < 15) {
            ARG = ARG + " ";
        }
        ARG = ARG + " > ";

        console.log("\t" + ARG.arg + c.name.help);
    };

    this.printBranch = function(currentBranch) {
        process.stdout.write(this.smallMargin);
        console.log("On branch:".verbose, currentBranch);
    };

    this.pf = function(str, lineNumber){
        if(str.length==0)
            return;

        var margin = str.indexOf("On branch") != -1 ? this.smallMargin : this.margin;
        if(!this.hide(str)) {
            process.stdout.write(margin);
        }

        this.notStaged(str);
        this.untracked(str);
        this.isStaged(str);
        if(!this.hide(str)){
            if(this.isGood(str, lineNumber)) {
                console.log(str.good);
            } else if(this.isVerbose(str, lineNumber)) {
                console.log(str.verbose);
            } else if(this.isChange(str, lineNumber)) {
                console.log(str.change);
            } else if(this.isImportant(str, lineNumber)) {
                  console.log(str.important);
            } else if(this.isALineItem(str, lineNumber) || this.state == this.UNTRACKED) {
                if(this.state == this.STAGED)
                    console.log(str.staged.staged);
                else if(this.state == this.NOT_STAGED)
                    console.log(str.change);
                else if(this.state == this.UNTRACKED)
                    console.log(str.change);
                else
                    console.log(str);

            } else {
                console.log(str);
            }
        }
    };

    this.isGood = function(str, lineNumber) {
        return str.indexOf("Your branch is up-to-date") != -1 || str.indexOf("nothing to commit, working directory clean") != -1;
    };

    this.isALineItem = function(str, lineNumber) {
        return str.indexOf("modified:") != -1 || str.indexOf("new file:") != -1 || str.indexOf("deleted") != -1;
    };

    this.isVerbose = function(str, lineNumber) {
        return str.indexOf("On branch") != -1;
    };

    this.isImportant = function(str, lineNumber) {
        return this.notStaged(str) || this.untracked(str) || this.isStaged(str);
    };

    this.isStaged = function(str) {
        var b = str.indexOf("Changes to be committed:") != -1;
        if(b)
            this.state = this.STAGED;
        return b;
    };

    this.notStaged = function(str) {
        var b = str.indexOf("Changes not staged for commit:") != -1 || str.indexOf("Unstaged changes after reset:") != -1;
        if(b)
            this.state = this.NOT_STAGED;
        return b;
    };

    this.untracked = function(str){
        var b = str.indexOf("Untracked files:") != -1;
        if(b)
            this.state = this.UNTRACKED;
        return b;
    };

    this.isChange = function(str, lineNumber) {
        return false;
    };

    this.hide = function(str, lineNumber) {
        return str.indexOf("(use \"git ") != -1;
    };

    this.hr = function(prefix) {
        prefix = prefix || "";
        console.log(prefix + "----------------------------------------------------------------------------------");
    };

    return this;
}

<|endoftext|>


<commit_before>/*jshint bitwise: false*/
/*global angular:false */
/*global document:false */

'use strict';
angular.module('PalettifyApp', ['ngAnimate'])
 .controller('MainController', function($scope,$http,$timeout) {
     $scope.dataLoaded = false;
     $scope.pContainer = true;
     $scope.backgroundclr = 'whitebg';
     $scope.buttonclr = 'darkbg';
     $scope.invert = true;

     $http({method: 'GET', url: 'app/data.json'})
     .success(function(data) {
       $scope.palette = Math.floor(Math.random()*data.length);
       $scope.titles = [];
       $scope.colors = [];
       $scope.lumi = [];

       for (var i in data) {
         $scope.colors.push(data[i].colors);
         $scope.titles.push(data[i].title);
       }

       angular.element(document.getElementsByClassName('tooltipnow')).tooltip();
       $scope.dataLoaded = true;
     })
     .error(function() {
       console.log('Ooooops! Something went wrong Charlie!');
     });

     $scope.nextPalette = function($event){
       $event.stopPropagation();
       $scope.pContainer = false;
       $timeout(function(){
         var last = $scope.palette;
         var next  = -1;
         while(next===-1||next===last){
           next = Math.floor(Math.random()*$scope.colors.length);
         }
         $scope.palette = next;
         $scope.pContainer = true;
       }, 300);
     };

     $scope.changeBackground = function(){
       if ($scope.backgroundclr==='whitebg') {
         $scope.backgroundclr = 'darkbg';
         $scope.buttonclr = 'whitebg';
         $scope.invert = false;
       }else{
         $scope.backgroundclr = 'whitebg';
         $scope.buttonclr = 'darkbg';
         $scope.invert=true;
       }
     };

     $scope.isLight = function(hex){
       var rgb,r,g,b,l;
       rgb = parseInt(hex, 16);
       r = (rgb >> 16) & 0xff;
       g = (rgb >>  8) & 0xff;
       b = (rgb >>  0) & 0xff;
       l = 0.2126 * r + 0.7152 * g + 0.0722 * b;
       console.log('Lumi is: '+l);
       if(l>220){
         return true;
       }else{
         return false;
       }
     };
});
<commit_msg>removed comments<commit_after>/*jshint bitwise: false*/
/*global angular:false */
/*global document:false */

'use strict';
angular.module('PalettifyApp', ['ngAnimate'])
 .controller('MainController', function($scope,$http,$timeout) {
     $scope.dataLoaded = false;
     $scope.pContainer = true;
     $scope.backgroundclr = 'whitebg';
     $scope.buttonclr = 'darkbg';
     $scope.invert = true;

     $http({method: 'GET', url: 'app/data.json'})
     .success(function(data) {
       $scope.palette = Math.floor(Math.random()*data.length);
       $scope.titles = [];
       $scope.colors = [];
       $scope.lumi = [];

       for (var i in data) {
         $scope.colors.push(data[i].colors);
         $scope.titles.push(data[i].title);
       }

       angular.element(document.getElementsByClassName('tooltipnow')).tooltip();
       $scope.dataLoaded = true;
     })
     .error(function() {
       console.log('Ooooops! Something went wrong Charlie!');
     });

     $scope.nextPalette = function($event){
       $event.stopPropagation();
       $scope.pContainer = false;
       $timeout(function(){
         var last = $scope.palette;
         var next  = -1;
         while(next===-1||next===last){
           next = Math.floor(Math.random()*$scope.colors.length);
         }
         $scope.palette = next;
         $scope.pContainer = true;
       }, 300);
     };

     $scope.changeBackground = function(){
       if ($scope.backgroundclr==='whitebg') {
         $scope.backgroundclr = 'darkbg';
         $scope.buttonclr = 'whitebg';
         $scope.invert = false;
       }else{
         $scope.backgroundclr = 'whitebg';
         $scope.buttonclr = 'darkbg';
         $scope.invert=true;
       }
     };

     $scope.isLight = function(hex){
       var rgb,r,g,b,l;
       rgb = parseInt(hex, 16);
       r = (rgb >> 16) & 0xff;
       g = (rgb >>  8) & 0xff;
       b = (rgb >>  0) & 0xff;
       l = 0.2126 * r + 0.7152 * g + 0.0722 * b;
       if(l>220){
         return true;
       }else{
         return false;
       }
     };
});
<|endoftext|>


<commit_before>var test = require('tape');

var u = require('../lib/helpers.js');
var REventTarget = require('../lib/reventtarget.js');

test('random_string', function (t) {
  var i, _i, _len, _ref;
  t.plan(5);
  t.notEqual(u.random_string(8), u.random_string(8));
  _ref = [1, 2, 3, 128];
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
    i = _ref[_i];
    t.equal(u.random_string(i).length, i);
  }
});

test('random_number_string', function (t) {
  t.plan(55);
  for (var i = 0; i <= 10; i++) {
    t.equal(u.random_number_string(10).length, 1);
    t.equal(u.random_number_string(100).length, 2);
    t.equal(u.random_number_string(1000).length, 3);
    t.equal(u.random_number_string(10000).length, 4);
    t.equal(u.random_number_string(100000).length, 5);
  }
});

test('amendUrl', function (t) {
  // NOTE: i stripped out tests that were depending on the DOM:
  t.plan(6);
  t.throws(function() {
    return u.amendUrl('');
  }, 'Wrong url');
  t.throws(function() {
    return u.amendUrl(false);
  },'Wrong url');
  t.throws(function() {
    return u.amendUrl('http://abc?a=a');
  }, 'Only basic urls are supported');
  t.throws(function() {
    return u.amendUrl('http://abc#a');
  }, 'Only basic urls are supported');
  t.equal(u.amendUrl('https://a:80/abc'), 'https://a:80/abc');
  t.equal(u.amendUrl('http://a:443/abc'), 'http://a:443/abc');
});

test('quote', function (t) {
  var all_chars = (function() {
    var _results, i;
    _results = [];
    for (i = 0; i <= 65535; i++) {
      _results.push(String.fromCharCode(i));
    }
    return _results;
  }()).join('');
  t.plan(8);
  t.equal(u.quote(''), '""');
  t.equal(u.quote('a'), '"a"');
  t.ok(['"\\t"', '"\\u0009"'].indexOf(u.quote('\t')) !== -1);
  t.ok(['"\\n"', '"\\u000a"'].indexOf(u.quote('\n')) !== -1);
  t.equal(u.quote('\x00\udfff\ufffe\uffff'), '"\\u0000\\udfff\\ufffe\\uffff"');
  t.equal(u.quote('\ud85c\udff7\ud800\ud8ff'), '"\\ud85c\\udff7\\ud800\\ud8ff"');
  t.equal(u.quote('\u2000\u2001\u0300\u0301'), '"\\u2000\\u2001\\u0300\\u0301"');
  t.ok(JSON.parse(u.quote(all_chars)) === all_chars, "Quote/unquote all 64K chars.");
});

test('detectProtocols', function (t) {
  var node_probed = {
    'websocket': true
  };
  t.plan(1);
  t.deepEqual(u.detectProtocols(node_probed, null, {}), ['websocket']);
 });

test("EventEmitter", function (t) {
  var bluff, handler0, handler1, handler2, handler3, handler4, log, r, single;
  t.plan(7);
  r = new REventTarget;
  r.addEventListener('message', function() {
    return t.ok(true);
  });
  r.onmessage = function() {
    return t.ok(false);
  };
  bluff = function() {
    return t.ok(false);
  };
  r.addEventListener('message', bluff);
  r.removeEventListener('message', bluff);
  r.addEventListener('message', bluff);
  r.addEventListener('message', function() {
    return t.ok(true);
  });
  r.onmessage = function() {
    return t.ok(true);
  };
  r.removeEventListener('message', bluff);
  r.dispatchEvent({
    type: 'message'
  });
  handler0 = function() {
    return log.push(0);
  };
  handler1 = function() {
    log.push(1);
    r.removeEventListener('test', handler0);
    r.removeEventListener('test', handler2);
    r.addEventListener('test', handler3);
    return r.addEventListener('test', handler4);
  };
  handler2 = function() {
    return log.push(2);
  };
  handler3 = function() {
    log.push(3);
    r.removeEventListener('test', handler1);
    r.removeEventListener('test', handler3);
    return r.removeEventListener('test', handler4);
  };
  handler4 = function() {
    return log.push(4);
  };
  r.addEventListener('test', handler0);
  r.addEventListener('test', handler1);
  r.addEventListener('test', handler2);
  log = [];
  r.dispatchEvent({
    type: 'test'
  });
  t.deepEqual(log, [0, 1, 2]);
  log = [];
  r.dispatchEvent({
    type: 'test'
  });
  t.deepEqual(log, [1, 3, 4]);
  log = [];
  r.dispatchEvent({
    type: 'test'
  });
  t.deepEqual(log, []);
  single = function() {
    return t.ok(true);
  };
  r.addEventListener('close', single);
  r.addEventListener('close', single);
  r.dispatchEvent({
    type: 'close'
  });
  r.removeEventListener('close', single);
  r.dispatchEvent({
    type: 'close'
  });
});<commit_msg>test: remove coffeescriptism<commit_after>var test = require('tape');

var u = require('../lib/helpers.js');

test('random_string', function (t) {
  t.plan(5);

  t.notEqual(
    u.random_string(8),
    u.random_string(8)
  );

  [1, 2, 3, 128].forEach(function (i) {
    t.equal(u.random_string(i).length, i);
  });
});

test('random_number_string', function (t) {
  t.plan(55);

  for (var i = 0; i <= 10; i++) {
    t.equal(u.random_number_string(10).length, 1);
    t.equal(u.random_number_string(100).length, 2);
    t.equal(u.random_number_string(1000).length, 3);
    t.equal(u.random_number_string(10000).length, 4);
    t.equal(u.random_number_string(100000).length, 5);
  }
});

test('amendUrl', function (t) {
  // NOTE: i stripped out tests that were depending on the DOM:
  t.plan(6);

  t.throws(function() {
    u.amendUrl('');
  }, 'Wrong url');

  t.throws(function() {
    u.amendUrl(false);
  },'Wrong url');

  t.throws(function() {
    u.amendUrl('http://abc?a=a');
  }, 'Only basic urls are supported');

  t.throws(function() {
    u.amendUrl('http://abc#a');
  }, 'Only basic urls are supported');

  t.equal(u.amendUrl('https://a:80/abc'), 'https://a:80/abc');

  t.equal(u.amendUrl('http://a:443/abc'), 'http://a:443/abc');

});

test('quote', function (t) {
  var all_chars = Array(65535).map(function (_, i) {
    return String.fromCharCode(i);
  }).join('');

  t.plan(8);

  t.equal(u.quote(''), '""');

  t.equal(u.quote('a'), '"a"');

  t.ok(['"\\t"', '"\\u0009"'].indexOf(u.quote('\t')) !== -1);

  t.ok(['"\\n"', '"\\u000a"'].indexOf(u.quote('\n')) !== -1);

  t.equal(u.quote('\x00\udfff\ufffe\uffff'), '"\\u0000\\udfff\\ufffe\\uffff"');

  t.equal(u.quote('\ud85c\udff7\ud800\ud8ff'), '"\\ud85c\\udff7\\ud800\\ud8ff"');

  t.equal(u.quote('\u2000\u2001\u0300\u0301'), '"\\u2000\\u2001\\u0300\\u0301"');

  t.ok(JSON.parse(u.quote(all_chars)) === all_chars, "Quote/unquote all 64K chars.");
});

test('detectProtocols', function (t) {
  var node_probed = {
    'websocket': true
  };
  t.plan(1);
  t.deepEqual(u.detectProtocols(node_probed, null, {}), ['websocket']);
 });

test("REventTarget", function (t) {
  var REventTarget = require('../lib/reventtarget.js');
  var bluff, handler0, handler1, handler2, handler3, handler4, log, r, single;
  t.plan(7);
  r = new REventTarget;
  r.addEventListener('message', function() {
    t.ok(true);
  });
  r.onmessage = function() {
    t.ok(false);
  };
  bluff = function() {
    t.ok(false);
  };
  r.addEventListener('message', bluff);
  r.removeEventListener('message', bluff);
  r.addEventListener('message', bluff);
  r.addEventListener('message', function() {
    t.ok(true);
  });
  r.onmessage = function() {
    t.ok(true);
  };
  r.removeEventListener('message', bluff);
  r.dispatchEvent({
    type: 'message'
  });
  handler0 = function() {
    log.push(0);
  };
  handler1 = function() {
    log.push(1);
    r.removeEventListener('test', handler0);
    r.removeEventListener('test', handler2);
    r.addEventListener('test', handler3);
    r.addEventListener('test', handler4);
  };
  handler2 = function() {
    log.push(2);
  };
  handler3 = function() {
    log.push(3);
    r.removeEventListener('test', handler1);
    r.removeEventListener('test', handler3);
    r.removeEventListener('test', handler4);
  };
  handler4 = function() {
    log.push(4);
  };
  r.addEventListener('test', handler0);
  r.addEventListener('test', handler1);
  r.addEventListener('test', handler2);
  log = [];
  r.dispatchEvent({
    type: 'test'
  });
  t.deepEqual(log, [0, 1, 2]);
  log = [];
  r.dispatchEvent({
    type: 'test'
  });
  t.deepEqual(log, [1, 3, 4]);
  log = [];
  r.dispatchEvent({
    type: 'test'
  });
  t.deepEqual(log, []);
  single = function() {
    t.ok(true);
  };
  r.addEventListener('close', single);
  r.addEventListener('close', single);
  r.dispatchEvent({
    type: 'close'
  });
  r.removeEventListener('close', single);
  r.dispatchEvent({
    type: 'close'
  });
});
<|endoftext|>


<commit_before>var pageIndex = 0;

$( document ).ready(function() {
  loadPageIntoElement("JSONP", addPage());
});

function addPage() {
	var pageId = "page" + pageIndex++;

	var tempContainer = document.createElement("div");
	tempContainer.innerHtml =
'
' +
'
'+
'
'+
'

'+
'
'+
'

'+
'
'+
'
';

	$(".wikibrowser-host").append(tempContainer.innerHtml);

	// Scroll to reveal the new pane
	var newPageOffset = $("#" + pageId).offset().left;
	$(".wikibrowser-host").animate({scrollLeft: newPageOffset}, 400);

	return pageId;
}

function loadPageIntoElement(page, element) {
	$.ajax({
	    url : "http://en.wikipedia.org/w/api.php?action=parse&format=json&callback=?&continue=&page=" + page,
	    data: {
	    	format: 'json'
	    },
	    dataType: 'jsonp',
	    cache: 'true' // defaults to false for jsonp.
	})
	.done(function(data) {
		$( "#" + element + " > .pre-content > h1" ).append( data.parse.displaytitle );
		$( "#" + element + " > .content" ).append( data.parse.text['*'] );
		$( "#" + element + " > .content a").each(fixHyperlink);
		$( "#" + element ).perfectScrollbar({
			wheelSpeed: 3
		});
	});
}

function fixHyperlink(index, element)
{
	var jElement = $(element);
	var address = jElement.attr('href');
	if (address.substring(0, 6) === '/wiki/')
	{
		jElement.attr('href', "http://en.wikipedia.org" + address);
		jElement.on('click', function() {
			loadPageIntoElement(address.substring(6), addPage());
			return false; // prevent going to href (wikipedia)
		})
	}
	if (address.substring(0, 1) !== '#')
	{
		jElement.attr('target', "_blank");
	}
}<commit_msg>Reverts he sample article<commit_after>var pageIndex = 0;

$( document ).ready(function() {
  loadPageIntoElement("JSONP", addPage());
  loadPageIntoElement("Copenhagen", addPage());
});

function addPage() {
	var pageId = "page" + pageIndex++;

	var tempContainer = document.createElement("div");
	tempContainer.innerHtml =
'
' +
'
'+
'
'+
'

'+
'
'+
'

'+
'
'+
'
';

	$(".wikibrowser-host").append(tempContainer.innerHtml);

	// Scroll to reveal the new pane
	var newPageOffset = $("#" + pageId).offset().left;
	$(".wikibrowser-host").animate({scrollLeft: newPageOffset}, 400);

	return pageId;
}

function loadPageIntoElement(page, element) {
	$.ajax({
	    url : "http://en.wikipedia.org/w/api.php?action=parse&format=json&callback=?&continue=&page=" + page,
	    data: {
	    	format: 'json'
	    },
	    dataType: 'jsonp',
	    cache: 'true' // defaults to false for jsonp.
	})
	.done(function(data) {
		$( "#" + element + " > .pre-content > h1" ).append( data.parse.displaytitle );
		$( "#" + element + " > .content" ).append( data.parse.text['*'] );
		$( "#" + element + " > .content a").each(fixHyperlink);
		$( "#" + element ).perfectScrollbar({
			wheelSpeed: 3
		});
	});
}

function fixHyperlink(index, element)
{
	var jElement = $(element);
	var address = jElement.attr('href');
	if (address.substring(0, 6) === '/wiki/')
	{
		jElement.attr('href', "http://en.wikipedia.org" + address);
		jElement.on('click', function() {
			loadPageIntoElement(address.substring(6), addPage());
			return false; // prevent going to href (wikipedia)
		})
	}
	if (address.substring(0, 1) !== '#')
	{
		jElement.attr('target', "_blank");
	}
}<|endoftext|>


<commit_before>/**
 * Copyright (c) 2002-2018 "Neo Technology,"
 * Network Engine for Objects in Lund AB [http://neotechnology.com]
 *
 * This file is part of Neo4j.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import neo4j from '../../src/v1';
import sharedNeo4j from '../internal/shared-neo4j';
import FakeConnection from '../internal/fake-connection';
import lolex from 'lolex';
import {DEFAULT_ACQUISITION_TIMEOUT, DEFAULT_MAX_SIZE} from '../../src/v1/internal/pool-config';
import {ServerVersion, VERSION_3_1_0} from '../../src/v1/internal/server-version';

describe('driver', () => {

  let clock;
  let driver;
  let serverVersion;

  beforeAll(done => {
    const tmpDriver = neo4j.driver('bolt://localhost', sharedNeo4j.authToken);
    ServerVersion.fromDriver(tmpDriver).then(version => {
      tmpDriver.close();
      serverVersion = version;
      done();
    });
  });

  afterEach(() => {
    if (clock) {
      clock.uninstall();
      clock = null;
    }
    if (driver) {
      driver.close();
      driver = null;
    }
  });

  it('should expose sessions', () => {
    // Given
    driver = neo4j.driver("bolt://localhost", sharedNeo4j.authToken);

    // When
    const session = driver.session();

    // Then
    expect( session ).not.toBeNull();
    driver.close();
  });

  it('should handle connection errors', done => {
    // Given
    driver = neo4j.driver("bolt://localhoste", sharedNeo4j.authToken);

    // Expect
    driver.onError = error => {
      //the error message is different whether in browser or node
      expect(error.message).not.toBeNull();
      expect(error.code).toEqual(neo4j.error.SERVICE_UNAVAILABLE);
      done();
    };

    // When
    startNewTransaction(driver);
  }, 10000);

  it('should handle wrong scheme', () => {
    expect(() => neo4j.driver("tank://localhost", sharedNeo4j.authToken))
      .toThrow(new Error('Unknown scheme: tank'));
  });

  it('should handle URL parameter string', () => {
    expect(() => neo4j.driver({uri: 'bolt://localhost'})).toThrowError(TypeError);

    expect(() => neo4j.driver(['bolt:localhost'])).toThrowError(TypeError);

    expect(() => {
      const driver = neo4j.driver(String('bolt://localhost'), sharedNeo4j.authToken);
      return driver.session();
    }).toBeDefined();
  });

  it('should fail early on wrong credentials', done => {
    // Given
    driver = neo4j.driver("bolt://localhost", wrongCredentials());

    // Expect
    driver.onError = err => {
      //the error message is different whether in browser or node
      expect(err.code).toEqual('Neo.ClientError.Security.Unauthorized');
      done();
    };

    // When
    startNewTransaction(driver);
  });

  it('should fail queries on wrong credentials', done => {
    driver = neo4j.driver('bolt://localhost', wrongCredentials());

    const session = driver.session();
    session.run('RETURN 1').catch(error => {
      expect(error.code).toEqual('Neo.ClientError.Security.Unauthorized');
      done();
    });
  });

  it('should indicate success early on correct credentials', done => {
    // Given
    driver = neo4j.driver("bolt://localhost", sharedNeo4j.authToken);

    // Expect
    driver.onCompleted = server => {
      expect(server.address).toBeDefined();
      done();
    };
  });

  it('should be possible to pass a realm with basic auth tokens', done => {
    // Given
    driver = neo4j.driver("bolt://localhost", neo4j.auth.basic(sharedNeo4j.username, sharedNeo4j.password, "native"));

    // Expect
    driver.onCompleted = server => {
      expect(server.address).toBeDefined();
      done();
    };
  });

  it('should be possible to create custom auth tokens', done => {
    // Given
    driver = neo4j.driver("bolt://localhost", neo4j.auth.custom(sharedNeo4j.username, sharedNeo4j.password, "native", "basic"));

    // Expect
    driver.onCompleted = server => {
      expect(server.address).toBeDefined();
      done();
    };
  });

  it('should be possible to create custom auth tokens with additional parameters', done => {
    // Given
    driver = neo4j.driver("bolt://localhost", neo4j.auth.custom(sharedNeo4j.username, sharedNeo4j.password, "native", "basic", {secret: 42}));

    // Expect
    driver.onCompleted = server => {
      expect(server.address).toBeDefined();
      done();
    };
  });

  it('should fail nicely when connecting with routing to standalone server', done => {
    // Given
    driver = neo4j.driver("bolt+routing://localhost", sharedNeo4j.authToken);

    // Expect
    driver.onError = error => {
      expect(error.message).toEqual(`Server at localhost:7687 can't perform routing. Make sure you are connecting to a causal cluster`);
      expect(error.code).toEqual(neo4j.error.SERVICE_UNAVAILABLE);
      done();
    };

    // When
    startNewTransaction(driver);
  });

  it('should have correct user agent', () => {
    const directDriver = neo4j.driver("bolt://localhost");
    expect(directDriver._userAgent).toBe("neo4j-javascript/0.0.0-dev");
    directDriver.close();

    const routingDriver = neo4j.driver("bolt+routing://localhost");
    expect(routingDriver._userAgent).toBe("neo4j-javascript/0.0.0-dev");
    routingDriver.close();
  });

  it('should fail when TRUST_ON_FIRST_USE is used with routing', () => {
    const createRoutingDriverWithTOFU = () => {
      driver = neo4j.driver('bolt+routing://localhost', sharedNeo4j.username, {
        encrypted: "ENCRYPTION_ON",
          trust: 'TRUST_ON_FIRST_USE'
      });
    };

    expect(createRoutingDriverWithTOFU).toThrow();
  });

  it('should fail when bolt:// scheme used with routing params', () => {
    expect(() => neo4j.driver('bolt://localhost:7687/?policy=my_policy')).toThrow();
  });

  it('should sanitize pool setting values in the config', () => {
    testConfigSanitizing('maxConnectionLifetime', 60 * 60 * 1000);
    testConfigSanitizing('maxConnectionPoolSize', DEFAULT_MAX_SIZE);
    testConfigSanitizing('connectionAcquisitionTimeout', DEFAULT_ACQUISITION_TIMEOUT);
  });

  it('should treat closed connections as invalid', () => {
    driver = neo4j.driver('bolt://localhost', sharedNeo4j.authToken);

    const connectionValid = driver._validateConnection(new FakeConnection().closed());

    expect(connectionValid).toBeFalsy();
  });

  it('should treat not old open connections as valid', () => {
    driver = neo4j.driver('bolt://localhost', sharedNeo4j.authToken, {maxConnectionLifetime: 10});

    const connection = new FakeConnection().withCreationTimestamp(12);
    clock = lolex.install();
    clock.setSystemTime(20);
    const connectionValid = driver._validateConnection(connection);

    expect(connectionValid).toBeTruthy();
  });

  it('should treat old open connections as invalid', () => {
    driver = neo4j.driver('bolt://localhost', sharedNeo4j.authToken, {maxConnectionLifetime: 10});

    const connection = new FakeConnection().withCreationTimestamp(5);
    clock = lolex.install();
    clock.setSystemTime(20);
    const connectionValid = driver._validateConnection(connection);

    expect(connectionValid).toBeFalsy();
  });

  it('should discard closed connections', done => {
    driver = neo4j.driver('bolt://localhost', sharedNeo4j.authToken);

    const session1 = driver.session();
    session1.run('CREATE () RETURN 42').then(() => {
      session1.close();

      // one connection should be established
      const connections1 = openConnectionFrom(driver);
      expect(connections1.length).toEqual(1);

      // close/break existing pooled connection
      connections1.forEach(connection => connection.close());

      const session2 = driver.session();
      session2.run('RETURN 1').then(() => {
        session2.close();

        // existing connection should be disposed and new one should be created
        const connections2 = openConnectionFrom(driver);
        expect(connections2.length).toEqual(1);

        expect(connections1[0]).not.toEqual(connections2[0]);

        done();
      });
    });
  });

  it('should discard old connections', done => {
    const maxLifetime = 100000;
    driver = neo4j.driver('bolt://localhost', sharedNeo4j.authToken, {maxConnectionLifetime: maxLifetime});

    const session1 = driver.session();
    session1.run('CREATE () RETURN 42').then(() => {
      session1.close();

      // one connection should be established
      const connections1 = openConnectionFrom(driver);
      expect(connections1.length).toEqual(1);

      // make existing connection look very old by advancing the `Date.now()` value
      const currentTime = Date.now();
      clock = lolex.install();
      clock.setSystemTime(currentTime + maxLifetime * 2);

      const session2 = driver.session();
      session2.run('RETURN 1').then(() => {
        session2.close();

        // old connection should be disposed and new one should be created
        const connections2 = openConnectionFrom(driver);
        expect(connections2.length).toEqual(1);

        expect(connections1[0]).not.toEqual(connections2[0]);

        done();
      });
    });
  });

  const exposedTypes = [
    'Node',
    'Path',
    'PathSegment',
    'Record',
    'Relationship',
    'Result',
    'ResultSummary',
    'UnboundRelationship',
  ];

  exposedTypes.forEach(type => {
    it(`should expose type ${type}`, () => {
      expect(undefined === neo4j.types[type]).toBe(false);
    });
  });

  it('should connect to IPv6 address without port', done => {
    testIPv6Connection('bolt://[::1]', done);
  });

  it('should connect to IPv6 address with port', done => {
    testIPv6Connection('bolt://[::1]:7687', done);
  });

  const nativeNumbers = [
    Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY,
    Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER,
    -0, 0,
    -42, 42,
    -999, 999,
    -1000, 1000,
    -9000000, 9000000,
    Number.MIN_SAFE_INTEGER + 1, Number.MAX_SAFE_INTEGER - 1
  ];

  nativeNumbers.forEach(number => {

    it(`should return native number ${number} when disableLosslessIntegers=true`, done => {
      testNumberInReturnedRecord(number, number, done);
    });

  });

  const integersWithNativeNumberEquivalent = [
    [neo4j.int(0), 0],
    [neo4j.int(42), 42],
    [neo4j.int(-100), -100],
    [neo4j.int(Number.MIN_SAFE_INTEGER), Number.MIN_SAFE_INTEGER],
    [neo4j.int(Number.MAX_SAFE_INTEGER), Number.MAX_SAFE_INTEGER],
    [neo4j.int('-9007199254740992'), Number.NEGATIVE_INFINITY], // Number.MIN_SAFE_INTEGER - 1
    [neo4j.int('9007199254740992'), Number.POSITIVE_INFINITY], // Number.MAX_SAFE_INTEGER + 1
    [neo4j.int('-9007199254749999'), Number.NEGATIVE_INFINITY], // Number.MIN_SAFE_INTEGER - 9007
    [neo4j.int('9007199254749999'), Number.POSITIVE_INFINITY], // Number.MAX_SAFE_INTEGER + 9008
  ];

  integersWithNativeNumberEquivalent.forEach(integerWithNativeNumber => {

    const integer = integerWithNativeNumber[0];
    const nativeNumber = integerWithNativeNumber[1];

    it(`should send Integer ${integer.toString()} and return native number ${nativeNumber} when disableLosslessIntegers=true`, done => {
      testNumberInReturnedRecord(integer, nativeNumber, done);
    });

  });

  function testIPv6Connection(url, done) {
    if (serverVersion.compareTo(VERSION_3_1_0) < 0) {
      // IPv6 listen address only supported starting from neo4j 3.1, so let's ignore the rest
      done();
    }

    driver = neo4j.driver(url, sharedNeo4j.authToken);

    const session = driver.session();
    session.run('RETURN 42').then(result => {
      expect(result.records[0].get(0).toNumber()).toEqual(42);
      session.close();
      done();
    });
  }

  function testNumberInReturnedRecord(inputNumber, expectedNumber, done) {
    driver = neo4j.driver('bolt://localhost', sharedNeo4j.authToken, {disableLosslessIntegers: true});

    const session = driver.session();
    session.run('RETURN $number AS n0, $number AS n1', {number: inputNumber}).then(result => {
      session.close();

      const records = result.records;
      expect(records.length).toEqual(1);
      const record = records[0];

      expect(record.get('n0')).toEqual(expectedNumber);
      expect(record.get('n1')).toEqual(expectedNumber);

      expect(record.get(0)).toEqual(expectedNumber);
      expect(record.get(1)).toEqual(expectedNumber);

      expect(record.toObject()).toEqual({n0: expectedNumber, n1: expectedNumber});

      done();
    });
  }

  /**
   * Starts new transaction to force new network connection.
   * @param {Driver} driver - the driver to use.
   */
  function startNewTransaction(driver) {
    const session = driver.session();
    expect(session.beginTransaction()).toBeDefined();
  }

  function wrongCredentials() {
    return neo4j.auth.basic('neo4j', 'who would use such a password');
  }

  function testConfigSanitizing(configProperty, defaultValue) {
    validateConfigSanitizing({}, defaultValue);
    validateConfigSanitizing({[configProperty]: 42}, 42);
    validateConfigSanitizing({[configProperty]: 0}, 0);
    validateConfigSanitizing({[configProperty]: '42'}, 42);
    validateConfigSanitizing({[configProperty]: '042'}, 42);
    validateConfigSanitizing({[configProperty]: -42}, Number.MAX_SAFE_INTEGER);
  }

  function validateConfigSanitizing(config, configProperty, expectedValue) {
    const driver = neo4j.driver('bolt://localhost', sharedNeo4j.authToken, config);
    try {
      expect(driver._config[configProperty]).toEqual(expectedValue);
    } finally {
      driver.close();
    }
  }

  function openConnectionFrom(driver) {
    return Array.from(Object.values(driver._openSessions));
  }

});
<commit_msg>spelling: localhost<commit_after>/**
 * Copyright (c) 2002-2018 "Neo Technology,"
 * Network Engine for Objects in Lund AB [http://neotechnology.com]
 *
 * This file is part of Neo4j.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import neo4j from '../../src/v1';
import sharedNeo4j from '../internal/shared-neo4j';
import FakeConnection from '../internal/fake-connection';
import lolex from 'lolex';
import {DEFAULT_ACQUISITION_TIMEOUT, DEFAULT_MAX_SIZE} from '../../src/v1/internal/pool-config';
import {ServerVersion, VERSION_3_1_0} from '../../src/v1/internal/server-version';

describe('driver', () => {

  let clock;
  let driver;
  let serverVersion;

  beforeAll(done => {
    const tmpDriver = neo4j.driver('bolt://localhost', sharedNeo4j.authToken);
    ServerVersion.fromDriver(tmpDriver).then(version => {
      tmpDriver.close();
      serverVersion = version;
      done();
    });
  });

  afterEach(() => {
    if (clock) {
      clock.uninstall();
      clock = null;
    }
    if (driver) {
      driver.close();
      driver = null;
    }
  });

  it('should expose sessions', () => {
    // Given
    driver = neo4j.driver("bolt://localhost", sharedNeo4j.authToken);

    // When
    const session = driver.session();

    // Then
    expect( session ).not.toBeNull();
    driver.close();
  });

  it('should handle connection errors', done => {
    // Given
    driver = neo4j.driver("bolt://local-host", sharedNeo4j.authToken);

    // Expect
    driver.onError = error => {
      //the error message is different whether in browser or node
      expect(error.message).not.toBeNull();
      expect(error.code).toEqual(neo4j.error.SERVICE_UNAVAILABLE);
      done();
    };

    // When
    startNewTransaction(driver);
  }, 10000);

  it('should handle wrong scheme', () => {
    expect(() => neo4j.driver("tank://localhost", sharedNeo4j.authToken))
      .toThrow(new Error('Unknown scheme: tank'));
  });

  it('should handle URL parameter string', () => {
    expect(() => neo4j.driver({uri: 'bolt://localhost'})).toThrowError(TypeError);

    expect(() => neo4j.driver(['bolt:localhost'])).toThrowError(TypeError);

    expect(() => {
      const driver = neo4j.driver(String('bolt://localhost'), sharedNeo4j.authToken);
      return driver.session();
    }).toBeDefined();
  });

  it('should fail early on wrong credentials', done => {
    // Given
    driver = neo4j.driver("bolt://localhost", wrongCredentials());

    // Expect
    driver.onError = err => {
      //the error message is different whether in browser or node
      expect(err.code).toEqual('Neo.ClientError.Security.Unauthorized');
      done();
    };

    // When
    startNewTransaction(driver);
  });

  it('should fail queries on wrong credentials', done => {
    driver = neo4j.driver('bolt://localhost', wrongCredentials());

    const session = driver.session();
    session.run('RETURN 1').catch(error => {
      expect(error.code).toEqual('Neo.ClientError.Security.Unauthorized');
      done();
    });
  });

  it('should indicate success early on correct credentials', done => {
    // Given
    driver = neo4j.driver("bolt://localhost", sharedNeo4j.authToken);

    // Expect
    driver.onCompleted = server => {
      expect(server.address).toBeDefined();
      done();
    };
  });

  it('should be possible to pass a realm with basic auth tokens', done => {
    // Given
    driver = neo4j.driver("bolt://localhost", neo4j.auth.basic(sharedNeo4j.username, sharedNeo4j.password, "native"));

    // Expect
    driver.onCompleted = server => {
      expect(server.address).toBeDefined();
      done();
    };
  });

  it('should be possible to create custom auth tokens', done => {
    // Given
    driver = neo4j.driver("bolt://localhost", neo4j.auth.custom(sharedNeo4j.username, sharedNeo4j.password, "native", "basic"));

    // Expect
    driver.onCompleted = server => {
      expect(server.address).toBeDefined();
      done();
    };
  });

  it('should be possible to create custom auth tokens with additional parameters', done => {
    // Given
    driver = neo4j.driver("bolt://localhost", neo4j.auth.custom(sharedNeo4j.username, sharedNeo4j.password, "native", "basic", {secret: 42}));

    // Expect
    driver.onCompleted = server => {
      expect(server.address).toBeDefined();
      done();
    };
  });

  it('should fail nicely when connecting with routing to standalone server', done => {
    // Given
    driver = neo4j.driver("bolt+routing://localhost", sharedNeo4j.authToken);

    // Expect
    driver.onError = error => {
      expect(error.message).toEqual(`Server at localhost:7687 can't perform routing. Make sure you are connecting to a causal cluster`);
      expect(error.code).toEqual(neo4j.error.SERVICE_UNAVAILABLE);
      done();
    };

    // When
    startNewTransaction(driver);
  });

  it('should have correct user agent', () => {
    const directDriver = neo4j.driver("bolt://localhost");
    expect(directDriver._userAgent).toBe("neo4j-javascript/0.0.0-dev");
    directDriver.close();

    const routingDriver = neo4j.driver("bolt+routing://localhost");
    expect(routingDriver._userAgent).toBe("neo4j-javascript/0.0.0-dev");
    routingDriver.close();
  });

  it('should fail when TRUST_ON_FIRST_USE is used with routing', () => {
    const createRoutingDriverWithTOFU = () => {
      driver = neo4j.driver('bolt+routing://localhost', sharedNeo4j.username, {
        encrypted: "ENCRYPTION_ON",
          trust: 'TRUST_ON_FIRST_USE'
      });
    };

    expect(createRoutingDriverWithTOFU).toThrow();
  });

  it('should fail when bolt:// scheme used with routing params', () => {
    expect(() => neo4j.driver('bolt://localhost:7687/?policy=my_policy')).toThrow();
  });

  it('should sanitize pool setting values in the config', () => {
    testConfigSanitizing('maxConnectionLifetime', 60 * 60 * 1000);
    testConfigSanitizing('maxConnectionPoolSize', DEFAULT_MAX_SIZE);
    testConfigSanitizing('connectionAcquisitionTimeout', DEFAULT_ACQUISITION_TIMEOUT);
  });

  it('should treat closed connections as invalid', () => {
    driver = neo4j.driver('bolt://localhost', sharedNeo4j.authToken);

    const connectionValid = driver._validateConnection(new FakeConnection().closed());

    expect(connectionValid).toBeFalsy();
  });

  it('should treat not old open connections as valid', () => {
    driver = neo4j.driver('bolt://localhost', sharedNeo4j.authToken, {maxConnectionLifetime: 10});

    const connection = new FakeConnection().withCreationTimestamp(12);
    clock = lolex.install();
    clock.setSystemTime(20);
    const connectionValid = driver._validateConnection(connection);

    expect(connectionValid).toBeTruthy();
  });

  it('should treat old open connections as invalid', () => {
    driver = neo4j.driver('bolt://localhost', sharedNeo4j.authToken, {maxConnectionLifetime: 10});

    const connection = new FakeConnection().withCreationTimestamp(5);
    clock = lolex.install();
    clock.setSystemTime(20);
    const connectionValid = driver._validateConnection(connection);

    expect(connectionValid).toBeFalsy();
  });

  it('should discard closed connections', done => {
    driver = neo4j.driver('bolt://localhost', sharedNeo4j.authToken);

    const session1 = driver.session();
    session1.run('CREATE () RETURN 42').then(() => {
      session1.close();

      // one connection should be established
      const connections1 = openConnectionFrom(driver);
      expect(connections1.length).toEqual(1);

      // close/break existing pooled connection
      connections1.forEach(connection => connection.close());

      const session2 = driver.session();
      session2.run('RETURN 1').then(() => {
        session2.close();

        // existing connection should be disposed and new one should be created
        const connections2 = openConnectionFrom(driver);
        expect(connections2.length).toEqual(1);

        expect(connections1[0]).not.toEqual(connections2[0]);

        done();
      });
    });
  });

  it('should discard old connections', done => {
    const maxLifetime = 100000;
    driver = neo4j.driver('bolt://localhost', sharedNeo4j.authToken, {maxConnectionLifetime: maxLifetime});

    const session1 = driver.session();
    session1.run('CREATE () RETURN 42').then(() => {
      session1.close();

      // one connection should be established
      const connections1 = openConnectionFrom(driver);
      expect(connections1.length).toEqual(1);

      // make existing connection look very old by advancing the `Date.now()` value
      const currentTime = Date.now();
      clock = lolex.install();
      clock.setSystemTime(currentTime + maxLifetime * 2);

      const session2 = driver.session();
      session2.run('RETURN 1').then(() => {
        session2.close();

        // old connection should be disposed and new one should be created
        const connections2 = openConnectionFrom(driver);
        expect(connections2.length).toEqual(1);

        expect(connections1[0]).not.toEqual(connections2[0]);

        done();
      });
    });
  });

  const exposedTypes = [
    'Node',
    'Path',
    'PathSegment',
    'Record',
    'Relationship',
    'Result',
    'ResultSummary',
    'UnboundRelationship',
  ];

  exposedTypes.forEach(type => {
    it(`should expose type ${type}`, () => {
      expect(undefined === neo4j.types[type]).toBe(false);
    });
  });

  it('should connect to IPv6 address without port', done => {
    testIPv6Connection('bolt://[::1]', done);
  });

  it('should connect to IPv6 address with port', done => {
    testIPv6Connection('bolt://[::1]:7687', done);
  });

  const nativeNumbers = [
    Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY,
    Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER,
    -0, 0,
    -42, 42,
    -999, 999,
    -1000, 1000,
    -9000000, 9000000,
    Number.MIN_SAFE_INTEGER + 1, Number.MAX_SAFE_INTEGER - 1
  ];

  nativeNumbers.forEach(number => {

    it(`should return native number ${number} when disableLosslessIntegers=true`, done => {
      testNumberInReturnedRecord(number, number, done);
    });

  });

  const integersWithNativeNumberEquivalent = [
    [neo4j.int(0), 0],
    [neo4j.int(42), 42],
    [neo4j.int(-100), -100],
    [neo4j.int(Number.MIN_SAFE_INTEGER), Number.MIN_SAFE_INTEGER],
    [neo4j.int(Number.MAX_SAFE_INTEGER), Number.MAX_SAFE_INTEGER],
    [neo4j.int('-9007199254740992'), Number.NEGATIVE_INFINITY], // Number.MIN_SAFE_INTEGER - 1
    [neo4j.int('9007199254740992'), Number.POSITIVE_INFINITY], // Number.MAX_SAFE_INTEGER + 1
    [neo4j.int('-9007199254749999'), Number.NEGATIVE_INFINITY], // Number.MIN_SAFE_INTEGER - 9007
    [neo4j.int('9007199254749999'), Number.POSITIVE_INFINITY], // Number.MAX_SAFE_INTEGER + 9008
  ];

  integersWithNativeNumberEquivalent.forEach(integerWithNativeNumber => {

    const integer = integerWithNativeNumber[0];
    const nativeNumber = integerWithNativeNumber[1];

    it(`should send Integer ${integer.toString()} and return native number ${nativeNumber} when disableLosslessIntegers=true`, done => {
      testNumberInReturnedRecord(integer, nativeNumber, done);
    });

  });

  function testIPv6Connection(url, done) {
    if (serverVersion.compareTo(VERSION_3_1_0) < 0) {
      // IPv6 listen address only supported starting from neo4j 3.1, so let's ignore the rest
      done();
    }

    driver = neo4j.driver(url, sharedNeo4j.authToken);

    const session = driver.session();
    session.run('RETURN 42').then(result => {
      expect(result.records[0].get(0).toNumber()).toEqual(42);
      session.close();
      done();
    });
  }

  function testNumberInReturnedRecord(inputNumber, expectedNumber, done) {
    driver = neo4j.driver('bolt://localhost', sharedNeo4j.authToken, {disableLosslessIntegers: true});

    const session = driver.session();
    session.run('RETURN $number AS n0, $number AS n1', {number: inputNumber}).then(result => {
      session.close();

      const records = result.records;
      expect(records.length).toEqual(1);
      const record = records[0];

      expect(record.get('n0')).toEqual(expectedNumber);
      expect(record.get('n1')).toEqual(expectedNumber);

      expect(record.get(0)).toEqual(expectedNumber);
      expect(record.get(1)).toEqual(expectedNumber);

      expect(record.toObject()).toEqual({n0: expectedNumber, n1: expectedNumber});

      done();
    });
  }

  /**
   * Starts new transaction to force new network connection.
   * @param {Driver} driver - the driver to use.
   */
  function startNewTransaction(driver) {
    const session = driver.session();
    expect(session.beginTransaction()).toBeDefined();
  }

  function wrongCredentials() {
    return neo4j.auth.basic('neo4j', 'who would use such a password');
  }

  function testConfigSanitizing(configProperty, defaultValue) {
    validateConfigSanitizing({}, defaultValue);
    validateConfigSanitizing({[configProperty]: 42}, 42);
    validateConfigSanitizing({[configProperty]: 0}, 0);
    validateConfigSanitizing({[configProperty]: '42'}, 42);
    validateConfigSanitizing({[configProperty]: '042'}, 42);
    validateConfigSanitizing({[configProperty]: -42}, Number.MAX_SAFE_INTEGER);
  }

  function validateConfigSanitizing(config, configProperty, expectedValue) {
    const driver = neo4j.driver('bolt://localhost', sharedNeo4j.authToken, config);
    try {
      expect(driver._config[configProperty]).toEqual(expectedValue);
    } finally {
      driver.close();
    }
  }

  function openConnectionFrom(driver) {
    return Array.from(Object.values(driver._openSessions));
  }

});
<|endoftext|>


<commit_before>'use strict';

var util = require('util');
var _ = require('lodash');
_.mixin(require("lodash-deep"));
var path = require('path');
var serve_static = require('serve-static');

module.exports = function (options) {
  var seneca = this;
  var plugin = 'dojos';
  var version = '1.0';

  options = seneca.util.deepextend({
    prefix: '/api/'
  }, options);

  seneca.add({ role: plugin, spec: 'web' }, spec_web);

  seneca.add({role: plugin, cmd: 'search'}, proxy);
  seneca.add({role: plugin, cmd: 'load'}, proxy);
  seneca.add({role: plugin, cmd: 'find'}, proxy);
  seneca.add({role: plugin, cmd: 'list'}, proxy);
  seneca.add({role: plugin, cmd: 'create'}, proxyNeedUser);
  seneca.add({role: plugin, cmd: 'update'}, proxyNeedUser);
  seneca.add({role: plugin, cmd: 'delete'}, proxyNeedUser);
  seneca.add({role: plugin, cmd: 'my_dojos'}, proxyNeedUser);
  seneca.add({role: plugin, cmd: 'dojos_count'}, proxy);
  seneca.add({role: plugin, cmd: 'dojos_by_country'}, proxy);
  seneca.add({role: plugin, cmd: 'dojos_state_count'}, proxy);
  seneca.add({role: plugin, cmd: 'bulk_update'}, proxyNeedUser);
  seneca.add({role: plugin, cmd: 'bulk_delete'}, proxyNeedUser);
  seneca.add({role: plugin, cmd: 'get_stats'}, proxyNeedUser);
  seneca.add({role: plugin, cmd: 'save_dojo_lead'}, proxyNeedUser);
  seneca.add({role: plugin, cmd: 'update_dojo_lead'}, proxyNeedUser);
  seneca.add({role: plugin, cmd: 'load_user_dojo_lead'}, proxyNeedUser);
  seneca.add({role: plugin, cmd: 'load_dojo_lead'}, proxyNeedUser);
  seneca.add({role: plugin, cmd: 'load_setup_dojo_steps'}, proxyNeedUser);
  seneca.add({role: plugin, cmd: 'load_usersdojos'}, proxy);
  seneca.add({role: plugin, cmd: 'search_dojo_leads'}, proxy);
  seneca.add({role: plugin, cmd: 'uncompleted_dojos'}, proxy);
  seneca.add({role: plugin, cmd: 'load_dojo_users'}, proxy);
  seneca.add({role: plugin, cmd: 'send_email'}, proxy);
  seneca.add({role: plugin, cmd: 'generate_user_invite_token'}, proxy);
  seneca.add({role: plugin, cmd: 'accept_user_invite'}, proxy);
  seneca.add({role: plugin, cmd: 'request_user_invite'}, proxy);
  seneca.add({role: plugin, cmd: 'accept_user_request'}, proxy);
  seneca.add({role: plugin, cmd: 'dojos_for_user'}, proxy);
  seneca.add({role: plugin, cmd: 'save_usersdojos'}, proxy);
  seneca.add({role: plugin, cmd: 'remove_usersdojos'}, proxy);
  seneca.add({role: plugin, cmd: 'get_user_permissions'}, proxy);
  seneca.add({role: plugin, cmd: 'get_user_types'}, proxy);
  seneca.add({role: plugin, cmd: 'load_user_dojo_lead'}, proxyNeedUser);

  function proxy(args, done) {
    var user = null;
    if(args.req$.seneca.user) user = args.req$.seneca.user;
    seneca.act(seneca.util.argprops(
      {user:user},
      args,
      {role:'cd-dojos'}
    ), done);
  }

  function proxyNeedUser(args, done) {
    // TODO - how to set response code of 400 here??
    if(!_.deepHas(args.req$, 'user.user')) return done(new Error('Not logged in, please log in first.'));
    return proxy(args, done);
  }

  function spec_web(args, done) {
    var public_folder = path.join(__dirname, 'public');

    done(null, {
      name: 'dojos',
      public: public_folder
    });
  }

  seneca.add({ init: plugin }, function (args, done) {
    var seneca = this;

    seneca.act({ role: plugin, spec: 'web' }, function (err, spec) {
      if (err) { return done(err); }

      var serve = serve_static(spec.public);
      var prefix = '/content/' + spec.name;

      seneca.act({ role: 'web', use: function (req, res, next) {
        var origurl = req.url;
        if (0 === origurl.indexOf(prefix)) {
          req.url = origurl.substring(prefix.length);
          serve(req, res, function () {
            req.url = origurl;
            next();
          });
        }
        else {
          return next();
        }
      }});

      done();
    });
  });

  // web interface
  seneca.act({ role: 'web', use: {
    prefix: options.prefix + version + '/',
    pin: { role: plugin, cmd: '*' },
    map: {
      'search': {POST: true, alias: 'dojos/search'},
      'create': {POST: true, alias: 'dojo_create'},
      'update': {PUT: true,  alias: 'dojos/:id'},
      'delete': {DELETE: true, alias: 'dojos/:id'},
      'list'  : {POST: true, alias: 'dojos'},
      'load'  : {GET: true, alias: 'dojos/:id'},
      'find'  : {POST: true, alias: 'dojos/find'},
      'my_dojos': {POST: true, alias: 'dojos/my_dojos'},
      'dojos_count': {GET: true, alias: 'dojos_count'},
      'dojos_by_country': {POST: true, alias:'dojos_by_country'},
      'dojos_state_count': {GET: true, alias: 'dojos_state_count/:country'},
      'bulk_update': {POST: true, alias: 'dojos/bulk_update'},
      'bulk_delete': {POST: true, alias: 'dojos/bulk_delete'},
      'get_stats': {POST: true, alias: 'dojos/stats'},
      'save_dojo_lead': {POST: true, alias: 'dojos/save_dojo_lead'},
      'update_dojo_lead': {PUT: true, alias: 'dojos/update_dojo_lead/:id'},
      'load_user_dojo_lead': {GET: true, alias: 'dojos/user_dojo_lead/:id'},
      'load_dojo_lead': {GET: true, alias: 'dojos/dojo_lead/:id'},
      'load_setup_dojo_steps': {GET: true, alias: 'load_setup_dojo_steps'},
      'load_usersdojos': {POST: true, alias: 'dojos/users'},
      'search_dojo_leads': {POST: true, alias: 'dojos/search_dojo_leads'},
      'uncompleted_dojos': {GET: true, alias: 'uncompleted_dojos'},
      'load_dojo_users': {POST: true, alias: 'dojos/load_dojo_users'},
      'generate_user_invite_token': {POST: true, alias: 'dojos/generate_user_invite_token'},
      'accept_user_invite': {POST: true, alias: 'dojos/accept_user_invite'},
      'request_user_invite': {POST: true, alias: 'dojos/request_user_invite'},
      'accept_user_request': {POST: true, alias: 'dojos/accept_user_request'},
      'dojos_for_user': {GET:true, alias: 'dojos/dojos_for_user/:id'},
      'save_usersdojos': {POST: true, alias: 'dojos/save_usersdojos'},
      'remove_usersdojos': {DELETE: true, alias: 'dojos/remove_usersdojos/:userId/:dojoId'},
      'get_user_permissions': {GET:true, alias: 'get_user_permissions'},
      'get_user_types': {GET: true, alias: 'get_user_types'}
    }
  }});

  return {
    name: plugin
  };

}<commit_msg>send zen hostname to dojos microservice<commit_after>'use strict';

var util = require('util');
var _ = require('lodash');
_.mixin(require("lodash-deep"));
var path = require('path');
var serve_static = require('serve-static');

module.exports = function (options) {
  var seneca = this;
  var plugin = 'dojos';
  var version = '1.0';

  options = seneca.util.deepextend({
    prefix: '/api/'
  }, options);

  seneca.add({ role: plugin, spec: 'web' }, spec_web);

  seneca.add({role: plugin, cmd: 'search'}, proxy);
  seneca.add({role: plugin, cmd: 'load'}, proxy);
  seneca.add({role: plugin, cmd: 'find'}, proxy);
  seneca.add({role: plugin, cmd: 'list'}, proxy);
  seneca.add({role: plugin, cmd: 'create'}, proxyNeedUser);
  seneca.add({role: plugin, cmd: 'update'}, proxyNeedUser);
  seneca.add({role: plugin, cmd: 'delete'}, proxyNeedUser);
  seneca.add({role: plugin, cmd: 'my_dojos'}, proxyNeedUser);
  seneca.add({role: plugin, cmd: 'dojos_count'}, proxy);
  seneca.add({role: plugin, cmd: 'dojos_by_country'}, proxy);
  seneca.add({role: plugin, cmd: 'dojos_state_count'}, proxy);
  seneca.add({role: plugin, cmd: 'bulk_update'}, proxyNeedUser);
  seneca.add({role: plugin, cmd: 'bulk_delete'}, proxyNeedUser);
  seneca.add({role: plugin, cmd: 'get_stats'}, proxyNeedUser);
  seneca.add({role: plugin, cmd: 'save_dojo_lead'}, proxyNeedUser);
  seneca.add({role: plugin, cmd: 'update_dojo_lead'}, proxyNeedUser);
  seneca.add({role: plugin, cmd: 'load_user_dojo_lead'}, proxyNeedUser);
  seneca.add({role: plugin, cmd: 'load_dojo_lead'}, proxyNeedUser);
  seneca.add({role: plugin, cmd: 'load_setup_dojo_steps'}, proxyNeedUser);
  seneca.add({role: plugin, cmd: 'load_usersdojos'}, proxy);
  seneca.add({role: plugin, cmd: 'search_dojo_leads'}, proxy);
  seneca.add({role: plugin, cmd: 'uncompleted_dojos'}, proxy);
  seneca.add({role: plugin, cmd: 'load_dojo_users'}, proxy);
  seneca.add({role: plugin, cmd: 'send_email'}, proxy);
  seneca.add({role: plugin, cmd: 'generate_user_invite_token'}, proxy);
  seneca.add({role: plugin, cmd: 'accept_user_invite'}, proxy);
  seneca.add({role: plugin, cmd: 'request_user_invite'}, proxy);
  seneca.add({role: plugin, cmd: 'accept_user_request'}, proxy);
  seneca.add({role: plugin, cmd: 'dojos_for_user'}, proxy);
  seneca.add({role: plugin, cmd: 'save_usersdojos'}, proxy);
  seneca.add({role: plugin, cmd: 'remove_usersdojos'}, proxy);
  seneca.add({role: plugin, cmd: 'get_user_permissions'}, proxy);
  seneca.add({role: plugin, cmd: 'get_user_types'}, proxy);
  seneca.add({role: plugin, cmd: 'load_user_dojo_lead'}, proxyNeedUser);

  function proxy(args, done) {
    var user = null;
    var host = args.req$.ip || '127.0.0.1';
    var port = process.env.PORT || 8000;
    var zenHostname = host + ':' + port;
    if(args.req$.seneca.user) user = args.req$.seneca.user;
    seneca.act(seneca.util.argprops(
      {user:user, zenHostname: zenHostname},
      args,
      {role:'cd-dojos'}
    ), done);
  }

  function proxyNeedUser(args, done) {
    // TODO - how to set response code of 400 here??
    if(!_.deepHas(args.req$, 'user.user')) return done(new Error('Not logged in, please log in first.'));
    return proxy(args, done);
  }

  function spec_web(args, done) {
    var public_folder = path.join(__dirname, 'public');

    done(null, {
      name: 'dojos',
      public: public_folder
    });
  }

  seneca.add({ init: plugin }, function (args, done) {
    var seneca = this;

    seneca.act({ role: plugin, spec: 'web' }, function (err, spec) {
      if (err) { return done(err); }

      var serve = serve_static(spec.public);
      var prefix = '/content/' + spec.name;

      seneca.act({ role: 'web', use: function (req, res, next) {
        var origurl = req.url;
        if (0 === origurl.indexOf(prefix)) {
          req.url = origurl.substring(prefix.length);
          serve(req, res, function () {
            req.url = origurl;
            next();
          });
        }
        else {
          return next();
        }
      }});

      done();
    });
  });

  // web interface
  seneca.act({ role: 'web', use: {
    prefix: options.prefix + version + '/',
    pin: { role: plugin, cmd: '*' },
    map: {
      'search': {POST: true, alias: 'dojos/search'},
      'create': {POST: true, alias: 'dojo_create'},
      'update': {PUT: true,  alias: 'dojos/:id'},
      'delete': {DELETE: true, alias: 'dojos/:id'},
      'list'  : {POST: true, alias: 'dojos'},
      'load'  : {GET: true, alias: 'dojos/:id'},
      'find'  : {POST: true, alias: 'dojos/find'},
      'my_dojos': {POST: true, alias: 'dojos/my_dojos'},
      'dojos_count': {GET: true, alias: 'dojos_count'},
      'dojos_by_country': {POST: true, alias:'dojos_by_country'},
      'dojos_state_count': {GET: true, alias: 'dojos_state_count/:country'},
      'bulk_update': {POST: true, alias: 'dojos/bulk_update'},
      'bulk_delete': {POST: true, alias: 'dojos/bulk_delete'},
      'get_stats': {POST: true, alias: 'dojos/stats'},
      'save_dojo_lead': {POST: true, alias: 'dojos/save_dojo_lead'},
      'update_dojo_lead': {PUT: true, alias: 'dojos/update_dojo_lead/:id'},
      'load_user_dojo_lead': {GET: true, alias: 'dojos/user_dojo_lead/:id'},
      'load_dojo_lead': {GET: true, alias: 'dojos/dojo_lead/:id'},
      'load_setup_dojo_steps': {GET: true, alias: 'load_setup_dojo_steps'},
      'load_usersdojos': {POST: true, alias: 'dojos/users'},
      'search_dojo_leads': {POST: true, alias: 'dojos/search_dojo_leads'},
      'uncompleted_dojos': {GET: true, alias: 'uncompleted_dojos'},
      'load_dojo_users': {POST: true, alias: 'dojos/load_dojo_users'},
      'generate_user_invite_token': {POST: true, alias: 'dojos/generate_user_invite_token'},
      'accept_user_invite': {POST: true, alias: 'dojos/accept_user_invite'},
      'request_user_invite': {POST: true, alias: 'dojos/request_user_invite'},
      'accept_user_request': {POST: true, alias: 'dojos/accept_user_request'},
      'dojos_for_user': {GET:true, alias: 'dojos/dojos_for_user/:id'},
      'save_usersdojos': {POST: true, alias: 'dojos/save_usersdojos'},
      'remove_usersdojos': {DELETE: true, alias: 'dojos/remove_usersdojos/:userId/:dojoId'},
      'get_user_permissions': {GET:true, alias: 'get_user_permissions'},
      'get_user_types': {GET: true, alias: 'get_user_types'}
    }
  }});

  return {
    name: plugin
  };

}<|endoftext|>