<commit_before>MathJax.Extension.Arabic = {
  version: '1.0.0',
  config: MathJax.Hub.CombineConfig("Arabic", {
    dict: {
      // A macros to force English zero in both languages
      'Zero': ['zero', 'Text', ['0', 'صفر']],  // Better localized Zero
      'Radius': ['radius', 'Text', ['r', 'نق']],  // Circle radius
      'Area': ['Area', 'Text', ['A', 'م']]  // Area of circles and other stuff
    },
    identifiersMap: {
      // Variable names
      'a': 'أ',
      'b': 'ب',  // TODO: Consider using Arabic letter dotless beh 0x66e instead
      'c': 'جـ',  // Suffixed with Unicode Arabic Tatweel 0x0640
      'x': 'س',
      'y': 'ص',
      'z': 'ع',
      'n': 'ن',

      // Function names
      'f': 'ق',  // TODO: Consider using dotless qaf (ٯ) instead
      'g': 'جـ',  // With Unicode Arabic Tatweel 0x0640
      'h': 'هـ',  // With Unicode Arabic Tatweel 0x0640

      // Mixed use
      'k': 'ك',
      'r': 'ر',
      't': 'ت',
      'd': 'د',  // Function, variable and (dx)
      'e': 'هـ',  // With Unicode Arabic Tatweel 0x0640
      'm': 'م',
      'l': 'ل',

      // Math functions
      'sin': 'جا',
      'cos': 'جتا',
      'tan': 'ظا',
      'cot': 'ظتا',
      'sec': 'قا',
      'csc': 'قتا',
      'log': 'لو'
    },
    numbersMap: {
      '0': '٠',
      '1': '١',
      '2': '٢',
      '3': '٣',
      '4': '٤',
      '5': '٥',
      '6': '٦',
      '7': '٧',
      '8': '٨',
      '9': '٩'
    },
    operatorsMap: {
      // English to Arabic punctuations
      ',': '،',
      ';': '؛',
      // Limits
      'lim': 'نهــا'
    },
    isArabicPage: (document.documentElement.lang === 'ar')
  }),
  arabicLanguageRegExp: /([\u0600-\u06FF]+)/g,
  TeX: function (english, arabic) {
    // Creates a translated TeX macro.

    return function (name) {
      var TEX = MathJax.InputJax.TeX;

      var tex;
      if ('ar' === this.stack.env.lang) {
        tex = arabic;
      } else {
        tex = english;
      }

      this.Push(TEX.Parse(tex).mml());
    };
  },
  Text: function (english, arabicText) {
    // Creates a translated TeX macro, with an Arabic plain text.

    return MathJax.Extension.Arabic.TeX(english, '\\fliph{\\text{' + arabicText + '}}');
  },
  Symbols: function (english, arabicSymbols) {
    // Creates a translated TeX macro that converts Arabic symbols into text nodes,
    // and treats everything else as normal TeX.
    var arabic = arabicSymbols.replace(
      MathJax.Extension.Arabic.arabicLanguageRegExp,
      '\\fliph{\\text{$1}}'
    );

    return MathJax.Extension.Arabic.TeX(english, arabic);
  }
};

MathJax.Hub.Startup.signal.Post('Arabic TeX Startup');

MathJax.Hub.Register.StartupHook('TeX Jax Ready', function () {
  var TEX = MathJax.InputJax.TeX;
  var Arabic = MathJax.Extension.Arabic;
  var texParsePush = TEX.Parse.prototype.Push;
  var texParseMMLToken = TEX.Parse.prototype.mmlToken;
  var dict = MathJax.Hub.config.Arabic.dict;

  var englishNumbersRegExp = /[0-9]/g;

  var escapeRegExp = (function () {
    var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
    var reHasRegExpChar = new RegExp(reRegExpChar.source);

    return function (string) {
      return string.replace(reRegExpChar,'\\$&');
    };
  }());

  var getKeysRegExp = function (map) {
    var keys = Object.keys(map).sort(function (a, b) {
      return b.length - a.length;
    });

    return new RegExp(keys.map(escapeRegExp).join('|'), 'gi');
  };

  var identifiersMap = MathJax.Hub.config.Arabic.identifiersMap;
  var identifiersKeysRegExp = getKeysRegExp(identifiersMap);

  var operatorsMap = MathJax.Hub.config.Arabic.operatorsMap;
  var operatorsKeysRegExp = getKeysRegExp(operatorsMap);

  TEX.Definitions.Add({
    macros: {
      'ar': 'HandleArabic',
      'alwaysar': 'MarkAsArabic',
      'fliph': 'HandleFlipHorizontal',
      'transx': 'TranslateTeX',
      'transt': 'TranslateText',
      'transs': 'TranslateSymbols'
    }
  });

  TEX.Definitions.Add({
    macros: function () {
      var definitions = {};

      Object.keys(dict).forEach(function (key) {
        var texCommand = dict[key][0];
        definitions[texCommand] = key;
      });

      return definitions;
    }()
  });

  TEX.Parse.Augment(function () {
    var parsers = {};

    Object.keys(dict).forEach(function (key) {
      var helperName = dict[key][1];  // Text, TeX or Symbols
      var helperParams = dict[key][2];

      parsers[key] = Arabic[helperName].apply(null, helperParams);
    });

    return parsers;
  }());

  TEX.Parse.Augment({
    flipHorizontal: function (token) {
      token.arabicFlipH = !token.arabicFlipH;
        // Invert the value, because flipping twice means, it is not flipped
      return token;
    },
    arabicNumber: function (token) {
      var numbersMap = MathJax.Hub.config.Arabic.numbersMap;
      var text = token.data[0].data[0];
      var mapped = text.replace(englishNumbersRegExp, function (m) {
        return numbersMap[m];
      });

      if (mapped !== text) {
        token.data[0].data[0] = mapped;
        token.arabicFontLang = 'ar';
      }

      return this.flipHorizontal(token);
    },
    arabicIdentifier: function (token) {
      var text = token.data[0].data[0];

      if ('chars' === token.data[0].type) {
        // English Symbols like X and Y
        var mapped = text.replace(identifiersKeysRegExp, function (m) {
          return identifiersMap[m.toLowerCase()];
        });

        if (mapped !== text) {
          token.data[0].data[0] = mapped;
          token.arabicFontLang = 'ar';
        }
      }

      return this.flipHorizontal(token);
    },
    arabicOperator: function (token) {
      var text = token.data[0].data[0];
      var mapped = text.replace(operatorsKeysRegExp, function (m) {
        return operatorsMap[m];
      });

      if (mapped !== text) {
        token = this.flipHorizontal(token);
        token.arabicFontLang = 'ar';
        token.data[0].data[0] = mapped;
      }

      return token;
    },
    _getArgumentMML: function (name) {
      //  returns an argument that is a single MathML element
      //  (in an mrow if necessary)
      //
      //  This functions has been copied here from extensions/TeX/HTML.js, to avoid
      //  adding a dependency.
      //
      //  TODO: Consider importing (as a dependency) this from HTML.js instead!
      var arg = this.ParseArg(name);
      if (arg.inferred && arg.data.length === 1) {
        arg = arg.data[0];
      } else {
        delete arg.inferred;
      }

      return arg;
    },
    Push: function () {
      var beforeLang = this.stack.env.lang;
      var retVal = texParsePush.apply(this, arguments);

      // Huge giant hack to propagate `lang` from Arrays (and other environments?)
      // to their children fractions and others.
      if (beforeLang) {
        if (!this.stack.env.lang) {
          this.stack.env.lang = beforeLang;
        }
      }

      return retVal;
    },
    mmlToken: function (token) {
      // TODO: Check for possible incompatibility with boldsymbol extension
      var parsedToken = texParseMMLToken.call(this, token);

      if ('ar' === this.stack.env.lang) {
        this.markArabicToken(parsedToken);
      }

      return parsedToken;
    },
    markArabicToken: function (token) {
      if ('mn' === token.type) {
        return this.arabicNumber(token);
      } else if ('mi' === token.type) {
        return this.arabicIdentifier(token);
      } else if ('mo' === token.type) {
        return this.arabicOperator(token);
      }

      return token;
    },
    HandleArabic: function (name) {
      if (MathJax.Hub.config.Arabic.isArabicPage) {
        this.MarkAsArabic(name);
      }
    },
    TranslateTeX: function (name) {
      var english = this.GetArgument(name);
      var arabicText = this.GetArgument(name);
      var helper = Arabic.TeX(english, arabicText);
      return helper.call(this, name);
    },
    TranslateText: function (name) {
      var english = this.GetArgument(name);
      var arabicText = this.GetArgument(name);
      var helper = Arabic.Text(english, arabicText);
      return helper.call(this, name);
    },
    TranslateSymbols: function (name) {
      var english = this.GetArgument(name);
      var arabicText = this.GetArgument(name);
      var helper = Arabic.Symbols(english, arabicText);
      return helper.call(this, name);
    },
    MarkAsArabic: function (name) {
      var originalLang = this.stack.env.lang;

      this.stack.env.lang = 'ar';
      var arg = this._getArgumentMML(name);

      console.log('originalLang', originalLang);
      this.stack.env.lang = originalLang;  // Reset the language for other elements.

      this.Push(this.flipHorizontal(arg));
    },
    HandleFlipHorizontal: function (name) {
      var arg = this._getArgumentMML(name);
      this.Push(this.flipHorizontal(arg));
    }
  });

  MathJax.Hub.Startup.signal.Post('Arabic TeX Ready');
});
<commit_msg>Localized the variables and created functions once to improve performance<commit_after>MathJax.Extension.Arabic = {
  version: '1.0.0',
  config: MathJax.Hub.CombineConfig("Arabic", {
    dict: {
      // A macros to force English zero in both languages
      'Zero': ['zero', 'Text', ['0', 'صفر']],  // Better localized Zero
      'Radius': ['radius', 'Text', ['r', 'نق']],  // Circle radius
      'Area': ['Area', 'Text', ['A', 'م']]  // Area of circles and other stuff
    },
    identifiersMap: {
      // Variable names
      'a': 'أ',
      'b': 'ب',  // TODO: Consider using Arabic letter dotless beh 0x66e instead
      'c': 'جـ',  // Suffixed with Unicode Arabic Tatweel 0x0640
      'x': 'س',
      'y': 'ص',
      'z': 'ع',
      'n': 'ن',

      // Function names
      'f': 'ق',  // TODO: Consider using dotless qaf (ٯ) instead
      'g': 'جـ',  // With Unicode Arabic Tatweel 0x0640
      'h': 'هـ',  // With Unicode Arabic Tatweel 0x0640

      // Mixed use
      'k': 'ك',
      'r': 'ر',
      't': 'ت',
      'd': 'د',  // Function, variable and (dx)
      'e': 'هـ',  // With Unicode Arabic Tatweel 0x0640
      'm': 'م',
      'l': 'ل',

      // Math functions
      'sin': 'جا',
      'cos': 'جتا',
      'tan': 'ظا',
      'cot': 'ظتا',
      'sec': 'قا',
      'csc': 'قتا',
      'log': 'لو'
    },
    numbersMap: {
      '0': '٠',
      '1': '١',
      '2': '٢',
      '3': '٣',
      '4': '٤',
      '5': '٥',
      '6': '٦',
      '7': '٧',
      '8': '٨',
      '9': '٩'
    },
    operatorsMap: {
      // English to Arabic punctuations
      ',': '،',
      ';': '؛',
      // Limits
      'lim': 'نهــا'
    },
    isArabicPage: (document.documentElement.lang === 'ar')
  }),
  arabicLanguageRegExp: /([\u0600-\u06FF]+)/g,
  TeX: function (english, arabic) {
    // Creates a translated TeX macro.

    return function (name) {
      var TEX = MathJax.InputJax.TeX;

      var tex;
      if ('ar' === this.stack.env.lang) {
        tex = arabic;
      } else {
        tex = english;
      }

      this.Push(TEX.Parse(tex).mml());
    };
  },
  Text: function (english, arabicText) {
    // Creates a translated TeX macro, with an Arabic plain text.

    return MathJax.Extension.Arabic.TeX(english, '\\fliph{\\text{' + arabicText + '}}');
  },
  Symbols: function (english, arabicSymbols) {
    // Creates a translated TeX macro that converts Arabic symbols into text nodes,
    // and treats everything else as normal TeX.
    var arabic = arabicSymbols.replace(
      MathJax.Extension.Arabic.arabicLanguageRegExp,
      '\\fliph{\\text{$1}}'
    );

    return MathJax.Extension.Arabic.TeX(english, arabic);
  }
};

