$(function() {
  if (!EVALEX_TRUSTED) {
    initPinBox();
  }
  /**
   * if we are in console mode, show the console.
   */
  if (CONSOLE_MODE && EVALEX) {
    openShell(null, $('div.console div.inner').empty(), 0);
  }
  $('div.traceback div.frame').each(function() {
    var
      target = $('pre', this),
      consoleNode = null,
      frameID = this.id.substring(6);
    target.click(function() {
      $(this).parent().toggleClass('expanded');
    });
    /**
     * Add an interactive console to the frames
     */
    if (EVALEX && target.is('.current')) {
      $('
')
        .attr('title', 'Open an interactive python shell in this frame')
        .click(function() {
          consoleNode = openShell(consoleNode, target, frameID);
          return false;
        })
        .prependTo(target);
    }
  });
  /**
   * toggle traceback types on click.
   */
  $('h2.traceback').click(function() {
    $(this).next().slideToggle('fast');
    $('div.plain').slideToggle('fast');
  }).css('cursor', 'pointer');
  $('div.plain').hide();
  /**
   * Add extra info (this is here so that only users with JavaScript
   * enabled see it.)
   */
  $('span.nojavascript')
    .removeClass('nojavascript')
    .html('
To switch between the interactive traceback and the plaintext ' + 'one, you can click on the "Traceback" headline. From the text ' + 'traceback you can also create a paste of it. ' + (!EVALEX ? '' : 'For code execution mouse-over the frame you want to debug and ' + 'click on the console icon on the right side.' + '
You can execute arbitrary Python code in the stack frames and ' + 'there are some extra helpers available for introspection:' + '
dump() shows all variables in the frame' +
          'dump(obj) dumps all that\'s known about the object').text(plainTraceback.text()));
});
function initPinBox() {
  $('.pin-prompt form').submit(function(evt) {
    evt.preventDefault();
    var pin = this.pin.value;
    var btn = this.btn;
    btn.disabled = true;
    $.ajax({
      dataType: 'json',
      url: document.location.pathname,
      data: {__debugger__: 'yes', cmd: 'pinauth', pin: pin,
             s: SECRET},
      success: function(data) {
        btn.disabled = false;
        if (data.auth) {
          EVALEX_TRUSTED = true;
          $('.pin-prompt').fadeOut();
        } else {
          if (data.exhausted) {
            alert('Error: too many attempts.  Restart server to retry.');
          } else {
            alert('Error: incorrect pin');
          }
        }
        console.log(data);
      },
      error: function() {
        btn.disabled = false;
        alert('Error: Could not verify PIN.  Network error?');
      }
    });
  });
}
function promptForPin() {
  if (!EVALEX_TRUSTED) {
    $.ajax({
      url: document.location.pathname,
      data: {__debugger__: 'yes', cmd: 'printpin', s: SECRET}
    });
    $('.pin-prompt').fadeIn(function() {
      $('.pin-prompt input[name="pin"]').focus();
    });
  }
}
/**
 * Helper function for shell initialization
 */
function openShell(consoleNode, target, frameID) {
  promptForPin();
  if (consoleNode)
    return consoleNode.slideToggle('fast');
  consoleNode = $('')
    .appendTo(target.parent())
    .hide()
  var historyPos = 0, history = [''];
  var output = $('[console ready]')
    .appendTo(consoleNode);
  var form = $('')
    .submit(function() {
      var cmd = command.val();
      $.get('', {
          __debugger__: 'yes', cmd: cmd, frm: frameID, s: SECRET}, function(data) {
        var tmp = $('