<commit_before>
// shuffle for character bar

// function shuffle(o){
//     for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
//     return o;
// };
//charbarkeys = shuffle(charbarkeys);

// calculate totals for percentages, then set up charbar
// check whether character is set up in characters, else don't add

$(document).ready(function() {

	var charstotal = 0;
	var colorspans = "";
	var isonlinespans = '
 > Clients connected (filtered)

';

	$.get("/charinfo.json", function(chars) {

		var charbarkeys = Object.keys(chars);
		var charlistkeys = Object.keys(characters);

		for (var i = 0; i < charbarkeys.length; ++i) {
			try {
				var name = charbarkeys[i];
				var exists = characters[name].color;
				charstotal = charstotal + chars[charbarkeys[i]];
			} catch(e) {
				console.log("Error: " + e);
			}
		}
		for (var i = 0; i < charlistkeys.length; ++i) {
			var name = charlistkeys[i];
			if (chars[charlistkeys[i]] !== undefined) {
				var current = chars[charbarkeys[i]];
				var percent = (current / charstotal) * 100;
				try {
					uppername = name.replace(/^(\w)/g, function(a,x){ return a.replace(x,x.toUpperCase()); });
					uppername = uppername.replace(/\s(\w)/g, function(a,x){ return a.replace(x,x.toUpperCase()); });
					escapedname = name.replace(/[()/\s]/g, '');
					colorspans = colorspans + '';
					isonlinespans = isonlinespans + ' x '+ current + ''
					} catch(e) {
						console.log("Error: " + e);
					}
				}
		}

		$('#charbar').html(colorspans);
		$('#isonlineblock').html(isonlinespans);
			$(function(){
			   function slide_in(){
				  $('#charbar span').removeClass("slidein");
			   };
			   window.setTimeout( slide_in, 100 );
			});

		if($('input[name="picky"]').is(':checked')) {
				$('#isonlineblock .isonlinechar').hide();
				$('#isonlineblock .iofiltered').show();
				var pickySync = $('#picky-icon input[class="butty"]')
				for (i=0; i<pickySync.length; i++) {
					if($(pickySync[i]).is(':checked')) {
						$('#isonlineblock span[data-char="' + $(pickySync[i]).attr('name') + '"]').show();
					}
				}
			} else {
				$('#isonlineblock .isonlinechar').show();
				$('#isonlineblock .iofiltered').hide();
			}

	});
});<commit_msg>reduce opacity slightly<commit_after>
// shuffle for character bar

// function shuffle(o){
//     for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
//     return o;
// };
//charbarkeys = shuffle(charbarkeys);

// calculate totals for percentages, then set up charbar
// check whether character is set up in characters, else don't add

$(document).ready(function() {

	var charstotal = 0;
	var colorspans = "";
	var isonlinespans = '
 > Clients connected (filtered)

';

	$.get("/charinfo.json", function(chars) {

		var charbarkeys = Object.keys(chars);
		var charlistkeys = Object.keys(characters);

		for (var i = 0; i < charbarkeys.length; ++i) {
			try {
				var name = charbarkeys[i];
				var exists = characters[name].color;
				charstotal = charstotal + chars[charbarkeys[i]];
			} catch(e) {
				console.log("Error: " + e);
			}
		}
		for (var i = 0; i < charlistkeys.length; ++i) {
			var name = charlistkeys[i];
			if (chars[charlistkeys[i]] !== undefined) {
				var current = chars[charbarkeys[i]];
				var percent = (current / charstotal) * 100;
				try {
					uppername = name.replace(/^(\w)/g, function(a,x){ return a.replace(x,x.toUpperCase()); });
					uppername = uppername.replace(/\s(\w)/g, function(a,x){ return a.replace(x,x.toUpperCase()); });
					escapedname = name.replace(/[()/\s]/g, '');
					colorspans = colorspans + '';
					isonlinespans = isonlinespans + ' x '+ current + ''
					} catch(e) {
						console.log("Error: " + e);
					}
				}
		}

		$('#charbar').html(colorspans);
		$('#isonlineblock').html(isonlinespans);
			$(function(){
			   function slide_in(){
				  $('#charbar span').removeClass("slidein");
			   };
			   window.setTimeout( slide_in, 100 );
			});

		if($('input[name="picky"]').is(':checked')) {
				$('#isonlineblock .isonlinechar').hide();
				$('#isonlineblock .iofiltered').show();
				var pickySync = $('#picky-icon input[class="butty"]')
				for (i=0; i<pickySync.length; i++) {
					if($(pickySync[i]).is(':checked')) {
						$('#isonlineblock span[data-char="' + $(pickySync[i]).attr('name') + '"]').show();
					}
				}
			} else {
				$('#isonlineblock .isonlinechar').show();
				$('#isonlineblock .iofiltered').hide();
			}

	});
});<|endoftext|>


<commit_before>// Create a fake global `window` and `document` object:
require('./testdom')('');

// Replace BigComplicatedComponent.js with a stub component.
global.reactModulesToStub = [
  'BigComplicatedComponent.js'
];

var assert = require('assert');

describe('CheckboxWithLabel', function() {
  it('changes the text after click', function() {
    var React = require('react/addons');
    var CheckboxWithLabel = require('../CheckboxWithLabel');
    var TestUtils = React.addons.TestUtils;

    // Render a checkbox with label in the document
    var checkbox = TestUtils.renderIntoDocument(
      <CheckboxWithLabel labelOn="On" labelOff="Off" />
    );

    // Verify that it's Off by default
    var label = TestUtils.findRenderedDOMComponentWithTag(
      checkbox, 'label');
    assert.equal(label.getDOMNode().textContent, 'Off');

    // Simulate a click and verify that it is now On
    var input = TestUtils.findRenderedDOMComponentWithTag(
      checkbox, 'input');
    TestUtils.Simulate.change(input);
    assert.equal(label.getDOMNode().textContent, 'On');
  });
});
<commit_msg>chore(testing): fix module dependecies<commit_after>// Create a fake global `window` and `document` object:
require('./testdom')('');

// Replace BigComplicatedComponent.js with a stub component.
global.reactModulesToStub = [
  'BigComplicatedComponent.js'
];

var assert = require('assert');

describe('CheckboxWithLabel', function() {
  it('changes the text after click', function() {
    var React = require('react/addons');
    var CheckboxWithLabel = require('../src/CheckboxWithLabel');
    var TestUtils = React.addons.TestUtils;

    // Render a checkbox with label in the document
    var checkbox = TestUtils.renderIntoDocument(
      <CheckboxWithLabel labelOn="On" labelOff="Off" />
    );

    // Verify that it's Off by default
    var label = TestUtils.findRenderedDOMComponentWithTag(
      checkbox, 'label');
    assert.equal(label.getDOMNode().textContent, 'Off');

    // Simulate a click and verify that it is now On
    var input = TestUtils.findRenderedDOMComponentWithTag(
      checkbox, 'input');
    TestUtils.Simulate.change(input);
    assert.equal(label.getDOMNode().textContent, 'On');
  });
});
<|endoftext|>