MathJax.Hub.Startup.signal.Post('Arabic TeX Startup');

MathJax.Hub.Register.StartupHook('TeX Jax Ready', function () {
  var TEX = MathJax.InputJax.TeX;
  var Arabic = MathJax.Extension.Arabic;
  var texParsePush = TEX.Parse.prototype.Push;
  var texParseMMLToken = TEX.Parse.prototype.mmlToken;
  var dict = MathJax.Hub.config.Arabic.dict;

  var escapeRegExp = (function () {
    var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
    var reHasRegExpChar = new RegExp(reRegExpChar.source);

    return function (string) {
      return string.replace(reRegExpChar,'\\$&');
    };
  }());

  var getKeysRegExp = function (map) {
    var keys = Object.keys(map).sort(function (a, b) {
      return b.length - a.length;
    });

    return new RegExp(keys.map(escapeRegExp).join('|'), 'gi');
  };

  TEX.Definitions.Add({
    macros: {
      'ar': 'HandleArabic',
      'alwaysar': 'MarkAsArabic',
      'fliph': 'HandleFlipHorizontal',
      'transx': 'TranslateTeX',
      'transt': 'TranslateText',
      'transs': 'TranslateSymbols'
    }
  });

  TEX.Definitions.Add({
    macros: function () {
      var definitions = {};

      Object.keys(dict).forEach(function (key) {
        var texCommand = dict[key][0];
        definitions[texCommand] = key;
      });

      return definitions;
    }()
  });

  TEX.Parse.Augment(function () {
    var parsers = {};

    Object.keys(dict).forEach(function (key) {
      var helperName = dict[key][1];  // Text, TeX or Symbols
      var helperParams = dict[key][2];

      parsers[key] = Arabic[helperName].apply(null, helperParams);
    });

    return parsers;
  }());

  TEX.Parse.Augment({
    flipHorizontal: function (token) {
      token.arabicFlipH = !token.arabicFlipH;
        // Invert the value, because flipping twice means, it is not flipped
      return token;
    },
    arabicNumber: (function () {
      var englishNumbersRegExp = /[0-9]/g;
      var numbersMap = MathJax.Hub.config.Arabic.numbersMap;

      var replaceNumber = function (m) {
        return numbersMap[m];
      };

      return function (token) {
        var text = token.data[0].data[0];
        var mapped = text.replace(englishNumbersRegExp, replaceNumber);

        if (mapped !== text) {
          token.data[0].data[0] = mapped;
          token.arabicFontLang = 'ar';
        }

        return this.flipHorizontal(token);
      }
    }()),
    arabicIdentifier: (function () {
      var identifiersMap = MathJax.Hub.config.Arabic.identifiersMap;
      var identifiersKeysRegExp = getKeysRegExp(identifiersMap);

      var replaceIdentifier = function (m) {
        return identifiersMap[m.toLowerCase()];
      };

      return function (token) {
        var text = token.data[0].data[0];

        if ('chars' === token.data[0].type) {
          // English Symbols like X and Y
          var mapped = text.replace(identifiersKeysRegExp, replaceIdentifier);

          if (mapped !== text) {
            token.data[0].data[0] = mapped;
            token.arabicFontLang = 'ar';
          }
        }

        return this.flipHorizontal(token);
      }
    }()),
    arabicOperator: (function () {
      var operatorsMap = MathJax.Hub.config.Arabic.operatorsMap;
      var operatorsKeysRegExp = getKeysRegExp(operatorsMap);

      var replaceOperator = function (m) {
        return operatorsMap[m];
      };

      return function (token) {
        var text = token.data[0].data[0];
        var mapped = text.replace(operatorsKeysRegExp, replaceOperator);

        if (mapped !== text) {
          token = this.flipHorizontal(token);
          token.arabicFontLang = 'ar';
          token.data[0].data[0] = mapped;
        }

        return token;
      }
    }()),
    _getArgumentMML: function (name) {
      //  returns an argument that is a single MathML element
      //  (in an mrow if necessary)
      //
      //  This functions has been copied here from extensions/TeX/HTML.js, to avoid
      //  adding a dependency.
      //
      //  TODO: Consider importing (as a dependency) this from HTML.js instead!
      var arg = this.ParseArg(name);
      if (arg.inferred && arg.data.length === 1) {
        arg = arg.data[0];
      } else {
        delete arg.inferred;
      }

      return arg;
    },
    Push: function () {
      var beforeLang = this.stack.env.lang;
      var retVal = texParsePush.apply(this, arguments);

      // Huge giant hack to propagate `lang` from Arrays (and other environments?)
      // to their children fractions and others.
      if (beforeLang) {
        if (!this.stack.env.lang) {
          this.stack.env.lang = beforeLang;
        }
      }

      return retVal;
    },
    mmlToken: function (token) {
      // TODO: Check for possible incompatibility with boldsymbol extension
      var parsedToken = texParseMMLToken.call(this, token);

      if ('ar' === this.stack.env.lang) {
        this.markArabicToken(parsedToken);
      }

      return parsedToken;
    },
    markArabicToken: function (token) {
      if ('mn' === token.type) {
        return this.arabicNumber(token);
      } else if ('mi' === token.type) {
        return this.arabicIdentifier(token);
      } else if ('mo' === token.type) {
        return this.arabicOperator(token);
      }

      return token;
    },
    HandleArabic: function (name) {
      if (MathJax.Hub.config.Arabic.isArabicPage) {
        this.MarkAsArabic(name);
      }
    },
    TranslateTeX: function (name) {
      var english = this.GetArgument(name);
      var arabicText = this.GetArgument(name);
      var helper = Arabic.TeX(english, arabicText);
      return helper.call(this, name);
    },
    TranslateText: function (name) {
      var english = this.GetArgument(name);
      var arabicText = this.GetArgument(name);
      var helper = Arabic.Text(english, arabicText);
      return helper.call(this, name);
    },
    TranslateSymbols: function (name) {
      var english = this.GetArgument(name);
      var arabicText = this.GetArgument(name);
      var helper = Arabic.Symbols(english, arabicText);
      return helper.call(this, name);
    },
    MarkAsArabic: function (name) {
      var originalLang = this.stack.env.lang;

      this.stack.env.lang = 'ar';
      var arg = this._getArgumentMML(name);

      console.log('originalLang', originalLang);
      this.stack.env.lang = originalLang;  // Reset the language for other elements.

      this.Push(this.flipHorizontal(arg));
    },
    HandleFlipHorizontal: function (name) {
      var arg = this._getArgumentMML(name);
      this.Push(this.flipHorizontal(arg));
    }
  });

  MathJax.Hub.Startup.signal.Post('Arabic TeX Ready');
});
<|endoftext|>


<commit_before>// Copyright © 2012 Martin Ueding <dev@martin-ueding.de>

var animationTime = 300;

/**
 * The time that has to elapse since the last AJAX event was sent off.
 */
var idleTime = 500;
var ajaxTimeout = 1000;

var ajaxActive = false;
var animationActive = false;
var currentData = [];
var currentQuery = "";
var lastAjax = 0;
var lastChange = 0;

/**
 * Initializes the search.
 */
var searchMain = function () {
	showField();
	attachListener();
};

var isAjaxActive = function () {
	console.debug('isAjaxActive()');
	var now = new Date().getTime();
	if (now - lastAjax > ajaxTimeout) {
		console.debug('isAjaxActive(): Timeout reached.');
		ajaxActive = false;
		return false;
	}
	else {
		console.debug('isAjaxActive(): Returning variable.');
		return ajaxActive;
	}
}

/**
 * Inserts the search field into the DOM and focuses it.
 */