<commit_before>(function(mod) {
  if (typeof exports == "object" && typeof module == "object") // CommonJS
    mod(require("../../lib/codemirror"));
  else if (typeof define == "function" && define.amd) // AMD
    define(["../../lib/codemirror"], mod);
  else // Plain browser env
    mod(CodeMirror);
})(function(CodeMirror) {
"use strict";

CodeMirror.defineMode('Objective-C', function(config) {

  var specialChars = /[+\-\/\\~<>=%|&?!;:.,^]/;

  var keywords = /\bclass\b|\bprivate\b|\bstatic\b|\bself\b|\bsuper\b|\bprotocol\b|\bproperty\b|\bprotocol\b|\bsynchronized\b|\bnonatomic\b|\bstrong\b|\bcopy\b|\bassign\b|\bselector\b|\bimplementation\b|\binterface\b|\bend\b|auto\b|\bbreak\b|\bcase\b|\bregister\b|\bcontinue\b|\breturn\b|\bdefault\b|\bdo\b|\bsizeof\b|\bentry\b|\bswitch\b|\bextern\b|\btypedef\b|\bunion\b|\bfor\b|\bgoto\b|\bwhile\b|\benum\b|\bvoid\b|\bYES\b|\bNO\b|\bnil\b|\bif\b|\belse/;

  var Context = function(tokenizer, parent) {
    this.next = tokenizer;
    this.parent = parent;
  };

  var Token = function(name, context, eos) {
    this.name = name;
    this.context = context;
    this.eos = eos;
  };

  var State = function() {
    this.context = new Context(next, null);
    this.expectVariable = true;
    this.indentation = 0;
    this.userIndentationDelta = 0;
  };

  State.prototype.userIndent = function(indentation) {
    this.userIndentationDelta = indentation > 0 ? (indentation / config.indentUnit - this.indentation) : 0;
  };

  var next = function(stream, context, state) {
    var token = new Token(null, context, false);
    var aChar = stream.next();

	if (aChar === '/') {
		if(stream.eat('*')) {
			token = nextBlockComment(stream, new Context(nextBlockComment, context));
			token.eos = true;
		} else if (stream.eat('/')) {
			token = nextLineComment(stream, new Context(nextLineComment, context));
		}
    } else if (aChar === '@') {
		if(stream.eat('"')) {
			token = nextString(stream, new Context(nextString, context));
		} else {
	        stream.eatWhile(specialChars);
	        token.name = 'operator';
	        token.eos = true;
	  	}
    } else if (aChar === '#') {
      if (stream.peek() === '\'') {
        stream.next();
        token = nextSymbol(stream, new Context(nextSymbol, context));
      } else {
        if (stream.eatWhile(/[^\n\/]/))
          token.name = 'string-2';
        else
          token.name = 'meta';
		  token.eos = true;
      }

    } else if (/[\[\]{}()]/.test(aChar)) {
		token.name = 'bracket';
		token.eos = true;
		if (aChar === '[') {
			state.indentation++;
		} else if (aChar === ']') {
			state.indentation = Math.max(0, state.indentation - 1);
		}

    } else if (specialChars.test(aChar)) {
      stream.eatWhile(specialChars);
	  if (aChar !== ';' && aChar !== ':' && aChar !== '.' && aChar !== ',')
      	token.name = 'operator';
      token.eos = true;

    } else if (/[\w_]/.test(aChar)) {
		stream.eatWhile(/[\w\d_]/);
		if(state.expectVariable) {
			if(keywords.test(stream.current())) {
				token.name = 'keyword';
				token.eos = true;
			} else {
				token.name = 'variable';
				if(stream.eat(/:/)) {
					token.name = 'null';
					token.eos = true;
				}
				if(stream.eat(/\(/) && token.name == 'variable') {
					stream.backUp(1);
					token.name = "def";
				}
			}
		} else {
			token.name = 'null';
		}
	} else {
      token.eos = state.expectVariable;
    }

    return token;
  };

  var nextLineComment = function(stream, context) {
    stream.eatWhile(/[^\n\/]/);
    return new Token('comment', context.parent, true);
  };

  var nextBlockComment = function(stream, context) {
    var maybeEnd = false, ch, ctx = context;
    while (ch = stream.next()) {
      if (ch == "/" && maybeEnd) {
		ctx = context.parent;
        break;
      }
      maybeEnd = (ch == "*");
    }
    return new Token('comment', ctx, true);
  };

  var nextString = function(stream, context) {
    stream.eatWhile(/[^"]/);
    return new Token('string', stream.eat('"') ? context.parent : context, false);
  };

  var nextSymbol = function(stream, context) {
    stream.eatWhile(/[^']/);
    return new Token('string-2', stream.eat('\'') ? context.parent : context, false);
  };

  return {
    startState: function() {
      return new State;
    },

    token: function(stream, state) {
      state.userIndent(stream.indentation());

      if (stream.eatSpace()) {
        return null;
      }

      var token = state.context.next(stream, state.context, state);
      state.context = token.context;
      state.expectVariable = token.eos;

      return token.name;
    },

    blankLine: function(state) {
      state.userIndent(0);
    },

    indent: function(state, textAfter) {
      var i = state.context.next === next && textAfter && textAfter.charAt(0) === ']' ? -1 : state.userIndentationDelta;
      return (state.indentation + i) * config.indentUnit;
    },

    electricChars: ']'
  };

});

CodeMirror.defineMIME('text/x-objc', {name: 'Objective-C'});

});
<commit_msg>Cleanup.<commit_after>(function(mod) {
  if (typeof exports == "object" && typeof module == "object") // CommonJS
    mod(require("../../lib/codemirror"));
  else if (typeof define == "function" && define.amd) // AMD
    define(["../../lib/codemirror"], mod);
  else // Plain browser env
    mod(CodeMirror);
})(function(CodeMirror) {
"use strict";

CodeMirror.defineMode('Objective-C', function(config) {

  var specialChars = /[+\-\/\\~<>=%|&?!;:.,^]/;

  var keywords = /\bclass\b|\bprivate\b|\bstatic\b|\bself\b|\bsuper\b|\bprotocol\b|\bproperty\b|\bprotocol\b|\bsynchronized\b|\bnonatomic\b|\bstrong\b|\bcopy\b|\bassign\b|\bselector\b|\bimplementation\b|\binterface\b|\bend\b|auto\b|\bbreak\b|\bcase\b|\bregister\b|\bcontinue\b|\breturn\b|\bdefault\b|\bdo\b|\bsizeof\b|\bentry\b|\bswitch\b|\bextern\b|\btypedef\b|\bunion\b|\bfor\b|\bgoto\b|\bwhile\b|\benum\b|\bvoid\b|\bYES\b|\bNO\b|\bnil\b|\bif\b|\belse/;

  var Context = function(tokenizer, parent) {
    this.next = tokenizer;
    this.parent = parent;
  };

  var Token = function(name, context, eos) {
    this.name = name;
    this.context = context;
    this.eos = eos;
  };

  var State = function() {
    this.context = new Context(next, null);
    this.expectVariable = true;
    this.indentation = 0;
    this.userIndentationDelta = 0;
  };

  State.prototype.userIndent = function(indentation) {
    this.userIndentationDelta = indentation > 0 ? (indentation / config.indentUnit - this.indentation) : 0;
  };

  var next = function(stream, context, state) {
    var token = new Token(null, context, false);
    var aChar = stream.next();

	if (aChar === '/') {
		if(stream.eat('*')) {
			token = nextBlockComment(stream, new Context(nextBlockComment, context));
			token.eos = true;
		} else if (stream.eat('/')) {
			token = nextLineComment(stream, new Context(nextLineComment, context));
		}
    } else if (aChar === '@') {
		if(stream.eat('"')) {
			token = nextString(stream, new Context(nextString, context));
		} else {
	        stream.eatWhile(specialChars);
	        token.name = 'operator';
	        token.eos = true;
	  	}
    } else if (aChar === '#') {
        if (stream.eatWhile(/[^\n\/]/))
          token.name = 'string-2';
        else
          token.name = 'meta';
		token.eos = true;
    } else if (/[\[\]{}()]/.test(aChar)) {
		token.name = 'bracket';
		token.eos = true;
		if (aChar === '[') {
			state.indentation++;
		} else if (aChar === ']') {
			state.indentation = Math.max(0, state.indentation - 1);
		}
    } else if (specialChars.test(aChar)) {
      stream.eatWhile(specialChars);
	  if (aChar !== ';' && aChar !== ':' && aChar !== '.' && aChar !== ',') token.name = 'operator';
      token.eos = true;
    } else if (/[\w_]/.test(aChar)) {
		stream.eatWhile(/[\w\d_]/);
		if(state.expectVariable) {
			if(keywords.test(stream.current())) {
				token.name = 'keyword';
				token.eos = true;
			} else {
				token.name = 'variable';
				if(stream.eat(/:/)) {
					token.name = 'null';
					token.eos = true;
				}
				if(stream.eat(/\(/) && token.name == 'variable') {
					stream.backUp(1);
					token.name = "def";
				}
			}
		} else {
			token.name = 'null';
		}
	}
    return token;
  };

  var nextLineComment = function(stream, context) {
    stream.eatWhile(/[^\n\/]/);
    return new Token('comment', context.parent, true);
  };

  var nextBlockComment = function(stream, context) {
    var maybeEnd = false, ch, ctx = context;
    while (ch = stream.next()) {
      if (ch == "/" && maybeEnd) {
		ctx = context.parent;
        break;
      }
      maybeEnd = (ch == "*");
    }
    return new Token('comment', ctx, true);
  };

  var nextString = function(stream, context) {
    stream.eatWhile(/[^"]/);
    return new Token('string', stream.eat('"') ? context.parent : context, false);
  };

  var nextSymbol = function(stream, context) {
    stream.eatWhile(/[^']/);
    return new Token('string-2', stream.eat('\'') ? context.parent : context, false);
  };

  return {
    startState: function() {
      return new State;
    },

    token: function(stream, state) {
      state.userIndent(stream.indentation());

      if (stream.eatSpace()) {
        return null;
      }

      var token = state.context.next(stream, state.context, state);
      state.context = token.context;
      state.expectVariable = token.eos;

      return token.name;
    },

    blankLine: function(state) {
      state.userIndent(0);
    },

    indent: function(state, textAfter) {
      var i = state.context.next === next && textAfter && textAfter.charAt(0) === ']' ? -1 : state.userIndentationDelta;
      return (state.indentation + i) * config.indentUnit;
    },

    electricChars: ']'
  };

});

CodeMirror.defineMIME('text/x-objc', {name: 'Objective-C'});

});
<|endoftext|>


<commit_before>(function($, Voer, document) {
    Voer.Materials = (function() {
        return {
            addFavorite : function (ele, params) {
                $.post('/ajax/add_favorite', params, function(data){
                    if (data.status) {
                        $('#voer-message-modal').find('.modal-title').html(data.message);
                        $('#voer-message-modal').modal('show');

                        $('#voer-message-modal').on('shown.bs.modal', function (e) {
                            window.setTimeout(function() {
                                $('#voer-message-modal').modal('hide');
                            }, 3000);
                        });

                        ele.html(data.favorite_count);
                    } else if (data.status === undefined) {
                        var currentUrl = window.location.pathname;
                        currentUrl = currentUrl.replace('\/', '');
                        window.location.href = '/user/login/?next=' + currentUrl;
                    }
                });
            }
        };
    })();

    Voer.Materials.run = function() {
        $(document).on('click', '.checkout-icon-favourite', function(){
            var btnSave = $(this);
            var mid = btnSave.attr('data-mid');
            var version = btnSave.attr('data-version');
            var csrfmiddlewaretoken = Voer.Helper.getCookie('csrftoken');

            Voer.Materials.addFavorite(btnSave, {mid: mid, version: version, csrfmiddlewaretoken: csrfmiddlewaretoken});
        });
    };
})(jQuery, window.Voer, window.document);<commit_msg>fixbug<commit_after>(function($, Voer, document) {
    Voer.Materials = (function() {
        return {
            addFavorite : function (ele, params) {
                $.post('/ajax/add_favorite', params, function(data){
                    if (data.status) {
                        $('#voer-message-modal').find('.modal-title').html(data.message);
                        $('#voer-message-modal').modal('show');

                        $('#voer-message-modal').on('shown.bs.modal', function (e) {
                            window.setTimeout(function() {
                                $('#voer-message-modal').modal('hide');
                            }, 3000);
                        });

                        ele.html(data.favorite_count);
                    } else if (data.status === undefined) {
                        var currentUrl = window.location.pathname;
                        window.location.href = '/user/login/?next=' + currentUrl;
                    }
                });
            }
        };
    })();

    Voer.Materials.run = function() {
        $(document).on('click', '.checkout-icon-favourite', function(){
            var btnSave = $(this);
            var mid = btnSave.attr('data-mid');
            var version = btnSave.attr('data-version');
            var csrfmiddlewaretoken = Voer.Helper.getCookie('csrftoken');

            Voer.Materials.addFavorite(btnSave, {mid: mid, version: version, csrfmiddlewaretoken: csrfmiddlewaretoken});
        });
    };
})(jQuery, window.Voer, window.document);<|endoftext|>


<commit_before>var gulp = require("gulp");
var open = require("../");

gulp.task("simple", function(){
  gulp.src("./index.html")
  .pipe(open());
});

gulp.task("template", function(){
  gulp.src("./second.html")
  .pipe(open("<%file.path%>"));
});

gulp.task("open", function(){
  var options = {
    app: "google-chrome"
  };
  gulp.src("./*.html")
  .pipe(open("file://<%= file.path %>", options));
});

gulp.task("url", function(){
  var options = {
    url: "http://localhost:3000",
    app: "firefox"
  };
  gulp.src("./")
  .pipe(open("", options));
});

gulp.task("default", function(){
  gulp.run("simple", "template", "open", "url");
});<commit_msg>Updateexamples<commit_after>var gulp = require("gulp");
var open = require("../");

gulp.task("simple", function(){
  gulp.src("./index.html")
  .pipe(open());
});

gulp.task("template", function(){
  gulp.src("./second.html")
  .pipe(open("<%file.path%>"));
});

gulp.task("open", function(){
  var options = {
    app: "google-chrome"
  };
  gulp.src("./*.html")
  .pipe(open("file://<%= file.path %>", options));
});

gulp.task("url", function(){
  var options = {
    url: "http://localhost:3000",
    app: "firefox"
  };
  gulp.src("./stubFile.html") // An actual file must be specified or gulp will overlook the task.
  .pipe(open("", options));
});

gulp.task("default", function(){
  gulp.run("simple", "template", "open", "url");
});<|endoftext|>


<commit_before>/*
  KittyBot
  Shows random Kitty pictures and gifs.
  See this code in action, by visiting @KittyBot on Telegram!
*/

var TeleBot = require('../');

// Create a new bot
var bot = new TeleBot({
  token: '-PASTEYOURTELEGRAMBOTAPITOKENHERE-',
  sleep: 1000,
});

// Great API for this
var API = 'https://thecatapi.com/api/images/get?format=src&type=';

// Command keyboard
var keys = bot.keyboard([
  ['/kitty', '/kittygif']
], { resize: true, once: false });

// On every text message
bot.on('text', function(msg) {
  console.log('[text] ' + msg.chat.id + ' ' + msg.text);
});

// On command "start" and "help"
bot.on(['/start', '/help'], function(msg) {
  return bot.sendMessage(msg.chat.id,
    '😺 Use commands: /kitty, /kittygif and /about', { markup: keys }
  );
});

// On command "about"
bot.on('/about', function(msg) {
  var text = '😽 This bot created by using TeleBot library ' +
    'https://github.com/kosmodrey/telebot Go check the source code!';
  return bot.sendMessage(msg.chat.id, text);
});

// On command "kitty" and "kittygif"
bot.on(['/kitty', '/kittygif'], function(msg) {
  var id = msg.chat.id, cmd = this.cmd[0];
  // Picture or gif?
  var promise = cmd == '/kitty' ?
    // Send downloaded data to user
    bot.sendPhoto(id, API + 'jpg', { name: 'kitty.jpg' }) :
    bot.sendDocument(id, API + 'gif', { name: 'kitty.gif' });
  // Send "uploading photo" action
  bot.sendAction(id, 'upload_photo');
  return promise.catch(function(error) {
    // Send an error
    bot.sendMessage(id, '😿 An error (' + error + ') occurred, try again.');
  });
});

// Start getting updates
bot.connect();
<commit_msg>Fix typo<commit_after>/*
  KittyBot
  Shows random Kitty pictures and gifs.
  See this code in action, by visiting @KittyBot on Telegram!
*/

var TeleBot = require('../');

// Create a new bot
var bot = new TeleBot({
  token: '-PASTEYOURTELEGRAMBOTAPITOKENHERE-',
  sleep: 1000,
});

// Great API for this
var API = 'https://thecatapi.com/api/images/get?format=src&type=';

// Command keyboard
var keys = bot.keyboard([
  ['/kitty', '/kittygif']
], { resize: true, once: false });

// On every text message
bot.on('text', function(msg) {
  console.log('[text] ' + msg.chat.id + ' ' + msg.text);
});

// On command "start" and "help"
bot.on(['/start', '/help'], function(msg) {
  return bot.sendMessage(msg.chat.id,
    '😺 Use commands: /kitty, /kittygif and /about', { markup: keys }
  );
});

// On command "about"
bot.on('/about', function(msg) {
  var text = '😽 This bot is powered by TeleBot library ' +
    'https://github.com/kosmodrey/telebot Go check the source code!';
  return bot.sendMessage(msg.chat.id, text);
});

// On command "kitty" and "kittygif"
bot.on(['/kitty', '/kittygif'], function(msg) {
  var id = msg.chat.id, cmd = this.cmd[0];
  // Picture or gif?
  var promise = cmd == '/kitty' ?
    // Send downloaded data to user
    bot.sendPhoto(id, API + 'jpg', { name: 'kitty.jpg' }) :
    bot.sendDocument(id, API + 'gif', { name: 'kitty.gif' });
  // Send "uploading photo" action
  bot.sendAction(id, 'upload_photo');
  return promise.catch(function(error) {
    // Send an error
    bot.sendMessage(id, '😿 An error (' + error + ') occurred, try again.');
  });
});

// Start getting updates
bot.connect();
<|endoftext|>


<commit_before>/*

    extensions.js

    additional primitives for SNAP!

    written by Jens Mönig

    Copyright (C) 2021 by Jens Mönig

    This file is part of Snap!.

    Snap! is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as
    published by the Free Software Foundation, either version 3 of
    the License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/

// Global settings /////////////////////////////////////////////////////

/*global modules, List, StageMorph, Costume, SpeechSynthesisUtterance*/

modules.extensions = '2021-June-15';

// Global stuff

var SnapExtensions = new Map();

/*
    SnapExtensions is a global dictionary of named functions which appear
    in the drop-down menus of the hidden extension "primitive" blocks sorted
    alphabetically.

    naming conventions
    ------------------
    domain-prefix_function-name(parameter-list)
    example: 'lst_sort(list, fn)'

    - domain-prefix:    3-letter lowercase identifier followee by an underscore
               e.g.:    err_, lst_, txt_, dta_, map_, tts_, xhr_, geo_

    - function-name: short, single word if possible, lowercase
    - parameter-list: comma separated names or type indicators

    function semantics
    ------------------
    - functions are called by the "primitive" blocks with any arguments provided
    - "this" refers to the current snap object (sprite or stage) at call-time
    - a reference to the current process is always passed as last argument
*/

// errors & exceptions (err_):

SnapExtensions.set(
    'err_error(msg)',
    function (msg) {
        throw new Error(msg);
    }
);

// list utils (lst_):

SnapExtensions.set(
    'lst_sort(list, fn)',
    function (data, fn, proc) {
        return proc.reportAtomicSort(data, fn);
    }
);

SnapExtensions.set(
    'lst_linked(list)',
    function (data) {
        return data.isLinked;
    }
);

// text utils (txt_):

SnapExtensions.set(
    'txt_lowercase(txt)',
    function (txt) {
        return txt.toLowerCase();
    }
);

// data sciene & frequency distribution analysis (dta_):

SnapExtensions.set(
    'dta_analyze(list)',
    function (list) {
        var dict = new Map(),
            result = [],
            data = list.itemsArray(),
            len = data.length,
            i;
        for (i = 0; i < len; i += 1) {
            if (dict.has(data[i])) {
                dict.set(data[i], dict.get(data[i]) + 1);
            } else {
                dict.set(data[i], 1);
            }
        }
        dict.forEach(function (value, key) {
            result.push(new List([key, value]));
        });
        return new List(result);
    }
);

SnapExtensions.set(
    'dta_group(list, fn)',
    function (data, fn, proc) {
        return proc.reportAtomicGroup(data, fn);
    }
);

// World map (map_):

SnapExtensions.set(
    'map_zoom',
    function () {
        return this.parentThatIsA(StageMorph).worldMap.zoom;
    }
);

SnapExtensions.set(
    'map_zoom(n)',
    function (num) {
        this.parentThatIsA(StageMorph).worldMap.setZoom(num);
    }
);

SnapExtensions.set(
    'map_lon(x)',
    function (x) {
        return this.parentThatIsA(StageMorph).worldMap.lonFromSnapX(x);
    }
);

SnapExtensions.set(
    'map_lat(y)',
    function (y) {
        return this.parentThatIsA(StageMorph).worldMap.latFromSnapY(y);
    }
);

SnapExtensions.set(
    'map_view(lon, lat)',
    function (lon, lat) {
        this.parentThatIsA(StageMorph).worldMap.setView(lon, lat);
    }
);

SnapExtensions.set(
    'map_y(lat)',
    function (lat) {
        return this.parentThatIsA(StageMorph).worldMap.snapYfromLat(lat);
    }
);

SnapExtensions.set(
    'map_x(lon)',
    function (lon) {
        return this.parentThatIsA(StageMorph).worldMap.snapXfromLon(lon);
    }
);

SnapExtensions.set(
    'map_pan(x, y)',
    function (x, y) {
        this.parentThatIsA(StageMorph).worldMap.panBy(x, y);
    }
);

SnapExtensions.set(
    'map_dist(lat1, lon1, lat2, lon2)',
    function (lat1, lon1, lat2, lon2) {
        return this.parentThatIsA(StageMorph).worldMap.distanceInKm(
            lat1,
            lon1,
            lat2,
            lon2
        );
    }
);

SnapExtensions.set(
    'map_update',
    function () {
        var stage = this.parentThatIsA(StageMorph);
        stage.worldMap.extent = stage.dimensions;
        stage.worldMap.render();
    }
);

SnapExtensions.set(
    'map_loaded',
    function () {
        return !this.parentThatIsA(StageMorph).worldMap.loading;
    }
);

SnapExtensions.set(
    'map_costume',
    function () {
        return new Costume(
            this.parentThatIsA(StageMorph).worldMap.canvas,
            'map'
        );
    }
);

SnapExtensions.set(
    'map_style(name)',
    function (name) {
        this.parentThatIsA(StageMorph).worldMap.setHost(name);
    }
);

// text-to-speech (tts_):

SnapExtensions.set(
    'tts_speak(txt, lang, pitch, rate)',
    function (msg, accent, pitch, rate) {
        var utter = new SpeechSynthesisUtterance(msg),
            isDone = false;
        utter.lang = accent;
        utter.pitch = pitch;
        utter.rate = rate;
        utter.onend = () => isDone = true;
        window.speechSynthesis.speak(utter);
        return () => isDone;
    }
);

// XHR:

SnapExtensions.set(
    'xhr_request(mth, url, dta, hdrs)',
    function (method, url, data, headers, proc) {
        var response, i, header;
        if (!proc.httpRequest) {
            proc.httpRequest = new XMLHttpRequest();
            proc.httpRequest.open(method, url, true);
            proc.assertType(headers, 'list');
            for (i = 1; i <= headers.length(); i += 1) {
                header = headers.at(i);
                proc.assertType(header, 'list');
                proc.httpRequest.setRequestHeader(
                    header.at(1),
                    header.at(2)
                );
            }
            proc.httpRequest.send(data || null);
        } else if (proc.httpRequest.readyState === 4) {
            response = proc.httpRequest.responseText;
            proc.httpRequest = null;
            return response;
        }
        proc.pushContext('doYield');
        proc.pushContext();
    }
);

// Geo-location (geo_)

SnapExtensions.set(
    'geo_location(acc?)',
    function (includeAccuracy) {
        var crd = new List(),
            myself = this,
            options = {
                enableHighAccuracy: true,
                timeout: 5000,
                maximumAge: 0
            };

        function success(pos) {
            crd = new List([
                pos.coords.latitude,
                pos.coords.longitude
            ]);
            if (includeAccuracy) {
                crd.add(pos.coords.accuracy);
            }
        }

        function error(err) {
            crd = new List([37.872099, -122.257852]);
            myself.inform('Warning:\nGeolocation failed.');
        }

        navigator.geolocation.getCurrentPosition(
            success,
            error,
            options
        );
        return () => crd;
    }
);

<commit_msg>Update extensions.js<commit_after>/*

    extensions.js

    additional primitives for SNAP!

    written by Jens Mönig

    Copyright (C) 2021 by Jens Mönig

    This file is part of Snap!.

    Snap! is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as
    published by the Free Software Foundation, either version 3 of
    the License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/

// Global settings /////////////////////////////////////////////////////

/*global modules, List, StageMorph, Costume, SpeechSynthesisUtterance,
IDE_Morph, CamSnapshotDialogMorph*/

modules.extensions = '2021-June-15';

// Global stuff

var SnapExtensions = new Map();

/*
    SnapExtensions is a global dictionary of named functions which appear
    in the drop-down menus of the hidden extension "primitive" blocks sorted
    alphabetically.

    naming conventions
    ------------------
    domain-prefix_function-name(parameter-list)
    example: 'lst_sort(list, fn)'

    - domain-prefix:    3-letter lowercase identifier followee by an underscore
               e.g.:    err_, lst_, txt_, dta_, map_, tts_, xhr_, geo_, mda_

    - function-name: short, single word if possible, lowercase
    - parameter-list: comma separated names or type indicators

    function semantics
    ------------------
    - functions are called by the "primitive" blocks with any arguments provided
    - "this" refers to the current snap object (sprite or stage) at call-time
    - a reference to the current process is always passed as last argument
*/

// errors & exceptions (err_):

SnapExtensions.set(
    'err_error(msg)',
    function (msg) {
        throw new Error(msg);
    }
);

// list utils (lst_):

SnapExtensions.set(
    'lst_sort(list, fn)',
    function (data, fn, proc) {
        return proc.reportAtomicSort(data, fn);
    }
);

SnapExtensions.set(
    'lst_linked(list)',
    function (data) {
        return data.isLinked;
    }
);

// text utils (txt_):

SnapExtensions.set(
    'txt_lowercase(txt)',
    function (txt) {
        return txt.toLowerCase();
    }
);

// data sciene & frequency distribution analysis (dta_):

SnapExtensions.set(
    'dta_analyze(list)',
    function (list) {
        var dict = new Map(),
            result = [],
            data = list.itemsArray(),
            len = data.length,
            i;
        for (i = 0; i < len; i += 1) {
            if (dict.has(data[i])) {
                dict.set(data[i], dict.get(data[i]) + 1);
            } else {
                dict.set(data[i], 1);
            }
        }
        dict.forEach(function (value, key) {
            result.push(new List([key, value]));
        });
        return new List(result);
    }
);

SnapExtensions.set(
    'dta_group(list, fn)',
    function (data, fn, proc) {
        return proc.reportAtomicGroup(data, fn);
    }
);

// World map (map_):

SnapExtensions.set(
    'map_zoom',
    function () {
        return this.parentThatIsA(StageMorph).worldMap.zoom;
    }
);

SnapExtensions.set(
    'map_zoom(n)',
    function (num) {
        this.parentThatIsA(StageMorph).worldMap.setZoom(num);
    }
);

SnapExtensions.set(
    'map_lon(x)',
    function (x) {
        return this.parentThatIsA(StageMorph).worldMap.lonFromSnapX(x);
    }
);

SnapExtensions.set(
    'map_lat(y)',
    function (y) {
        return this.parentThatIsA(StageMorph).worldMap.latFromSnapY(y);
    }
);

SnapExtensions.set(
    'map_view(lon, lat)',
    function (lon, lat) {
        this.parentThatIsA(StageMorph).worldMap.setView(lon, lat);
    }
);

SnapExtensions.set(
    'map_y(lat)',
    function (lat) {
        return this.parentThatIsA(StageMorph).worldMap.snapYfromLat(lat);
    }
);

SnapExtensions.set(
    'map_x(lon)',
    function (lon) {
        return this.parentThatIsA(StageMorph).worldMap.snapXfromLon(lon);
    }
);

SnapExtensions.set(
    'map_pan(x, y)',
    function (x, y) {
        this.parentThatIsA(StageMorph).worldMap.panBy(x, y);
    }
);

SnapExtensions.set(
    'map_dist(lat1, lon1, lat2, lon2)',
    function (lat1, lon1, lat2, lon2) {
        return this.parentThatIsA(StageMorph).worldMap.distanceInKm(
            lat1,
            lon1,
            lat2,
            lon2
        );
    }
);

SnapExtensions.set(
    'map_update',
    function () {
        var stage = this.parentThatIsA(StageMorph);
        stage.worldMap.extent = stage.dimensions;
        stage.worldMap.render();
    }
);

SnapExtensions.set(
    'map_loaded',
    function () {
        return !this.parentThatIsA(StageMorph).worldMap.loading;
    }
);

SnapExtensions.set(
    'map_costume',
    function () {
        return new Costume(
            this.parentThatIsA(StageMorph).worldMap.canvas,
            'map'
        );
    }
);

SnapExtensions.set(
    'map_style(name)',
    function (name) {
        this.parentThatIsA(StageMorph).worldMap.setHost(name);
    }
);

// text-to-speech (tts_):

SnapExtensions.set(
    'tts_speak(txt, lang, pitch, rate)',
    function (msg, accent, pitch, rate) {
        var utter = new SpeechSynthesisUtterance(msg),
            isDone = false;
        utter.lang = accent;
        utter.pitch = pitch;
        utter.rate = rate;
        utter.onend = () => isDone = true;
        window.speechSynthesis.speak(utter);
        return () => isDone;
    }
);

// XHR:

SnapExtensions.set(
    'xhr_request(mth, url, dta, hdrs)',
    function (method, url, data, headers, proc) {
        var response, i, header;
        if (!proc.httpRequest) {
            proc.httpRequest = new XMLHttpRequest();
            proc.httpRequest.open(method, url, true);
            proc.assertType(headers, 'list');
            for (i = 1; i <= headers.length(); i += 1) {
                header = headers.at(i);
                proc.assertType(header, 'list');
                proc.httpRequest.setRequestHeader(
                    header.at(1),
                    header.at(2)
                );
            }
            proc.httpRequest.send(data || null);
        } else if (proc.httpRequest.readyState === 4) {
            response = proc.httpRequest.responseText;
            proc.httpRequest = null;
            return response;
        }
        proc.pushContext('doYield');
        proc.pushContext();
    }
);

// Geo-location (geo_)

SnapExtensions.set(
    'geo_location(acc?)',
    function (includeAccuracy) {
        var crd = new List(),
            myself = this,
            options = {
                enableHighAccuracy: true,
                timeout: 5000,
                maximumAge: 0
            };

        function success(pos) {
            crd = new List([
                pos.coords.latitude,
                pos.coords.longitude
            ]);
            if (includeAccuracy) {
                crd.add(pos.coords.accuracy);
            }
        }

        function error(err) {
            crd = new List([37.872099, -122.257852]);
            myself.inform('Warning:\nGeolocation failed.');
        }

        navigator.geolocation.getCurrentPosition(
            success,
            error,
            options
        );
        return () => crd;
    }
);

// MediaComp (mda_)

SnapExtensions.set(
    'mda_snap',
    function () {
        var camDialog,
            result = false;
        camDialog = new CamSnapshotDialogMorph(
            this.parentThatIsA(IDE_Morph),
            this,
            () => result = null,
            function (costume) {
                result = costume;
                this.close();
            }
        );
        camDialog.key = 'camera';
        camDialog.popUp(this.world());
        return () => result;
    }
);
<|endoftext|>


<commit_before>/*
 * jquery.coords
 * https://github.com/ducksboard/gridster.js
 *
 * Copyright (c) 2012 ducksboard
 * Licensed under the MIT licenses.
 */

;(function($, window, document, undefined){
    /**
    * Creates objects with coordinates (x1, y1, x2, y2, cx, cy, width, height)
    * to simulate DOM elements on the screen.
    * Coords is used by Gridster to create a faux grid with any DOM element can
    * collide.
    *
    * @class Coords
    * @param {HTMLElement|Object} obj The jQuery HTMLElement or a object with: left,
    * top, width and height properties.
    * @return {Object} Coords instance.
    * @constructor
    */
    function Coords(obj) {
        if (obj[0] && $.isPlainObject(obj[0])) {
            this.data = obj[0];
        }else {
            this.el = obj;
        }

        this.isCoords = true;
        this.coords = {};
        this.init();
        return this;
    }

    var fn = Coords.prototype;

    fn.init = function(){
        this.set();
        this.original_coords = this.get();
    };

    fn.set = function(update, not_update_offsets) {
        var el = this.el;

        if (el && !update) {
            this.data = el.offset();
            this.data.width = el.width();
            this.data.height = el.height();
        }

        if (el && update && !not_update_offsets) {
            var offset = el.offset();
            this.data.top = offset.top;
            this.data.left = offset.left;
        }

        var d = this.data;

        this.coords.x1 = d.left;
        this.coords.y1 = d.top;
        this.coords.x2 = d.left + d.width;
        this.coords.y2 = d.top + d.height;
        this.coords.cx = d.left + (d.width / 2);
        this.coords.cy = d.top + (d.height / 2);
        this.coords.width  = d.width;
        this.coords.height = d.height;
        this.coords.el  = el || false ;

        return this;
    };

    fn.update = function(data){
        if (!data && !this.el) {
            return this;
        }

        if (data) {
            var new_data = $.extend({}, this.data, data);
            this.data = new_data;
            return this.set(true, true);
        }

        this.set(true);
        return this;
    };

    fn.get = function(){
        return this.coords;
    };

    fn.destroy = function() {
        this.el.removeData('coords');
        delete this.el;
    };

    //jQuery adapter
    $.fn.coords = function() {
        if (this.data('coords') ) {
            return this.data('coords');
        }

        var ins = new Coords(this, arguments[0]);
        this.data('coords', ins);
        return ins;
    };

}(jQuery, window, document));
<commit_msg>feat(coords): allow both (left/x1) and (top/y1) attr keys<commit_after>/*
 * jquery.coords
 * https://github.com/ducksboard/gridster.js
 *
 * Copyright (c) 2012 ducksboard
 * Licensed under the MIT licenses.
 */

;(function($, window, document, undefined){
    /**
    * Creates objects with coordinates (x1, y1, x2, y2, cx, cy, width, height)
    * to simulate DOM elements on the screen.
    * Coords is used by Gridster to create a faux grid with any DOM element can
    * collide.
    *
    * @class Coords
    * @param {HTMLElement|Object} obj The jQuery HTMLElement or a object with: left,
    * top, width and height properties.
    * @return {Object} Coords instance.
    * @constructor
    */
    function Coords(obj) {
        if (obj[0] && $.isPlainObject(obj[0])) {
            this.data = obj[0];
        }else {
            this.el = obj;
        }

        this.isCoords = true;
        this.coords = {};
        this.init();
        return this;
    }

    var fn = Coords.prototype;

    fn.init = function(){
        this.set();
        this.original_coords = this.get();
    };

    fn.set = function(update, not_update_offsets) {
        var el = this.el;

        if (el && !update) {
            this.data = el.offset();
            this.data.width = el.width();
            this.data.height = el.height();
        }

        if (el && update && !not_update_offsets) {
            var offset = el.offset();
            this.data.top = offset.top;
            this.data.left = offset.left;
        }

        var d = this.data;

        typeof d.left === 'undefined' && (d.left = d.x1);
        typeof d.top === 'undefined' && (d.top = d.y1);

        this.coords.x1 = d.left;
        this.coords.y1 = d.top;
        this.coords.x2 = d.left + d.width;
        this.coords.y2 = d.top + d.height;
        this.coords.cx = d.left + (d.width / 2);
        this.coords.cy = d.top + (d.height / 2);
        this.coords.width  = d.width;
        this.coords.height = d.height;
        this.coords.el  = el || false ;

        return this;
    };

    fn.update = function(data){
        if (!data && !this.el) {
            return this;
        }

        if (data) {
            var new_data = $.extend({}, this.data, data);
            this.data = new_data;
            return this.set(true, true);
        }

        this.set(true);
        return this;
    };

    fn.get = function(){
        return this.coords;
    };

    fn.destroy = function() {
        this.el.removeData('coords');
        delete this.el;
    };

    //jQuery adapter
    $.fn.coords = function() {
        if (this.data('coords') ) {
            return this.data('coords');
        }

        var ins = new Coords(this, arguments[0]);
        this.data('coords', ins);
        return ins;
    };

}(jQuery, window, document));
<|endoftext|>


<commit_before>
;(function ($, window, document, undefined) {

	var pluginName = 'Dotter',
		defaults = {};
	function Dotter(elem, options){
		this.elem = elem;
		this.options = $.extend({}, defaults, options);
		this._defaults = defaults;
		this._name = pluginName;

		this.init();
		this.execute();
	}

	Dotter.prototype.init = function(){
	    this._originString = this.elem.text().toString();
	};

    Dotter.prototype.execute = function(){
		var fontSize = this.elem.css('font-size');
		var div = $('').appendTo('body');
		var words = this._originString.split('');
		var dotLength = getDotLength(div);
		var currentLength = [];
		var i=0;
		while(div.width()+(dotLength*3) <= this.elem.width() && i<words.length){
			div.append(words[i]);
			currentLength.push(words[i]);
			i++;
		}
		if(div.width()+(dotLength*3) > this.elem.width()){
			currentLength = currentLength.splice(0, (currentLength.length)-1);
		}
		var theString;
		if(i === words.length)
			theString = currentLength.join('');
		else
			theString = currentLength.join('') + '...';
		this.elem.html(theString);
		div.remove();
		return this.elem;
		function getDotLength(div){
			div.html('.');
			var length = div.width();
			div.html('');
			return length;
		}
	}

	$.fn[pluginName] = function ( options ) {
		var self = this;
		return this.each(function () {
			if (!$.data(this, 'plugin_' + pluginName)) {
				$.data(this, 'plugin_' + pluginName, new Dotter( self, options ));
			}
			else{
			    $.data(this, 'plugin_' + pluginName).execute();
			}
		});
	};

})(jQuery, window, document);
<commit_msg>turns span tag to hidden<commit_after>
;(function ($, window, document, undefined) {

	var pluginName = 'Dotter',
		defaults = {};
	function Dotter(elem, options){
		this.elem = elem;
		this.options = $.extend({}, defaults, options);
		this._defaults = defaults;
		this._name = pluginName;

		this.init();
		this.execute();
	}

	Dotter.prototype.init = function(){
	    this._originString = this.elem.text().toString();
	};

    Dotter.prototype.execute = function(){
		var fontSize = this.elem.css('font-size');
		var div = $('').appendTo('body');
		var words = this._originString.split('');
		var dotLength = getDotLength(div);
		var currentLength = [];
		var i=0;
		while(div.width()+(dotLength*3) < this.elem.width() && i<words.length){
			div.append(words[i]);
			currentLength.push(words[i]);
			i++;
		}
		if(div.width()+(dotLength*3) > this.elem.width()){
			currentLength = currentLength.splice(0, (currentLength.length)-1);
		}
		var theString;
		if(i === words.length)
			theString = currentLength.join('');
		else
			theString = currentLength.join('') + '...';
		this.elem.html(theString);
		div.remove();
		return this.elem;
		function getDotLength(div){
			div.html('.');
			var length = div.width();
			div.html('');
			return length;
		}
	}

	$.fn[pluginName] = function ( options ) {
		var self = this;
		return this.each(function () {
			if (!$.data(this, 'plugin_' + pluginName)) {
				$.data(this, 'plugin_' + pluginName, new Dotter( self, options ));
			}
			else{
			    $.data(this, 'plugin_' + pluginName).execute();
			}
		});
	};

})(jQuery, window, document);<|endoftext|>


<commit_before>(function($, undefined) {

$.fn.geokbd = function(options) {
	var
	isOn,
	inputs = $([]),
	switchers = $([]),
	defaults = {
		on: true,
		hotkey: '~'
	},
	settings = (typeof options === 'object' ? $.extend({}, defaults, options) : defaults);

	// first come up with affected set of input elements
	this.each(function() {
		var $this = $(this);
		if ($this.is(':text, textarea')) {
			inputs = inputs.add($this);
		} else if ($this.is('form')) {
			inputs = inputs.add($this.find(':text, textarea'));
		} else if ($this.is(':checkbox')) {
			switchers = switchers.add($this);
		} else if ($this.hasClass('switchButton')){
			switchers = switchers.add($this);
		}
	});

	function toggleLang() {
      $('.switch').toggleClass('active-kbd');
      isOn = !isOn;
      $('.switch').prop('checked', isOn);
	}

	function enableLang() {
		isOn = true
		$('.switch').prop('checked', isOn);
		$('.switch').removeClass('active-kbd');
	}

	function disableLang() {
		isOn = false
		$('.switch').prop('checked', isOn);
		$('.switch').addClass('active-kbd');
	}

	function getIsOn() {
		return isOn
	}

  switchers
    .click(function() {
    	toggleLang();
    });

  switchers.enableLang 	= enableLang
  switchers.disableLang = disableLang
  switchers.getIsOn 		= getIsOn

	toggleLang(isOn = false);

	$(document).keypress(function(e) {
		if (e.target.type === 'password' || e.target.type === 'email') {return;}

		if ( $(e.target).attr('maxlength') !== undefined ) {
			var limit = parseInt($(e.target).attr('maxlength'));
			var currentLength = $(e.target).val().length;
			if (currentLength >= limit) {return;}
		}

		var ch = String.fromCharCode(e.which), kach;
		if (settings.hotkey === ch) {
			toggleLang();
			e.preventDefault();
		}

		if (!isOn) {
			return;
		}

		if (!$(e.target).is('input')) {return;}

		kach = translateToKa.call(ch);

		if (ch !== kach) {
			if (navigator.appName.indexOf("Internet Explorer")!=-1) {
				window.event.keyCode = kach.charCodeAt(0);
			} else {
				pasteTo.call(kach, e.target);
				e.preventDefault();
			}
        }
	});

	function translateToKa() {
		var index, chr, text = [], symbols = "abgdevzTiklmnopJrstufqRySCcZwWxjh";

		for (var i = 0; i < this.length; i++) {
			chr = this.substr(i, 1);
			if ((index = symbols.indexOf(chr)) >= 0) {
				text.push(String.fromCharCode(index + 4304));
			} else {
				text.push(chr);
			}
		}
		return text.join('');
	}

	function pasteTo(field) {
		field.focus();
		if (document.selection) {
			var range = document.selection.createRange();
			if (range) {
				range.text = this;
			}
		} else if (field.selectionStart !== undefined) {
			var scroll = field.scrollTop, start = field.selectionStart, end = field.selectionEnd;
			var value = field.value.substr(0, start) + this + field.value.substr(end, field.value.length);
			field.value = value;
			field.scrollTop = scroll;
			field.setSelectionRange(start + this.length, start + this.length);
		} else {
			field.value += this;
			field.setSelectionRange(field.value.length, field.value.length);
		}
	}

	return switchers
};

}(jQuery));
<commit_msg>Add keyboard switching for `<commit_after>(function($, undefined) {

$.fn.geokbd = function(options) {
	var
	isOn,
	inputs = $([]),
	switchers = $([]),
	defaults = {
		on: true,
		hotkeys: ['~', '`']
	},
	settings = (typeof options === 'object' ? $.extend({}, defaults, options) : defaults);

	// first come up with affected set of input elements
	this.each(function() {
		var $this = $(this);
		if ($this.is(':text, textarea')) {
			inputs = inputs.add($this);
		} else if ($this.is('form')) {
			inputs = inputs.add($this.find(':text, textarea'));
		} else if ($this.is(':checkbox')) {
			switchers = switchers.add($this);
		} else if ($this.hasClass('switchButton')){
			switchers = switchers.add($this);
		}
	});

	function toggleLang() {
      $('.switch').toggleClass('active-kbd');
      isOn = !isOn;
      $('.switch').prop('checked', isOn);
	}

	function enableLang() {
		isOn = true
		$('.switch').prop('checked', isOn);
		$('.switch').removeClass('active-kbd');
	}

	function disableLang() {
		isOn = false
		$('.switch').prop('checked', isOn);
		$('.switch').addClass('active-kbd');
	}

	function getIsOn() {
		return isOn
	}

  switchers
    .click(function() {
    	toggleLang();
    });

  switchers.enableLang 	= enableLang
  switchers.disableLang = disableLang
  switchers.getIsOn 		= getIsOn

	toggleLang(isOn = false);

	$(document).keypress(function(e) {
		if (e.target.type === 'password' || e.target.type === 'email') {return;}

		if ( $(e.target).attr('maxlength') !== undefined ) {
			var limit = parseInt($(e.target).attr('maxlength'));
			var currentLength = $(e.target).val().length;
			if (currentLength >= limit) {return;}
		}

		var ch = String.fromCharCode(e.which), kach;
		if (settings.hotkeys.indexOf(ch) != -1) {
			toggleLang();
			e.preventDefault();
		}

		if (!isOn) {
			return;
		}

		if (!$(e.target).is('input')) {return;}

		kach = translateToKa.call(ch);

		if (ch !== kach) {
			if (navigator.appName.indexOf("Internet Explorer")!=-1) {
				window.event.keyCode = kach.charCodeAt(0);
			} else {
				pasteTo.call(kach, e.target);
				e.preventDefault();
			}
        }
	});

	function translateToKa() {
		var index, chr, text = [], symbols = "abgdevzTiklmnopJrstufqRySCcZwWxjh";

		for (var i = 0; i < this.length; i++) {
			chr = this.substr(i, 1);
			if ((index = symbols.indexOf(chr)) >= 0) {
				text.push(String.fromCharCode(index + 4304));
			} else {
				text.push(chr);
			}
		}
		return text.join('');
	}

	function pasteTo(field) {
		field.focus();
		if (document.selection) {
			var range = document.selection.createRange();
			if (range) {
				range.text = this;
			}
		} else if (field.selectionStart !== undefined) {
			var scroll = field.scrollTop, start = field.selectionStart, end = field.selectionEnd;
			var value = field.value.substr(0, start) + this + field.value.substr(end, field.value.length);
			field.value = value;
			field.scrollTop = scroll;
			field.setSelectionRange(start + this.length, start + this.length);
		} else {
			field.value += this;
			field.setSelectionRange(field.value.length, field.value.length);
		}
	}

	return switchers
};

}(jQuery));
<|endoftext|>


<commit_before>
const dayOfWeek = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
const month = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];

module.exports = {

    getFormatDateString: function(updatedAt) {

        let difference = (new Date() - updatedAt) / 1000 / 60;// in minutes

        if (difference >= 60) {

            difference = difference / 60;

            if (difference >= 24) {
                return dayOfWeek[updatedAt.getDay()] + ' ' + month[updatedAt.getMonth()] + ' ' + updatedAt.getDate() + ' ' + updatedAt.getFullYear();
            }

            return Number.parseInt(difference) + ' hr';
        }

        return Number.parseInt(difference) + ' min';

    }
}
<commit_msg>removed some extra whitespace<commit_after>
const dayOfWeek = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
const month = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];

module.exports = {

    getFormatDateString: function(updatedAt) {

        let difference = (new Date() - updatedAt) / 1000 / 60;// in minutes

        if (difference >= 60) {
            difference = difference / 60;
            if (difference >= 24) {
                return dayOfWeek[updatedAt.getDay()] + ' ' + month[updatedAt.getMonth()] + ' ' + updatedAt.getDate() + ' ' + updatedAt.getFullYear();
            }
            return Number.parseInt(difference) + ' hr';
        }

        return Number.parseInt(difference) + ' min';
    }
}
<|endoftext|>


<commit_before>// Load wetfish basic
var $ = require('wetfish-basic');
require('dragondrop');

// Load other stuff
var extend = require('extend');
var helper = require('./helper');
var TextMagick = require('../plugins/textmagick');

// Helper functions for creating elements on the page
var create =
{
    element: function(element, options)
    {
        // Does the element already exist on the page?
        if(!document.contains(element))
        {
            // Add the new element to the workspace
            $('.workspace').el[0].appendChild(element);
        }

        // Check if audio / video specific options need to be added
        if(options.type == 'audio' || options.type == 'video')
        {
            $(element).attr('volume', options.volume);
            $(element).attr('autoplay', options.autoplay);
            $(element).attr('loop', options.loop);
            $(element).attr('controls', options.controls);
        }

        // Add license information if provided
        $(element).data('desc', options.desc);
        $(element).data('license', options.license);

        // Make sure it's on the top layer
        $(element).style({'z-index': helper.layers + 1});

        // Centered option automatically centers the new element in the middle of the page
        if(options.centered)
        {
            $(element).style({
                'position': 'absolute',
                'left': ($(window).width() / 2 - $(element).width() / 2) + 'px',
                'top': ($(window).height() / 2 - $(element).height() / 2) + 'px',
            });
        }

        // If a specific position was passed
        if(options.position)
        {
            $(element).style({
                'position': 'absolute',
                'left': options.position.left + 'px',
                'top': options.position.top + 'px',
            });
        }

        // Duration option will remove the element after a certain amount of time
        if(options.duration)
        {
            setTimeout(function()
            {
                $(element).remove();
            }, options.duration);
        }

        $(element).dragondrop();

        // Ensure the element being dragged is always on top
        $(element).on('dragstart', function()
        {
            helper.layers++;
            $(this).style({'z-index': helper.layers});

            // Trigger an event on the workspace
            $('.workspace').trigger('start', element);
        });

        $(element).on('dragend', function()
        {
            // Trigger an event on the workspace
            $('.workspace').trigger('dragend', element);
        });
    },

    image: function(options)
    {
        var image;
        var defaults =
        {
            type: 'image',
            centered: true,
        };

        // Deep combine user given options with defaults
        options = extend(true, defaults, options);

        // Check if any old save data was provided in the options
        if(options.id && options.saved)
        {
            var id = options.id;
            var saved = JSON.parse(options.saved);
            delete options.id;
            delete options.saved;

            // Combine old save data with new form data
            options = extend(true, saved, options);

            // And now check if the saved element ID actually exists on the page
            if($('#' + id).el.length)
            {
                image = $('#' + id).el[0];
            }
        }

        image = image || document.createElement('img');
        $(image).attr('src', options.url);

        create.element(image, options);
        return {element: image, options: options};
    },

    audio: function(options)
    {
        var audio;
        var defaults =
        {
            type: 'audio',
            volume: 1,
            autoplay: true,
            loop: true,
            controls: true,
            centered: true,
        };

        // Deep combine user given options with defaults
        options = extend(true, defaults, options);

        // Check if any old save data was provided in the options
        if(options.id && options.saved)
        {
            var id = options.id;
            var saved = JSON.parse(options.saved);
            delete options.id;
            delete options.saved;

            // Combine old save data with new form data
            options = extend(true, saved, options);

            // And now check if the saved element ID actually exists on the page
            if($('#' + id).el.length)
            {
                audio = $('#' + id).el[0];
            }
        }

        audio = audio || document.createElement('audio');
        $(audio).attr('src', options.url);

        create.element(audio, options);
        return {element: audio, options: options};
    },

    video: function(options)
    {
        var video;
        var defaults =
        {
            type: 'video',
            volume: 1,
            autoplay: true,
            loop: true,
            controls: true,
            centered: true,
        };

        // Deep combine user given options with defaults
        options = extend(true, defaults, options);

        // Check if any old save data was provided in the options
        if(options.id && options.saved)
        {
            var id = options.id;
            var saved = JSON.parse(options.saved);
            delete options.id;
            delete options.saved;

            // Combine old save data with new form data
            options = extend(true, saved, options);

            // And now check if the saved element ID actually exists on the page
            if($('#' + id).el.length)
            {
                video = $('#' + id).el[0];
            }
        }

        video = video || document.createElement('video');
        $(video).attr('src', options.url);

        create.element(video, options);
        return {element: video, options: options};
    },

    text: function(options)
    {
        var text;
        var element;
        var defaults =
        {
            type: 'text',
            centered: true,
        };

        // Deep combine user given options with defaults
        options = extend(true, defaults, options);

        // Check if any old save data was provided in the options
        if(options.id && options.saved)
        {
            var id = options.id;
            var saved = JSON.parse(options.saved);
            delete options.id;
            delete options.saved;

            // Combine old save data with new form data
            options = extend(true, saved, options);

            // And now check if the saved element ID actually exists on the page
            if($('#' + id).el.length)
            {
                element = $('#' + id).el[0];
                text = element.textmagick;

                text.setText(options.text);
                text.setOptions(options);
            }
        }
        else
        {
            text = new TextMagick(options.text, options);
            element = text.getElement();

            create.element(element, options);
        }

        text.resize();

        return {element: element, text: text, options: options};
    },

    background: function(options)
    {
        if(options.background)
        {
            $('body').style({'background': options.background});
        }

        if(options.image)
        {
            $('body').style({'background-image': 'url("'+options.image+'")'});
        }

        if(options.repeat)
        {
            $('body').style({'background-repeat': options.repeat});
        }

        if(options.position)
        {
            $('body').style({'background-position': options.position});
        }
    }
};

module.exports = create;
<commit_msg>Prevent dragging new elements while in tool mode<commit_after>// Load wetfish basic
var $ = require('wetfish-basic');
require('dragondrop');

// Load other stuff
var extend = require('extend');
var helper = require('./helper');
var TextMagick = require('../plugins/textmagick');

// Helper functions for creating elements on the page
var create =
{
    element: function(element, options)
    {
        // Does the element already exist on the page?
        if(!document.contains(element))
        {
            // Add the new element to the workspace
            $('.workspace').el[0].appendChild(element);
        }

        // Check if audio / video specific options need to be added
        if(options.type == 'audio' || options.type == 'video')
        {
            $(element).attr('volume', options.volume);
            $(element).attr('autoplay', options.autoplay);
            $(element).attr('loop', options.loop);
            $(element).attr('controls', options.controls);
        }

        // Add license information if provided
        $(element).data('desc', options.desc);
        $(element).data('license', options.license);

        // Make sure it's on the top layer
        $(element).style({'z-index': helper.layers + 1});

        // Centered option automatically centers the new element in the middle of the page
        if(options.centered)
        {
            $(element).style({
                'position': 'absolute',
                'left': ($(window).width() / 2 - $(element).width() / 2) + 'px',
                'top': ($(window).height() / 2 - $(element).height() / 2) + 'px',
            });
        }

        // If a specific position was passed
        if(options.position)
        {
            $(element).style({
                'position': 'absolute',
                'left': options.position.left + 'px',
                'top': options.position.top + 'px',
            });
        }

        // Duration option will remove the element after a certain amount of time
        if(options.duration)
        {
            setTimeout(function()
            {
                $(element).remove();
            }, options.duration);
        }

        $(element).dragondrop();

        // Add disabled class if we're currently in tool mode, to prevent users from dragging newly created elements while still using a tool
        if($('body').hasClass('tool-mode'))
        {
            $(element).addClass('disabled');
        }

        // Ensure the element being dragged is always on top
        $(element).on('dragstart', function()
        {
            helper.layers++;
            $(this).style({'z-index': helper.layers});

            // Trigger an event on the workspace
            $('.workspace').trigger('start', element);
        });

        $(element).on('dragend', function()
        {
            // Trigger an event on the workspace
            $('.workspace').trigger('dragend', element);
        });
    },

    image: function(options)
    {
        var image;
        var defaults =
        {
            type: 'image',
            centered: true,
        };

        // Deep combine user given options with defaults
        options = extend(true, defaults, options);

        // Check if any old save data was provided in the options
        if(options.id && options.saved)
        {
            var id = options.id;
            var saved = JSON.parse(options.saved);
            delete options.id;
            delete options.saved;

            // Combine old save data with new form data
            options = extend(true, saved, options);

            // And now check if the saved element ID actually exists on the page
            if($('#' + id).el.length)
            {
                image = $('#' + id).el[0];
            }
        }

        image = image || document.createElement('img');
        $(image).attr('src', options.url);

        create.element(image, options);
        return {element: image, options: options};
    },

    audio: function(options)
    {
        var audio;
        var defaults =
        {
            type: 'audio',
            volume: 1,
            autoplay: true,
            loop: true,
            controls: true,
            centered: true,
        };

        // Deep combine user given options with defaults
        options = extend(true, defaults, options);

        // Check if any old save data was provided in the options
        if(options.id && options.saved)
        {
            var id = options.id;
            var saved = JSON.parse(options.saved);
            delete options.id;
            delete options.saved;

            // Combine old save data with new form data
            options = extend(true, saved, options);

            // And now check if the saved element ID actually exists on the page
            if($('#' + id).el.length)
            {
                audio = $('#' + id).el[0];
            }
        }

        audio = audio || document.createElement('audio');
        $(audio).attr('src', options.url);

        create.element(audio, options);
        return {element: audio, options: options};
    },

    video: function(options)
    {
        var video;
        var defaults =
        {
            type: 'video',
            volume: 1,
            autoplay: true,
            loop: true,
            controls: true,
            centered: true,
        };

        // Deep combine user given options with defaults
        options = extend(true, defaults, options);

        // Check if any old save data was provided in the options
        if(options.id && options.saved)
        {
            var id = options.id;
            var saved = JSON.parse(options.saved);
            delete options.id;
            delete options.saved;

            // Combine old save data with new form data
            options = extend(true, saved, options);

            // And now check if the saved element ID actually exists on the page
            if($('#' + id).el.length)
            {
                video = $('#' + id).el[0];
            }
        }

        video = video || document.createElement('video');
        $(video).attr('src', options.url);

        create.element(video, options);
        return {element: video, options: options};
    },

    text: function(options)
    {
        var text;
        var element;
        var defaults =
        {
            type: 'text',
            centered: true,
        };

        // Deep combine user given options with defaults
        options = extend(true, defaults, options);

        // Check if any old save data was provided in the options
        if(options.id && options.saved)
        {
            var id = options.id;
            var saved = JSON.parse(options.saved);
            delete options.id;
            delete options.saved;

            // Combine old save data with new form data
            options = extend(true, saved, options);

            // And now check if the saved element ID actually exists on the page
            if($('#' + id).el.length)
            {
                element = $('#' + id).el[0];
                text = element.textmagick;

                text.setText(options.text);
                text.setOptions(options);
            }
        }
        else
        {
            text = new TextMagick(options.text, options);
            element = text.getElement();

            create.element(element, options);
        }

        text.resize();

        return {element: element, text: text, options: options};
    },

    background: function(options)
    {
        if(options.background)
        {
            $('body').style({'background': options.background});
        }

        if(options.image)
        {
            $('body').style({'background-image': 'url("'+options.image+'")'});
        }

        if(options.repeat)
        {
            $('body').style({'background-repeat': options.repeat});
        }

        if(options.position)
        {
            $('body').style({'background-position': options.position});
        }
    }
};

module.exports = create;
<|endoftext|>


<commit_before>'use strict';

const OPTIONS_PAGE = 'html/options.html';

/**
 * @exports newtaboverride
 */
const newtaboverride = {
  parseVersion (version) {
    const x = version.split('.');
    const major = parseInt(x[0]) || 0;
    const minor = parseInt(x[1]) || 0;
    const patch = parseInt(x[2]) || 0;

    return { major, minor, patch }
  },

  /**
   * Fired when the extension is first installed, when the extension is updated to a new version or when the browser
   * is updated to a new version. We want to show a badge on our toolbar icon when the extension is first installed
   * or. If the legacy version of this add-on was installed we want to open the options page.
   *
   * @param {runtime.OnInstalledReason} details - details.reason contains the reason why this event is being dispatched
   *
   * @returns {void}
   */
  onInstalledHandler (details) {
    if (details.reason === 'install') {
      browser.browserAction.setBadgeText({ text : '★' });
    }

    if (details.reason === 'update') {
      if (newtaboverride.parseVersion(details.previousVersion).major < 7) {
        browser.runtime.openOptionsPage();
        browser.storage.local.set({show_compat_notice : true});
      }
      else {
        browser.storage.local.set({show_compat_notice : false});
      }
    }
  },

  /**
   * Fired whenever the user changes the input, after the user has started interacting with the add-on by entering
   * its keyword in the address bar and then pressing the space key.
   *
   * @param {string} input - user input in the address bar, not including the add-on's keyword itself or the space
   *                 after the keyword

   *                 Supported value: settings
   * @param {function} suggest - a callback function that the event listener can call to supply suggestions for the
   *                   address bar's drop-down list
   *
   * @returns {void}
   */
  showOmniboxSuggestions (input, suggest) {
    const availableCommands = ['settings'];
    const suggestions = [];

    for (const command of availableCommands) {
      if (command.indexOf(input) !== -1) {
        suggestions.push({
          content : command,
          description : browser.i18n.getMessage('omnibox_command_' + command)
        });
      }

      if (suggestions.length === 0) {
        suggestions.push({
          content : 'settings',
          description : browser.i18n.getMessage('omnibox_command_settings')
        });
      }
    }

    suggest(suggestions);
  },

  /**
   * Fired when the user has selected one of the suggestions the add-on has added to the address bar's drop-down list.
   *
   * @param {string} input - this is the value that the user selected
   *
   * @returns {void}
   */
  callOmniboxAction (input) {
    switch (input) {
      case 'settings':
      default:
        newtaboverride.openUserInterfaceInCurrentTab();
    }
  },

  /**
   * Fired when the toolbar icon is clicked. This method is used to open the user interface in a new tab or to switch
   * to the tab with the user interface if the user interface is already opened.
   *
   * @returns {void}
   */
  openUserInterface () {
    const url = browser.extension.getURL(OPTIONS_PAGE);

    browser.browserAction.setBadgeText({ text : '' });
    browser.tabs.query({}, (tabs) => {
      let tabId = null;

      for (const tab of tabs) {
        if (tab.url === url) {
          tabId = tab.id;
          break;
        }
      }

      if (tabId) {
        browser.tabs.update(tabId, { active : true });
      }
      else {
        browser.tabs.create({ url });
      }
    });
  },

  /**
   * This method is used to open the user interface in the current tab. It's used for the omnibox suggestions.
   *
   * @returns {void}
   */
  openUserInterfaceInCurrentTab () {
    browser.tabs.update(null, { url : browser.extension.getURL(OPTIONS_PAGE) });
  }
};

browser.browserAction.onClicked.addListener(newtaboverride.openUserInterface);
browser.omnibox.onInputChanged.addListener(newtaboverride.showOmniboxSuggestions);
browser.omnibox.onInputEntered.addListener(newtaboverride.callOmniboxAction);
browser.omnibox.setDefaultSuggestion({ description : browser.i18n.getMessage('omnibox_default_description') });
browser.runtime.onInstalled.addListener(newtaboverride.onInstalledHandler);
<commit_msg>added whitespaces<commit_after>'use strict';

const OPTIONS_PAGE = 'html/options.html';

/**
 * @exports newtaboverride
 */
const newtaboverride = {
  parseVersion (version) {
    const x = version.split('.');
    const major = parseInt(x[0]) || 0;
    const minor = parseInt(x[1]) || 0;
    const patch = parseInt(x[2]) || 0;

    return { major, minor, patch }
  },

  /**
   * Fired when the extension is first installed, when the extension is updated to a new version or when the browser
   * is updated to a new version. We want to show a badge on our toolbar icon when the extension is first installed
   * or. If the legacy version of this add-on was installed we want to open the options page.
   *
   * @param {runtime.OnInstalledReason} details - details.reason contains the reason why this event is being dispatched
   *
   * @returns {void}
   */
  onInstalledHandler (details) {
    if (details.reason === 'install') {
      browser.browserAction.setBadgeText({ text : '★' });
    }

    if (details.reason === 'update') {
      if (newtaboverride.parseVersion(details.previousVersion).major < 7) {
        browser.runtime.openOptionsPage();
        browser.storage.local.set({ show_compat_notice : true });
      }
      else {
        browser.storage.local.set({ show_compat_notice : false });
      }
    }
  },

  /**
   * Fired whenever the user changes the input, after the user has started interacting with the add-on by entering
   * its keyword in the address bar and then pressing the space key.
   *
   * @param {string} input - user input in the address bar, not including the add-on's keyword itself or the space
   *                 after the keyword

   *                 Supported value: settings
   * @param {function} suggest - a callback function that the event listener can call to supply suggestions for the
   *                   address bar's drop-down list
   *
   * @returns {void}
   */
  showOmniboxSuggestions (input, suggest) {
    const availableCommands = ['settings'];
    const suggestions = [];

    for (const command of availableCommands) {
      if (command.indexOf(input) !== -1) {
        suggestions.push({
          content : command,
          description : browser.i18n.getMessage('omnibox_command_' + command)
        });
      }

      if (suggestions.length === 0) {
        suggestions.push({
          content : 'settings',
          description : browser.i18n.getMessage('omnibox_command_settings')
        });
      }
    }

    suggest(suggestions);
  },

  /**
   * Fired when the user has selected one of the suggestions the add-on has added to the address bar's drop-down list.
   *
   * @param {string} input - this is the value that the user selected
   *
   * @returns {void}
   */
  callOmniboxAction (input) {
    switch (input) {
      case 'settings':
      default:
        newtaboverride.openUserInterfaceInCurrentTab();
    }
  },

  /**
   * Fired when the toolbar icon is clicked. This method is used to open the user interface in a new tab or to switch
   * to the tab with the user interface if the user interface is already opened.
   *
   * @returns {void}
   */
  openUserInterface () {
    const url = browser.extension.getURL(OPTIONS_PAGE);

    browser.browserAction.setBadgeText({ text : '' });
    browser.tabs.query({}, (tabs) => {
      let tabId = null;

      for (const tab of tabs) {
        if (tab.url === url) {
          tabId = tab.id;
          break;
        }
      }

      if (tabId) {
        browser.tabs.update(tabId, { active : true });
      }
      else {
        browser.tabs.create({ url });
      }
    });
  },

  /**
   * This method is used to open the user interface in the current tab. It's used for the omnibox suggestions.
   *
   * @returns {void}
   */
  openUserInterfaceInCurrentTab () {
    browser.tabs.update(null, { url : browser.extension.getURL(OPTIONS_PAGE) });
  }
};

browser.browserAction.onClicked.addListener(newtaboverride.openUserInterface);
browser.omnibox.onInputChanged.addListener(newtaboverride.showOmniboxSuggestions);
browser.omnibox.onInputEntered.addListener(newtaboverride.callOmniboxAction);
browser.omnibox.setDefaultSuggestion({ description : browser.i18n.getMessage('omnibox_default_description') });
browser.runtime.onInstalled.addListener(newtaboverride.onInstalledHandler);
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types'
import Helmet from 'react-helmet'
import { useStaticQuery, graphql } from 'gatsby';

import humanize from 'humanize-plus';

function SEO({ description, meta, title, type, tweet, image, readingTime, words}) {
  const { site } = useStaticQuery(
    graphql`
      query {
        site {
          siteMetadata {
            defaultTitle
            description
            author
            siteUrl
          }
        }
      }
    `
  )

  const lang = 'en';

  const seo = {
    title: title || site.siteMetadata.defaultTitle,
    metaDescription: description || site.siteMetadata.description,
    pageType: type || `website`,
  }

  if (typeof(image.medium) !== 'undefined') {
    const image_url = `${site.siteMetadata.siteUrl}${image.medium}`;

    meta.push({name: `og:image`, content: image_url });
    meta.push({ name: `twitter:image`, content: image_url});
  }

  if (readingTime > 0) {
    const rounded_time = Math.ceil(readingTime) || 0;

    meta.push({name: `twitter:label1`, content: `Reading Time`});
    meta.push({name: `twitter:data1`, content: `${rounded_time} minutes`});
  }

  if (words > 0) {
    const humanised_words = humanize.compactInteger(words, 1) || 0;

    meta.push({name: `twitter:label2`, content: `Words`});
    meta.push({name: `twitter:data2`, content: `${humanised_words}`});
  }

  return (
    <Helmet
      htmlAttributes={{
        lang,
      }}
      title={seo.title}
      titleTemplate={`%s | ${site.siteMetadata.defaultTitle}`}
      meta={[
        {
          name: `description`,
          content: seo.metaDescription,
        },
        {
          property: `og:title`,
          content: seo.title,
        },
        {
          property: `og:description`,
          content: seo.metaDescription,
        },
        {
          property: `og:type`,
          content: seo.pageType,
        },
        {
          name: `twitter:card`,
          content: `summary_large_image`,
        },
        {
          name: `twitter:creator`,
          content: `@ajfisher`,
        },
        {
          name: `twitter:site`,
          content: `@ajfisher`,
        },
        {
          name: `twitter:title`,
          content: seo.title,
        },
        {
          name: `twitter:description`,
          content: tweet || seo.metaDescription,
        },
      ].concat(meta)}
    />
  )
}

SEO.defaultProps = {
  lang: `en`,
  meta: [],
  description: ``,
  tweet: ``,
  image: ``,
  readingTime: 0,
  words: 0
}

SEO.propTypes = {
  description: PropTypes.string,
  lang: PropTypes.string,
  meta: PropTypes.arrayOf(PropTypes.object),
  title: PropTypes.string.isRequired,
  readingTime: PropTypes.number,
  words: PropTypes.number
}

export default SEO
<commit_msg>fix: resolved meta tag issues closes #40<commit_after>import React from 'react';
import PropTypes from 'prop-types'
import Helmet from 'react-helmet'
import { useStaticQuery, graphql } from 'gatsby';

import humanize from 'humanize-plus';

function SEO({ description, meta, title, type, tweet, image, readingTime, words}) {
  const { site } = useStaticQuery(
    graphql`
      query {
        site {
          siteMetadata {
            defaultTitle
            description
            author
            siteUrl
          }
        }
      }
    `
  )

  const lang = 'en';

  const seo = {
    title: title || site.siteMetadata.defaultTitle,
    metaDescription: description || site.siteMetadata.description,
    pageType: type || `website`,
  }

  const card_meta = [];

  if (typeof(image.medium) !== 'undefined') {
    const image_url = `${site.siteMetadata.siteUrl}${image.medium}`;

    card_meta.push({name: `og:image`, content: image_url });
    card_meta.push({ name: `twitter:image`, content: image_url});
  }

  if (readingTime > 0) {
    const rounded_time = Math.ceil(readingTime) || 0;

    card_meta.push({name: `twitter:label1`, content: `Reading Time`});
    card_meta.push({name: `twitter:data1`, content: `${rounded_time} minutes`});
  }

  if (words > 0) {
    const humanised_words = humanize.compactInteger(words, 1) || 0;

    card_meta.push({name: `twitter:label2`, content: `Words`});
    card_meta.push({name: `twitter:data2`, content: `${humanised_words}`});
  }

  return (
    <Helmet
      htmlAttributes={{
        lang,
      }}
      title={seo.title}
      titleTemplate={`%s | ${site.siteMetadata.defaultTitle}`}
      meta={[
        {
          name: `description`,
          content: seo.metaDescription,
        },
        {
          property: `og:title`,
          content: seo.title,
        },
        {
          property: `og:description`,
          content: seo.metaDescription,
        },
        {
          property: `og:type`,
          content: seo.pageType,
        },
        {
          name: `twitter:card`,
          content: `summary_large_image`,
        },
        {
          name: `twitter:creator`,
          content: `@ajfisher`,
        },
        {
          name: `twitter:site`,
          content: `@ajfisher`,
        },
        {
          name: `twitter:title`,
          content: seo.title,
        },
        {
          name: `twitter:description`,
          content: tweet || seo.metaDescription,
        },
      ].concat(meta).concat(card_meta)}
    />
  )
}

SEO.defaultProps = {
  lang: `en`,
  meta: [],
  description: ``,
  tweet: ``,
  image: ``,
  readingTime: 0,
  words: 0
}

SEO.propTypes = {
  description: PropTypes.string,
  lang: PropTypes.string,
  meta: PropTypes.arrayOf(PropTypes.object),
  title: PropTypes.string.isRequired,
  readingTime: PropTypes.number,
  words: PropTypes.number
}

export default SEO
<|endoftext|>