var showField = function () {
	console.debug('showField()');
	$('#navigation').after('
<input id="search_input" type="text" />
');
	$('#search_input').focus();
	//$('#search_input').focusout(exitSearch);
};

/**
 * Attaches the listeners to the search input field.
 */
var attachListener = function () {
	console.debug('attachListener()');
	$('#search_input').keyup(formChanged);
};

/**
 * This is called whenever the input has changed.
 *
 * It does not necessarily fire off an AJAX request if the last one was just a
 * little time ago.
 */
var formChanged = function () {
	console.debug('formChanged()');
	var newQuery = $(this).val();
	if (newQuery == currentQuery) {
		console.debug('formChanged(): Query did not change, abort.');
		return;
	}
	currentQuery = newQuery;
	lastChange = new Date().getTime();
	waitToQuery();
};

/**
 * Checks whether another AJAX request can be performed. Otherwise this
 * function will wait and call itself again.
 */
var waitToQuery = function () {
	console.debug('waitToQuery()');

	if (isAjaxActive()) {
		console.debug('waitToQuery(): AJAX still active, abort.');
		return;
	}

	var now = new Date().getTime();
	var elapsed = now - lastChange;

	if (elapsed > idleTime) {
		console.debug('waitToQuery(): Performing update.');
		hideResultPane();
		performQuery();
	}
	else {
		var toWait = idleTime - elapsed;
		console.debug('waitToQuery(): Still have to wait '+toWait+'.');
		setTimeout(waitToQuery, toWait);
	}
};

/**
 * Performs the actual AJAX request and queries the database.
 */
var performQuery = function () {
	console.debug('perfomQuery()');
	ajaxActive = true;
	lastAjax = new Date().getTime();
	$.ajax({
		dataType: 'json',
		success: querySuccess,
		type: 'GET',
		url: 'bookmarks/search/'+currentQuery,
	});
};

/**
 * This is called when the AJAX request suceeds.
 */
var querySuccess = function (data, textStatus, jqXHR) {
	console.debug('querySuccess()');
	ajaxActive = false;
	console.debug(data);
	currentData = data;
	updateResultPane();
};

var ajaxError = function (data, textStatus, jqXHR) {
	console.debug('ajaxError()');
	ajaxActive = false;
};

/**
 * Initializes the result pane, creates it if needed.
 */
var initResultPane = function () {
	console.debug('initResultPane()');
	if ($('#search_result_pane').length == 0) {
		$('#search').append('

');
		$('#search_result_pane').slideUp(0);
	}
};

/**
 * Hides the result pane. When the animation is done, the ``animationDone()``
 * will be called.
 */
var hideResultPane = function () {
	console.debug('hideResultPane()');
	if ($('#search_result_pane').length > 0) {
		animationActive = true;
		$('#search_result_pane').slideUp(animationTime, animationDone);
	}
};

/**
 * Inserts the current data into the results pane and slides it down.
 */
var updateResultPane = function () {
	console.debug('updateResultPane()');

	if (ajaxActive || animationActive) {
		console.debug('updateResultPane(): Quitting since active.');
		return;
	}

	if (currentData === null) {
		console.debug('updateResultPane(): currentData is null');
		return;
	}

	initResultPane();
	var searchResultPane = $('#search_result_pane');
	searchResultPane.html(formatResults(currentData));
	searchResultPane.slideDown(animationTime);
};

/**
 * Called when the slide up animation is done.
 */
var animationDone = function () {
	console.debug('animationDone()');
	animationActive = false;
	updateResultPane();
};

/**
 * Formats the results.
 *
 * @param data Data from database.
 * @return HTML string.
 */
var formatResults = function (data) {
	console.debug('formatResults()');
	var parts = [];

	for (var rowNum = 0; rowNum < data.length; rowNum++) {
		var row = data[rowNum];
		var hitTarget = 'bookmarks/visit/'+row.Bookmark.id;
		var viewTarget = 'bookmarks/view/'+row.Bookmark.id;

		parts.push('
');
		parts.push('');
		parts.push(row.Bookmark.title);
		parts.push('');
		parts.push('
');
		parts.push('');
		parts.push(row.Bookmark.url);
		parts.push('');
		parts.push('');
		// TODO I18n.
		parts.push('view');
		parts.push('');
		parts.push('
');
		parts.push('
');
	}

	var result = '
'+parts.join('')+'
';
	console.debug(result);
	return result;
};

/**
 * Deletes the cached data and hides the result pane.
 */
var exitSearch = function () {
	currentData = null;
	hideResultPane();
};

$(searchMain);
<commit_msg>Init selection at 0<commit_after>// Copyright © 2012 Martin Ueding <dev@martin-ueding.de>

var animationTime = 300;

/**
 * The time that has to elapse since the last AJAX event was sent off.
 */
var idleTime = 500;
var ajaxTimeout = 1000;

var ajaxActive = false;
var animationActive = false;
var currentData = [];
var currentQuery = "";
var currentSelection = 0;
var lastAjax = 0;
var lastChange = 0;

/**
 * Initializes the search.
 */
var searchMain = function () {
	showField();
	attachListener();
};

var isAjaxActive = function () {
	console.debug('isAjaxActive()');
	var now = new Date().getTime();
	if (now - lastAjax > ajaxTimeout) {
		console.debug('isAjaxActive(): Timeout reached.');
		ajaxActive = false;
		return false;
	}
	else {
		console.debug('isAjaxActive(): Returning variable.');
		return ajaxActive;
	}
}

/**
 * Inserts the search field into the DOM and focuses it.
 */
var showField = function () {
	console.debug('showField()');
	$('#navigation').after('
<input id="search_input" type="text" />
');
	$('#search_input').focus();
	//$('#search_input').focusout(exitSearch);
};

/**
 * Attaches the listeners to the search input field.
 */
var attachListener = function () {
	console.debug('attachListener()');
	$('#search_input').keyup(formChanged);
};

/**
 * This is called whenever the input has changed.
 *
 * It does not necessarily fire off an AJAX request if the last one was just a
 * little time ago.
 */
var formChanged = function () {
	console.debug('formChanged()');
	var newQuery = $(this).val();
	if (newQuery == currentQuery) {
		console.debug('formChanged(): Query did not change, abort.');
		return;
	}
	currentQuery = newQuery;
	lastChange = new Date().getTime();
	waitToQuery();
};

/**
 * Checks whether another AJAX request can be performed. Otherwise this
 * function will wait and call itself again.
 */
var waitToQuery = function () {
	console.debug('waitToQuery()');

	if (isAjaxActive()) {
		console.debug('waitToQuery(): AJAX still active, abort.');
		return;
	}

	var now = new Date().getTime();
	var elapsed = now - lastChange;

	if (elapsed > idleTime) {
		console.debug('waitToQuery(): Performing update.');
		hideResultPane();
		performQuery();
	}
	else {
		var toWait = idleTime - elapsed;
		console.debug('waitToQuery(): Still have to wait '+toWait+'.');
		setTimeout(waitToQuery, toWait);
	}
};

/**
 * Performs the actual AJAX request and queries the database.
 */
var performQuery = function () {
	console.debug('perfomQuery()');
	ajaxActive = true;
	lastAjax = new Date().getTime();
	$.ajax({
		dataType: 'json',
		success: querySuccess,
		type: 'GET',
		url: 'bookmarks/search/'+currentQuery,
	});
};

/**
 * This is called when the AJAX request suceeds.
 */
var querySuccess = function (data, textStatus, jqXHR) {
	console.debug('querySuccess()');
	ajaxActive = false;
	console.debug(data);
	currentData = data;
	updateResultPane();
};

var ajaxError = function (data, textStatus, jqXHR) {
	console.debug('ajaxError()');
	ajaxActive = false;
};

/**
 * Initializes the result pane, creates it if needed.
 */
var initResultPane = function () {
	console.debug('initResultPane()');
	if ($('#search_result_pane').length == 0) {
		$('#search').append('

');
		$('#search_result_pane').slideUp(0);
	}
};

/**
 * Hides the result pane. When the animation is done, the ``animationDone()``
 * will be called.
 */
var hideResultPane = function () {
	console.debug('hideResultPane()');
	if ($('#search_result_pane').length > 0) {
		animationActive = true;
		$('#search_result_pane').slideUp(animationTime, animationDone);
	}
};

/**
 * Inserts the current data into the results pane and slides it down.
 */
var updateResultPane = function () {
	console.debug('updateResultPane()');

	if (ajaxActive || animationActive) {
		console.debug('updateResultPane(): Quitting since active.');
		return;
	}

	if (currentData === null) {
		console.debug('updateResultPane(): currentData is null');
		return;
	}

	initResultPane();
	var searchResultPane = $('#search_result_pane');
	currentSelection = 0;
	searchResultPane.html(formatResults(currentData));
	searchResultPane.slideDown(animationTime);
};

/**
 * Called when the slide up animation is done.
 */
var animationDone = function () {
	console.debug('animationDone()');
	animationActive = false;
	updateResultPane();
};

/**
 * Formats the results.
 *
 * @param data Data from database.
 * @return HTML string.
 */
var formatResults = function (data) {
	console.debug('formatResults()');
	var parts = [];

	for (var rowNum = 0; rowNum < data.length; rowNum++) {
		var row = data[rowNum];
		var hitTarget = 'bookmarks/visit/'+row.Bookmark.id;
		var viewTarget = 'bookmarks/view/'+row.Bookmark.id;

		parts.push('
');
		parts.push('');
		parts.push(row.Bookmark.title);
		parts.push('');
		parts.push('
');
		parts.push('');
		parts.push(row.Bookmark.url);
		parts.push('');
		parts.push('');
		// TODO I18n.
		parts.push('view');
		parts.push('');
		parts.push('
');
		parts.push('
');
	}

	var result = '
'+parts.join('')+'
';
	console.debug(result);
	return result;
};

/**
 * Deletes the cached data and hides the result pane.
 */
var exitSearch = function () {
	currentData = null;
	hideResultPane();
};

$(searchMain);
<|endoftext|>


<commit_before>const fs = require('fs');
const markdown = require('markdown').markdown;
const express = require('express');
const app = express();

app.use(express.static(__dirname + '/public'));

app.set('view engine', 'jade');
app.set('views', __dirname + '/views');

app.get('/guides', function(req, res){
  res.render('guides/index');
});

app.get('/guides/:topic', function(req, res){
  try {
    var topic_doc = fs.readFileSync('./website/app/data/guides/' + req.params.topic + '.md', 'utf8');
    var topic_data = markdown.toHTML(topic_doc);
  } catch(e) {
    console.log(e);
  }
  res.render('guides/topic', { topic_data: topic_data });
});

app.get('/tutorial', function(req, res){
  res.render('tutorial/index');
});

app.get('/tutorial/:step', function(req, res){
  try {
    var step_doc = fs.readFileSync('./website/app/data/tutorial/' + req.params.step + '.md', 'utf8');
    var step_data = markdown.toHTML(step_doc);
  } catch(e) {
    console.log(e);
  }
  res.render('tutorial/step', { step_data: step_data });
});

app.get('/about', function(req, res){
  res.render('about');
});

app.get('/', function(req, res){
  res.sendFile(__dirname + '/views/index.html');
});

module.exports = app;
<commit_msg>pass step number to tutorial for back and next buttons<commit_after>const fs = require('fs');
const markdown = require('markdown').markdown;
const express = require('express');
const app = express();

app.use(express.static(__dirname + '/public'));

app.set('view engine', 'jade');
app.set('views', __dirname + '/views');

app.get('/guides', function(req, res){
  res.render('guides/index');
});

app.get('/guides/:topic', function(req, res){
  try {
    var topic_doc = fs.readFileSync('./website/app/data/guides/' + req.params.topic + '.md', 'utf8');
    var topic_data = markdown.toHTML(topic_doc);
  } catch(e) {
    console.log(e);
  }
  res.render('guides/topic', { topic_data: topic_data });
});

app.get('/tutorial', function(req, res){
  res.render('tutorial/index');
});

app.get('/tutorial/:step', function(req, res){
  var step_num = parseInt(req.params.step);
  try {
    var step_doc = fs.readFileSync('./website/app/data/tutorial/step-' + req.params.step + '.md', 'utf8');
    var step_data = markdown.toHTML(step_doc);
  } catch(e) {
    console.log(e);
  }
  res.render('tutorial/step', { step_data: step_data, step_num: step_num });
});

app.get('/about', function(req, res){
  res.render('about');
});

app.get('/', function(req, res){
  res.sendFile(__dirname + '/views/index.html');
});

module.exports = app;
<|endoftext|>


<commit_before>var path = require('path'),
    url = require('url'),
    async = require('async'),
    exec = require('child_process').exec,
    icomoonPath = require.resolve('icomoon-phantomjs'),
    vm = require('vm'),
    Tempfile = require('temporary/lib/file'),
    request = require('request'),
    quote = require('shell-quote').quote,
    Zip = require('node-zip');

function IcoMoonPhantomJsEngine(options) {
  // Create a place to store files
  this.files = [];
}
IcoMoonPhantomJsEngine.prototype = {
  // Method to add new SVGs
  addSvg: function (file, cb) {
    // Save the path for later
    this.files.push(file);
    cb();
  },
  // Method to export resulting fonts/map
  'export': function (callback) {
    // Set up shared variables
    var files = this.files,
        tmp,
        zipFiles,
        namespace,
        retObj = {};

    // If there are no files, exit early
    if (files.length === 0) {
      return callback(new Error('No files were provided to `fontsmith`. Exiting early.'));
    }

    // In series
    async.waterfall([
      // Write paths to file
      function writeTmpFile (cb) {
        tmp = new Tempfile();
        tmp.writeFile(JSON.stringify(files), 'utf8', cb);
      },
      // Invoke icomoon-phantomjs
      function execIcoMoon (cb) {
        var tmpPath = tmp.path;
        // TODO: Move onto programatic API once its coded
        exec(quote(['phantomjs', icomoonPath, tmpPath]), cb);
      },
      // Handle any stderr errors
      function handleIcoMoon (stdout, stderr, cb) {
        // If there is an stderr
        if (stderr) {
          // Strip out lines that are complaints about fonts
          // https://github.com/twolfson/grunt-fontsmith/issues/10
          var errLines = stderr.split(/\n/g);
          var validErrLines = errLines.filter(function (line) {
            if (line.match(/(WARNING: Method userSpaceScaleFactor|CoreText performance note:)/)) {
              return false;
            }

            // Filter out falsy (empty) lines
            return line;
          });

          // If there still is an error, callback with it
          if (validErrLines.length) {
            var err = new Error(validErrLines.join('\n'));
            return cb(err);
          }
        }

        // Otherwise, continue with stdout
        cb(null, stdout);
      },
      // Download our zip
      function downloadIcoMoonZip (zipUrl, cb) {
        request({'url': zipUrl, 'encoding': 'binary'}, cb);
      },
      // Parse out the zip
      function extractZip (res, body, cb) {
        // Prepare the zip files for easier interfacing
        var zip = new Zip(body),
            urlPath = res.request.path;

        // Save the namespace and zipFiles for further iterations
        namespace = path.basename(urlPath, '.zip');
        zipFiles = zip.files;

        // Continue to the next section
        cb();
      },
      // Pluck out fonts
      function pluckFonts (cb) {
        retObj.fonts = {
          svg: zipFiles[namespace + '/fonts/icomoon.svg'].data,
          ttf: zipFiles[namespace + '/fonts/icomoon.ttf'].data,
          woff: zipFiles[namespace + '/fonts/icomoon.woff'].data,
          eot: zipFiles[namespace + '/fonts/icomoon.eot'].data,
          'dev-svg': zipFiles[namespace + '/fonts/icomoon.dev.svg'].data
        };
        cb();
      },
      // Extract mapping for SVGs
      function pluckMapping (cb) {
        // Grab the substring of IE JS that specifies a filename mapping
        var ieJs = zipFiles[namespace + '/lte-ie7.js'].data,
            iconsVarSubstr = ieJs.match(/var\s*icons[^\}]+}/)[0];
            iconWindow = {};
        vm.runInNewContext(iconsVarSubstr, iconWindow);

        // Pluck out namespaced keys and get off of HTML entities
        var iconNamespaceObj = iconWindow.icons,
            iconNamespaceKeys = Object.getOwnPropertyNames(iconNamespaceObj),
            iconObj = {};
        iconNamespaceKeys.forEach(function (nsKey) {
          var key = nsKey.replace('icon-', ''),
              strVal = iconNamespaceObj[nsKey].replace('&#x', '').replace(';'),
              val = parseInt(strVal, 16);
          iconObj[key] = val;
        });

        // Save the normalized iconKey
        retObj.map = iconObj;

        // Continue
        cb();
      },
      // Callback with the formalized object
      function callbackWithResults (cb) {
        cb(null, retObj);
      }
    ], callback);
  }
};

// Async function to create a new engine
function createPalette(options, cb) {
  var palette = new IcoMoonPhantomJsEngine(options);
  cb(null, palette);
}

// Expose create and our engine
module.exports = {
  create: createPalette,
  IcoMoonPhantomJsEngine: IcoMoonPhantomJsEngine
};
<commit_msg>Add exec option to use different SSL protocol<commit_after>var path = require('path'),
    url = require('url'),
    async = require('async'),
    exec = require('child_process').exec,
    icomoonPath = require.resolve('icomoon-phantomjs'),
    vm = require('vm'),
    Tempfile = require('temporary/lib/file'),
    request = require('request'),
    quote = require('shell-quote').quote,
    Zip = require('node-zip');

function IcoMoonPhantomJsEngine(options) {
  // Create a place to store files
  this.files = [];
}
IcoMoonPhantomJsEngine.prototype = {
  // Method to add new SVGs
  addSvg: function (file, cb) {
    // Save the path for later
    this.files.push(file);
    cb();
  },
  // Method to export resulting fonts/map
  'export': function (callback) {
    // Set up shared variables
    var files = this.files,
        tmp,
        zipFiles,
        namespace,
        retObj = {};

    // If there are no files, exit early
    if (files.length === 0) {
      return callback(new Error('No files were provided to `fontsmith`. Exiting early.'));
    }

    // In series
    async.waterfall([
      // Write paths to file
      function writeTmpFile (cb) {
        tmp = new Tempfile();
        tmp.writeFile(JSON.stringify(files), 'utf8', cb);
      },
      // Invoke icomoon-phantomjs
      function execIcoMoon (cb) {
        var tmpPath = tmp.path;
        // TODO: Move onto programatic API once its coded
        exec(quote(['phantomjs', '--ssl-protocol=tlsv1', icomoonPath, tmpPath]), cb);
      },
      // Handle any stderr errors
      function handleIcoMoon (stdout, stderr, cb) {
        // If there is an stderr
        if (stderr) {
          // Strip out lines that are complaints about fonts
          // https://github.com/twolfson/grunt-fontsmith/issues/10
          var errLines = stderr.split(/\n/g);
          var validErrLines = errLines.filter(function (line) {
            if (line.match(/(WARNING: Method userSpaceScaleFactor|CoreText performance note:)/)) {
              return false;
            }

            // Filter out falsy (empty) lines
            return line;
          });

          // If there still is an error, callback with it
          if (validErrLines.length) {
            var err = new Error(validErrLines.join('\n'));
            return cb(err);
          }
        }

        // Otherwise, continue with stdout
        cb(null, stdout);
      },
      // Download our zip
      function downloadIcoMoonZip (zipUrl, cb) {
        request({'url': zipUrl, 'encoding': 'binary'}, cb);
      },
      // Parse out the zip
      function extractZip (res, body, cb) {
        // Prepare the zip files for easier interfacing
        var zip = new Zip(body),
            urlPath = res.request.path;

        // Save the namespace and zipFiles for further iterations
        namespace = path.basename(urlPath, '.zip');
        zipFiles = zip.files;

        // Continue to the next section
        cb();
      },
      // Pluck out fonts
      function pluckFonts (cb) {
        retObj.fonts = {
          svg: zipFiles[namespace + '/fonts/icomoon.svg'].data,
          ttf: zipFiles[namespace + '/fonts/icomoon.ttf'].data,
          woff: zipFiles[namespace + '/fonts/icomoon.woff'].data,
          eot: zipFiles[namespace + '/fonts/icomoon.eot'].data,
          'dev-svg': zipFiles[namespace + '/fonts/icomoon.dev.svg'].data
        };
        cb();
      },
      // Extract mapping for SVGs
      function pluckMapping (cb) {
        // Grab the substring of IE JS that specifies a filename mapping
        var ieJs = zipFiles[namespace + '/lte-ie7.js'].data,
            iconsVarSubstr = ieJs.match(/var\s*icons[^\}]+}/)[0];
            iconWindow = {};
        vm.runInNewContext(iconsVarSubstr, iconWindow);

        // Pluck out namespaced keys and get off of HTML entities
        var iconNamespaceObj = iconWindow.icons,
            iconNamespaceKeys = Object.getOwnPropertyNames(iconNamespaceObj),
            iconObj = {};
        iconNamespaceKeys.forEach(function (nsKey) {
          var key = nsKey.replace('icon-', ''),
              strVal = iconNamespaceObj[nsKey].replace('&#x', '').replace(';'),
              val = parseInt(strVal, 16);
          iconObj[key] = val;
        });

        // Save the normalized iconKey
        retObj.map = iconObj;

        // Continue
        cb();
      },
      // Callback with the formalized object
      function callbackWithResults (cb) {
        cb(null, retObj);
      }
    ], callback);
  }
};

// Async function to create a new engine
function createPalette(options, cb) {
  var palette = new IcoMoonPhantomJsEngine(options);
  cb(null, palette);
}

// Expose create and our engine
module.exports = {
  create: createPalette,
  IcoMoonPhantomJsEngine: IcoMoonPhantomJsEngine
};
<|endoftext|>


<commit_before>var MBR = function() {
}
MBR.main = function(device) {
	console.log("MBR: main");
	console.log("MBR: start Boot Loader");
	Loader.main(device);
}

var Loader = function() {
}
Loader.logo = "\033[32m" +
"        .__       .__     \n" +
"__  _  _|__| _____|  |__  \n" +
"\\ \\/ \\/ /  |/  ___/  |  \\ \n" +
" \\     /|  |\\___ \\|   Y  \\\n" +
"  \\/\\_/ |__/____  >___|  /\n" +
"                \\/     \\/   \033[31mLoader\033[0m\n";
Loader.tickid;
Loader.state;
Loader.waiting;
Loader.isCounting = true;
Loader.device;
Loader.config;
Loader.main = function(device) {
	console.log("Loader: main");
	console.log("Loader: register 100ms-timer");
	Loader.tickid = Emulator.registerTimer(100, Loader.tick);
	console.log("Loader: register key interrupt");
	Emulator.interrupts['key'] = Loader.key;
	Loader.device = device;
	var text = "\033[2J\033[0;0H\033[?25l" + Loader.logo + "\033[s";
	Emulator.output(text);
	Loader.state = 0;
}
Loader.key = function(keycode) {
	if (KeyCodes.isEnter(keycode)) {
		Loader.boot();
		return;
	}
	var char = KeyCodes.normalKey(keycode);
	if (char == 'w') Loader.selected--;
	if (char == 's') Loader.selected++;
	Loader.selected %= Loader.config.systems.length;
	if (Loader.selected < 0)
		Loader.selected += Loader.config.systems.length;
	Loader.outputSystems();
	Loader.isCounting = false;
}
Loader.tick = function() {
	switch(Loader.state) {
	case 0:
		console.log("Loader: load config");
		Loader.config = JSON.parse(Emulator.Request.get(Loader.device.name + "/" + Loader.device.mbr + "/config.json", "", false, ret))
		Loader.selected = Loader.config.default;
		Loader.waiting = Loader.config.sleep * 10;
		Loader.state++;
		break;
	case 1:
		Loader.outputSystems();
		Loader.state++;
		break;
	case 2:
		if (!Loader.isCounting)
			Loader.state++;
		if (Loader.waiting > 0)
			Loader.outputSystems();
		else
			Loader.boot();
		Loader.waiting--;
		break;
	case 3:
		break;
	case 4:
		Emulator.output(".");
		break;
	default:
		break;
	}
}
Loader.outputSystems = function() {
	var systems = Loader.config.systems;
	var text = "\033[u\n\n\n\n";
	for(var i = 0; i < systems.length; i++) {
		var string = "-> " + systems[i].label + " " + systems[i].kernel;
		var length = Emulator.Output.xsize - string.length - 10
		text += "\033[5C\033[46m\033[31m" + ((i == Loader.selected) ? "->" : "  ") + " \033[30m" + systems[i].label + " \033[34m" + systems[i].kernel;
		for (var j = 0; j < length; j++)
			text += " ";
		text += "\033[0m\n";
	}
	text += "\n\nSelect OS to boot... [w, s]";

	if (Loader.isCounting)
		text += "\n\nAuto-boot in " + parseInt((Loader.waiting / 10)) + " seconds..."

	Emulator.output(text);
}
Loader.boot = function() {
	var device = Emulator.Devices.getHarddisks();
	var system = Loader.config.systems[Loader.selected];
	device = device[system.hdd];
	var partition = device.partitions[system.partition];
	var loadstring = device.name + "/" + partition.name + "/" + system.kernel
	Emulator.output("\n\nTrying to boot " + loadstring + "..");
	Loader.state = 3;
	Emulator.Request.include(loadstring, Loader.finished);
}
Loader.finished = function() {
	console.log("Loader: stop BIOS");
	console.log("loader: remove all event handlers");
	Emulator.interrupts = new Array();
	Emulator.unregisterTimer(Loader.tickid);
	console.log("Loader: start OS");
	var system = Loader.config.systems[Loader.selected];
	try {
		OS.main(system);
		Emulator.output("\nKernel loaded successfully.");
	} catch (exception) {
		console.dir(exception);
		Emulator.output("\nFailed to load kernel...\n\n");
		Emulator.output("\033[31msystem halt\033[0m");
	}
}
<commit_msg>i forgot that one<commit_after>var MBR = function() {
}
MBR.main = function(device) {
	console.log("MBR: main");
	console.log("MBR: start Boot Loader");
	Loader.main(device);
}

var Loader = function() {
}
Loader.logo = "\033[32m" +
"        .__       .__     \n" +
"__  _  _|__| _____|  |__  \n" +
"\\ \\/ \\/ /  |/  ___/  |  \\ \n" +
" \\     /|  |\\___ \\|   Y  \\\n" +
"  \\/\\_/ |__/____  >___|  /\n" +
"                \\/     \\/   \033[31mLoader\033[0m\n";
Loader.tickid;
Loader.state;
Loader.waiting;
Loader.isCounting = true;
Loader.device;
Loader.config;
Loader.main = function(device) {
	console.log("Loader: main");
	console.log("Loader: register 100ms-timer");
	Loader.tickid = Emulator.registerTimer(100, Loader.tick);
	console.log("Loader: register key interrupt");
	Emulator.interrupts['key'] = Loader.key;
	Loader.device = device;
	var text = "\033[2J\033[0;0H\033[?25l" + Loader.logo + "\033[s";
	Emulator.output(text);
	Loader.state = 0;
}
Loader.key = function(keycode) {
	if (KeyCodes.isEnter(keycode)) {
		Loader.boot();
		return;
	}
	var char = KeyCodes.normalKey(keycode);
	if (char == 'w') Loader.selected--;
	if (char == 's') Loader.selected++;
	Loader.selected %= Loader.config.systems.length;
	if (Loader.selected < 0)
		Loader.selected += Loader.config.systems.length;
	Loader.outputSystems();
	Loader.isCounting = false;
}
Loader.tick = function() {
	switch(Loader.state) {
	case 0:
		console.log("Loader: load config");
		Loader.config = JSON.parse(Emulator.Request.get(Loader.device.name + "/" + Loader.device.mbr + "/config.json", "", false, ret))
		Loader.selected = Loader.config.default;
		Loader.waiting = Loader.config.sleep * 10;
		Loader.state++;
		break;
	case 1:
		Loader.outputSystems();
		Loader.state++;
		break;
	case 2:
		if (!Loader.isCounting)
			Loader.state++;
		if (Loader.waiting > 0)
			Loader.outputSystems();
		else
			Loader.boot();
		Loader.waiting--;
		break;
	case 3:
		break;
	case 4:
		Emulator.output(".");
		break;
	default:
		break;
	}
}
Loader.outputSystems = function() {
	var systems = Loader.config.systems;
	var text = "\033[u\n\n\n\n";
	for(var i = 0; i < systems.length; i++) {
		var string = "-> " + systems[i].label + " " + systems[i].kernel;
		var length = Emulator.Output.xsize - string.length - 10
		text += "\033[5C\033[46m\033[31m" + ((i == Loader.selected) ? "->" : "  ") + " \033[30m" + systems[i].label + " \033[34m" + systems[i].kernel;
		for (var j = 0; j < length; j++)
			text += " ";
		text += "\033[0m\n";
	}
	text += "\n\nSelect OS to boot... [w, s]";

	if (Loader.isCounting)
		text += "\n\nAuto-boot in " + parseInt((Loader.waiting / 10)) + " seconds..."

	Emulator.output(text);
}
Loader.boot = function() {
	var device = Emulator.Devices.getHarddisks();
	var system = Loader.config.systems[Loader.selected];
	device = device[system.hdd];
	var partition = device.partitions[system.partition];
	var loadstring = device.name + "/" + partition.name + "/" + system.kernel
	Emulator.output("\n\nTrying to boot " + loadstring + "..");
	Loader.state = 4;
	Emulator.Request.include(loadstring, Loader.finished);
}
Loader.finished = function() {
	console.log("Loader: stop BIOS");
	console.log("loader: remove all event handlers");
	Emulator.interrupts = new Array();
	Emulator.unregisterTimer(Loader.tickid);
	console.log("Loader: start OS");
	var system = Loader.config.systems[Loader.selected];
	try {
		OS.main(system);
		Emulator.output("\nKernel loaded successfully.");
	} catch (exception) {
		console.dir(exception);
		Emulator.output("\nFailed to load kernel...\n\n");
		Emulator.output("\033[31msystem halt\033[0m");
	}
}
<|endoftext|>


<commit_before>/*
      ___           ___           ___         ___          ___
     /__/\         /__/\         /  /\       /  /\        /  /\
    _\_ \:\        \  \:\       /  /::\     /  /:/       /  /:/_
   /__/\ \:\        \__\:\     /  /:/\:\   /__/::\      /  /:/ /\
  _\_ \:\ \:\   ___ /  /::\   /  /:/  \:\  \__\/\:\    /  /:/ /::\
 /__/\ \:\ \:\ /__/\  /:/\:\ /__/:/ \__\:\    \  \:\  /__/:/ /:/\:\
 \  \:\ \:\/:/ \  \:\/:/__\/ \  \:\ /  /:/     \__\:\ \  \:\/:/~/:/
  \  \:\ \::/   \  \::/       \  \:\  /:/      /  /:/  \  \::/ /:/
   \  \:\/:/     \  \:\        \  \:\/:/      /__/:/    \__\/ /:/
    \  \::/       \  \:\        \  \::/       \__\/       /__/:/
     \__\/         \__\/         \__\/                    \__\/

    @author Dan Morgan, Jim Kogler, Neil Dahlke
    @version 0.0.1
*/

(function() {

    window.Who = window.Who || {

        clearsInput : function(data) {
            var _$el = null;

            if (!!data.label) {
                _$el = Q.findValueByLabel(data);
            } else if (!!data.placeholderText) {
                _$el = Q.findValueByPlaceholderText(data);
            }

            if (_$el && _$el.length == 1) {
                _$el.val("");
            } else {
                console.log("Incorrect number of inputs returned.");
            }
        },

        clicksButton : function(data) {
            data.type = "BUTTON";
            this.clicksElement(data);
        },

        clicksCheckbox : function(data) {
            data.type = 'input[type="checkbox"]';
            this.clicksElement(data);
        },

        clicksElement : function(data) {

            // TODO: determine how we should handle elements that have no text and only have icons.

            var ele;
            if (!!data.text) {
                ele = Q.findElWithText(data);
            } else if (!!data.label) {
                ele = Q.findValueByLabel(data);
            } else if (!!data.placeholderText) {
                ele = Q.findValueByPlaceholderText(data);
            } else {
                ele = Q.findEl(data);
            }

            if (!!ele && ele.length > 0) {
                data.status = true;
                try {
                    var el = $(ele[0]);

                    if (el.click) {
                        el.click();
                        // TODO: This is some coolness! It'll show where the user clicked, but there is something
                        // going on that needs debugging.
                        // $('#click_spot').remove();
                        // $('
').appendTo('body')
                        //     .css({
                        //         left : event.x,
                        //         top : event.y,
                        //         height : '50px',
                        //         width : '50px',
                        //         'border-radius' : '50%'
                        //     })
                        //    .fadeOut();
                    } else {
                        data.status = false;
                        console.log("Click was not a function.")
                    }

                } catch(Exception) {
                    data.status = false;
                    console.log(Exception);
                }
            } else {
                data.status = false;
                console.log(data.query + " not found");
            }
            return data.status;
        },

        clicksLink : function(data) {
            data.type = "LINK";
            this.clicksElement(data);
        },

        clicksRadio : function(data) {
            data.type = 'input[type="radio"]';
            this.clicksElement(data);
        },

        hoversOver : function(data) {
            // TODO: Combine like functionality of clicksElement
            var _$el;
            if (!!data.text) {
                _$el = Q.findElWithText(data);
            } else if (!!data.label) {
                _$el = Q.findValueByLabel(data);
            } else if (!!data.placeholderText) {
                _$el = Q.findValueByPlaceholderText(data);
            } else {
                _$el = Q.findEl(data);
            }

            if (!!_$el && _$el.length > 0) {
                data.status = true;
                try {
                    var _$mouseEl = $(_$el[0]);
                    if (_$mouseEl.mouseover) {
                        _$mouseEl.mouseover();

                        if (data.msToOut) {
                            setTimeout(function(){
                                _$mouseEl.mouseout();
                            }, data.msToOut);
                        }
                    } else {
                        data.status = false;
                        data.exception = "Mouseover was not a function.";
                    }

                } catch(Exception) {
                    data.status = false;
                    data.exception = Exception;
                }

            } else {

                data.status = false;
                data.exception = data.query + " not found";

            }

            return data.status;
        },

        passesTime : function(data) {
            var _ms = data.ms || 1000,
                _flag = false,
                _callback = data.thenWho || function(){ _flag = true; },
                _waitingFn = data.whileWaiting || function(){ return _flag; };

            setTimeout(_callback, _ms);
            return _waitingFn;
        },

        readsFormValue : function(data) {

            var _$el = null;

            if (!!data.label) {
                _$el = Q.findValueByLabel(data);
            } else if (!!data.placeholderText) {
                _$el = Q.findValueByPlaceholderText(data);
            }

            if (_$el && _$el.length) {
                return _$el.val();
            }

        },

        resetContext : function() {
            this.setContext("body");
        },

        seesElWithPlaceholderText : function(data) {
            var $el = $(Q.findValueByPlaceholderText(data));
            return ($el && ($el.length == 1));
        },

        seesElementWithText : function(data) {
            data.visible = true;
            var element = Q.findElWithText(data);
            return (element && element.length == 1);
        },

        seesImages : function(data) {
            data = data || {};
            data.type = "img";
            data.numImages = data.numImages || 1;
            data.visible = true;
            var $el = $(Q.findEl(data));

            // TODO: add option withAltTag

            // var _isVisible = false;
            // $el.load(function(){
            //         alert('Good image!');
            //         _isVisible = true;
            //         return true;
            //     })
            //     .error(function(){
            //         alert('Bad image!');
            //         return false;
            //     });

            return ($el && $el.length == data.numImages);
        },

        selectsFromDropDown : function(data) {

            data.valueType = 'select';
            var _optionText = data.optionText || "",
                _$selectBoxes = Q.findValueByLabel(data),
                _box = _$selectBoxes[0],
                _match = false;

            for (var i = 0; i < _box.length || _match; i++) {
                var _optLabel = _box[i].label;
                if (_optionText === _optLabel) {
                    $(_box).val(_box[i].value);
                    _match = true;
                }
            }

            if (!_match) {
                console.log('Who is unable to match the dropdown and option text.');
            }
        },

        setContext : function(context) {
            this.context = Q.context = $(context);
            $('*').removeClass('who-context');
            $(context).addClass('who-context');
        },

        typesValueIntoForm : function(data) {
            data.type = data.type || 'label';

            var $el;

            if (data.label) {
                $el = Q.findValueByLabel(data);
            } else if (!!data.placeholderText) {
                $el = Q.findValueByPlaceholderText(data);
            } else {
                $el = Q.findEl(data);
            }

            if (!$el) {
                return false;
            }

            var str = data.text;
            var c = '';
            $el.val('');

            for(var i=0; i<str.length; i++) {
                c = str[i];
                $el.keydown();
                $el.val($el.val() + c);
                $el.keyup();
                $el.keypress();
            }
        },

        typesEnterKey : function(data) {

            var $el;

            if (!!data.label) {
                $el = Q.findValueByLabel(data)  ;
            } else if (!!data.placeholderText) {
                $el = Q.findValueByPlaceholderText(data);
            } else {
                $el = Q.findEl(data);
            }

            if (!$el) {
                return false;
            }

            // var e = jQuery.Event("keypress");
            // e.which = 13;
            // e.keyCode = 13;
            // $el.trigger(e);
            $el.parents('form').submit();
        },

        DEV : {

            findHiddenInputThroughInspection : function(data) {
                data.type = "input[type='hidden'][name='"+data.name+"']";
                var retVal = Query.findEl(data);
                return $(retVal);
            },

            findElByID : function(data) {
                if (!data.id) {
                    throw new Error("Method requires an ID to be passed in.");
                }
                return ($('#'+data.id));
            },

            findElByClass : function(data) {
                if (!data.className) {
                    throw new Error("Method requires an className to be passed in.");
                }
                return ($('.'+data.id));
            },

            clearAllInputs : function() {
                $('input[type=text]').val("");
            }

        }
    };

})();

var Q = {
    LINK : "a",
    BUTTON : "button,input[type=button],input[type=submit]",
    INPUT : "input,textarea,select",
    findEl : function(data) {
        var els = this.findEls(data);
        if (els.length == 1) {
            return els[0];
        } else {
            console.log('Too many elements found for ' + data.query);
            return null;
        }
    },

    findEls : function(data) {

        if (data.type && !data.query) {
            data.query = Q[data.type.toUpperCase()] || data.type;
        }

        var retVal = this.mergeFind(data);

        if (data.visible) {
            retVal = retVal.filter(":visible");
            if (retVal !== null) {
                for(var i = 0; i < retVal.length; i++) {
                    var elNum = 0;
                    var $rV = $(retVal[i][0]);
                    $rV.parents().each(function() {
                        var $parent = $(this);
                        if (!$parent.is(':visible')) {
                            retVal.splice(elNum, elNum);
                            return;
                        }
                    });
                    elNum++;
                }
            }
        }

        return retVal;
    },

    findElWithText : function(data) {
        var _elements = this.findEls(data);
        var _retVal = null;
        var _caseFunc = function(x) {return x;};
        if (!data.caseSensitive) _caseFunc = function(x) {return x.toLowerCase();};
        var _text = _caseFunc(data.text),
            _match = false,
            _partial = (!!data.findByPartial) ? data.findByPartial : false;

        _elements.each(function(i,v) {
            var _elText = _caseFunc($.trim($(v).text())) || _caseFunc($.trim($(v).val()));

            if (_partial) {
                _match = (_elText.indexOf(_text) != -1);
            } else {
                _match =  (_elText == _text);
            }

            if (_match) {
                _retVal = $(v);
            }

        });

        return _retVal;
    },

    // TODO: Consolidate this function and findValueByPlaceholderText
    findValueByLabel : function(data) {
        var _caseFunc = function(x) { return x; },
            _$matchingField = null,
            _self = this,
            _valueType = data.valueType || 'input';

        data.visible = true;
        data.type = 'label';

        if (!data.label) {
            return false;
        }

        if (!data.caseSensitive) {
            _caseFunc = function(x) {
                return x.toLowerCase();
            };
        }

        var _labels = this.findEls(data),
            _text = _caseFunc(data.label);

        for(var i = 0; i < _labels.length; i++) {
            var $label = $(_labels[i]),
                _labelText = _caseFunc($label.html()),
                _forInput = $label.attr('for') || null,
                _match = false,
                _partial = (!!data.findByPartial) ? data.findByPartial : false;

            if (_partial) {
                _match = (_labelText.indexOf(_text) != -1);
            } else {
                _match =  (_labelText == _text);
            }

            if (!_forInput) {
                console.log("The label you are looking for must have a for tag that corresponds to it's input.");
            }

            if (_match) {
                _$matchingField = $(_valueType+'[name="'+_forInput+'"]');
                _$matchingField = _$matchingField.length === 0 ? $('#'+_forInput) : _$matchingField;
                _$matchingField = _$matchingField.length === 0 ? $('.'+_forInput) : _$matchingField;
                break;
            }

        }

        return _$matchingField;
    },

    findValueByPlaceholderText : function(data) {

        var _caseFunc = function(x) { return x; },
            _$matchingField = null,
            _self = this,
            _valueType = data.valueType || 'input',
            _inputs = null,
            _placeholderText = null;

        if (!data.placeholderText) {
            return false;
        }

        if (!data.caseSensitive) {
            _caseFunc = function(x) {
                x = x || "";
                return x.toLowerCase();
            };
        }

        data.visible = true;
        data.type = 'INPUT';

        _inputs = this.findEls(data);
        _placeholderText = _caseFunc(data.placeholderText);

        for(var i = 0; i < _inputs.length; i++) {
            var $input = $(_inputs[i]),
                _inputPlaceholder = _caseFunc($input.attr('placeholder')),
                _match = false,
                _partial = (!!data.findByPartial) ? data.findByPartial : false;

            if (_partial) {
                _match = (_inputPlaceholder.indexOf(_placeholderText) != -1);
            } else {
                _match =  (_inputPlaceholder == _placeholderText);
            }

            if (_match) {
                _$matchingField = $input;
            }
        }

        return _$matchingField;
    },

    mergeFind : function(data) {
        var _query = data.query || "",
            _types = _query.split(','),
            _contextSelector = this.context.selector,
            _qString = "",
            _qResult = null;

        for(var i = 0; i < _types.length; i++) {
            _qString += _contextSelector + ' ' + _types[i];
            if (i != _types.length - 1) {
                // If this is added at the end it will
                // bomb out the jQuery selector.
                _qString += ',';
            }
        }

        _qResult = $(_qString);
        return _qResult;
    }
};<commit_msg>Updated who.js<commit_after>/*
      ___           ___           ___         ___          ___
     /__/\         /__/\         /  /\       /  /\        /  /\
    _\_ \:\        \  \:\       /  /::\     /  /:/       /  /:/_
   /__/\ \:\        \__\:\     /  /:/\:\   /__/::\      /  /:/ /\
  _\_ \:\ \:\   ___ /  /::\   /  /:/  \:\  \__\/\:\    /  /:/ /::\
 /__/\ \:\ \:\ /__/\  /:/\:\ /__/:/ \__\:\    \  \:\  /__/:/ /:/\:\
 \  \:\ \:\/:/ \  \:\/:/__\/ \  \:\ /  /:/     \__\:\ \  \:\/:/~/:/
  \  \:\ \::/   \  \::/       \  \:\  /:/      /  /:/  \  \::/ /:/
   \  \:\/:/     \  \:\        \  \:\/:/      /__/:/    \__\/ /:/
    \  \::/       \  \:\        \  \::/       \__\/       /__/:/
     \__\/         \__\/         \__\/                    \__\/

    @author Dan Morgan, Jim Kogler, Neil Dahlke
    @version 0.0.1
*/

(function() {

    window.Who = window.Who || {

        clearsInput : function(data) {
            var _$el = null;

            if (!!data.label) {
                _$el = Q.findValueByLabel(data);
            } else if (!!data.placeholderText) {
                _$el = Q.findValueByPlaceholderText(data);
            }

            if (_$el && _$el.length == 1) {
                _$el.val("");
            } else {
                console.log("Incorrect number of inputs returned.");
            }
        },

        clicksButton : function(data) {
            data.type = "BUTTON";
            this.clicksElement(data);
        },

        clicksCheckbox : function(data) {
            data.type = 'input[type="checkbox"]';
            this.clicksElement(data);
        },

        clicksElement : function(data) {

            // TODO: determine how we should handle elements that have no text and only have icons.

            var _$el;
            if (!!data.text) {
                _$el = Q.findElWithText(data);
            } else if (!!data.label) {
                _$el = Q.findValueByLabel(data);
            } else if (!!data.placeholderText) {
                _$el = Q.findValueByPlaceholderText(data);
            } else {
                _$el = Q.findEl(data);
            }

            if (!!_$el && _$el.length > 0) {

                data.status = true;

                try {

                    var _$tmpEl = $(_$el[0]);

                    if (_$tmpEl.click) {
                        _$tmpEl.click();
                        // TODO: This is some coolness! It'll show where the user clicked, but there is something
                        // going on that needs debugging.
                        // $('#click_spot').remove();
                        // $('
').appendTo('body')
                        //     .css({
                        //         left : event.x,
                        //         top : event.y,
                        //         height : '50px',
                        //         width : '50px',
                        //         'border-radius' : '50%'
                        //     })
                        //    .fadeOut();
                    } else {
                        data.status = false;
                        console.log("Click was not a function.");
                    }

                } catch(Exception) {
                    data.status = false;
                    console.log(Exception);
                }
            } else {
                data.status = false;
                console.log(data.text + " not found");
            }
            return data.status;
        },

        clicksLink : function(data) {
            // User can pass in an object, or simply the string of text we're looking for.
            var _options = null;
            if (data && typeof data == "string") {
                _options = {
                    text : data
                };
            } else if (data && typeof data == "object") {
                _options = data;
            }
            _options.type = "LINK";

            this.clicksElement(_options);
        },

        clicksRadio : function(data) {
            data.type = 'input[type="radio"]';
            this.clicksElement(data);
        },

        hoversOver : function(data) {
            // TODO: Combine like functionality of clicksElement
            var _$el;
            if (!!data.text) {
                _$el = Q.findElWithText(data);
            } else if (!!data.label) {
                _$el = Q.findValueByLabel(data);
            } else if (!!data.placeholderText) {
                _$el = Q.findValueByPlaceholderText(data);
            } else {
                _$el = Q.findEl(data);
            }

            if (!!_$el && _$el.length > 0) {
                data.status = true;
                try {
                    var _$mouseEl = $(_$el[0]);
                    if (_$mouseEl.mouseover) {
                        _$mouseEl.mouseover();

                        if (data.msToOut) {
                            setTimeout(function(){
                                _$mouseEl.mouseout();
                            }, data.msToOut);
                        }
                    } else {
                        data.status = false;
                        data.exception = "Mouseover was not a function.";
                    }

                } catch(Exception) {
                    data.status = false;
                    data.exception = Exception;
                }

            } else {

                data.status = false;
                data.exception = data.query + " not found";

            }

            return data.status;
        },

        passesTime : function(data) {
            var _ms = data.ms || 1000,
                _flag = false,
                _callback = data.thenWho || function(){ _flag = true; },
                _waitingFn = data.whileWaiting || function(){ return _flag; };

            setTimeout(_callback, _ms);
            return _waitingFn;
        },

        readsFormValue : function(data) {

            var _$el = null;

            if (data.label) {
                _$el = Q.findValueByLabel(data);
            } else if (!!data.placeholderText) {
                _$el = Q.findValueByPlaceholderText(data);
            }

            if (_$el && _$el.length == 1) {
                return _$el.val();
            }

        },

        resetContext : function() {
            this.setContext("body");
        },

        seesElWithPlaceholderText : function(data) {
            var $el = $(Q.findValueByPlaceholderText(data));
            return ($el && ($el.length == 1));
        },

        seesElementWithText : function(data) {
            data.visible = true;
            var element = Q.findElWithText(data);
            return (element && element.length == 1);
        },

        seesImages : function(data) {
            data = data || {};
            data.type = "img";
            data.numImages = data.numImages || 1;
            data.visible = true;
            var $el = $(Q.findEl(data));

            // TODO: add option withAltTag

            // var _isVisible = false;
            // $el.load(function(){
            //         alert('Good image!');
            //         _isVisible = true;
            //         return true;
            //     })
            //     .error(function(){
            //         alert('Bad image!');
            //         return false;
            //     });

            return ($el && $el.length == data.numImages);
        },

        selectsFromDropDown : function(data) {

            data.valueType = 'select';

            var _optionText = data.optionText || "",
                _selectBoxes = Q.findValueByLabel(data),
                _$box = $(_selectBoxes[0])[0],
                _match = false;

            for (var opt = 0; opt < _$box.length; opt++) {

                var _optLabel = !!_$box[opt] ? _$box[opt].label : '';

                if (_optionText === _optLabel) {
                    $(_$box).val(_$box[opt].value);
                }
            }

            if (!_match) {
                console.log('Who is unable to match the dropdown and option text.');
            }
        },

        setContext : function(context) {

            if (typeof context == "string") {
                this.context = Q.context = $(context);
            } else if (typeof context == "object") {
                this.context = Q.context = context;
            }

            $('*').removeClass('who-context');
            $(context).addClass('who-context');

        },

        setContextToParentOfEl : function(data) {
            var _parentElQuery = data.parentElQuery || null,
                _$el = null;

            if (!!data.text) {
                _$el = Q.findElWithText(data);
            } else if (!!data.label) {
                _$el = Q.findValueByLabel(data);
            } else if (!!data.placeholderText) {
                _$el = Q.findValueByPlaceholderText(data);
            } else {
                _$el = Q.findEl(data);
            }

            if (_parentElQuery) {

                var _$tmpParent = _$el.closest(_parentElQuery);

                if (_$tmpParent.length > 0) {
                    this.setContext(_$tmpParent);
                }

            } else {
                console.log('Cannot set context to parent element without the option parentElType.');
            }

        },

        typesValueIntoForm : function(data) {
            data.type = data.type || 'label';

            var $el;

            if (data.label) {
                $el = Q.findValueByLabel(data);
            } else if (!!data.placeholderText) {
                $el = Q.findValueByPlaceholderText(data);
            } else {
                $el = Q.findEl(data);
            }

            if (!$el) {
                return false;
            }

            var str = data.text;
            var c = '';
            $el.val('');

            for(var i=0; i<str.length; i++) {
                c = str[i];
                $el.keydown();
                $el.val($el.val() + c);
                $el.keyup();
                $el.keypress();
            }
        },

        typesEnterKey : function(data) {

            var $el;

            if (!!data.label) {
                $el = Q.findValueByLabel(data)  ;
            } else if (!!data.placeholderText) {
                $el = Q.findValueByPlaceholderText(data);
            } else {
                $el = Q.findEl(data);
            }

            if (!$el) {
                return false;
            }

            // var e = jQuery.Event("keypress");
            // e.which = 13;
            // e.keyCode = 13;
            // $el.trigger(e);
            $el.parents('form').submit();
        },

        DEV : {

            findHiddenInputThroughInspection : function(data) {
                data.type = "input[type='hidden'][name='"+data.name+"']";
                var retVal = Query.findEl(data);
                return $(retVal);
            },

            findElByID : function(data) {
                if (!data.id) {
                    throw new Error("Method requires an ID to be passed in.");
                }
                return ($('#'+data.id));
            },

            findElByClass : function(data) {
                if (!data.className) {
                    throw new Error("Method requires an className to be passed in.");
                }
                return ($('.'+data.id));
            },

            clearAllInputs : function() {
                $('input[type=text]').val("");
            }

        }
    };

})();

var Q = {
    LINK : "a",
    BUTTON : "button,input[type=button],input[type=submit]",
    INPUT : "input,textarea,select",

    findClosest : function(data) {

    },

    findEl : function(data) {
        var els = this.findEls(data);
        if (els.length == 1) {
            return els[0];
        } else {
            console.log('Too many elements found for ' + data.query);
            return null;
        }
    },

    findEls : function(data) {

        if (data.type && !data.query) {
            data.query = Q[data.type.toUpperCase()] || data.type;
        }

        var retVal = this.mergeFind(data);

        if (data.visible) {
            retVal = retVal.filter(":visible");
            if (retVal !== null) {
                for(var i = 0; i < retVal.length; i++) {
                    var elNum = 0;
                    var $rV = $(retVal[i][0]);
                    $rV.parents().each(function() {
                        var $parent = $(this);
                        if (!$parent.is(':visible')) {
                            retVal.splice(elNum, elNum);
                            return;
                        }
                    });
                    elNum++;
                }
            }
        }

        return retVal;
    },

    findElWithText : function(data) {

        var _elements = this.findEls(data);
        var _retVal = null;
        var _caseFunc = function(x) {return x;};

        if (!data.caseSensitive) _caseFunc = function(x) {return x.toLowerCase();};

        var _text = _caseFunc(data.text),
            _match = false,
            _partial = (!!data.findByPartial) ? data.findByPartial : false;

        _elements.each(function(i,v) {

            var _elText = _caseFunc($.trim($(v).text())) || _caseFunc($.trim($(v).val()));

            if (_partial) {
                _match = (_elText.indexOf(_text) != -1);
            } else {
                _match =  (_elText == _text);
            }

            if (_match && _retVal === null) {
                _retVal = $(v);
            }

        });

        return _retVal;
    },

    // TODO: Consolidate this function and findValueByPlaceholderText
    findValueByLabel : function(data) {
        var _caseFunc = function(x) { return x; },
            _$matchingField = null,
            _self = this,
            _valueType = data.valueType || 'input';

        data.visible = true;
        data.type = 'label';

        if (!data.label) {
            return false;
        }

        if (!data.caseSensitive) {
            _caseFunc = function(x) {
                return x.toLowerCase();
            };
        }

        var _labels = this.findEls(data),
            _text = _caseFunc(data.label);

        for(var i = 0; i < _labels.length; i++) {
            var $label = $(_labels[i]),
                _labelText = _caseFunc($label.html()),
                _forInput = $label.attr('for') || null,
                _match = false,
                _partial = (!!data.findByPartial) ? data.findByPartial : false;

            if (_partial) {
                _match = (_labelText.indexOf(_text) != -1);
            } else {
                _match =  (_labelText == _text);
            }

            if (!_forInput) {
                console.log("The label "+_labelText +" you are looking for must have a for tag that corresponds to it's input.");
            }

            if (_match) {
                var _byName = this.context.selector + " " +_valueType+'[name="'+_forInput+'"]',
                    _byID = this.context.selector + ' #'+_forInput,
                    _byClass = this.context.selector + ' .'+_forInput;

                _$matchingField = $(_byName);
                _$matchingField = _$matchingField.length === 0 ? $(_byID) : _$matchingField;
                _$matchingField = _$matchingField.length === 0 ? $(_byClass) : _$matchingField;
            }

        }

        return _$matchingField;
    },

    findValueByPlaceholderText : function(data) {

        var _caseFunc = function(x) { return x; },
            _$matchingField = null,
            _self = this,
            _valueType = data.valueType || 'input',
            _inputs = null,
            _placeholderText = null;

        if (!data.placeholderText) {
            return false;
        }

        if (!data.caseSensitive) {
            _caseFunc = function(x) {
                x = x || "";
                return x.toLowerCase();
            };
        }

        data.visible = true;
        data.type = 'INPUT';

        _inputs = this.findEls(data);
        _placeholderText = _caseFunc(data.placeholderText);

        for(var i = 0; i < _inputs.length; i++) {
            var $input = $(_inputs[i]),
                _inputPlaceholder = _caseFunc($input.attr('placeholder')),
                _match = false,
                _partial = (!!data.findByPartial) ? data.findByPartial : false;

            if (_partial) {
                _match = (_inputPlaceholder.indexOf(_placeholderText) != -1);
            } else {
                _match =  (_inputPlaceholder == _placeholderText);
            }

            if (_match) {
                _$matchingField = $input;
            }
        }

        return _$matchingField;
    },

    mergeFind : function(data) {
        var _query = data.query || "",
            _types = _query.split(','),
            _contextSelector = this.context.selector,
            _qString = "",
            _qResult = null;

        for(var i = 0; i < _types.length; i++) {
            _qString += _contextSelector + ' ' + _types[i];
            if (i != _types.length - 1) {
                // If this is added at the end it will
                // bomb out the jQuery selector.
                _qString += ',';
            }
        }

        _qResult = $(_qString);
        return _qResult;
    }
};<|endoftext|>


<commit_before>var write = require('./write'),
    geojson = require('./geojson'),
    prj = require('./prj'),
    JSZip = require('jszip');

module.exports = function(gj, options) {

    var zip = new JSZip(),
        layers = zip.folder(options && options.folder ? options.folder : 'layers');

    [geojson.point(gj), geojson.line(gj), geojson.polygon(gj)]
        .forEach(function(l) {
        if (l.geometries.length) {
            write(
                // field definitions
                l.properties,
                // geometry type
                l.type,
                // geometries
                l.geometries,
                function(err, files) {
                    var fileName = options && options.types[l.type] ? options.types[l.type] : l.type;
                    layers.file(fileName + '.shp', files.shp.buffer, { binary: true });
                    layers.file(fileName + '.shx', files.shx.buffer, { binary: true });
                    layers.file(fileName + '.dbf', files.dbf.buffer, { binary: true });
                    layers.file(fileName + '.prj', prj);
                });
        }
    });

    return zip.generate({compression:'STORE'});
};
<commit_msg>Type names in options are in lower case now<commit_after>var write = require('./write'),
    geojson = require('./geojson'),
    prj = require('./prj'),
    JSZip = require('jszip');

module.exports = function(gj, options) {

    var zip = new JSZip(),
        layers = zip.folder(options && options.folder ? options.folder : 'layers');

    [geojson.point(gj), geojson.line(gj), geojson.polygon(gj)]
        .forEach(function(l) {
        if (l.geometries.length) {
            write(
                // field definitions
                l.properties,
                // geometry type
                l.type,
                // geometries
                l.geometries,
                function(err, files) {
                    var fileName = options && options.types[l.type.toLowerCase()] ? options.types[l.type.toLowerCase()] : l.type;
                    layers.file(fileName + '.shp', files.shp.buffer, { binary: true });
                    layers.file(fileName + '.shx', files.shx.buffer, { binary: true });
                    layers.file(fileName + '.dbf', files.dbf.buffer, { binary: true });
                    layers.file(fileName + '.prj', prj);
                });
        }
    });

    return zip.generate({compression:'STORE'});
};
<|endoftext|>


<commit_before>'use strict';

import Tool from '../packages/tools/Tool'

/*
 * Abstract class for annotation tools like StrongTool, EmphasisTool, LinkTool.
 *
 * @component
 */

function AnnotationTool() {
  Tool.apply(this, arguments);
}

AnnotationTool.Prototype = function() {
  var _super = AnnotationTool.super.prototype;

  this.render = function($$) {
    var el = _super.render.call(this, $$);
    el.addClass('sm-annotation-tool');
    return el;
  };

  this.renderButton = function($$) {
    var el = _super.renderButton.call(this, $$);
    el.append(this.renderMode($$));
    return el;
  };

  /*
    Renders a small hint for the mode (expand, truncate, edit, etc)
  */
  this.renderMode = function($$) {
    var mode = this.props.mode;
    var el = $$('div').addClass('se-mode');

    var iconEl = this.context.iconProvider.renderIcon($$, mode);
    if (iconEl) {
      el.append(iconEl);
    }
    return el;
  };
};

Tool.extend(AnnotationTool);
export default AnnotationTool;
<commit_msg>ES6 AnnotationTool.<commit_after>import Tool from '../packages/tools/Tool'

/*
 * Abstract class for annotation tools like StrongTool, EmphasisTool, LinkTool.
 *
 * @component
 */

class AnnotationTool extends Tool {

  render($$) {
    let el = super.render.call(this, $$)
    el.addClass('sm-annotation-tool')
    return el
  }

  renderButton($$) {
    let el = super.renderButton.call(this, $$)
    el.append(this.renderMode($$))
    return el
  }

  /*
    Renders a small hint for the mode (expand, truncate, edit, etc)
  */
  renderMode($$) {
    let mode = this.props.mode
    let el = $$('div').addClass('se-mode')

    let iconEl = this.context.iconProvider.renderIcon($$, mode)
    if (iconEl) {
      el.append(iconEl)
    }
    return el
  }
}

export default AnnotationTool
<|endoftext|>