<commit_before>/*
 Preferences Library

 Usage:
   var value = window['piro.sakura.ne.jp'].prefs.getPref('my.extension.pref');
   window['piro.sakura.ne.jp'].prefs.setPref('my.extension.pref', true);
   window['piro.sakura.ne.jp'].prefs.clearPref('my.extension.pref');
   var listener = {
         domains : [
           'browser.tabs',
           'extensions.someextension'
         ],
         observe : function(aSubject, aTopic, aData)
         {
           if (aTopic != 'nsPref:changed') return;
           var value = window['piro.sakura.ne.jp'].prefs.getPref(aData);
         }
       };
   window['piro.sakura.ne.jp'].prefs.addPrefListener(listener);
   window['piro.sakura.ne.jp'].prefs.removePrefListener(listener);

 license: The MIT License, Copyright (c) 2009-2010 YUKI "Piro" Hiroshi
   http://github.com/piroor/fxaddonlibs/blob/master/license.txt
 original:
   http://github.com/piroor/fxaddonlibs/blob/master/prefs.js
   http://github.com/piroor/fxaddonlibs/blob/master/prefs.test.js
*/

/* To work as a JS Code Module  */
if (typeof window == 'undefined' ||
	(window && typeof window.constructor == 'function')) {
	this.EXPORTED_SYMBOLS = ['prefs'];

	// If namespace.jsm is available, export symbols to the shared namespace.
	// See: http://github.com/piroor/fxaddonlibs/blob/master/namespace.jsm
	try {
		let ns = {};
		Components.utils.import('resource://my-modules/namespace.jsm', ns);
		/* var */ window = ns.getNamespaceFor('piro.sakura.ne.jp');
	}
	catch(e) {
		window = {};
	}
}

(function() {
	const currentRevision = 8;

	if (!('piro.sakura.ne.jp' in window)) window['piro.sakura.ne.jp'] = {};

	var loadedRevision = 'prefs' in window['piro.sakura.ne.jp'] ?
			window['piro.sakura.ne.jp'].prefs.revision :
			0 ;
	if (loadedRevision && loadedRevision > currentRevision) {
		return;
	}

	const Cc = Components.classes;
	const Ci = Components.interfaces;

	window['piro.sakura.ne.jp'].prefs = {
		revision : currentRevision,

		Prefs : Cc['@mozilla.org/preferences;1']
					.getService(Ci.nsIPrefBranch)
					.QueryInterface(Ci.nsIPrefBranch2),

		DefaultPrefs : Cc['@mozilla.org/preferences-service;1']
					.getService(Ci.nsIPrefService)
					.getDefaultBranch(null),

		getPref : function(aPrefstring, aInterface, aBranch)
		{
			if (!aInterface || aInterface instanceof Ci.nsIPrefBranch)
				[aBranch, aInterface] = [aInterface, aBranch];

			aBranch = aBranch || this.Prefs;

			var type = aBranch.getPrefType(aPrefstring);
			if (type == aBranch.PREF_INVALID)
				return null;

			if (aInterface)
				return aBranch.getComplexValue(aPrefstring, aInterface);

			switch (type)
			{
				case aBranch.PREF_STRING:
					return decodeURIComponent(escape(aBranch.getCharPref(aPrefstring)));

				case aBranch.PREF_INT:
					return aBranch.getIntPref(aPrefstring);

				case aBranch.PREF_BOOL:
					return aBranch.getBoolPref(aPrefstring);

				case aBranch.PREF_INVALID:
				default:
					return null;
			}
		},

		getDefaultPref : function(aPrefstring, aInterface)
		{
			return this.getPref(aPrefstring, this.DefaultPrefs, aInterface);
		},

		setPref : function(aPrefstring, aNewValue, aBranch)
		{
			aBranch = aBranch || this.Prefs;
			switch (typeof aNewValue)
			{
				case 'string':
					return aBranch.setCharPref(aPrefstring, unescape(encodeURIComponent(aNewValue)));

				case 'number':
					return aBranch.setIntPref(aPrefstring, parseInt(aNewValue));

				default:
					return aBranch.setBoolPref(aPrefstring, !!aNewValue);
			}
		},

		setDefaultPref : function(aPrefstring, aNewValue)
		{
			return this.setPref(aPrefstring, aNewValue, this.DefaultPrefs);
		},

		clearPref : function(aPrefstring)
		{
			if (this.Prefs.prefHasUserValue(aPrefstring))
				this.Prefs.clearUserPref(aPrefstring);
		},

		getDescendant : function(aRoot, aBranch)
		{
			aBranch = aBranch || this.Prefs;
			return aBranch.getChildList(aRoot, {}).sort();
		},

		getChildren : function(aRoot, aBranch)
		{
			return this.getDescendant(aRoot, aBranch)
					.filter(function(aPrefstring) {
						var name = aPrefstring.replace(aRoot, '');
						if (name.charAt(0) == '.')
							name = name.substring(1);
						return name.indexOf('.') < 0;
					});
		},

		addPrefListener : function(aObserver)
		{
			var domains = ('domains' in aObserver) ? aObserver.domains : [aObserver.domain] ;
			try {
				for each (var domain in domains)
					this.Prefs.addObserver(domain, aObserver, false);
			}
			catch(e) {
			}
		},

		removePrefListener : function(aObserver)
		{
			var domains = ('domains' in aObserver) ? aObserver.domains : [aObserver.domain] ;
			try {
				for each (var domain in domains)
					this.Prefs.removeObserver(domain, aObserver, false);
			}
			catch(e) {
			}
		}
	};
})();

if (window != this) { // work as a JS Code Module
	this.prefs = window['piro.sakura.ne.jp'].prefs;
}
<commit_msg>Update library<commit_after>/*
 Preferences Library

 Usage:
   var value = window['piro.sakura.ne.jp'].prefs.getPref('my.extension.pref');
   window['piro.sakura.ne.jp'].prefs.setPref('my.extension.pref', true);
   window['piro.sakura.ne.jp'].prefs.clearPref('my.extension.pref');
   var listener = {
         domains : [
           'browser.tabs',
           'extensions.someextension'
         ],
         observe : function(aSubject, aTopic, aData)
         {
           if (aTopic != 'nsPref:changed') return;
           var value = window['piro.sakura.ne.jp'].prefs.getPref(aData);
         }
       };
   window['piro.sakura.ne.jp'].prefs.addPrefListener(listener);
   window['piro.sakura.ne.jp'].prefs.removePrefListener(listener);

 license: The MIT License, Copyright (c) 2009-2013 YUKI "Piro" Hiroshi
 original:
   http://github.com/piroor/fxaddonlib-prefs
*/

/* To work as a JS Code Module  */
if (typeof window == 'undefined' ||
	(window && typeof window.constructor == 'function')) {
	this.EXPORTED_SYMBOLS = ['prefs'];

	// If namespace.jsm is available, export symbols to the shared namespace.
	// See: http://github.com/piroor/fxaddonlibs/blob/master/namespace.jsm
	try {
		let ns = {};
		Components.utils.import('resource://my-modules/namespace.jsm', ns);
		/* var */ window = ns.getNamespaceFor('piro.sakura.ne.jp');
	}
	catch(e) {
		window = {};
	}
}

(function() {
	const currentRevision = 13;

	if (!('piro.sakura.ne.jp' in window)) window['piro.sakura.ne.jp'] = {};

	var loadedRevision = 'prefs' in window['piro.sakura.ne.jp'] ?
			window['piro.sakura.ne.jp'].prefs.revision :
			0 ;
	if (loadedRevision && loadedRevision > currentRevision) {
		return;
	}

	const Cc = Components.classes;
	const Ci = Components.interfaces;

	window['piro.sakura.ne.jp'].prefs = {
		revision : currentRevision,

		Prefs : Cc['@mozilla.org/preferences;1']
					.getService(Ci.nsIPrefBranch)
					.QueryInterface(Ci.nsIPrefBranch2),

		DefaultPrefs : Cc['@mozilla.org/preferences-service;1']
					.getService(Ci.nsIPrefService)
					.getDefaultBranch(null),

		getPref : function(aPrefstring, aInterface, aBranch)
		{
			if (!aInterface || aInterface instanceof Ci.nsIPrefBranch)
				[aBranch, aInterface] = [aInterface, aBranch];

			aBranch = aBranch || this.Prefs;

			var type = aBranch.getPrefType(aPrefstring);
			if (type == aBranch.PREF_INVALID)
				return null;

			if (aInterface)
				return aBranch.getComplexValue(aPrefstring, aInterface);

			try {
				switch (type)
				{
					case aBranch.PREF_STRING:
						return decodeURIComponent(escape(aBranch.getCharPref(aPrefstring)));

					case aBranch.PREF_INT:
						return aBranch.getIntPref(aPrefstring);

					case aBranch.PREF_BOOL:
						return aBranch.getBoolPref(aPrefstring);

					case aBranch.PREF_INVALID:
					default:
						return null;
				}
			} catch(e) {
				// getXXXPref can raise an error if it is the default branch.
				return null;
			}
		},

		getLocalizedPref : function(aPrefstring)
		{
			try {
				return this.getPref(aPrefstring, Ci.nsIPrefLocalizedString).data;
			} catch(e) {
				return this.getPref(aPrefstring);
			}
		},

		getDefaultPref : function(aPrefstring, aInterface)
		{
			return this.getPref(aPrefstring, this.DefaultPrefs, aInterface);
		},

		setPref : function(aPrefstring, aNewValue)
		{
			var branch = this.Prefs;
			var interface = null;
			if (arguments.length > 2) {
				for (let i = 2; i < arguments.length; i++)
				{
					let arg = arguments[i];
					if (!arg)
						continue;
					if (arg instanceof Ci.nsIPrefBranch)
						branch = arg;
					else
						interface = arg;
				}
			}
			if (interface &&
				aNewValue instanceof Ci.nsISupports) {
				return branch.setComplexValue(aPrefstring, interface, aNewValue);
			}
			switch (typeof aNewValue)
			{
				case 'string':
					return branch.setCharPref(aPrefstring, unescape(encodeURIComponent(aNewValue)));

				case 'number':
					return branch.setIntPref(aPrefstring, parseInt(aNewValue));

				default:
					return branch.setBoolPref(aPrefstring, !!aNewValue);
			}
		},

		setDefaultPref : function(aPrefstring, aNewValue)
		{
			return this.setPref(aPrefstring, aNewValue, this.DefaultPrefs);
		},

		clearPref : function(aPrefstring)
		{
			if (this.Prefs.prefHasUserValue(aPrefstring))
				this.Prefs.clearUserPref(aPrefstring);
		},

		getDescendant : function(aRoot, aBranch)
		{
			aBranch = aBranch || this.Prefs;
			return aBranch.getChildList(aRoot, {}).sort();
		},

		getChildren : function(aRoot, aBranch)
		{
			var foundChildren = {};
			var possibleChildren = [];
			var actualChildren = [];
			this.getDescendant(aRoot, aBranch)
					.forEach(function(aPrefstring) {
						var name = aPrefstring.replace(aRoot, '');
						if (name.charAt(0) == '.')
							name = name.substring(1);
						if (name.indexOf('.') < 0) {
							if (!(aPrefstring in foundChildren)) {
								actualChildren.push(aPrefstring);
								foundChildren[aPrefstring] = true;
							}
						}
						else {
							let possibleChildKey = aRoot + name.split('.')[0];
							if (possibleChildKey && !(possibleChildKey in foundChildren)) {
								possibleChildren.push(possibleChildKey);
								foundChildren[possibleChildKey] = true;
							}
						}
					});
			return possibleChildren.concat(actualChildren).sort();
		},

		addPrefListener : function(aObserver)
		{
			var domains = ('domains' in aObserver) ? aObserver.domains : [aObserver.domain] ;
			try {
				for each (var domain in domains)
					this.Prefs.addObserver(domain, aObserver, false);
			}
			catch(e) {
			}
		},

		removePrefListener : function(aObserver)
		{
			var domains = ('domains' in aObserver) ? aObserver.domains : [aObserver.domain] ;
			try {
				for each (var domain in domains)
					this.Prefs.removeObserver(domain, aObserver, false);
			}
			catch(e) {
			}
		}
	};
})();

if (window != this) { // work as a JS Code Module
	this.prefs = window['piro.sakura.ne.jp'].prefs;
}
<|endoftext|>


<commit_before>function GM_runScript(code, sandbox, maxJSVersion) { Components.utils.evalInSandbox(code, sandbox, maxJSVersion); }
// NOTE:
// This function is intentionally contained completely within line one.
// This is used to grant the a predictable file/line numbers to exceptions
// raised inside the eval.
//
// This is a workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=307984
//
// Users: If you see an error coming from this file, that's because we haven't
// yet found a way to work around the bug completely.  If you have asynchronous
// code (setTimeout, any kind of event listener or GM_xmlhttpRequest callback),
// any errors within it will be reported as coming from this file, as their
// eval source (line 1) + the line within your script (and any prepended
// @required scripts).
//
// The rest of the module follows.
//

var EXPORTED_SYMBOLS = ["GM_runScript", "GM_runScript_filename"];

GM_runScript_filename = Components.stack.filename;
<commit_msg>More for someone to read, if they can follow the error.<commit_after>function GM_runScript(code, sandbox, maxJSVersion) { Components.utils.evalInSandbox(code, sandbox, maxJSVersion); }
// NOTE:
// This function is intentionally contained completely within line one.
// This is used to grant the a predictable file/line numbers to exceptions
// raised inside the eval.
//
// This is a workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=307984
//
// Users: If you see an error coming from this file, that's because we haven't
// yet found a way to work around the bug completely.  If you have asynchronous
// code (setTimeout, any kind of event listener or GM_xmlhttpRequest callback),
// any errors within it will be reported as coming from this file at one line
// number higher than the real the line within your script (and any prepended
// @require files).
//
// For example, this script:
//   https://gist.github.com/1154205
// Generated an line in the error console like:
//   Error: undefined is not a function
//   Source File: resource://greasemonkey/runScript.js
//   Line: 27
// This error is actually from line 26 of the script which indeed is
// "undefined();" and guaranteed to cause an error.  Because it was called
// inside a setTimeout(), we were unable to catch and fix the error.
//

var EXPORTED_SYMBOLS = ["GM_runScript", "GM_runScript_filename"];

GM_runScript_filename = Components.stack.filename;
<|endoftext|>


<commit_before>'use strict';

const { Router } = require('express');
const NoAccessError = require('../error/no-access-error');
const requireContentType = require('../middleware/content_type_checker');

const checkPermission = permission => {
    return async (req, res, next) => {
        if (!permission) {
            return next();
        }
        if (await req.checkRbac(permission)) {
            return next();
        }
        return res
            .status(403)
            .json(new NoAccessError(permission))
            .end();
    };
};

/**
 * Base class for Controllers to standardize binding to express Router.
 */
class Controller {
    constructor(config) {
        const router = Router();
        this.app = router;
        this.config = config;
    }

    get(path, handler, permission) {
        this.app.get(path, checkPermission(permission), handler.bind(this));
    }

    post(path, handler, permission, ...acceptedContentTypes) {
        this.app.post(
            path,
            checkPermission(permission),
            requireContentType(...acceptedContentTypes),
            handler.bind(this),
        );
    }

    put(path, handler, permission, ...acceptedContentTypes) {
        this.app.put(
            path,
            checkPermission(permission),
            requireContentType(...acceptedContentTypes),
            handler.bind(this),
        );
    }

    delete(path, handler, permission) {
        this.app.delete(path, checkPermission(permission), handler.bind(this));
    }

    fileupload(path, filehandler, handler, permission) {
        this.app.post(
            path,
            checkPermission(permission),
            filehandler,
            handler.bind(this),
        );
    }

    use(path, router) {
        this.app.use(path, router);
    }

    get router() {
        return this.app;
    }
}

module.exports = Controller;
<commit_msg>fix: should only do checkRbac if it exists<commit_after>'use strict';

const { Router } = require('express');
const NoAccessError = require('../error/no-access-error');
const requireContentType = require('../middleware/content_type_checker');

const checkPermission = permission => {
    return async (req, res, next) => {
        if (!permission) {
            return next();
        }
        if (req.checkRbac && (await req.checkRbac(permission))) {
            return next();
        }
        return res
            .status(403)
            .json(new NoAccessError(permission))
            .end();
    };
};

/**
 * Base class for Controllers to standardize binding to express Router.
 */
class Controller {
    constructor(config) {
        const router = Router();
        this.app = router;
        this.config = config;
    }

    get(path, handler, permission) {
        this.app.get(path, checkPermission(permission), handler.bind(this));
    }

    post(path, handler, permission, ...acceptedContentTypes) {
        this.app.post(
            path,
            checkPermission(permission),
            requireContentType(...acceptedContentTypes),
            handler.bind(this),
        );
    }

    put(path, handler, permission, ...acceptedContentTypes) {
        this.app.put(
            path,
            checkPermission(permission),
            requireContentType(...acceptedContentTypes),
            handler.bind(this),
        );
    }

    delete(path, handler, permission) {
        this.app.delete(path, checkPermission(permission), handler.bind(this));
    }

    fileupload(path, filehandler, handler, permission) {
        this.app.post(
            path,
            checkPermission(permission),
            filehandler,
            handler.bind(this),
        );
    }

    use(path, router) {
        this.app.use(path, router);
    }

    get router() {
        return this.app;
    }
}

module.exports = Controller;
<|endoftext|>


<commit_before>{% load i18n %}
{% load extratags %}

function verify_json_data(data_str, filename, filenum)
{
    var json_data;

    try {
	json_data = JSON.parse(data_str);
    } catch(e) {
	alert(filename + 'does not look like a valid GeoJson or Umap export file (json parse error)');
	return false;
    }

    if (json_data.type == 'umap') {
	return verify_umap_json_data(json_data, filename, filenum);
    } else if (json_data.type == 'FeatureCollection') {
	return verify_geojson_data(json_data, filename, filenum);
    }

    alert(filename + ' does not look like a valid GeoJson or Umap export file (wrong or missing type info)');

    return false;
}

function verify_geojson_data(json_data, filename, filenum)
{
    var color = file_colors[filenum % file_colors.length];
    var json_layer = L.geoJson(json_data, {
	style: function(feature) {
	    return { color: color };
	}});

    var new_bbox = json_layer.getBounds();

    if ('_northEast' in new_bbox === false) {
	alert(filename + ' does not seem to contain geometry data');
	return false;
    }

    $('#step-location-bbox').tab('show') // Select geo location tab

    return json_layer;
}

// TODO - this shouldn't be hardcoded, but read from the config file instead
var umap_style_mapping = {
    "OpenStreetMap"            : "CartoOsm",
    "OSM-monochrome"           : "CartoOsmBw",
    "OSM Humanitarian (OSM-FR)": "Humanitarian",
    "OSM-Fr"                   : "French",
    "OSM hikebikemap"          : "HikeBikeMap",
    "OSM Deutschland (OSM-DE)" : "GermanCartoOSM",
    "OSM OpenTopoMap"          : "OpenTopoMap",
    "OSM OpenRiverboatMap"     : "OpenRiverboatMap",
    "OSM Toner (Stamen)"       : "Toner"
};

function verify_umap_json_data(json_data, filename, filenum)
{
    var layer, feature, new_features = [];

    for (layer in json_data.layers) {
	for (feature in json_data.layers[layer].features) {
	    new_features.push(json_data.layers[layer].features[feature]);
	}
    }

    var new_geojson = {'type': 'FeatureCollection', 'features': new_features};

    var color = file_colors[filenum % file_colors.length];
    var json_layer = L.geoJson(new_geojson, {
	style: function(feature) {
	    return { color: color };
	}});
    var new_bbox = json_layer.getBounds();

    if ('_northEast' in new_bbox === false) {
	alert(filename + ' does not seem to contain geometry data');
	return false;
    }

    $('#step-location-bbox').tab('show') // Select geo location tab
    $('#id_maptitle').val(json_data.properties.name);

    var umap_title;
    try {
	umap_title = json_data.properties.tilelayer.name;
    } catch (err) {
	umap_title = "OSM-Fr"; // TODO: why this title?
    }
    if (umap_title in umap_style_mapping) {
	// TODO: add a proper function for this
	$("input:radio[name=stylesheet][value='"+umap_style_mapping[umap_title]+"']").prop("checked",true);
    }

    return json_layer;
}
<commit_msg>only set map style if really given in the umap file<commit_after>{% load i18n %}
{% load extratags %}

function verify_json_data(data_str, filename, filenum)
{
    var json_data;

    try {
	json_data = JSON.parse(data_str);
    } catch(e) {
	alert(filename + 'does not look like a valid GeoJson or Umap export file (json parse error)');
	return false;
    }

    if (json_data.type == 'umap') {
	return verify_umap_json_data(json_data, filename, filenum);
    } else if (json_data.type == 'FeatureCollection') {
	return verify_geojson_data(json_data, filename, filenum);
    }

    alert(filename + ' does not look like a valid GeoJson or Umap export file (wrong or missing type info)');

    return false;
}

function verify_geojson_data(json_data, filename, filenum)
{
    var color = file_colors[filenum % file_colors.length];
    var json_layer = L.geoJson(json_data, {
	style: function(feature) {
	    return { color: color };
	}});

    var new_bbox = json_layer.getBounds();

    if ('_northEast' in new_bbox === false) {
	alert(filename + ' does not seem to contain geometry data');
	return false;
    }

    $('#step-location-bbox').tab('show') // Select geo location tab

    return json_layer;
}

// TODO - this shouldn't be hardcoded, but read from the config file instead
var umap_style_mapping = {
    "OpenStreetMap"            : "CartoOsm",
    "OSM-monochrome"           : "CartoOsmBw",
    "OSM Humanitarian (OSM-FR)": "Humanitarian",
    "OSM-Fr"                   : "French",
    "OSM hikebikemap"          : "HikeBikeMap",
    "OSM Deutschland (OSM-DE)" : "GermanCartoOSM",
    "OSM OpenTopoMap"          : "OpenTopoMap",
    "OSM OpenRiverboatMap"     : "OpenRiverboatMap",
    "OSM Toner (Stamen)"       : "Toner"
};

function verify_umap_json_data(json_data, filename, filenum)
{
    var layer, feature, new_features = [];

    for (layer in json_data.layers) {
	for (feature in json_data.layers[layer].features) {
	    new_features.push(json_data.layers[layer].features[feature]);
	}
    }

    var new_geojson = {'type': 'FeatureCollection', 'features': new_features};

    var color = file_colors[filenum % file_colors.length];
    var json_layer = L.geoJson(new_geojson, {
	style: function(feature) {
	    return { color: color };
	}});
    var new_bbox = json_layer.getBounds();

    if ('_northEast' in new_bbox === false) {
	alert(filename + ' does not seem to contain geometry data');
	return false;
    }

    $('#step-location-bbox').tab('show') // Select geo location tab
    $('#id_maptitle').val(json_data.properties.name);

    try {
	var umap_style = json_data.properties.tilelayer.name;
	if (umap_style in umap_style_mapping) {
	    // TODO: add a proper function for selecting the map style
	    $("input:radio[name=stylesheet][value='" + umap_style_mapping[umap_style] + "']").prop("checked", true);
	}
    } catch {
	// ignore
    }

    return json_layer;
}
<|endoftext|>


<commit_before>module.exports = function(old, cfg) {

  var data = cfg;

  if (data.clock) {
    data.clock.showTenths = data.pref.clockTenths;
    data.clock.showBar = data.pref.clockBar;
  }

  if (cfg.game.moves) data.game.moves = data.game.moves.split(' ');
  else data.game.moves = [];

  return data;
};
<commit_msg>Fix clock-time bar in correspondence<commit_after>module.exports = function(old, cfg) {

  var data = cfg;

  if (data.clock) {
    data.clock.showTenths = data.pref.clockTenths;
    data.clock.showBar = data.pref.clockBar;
  }

  if (data.correspondence) {
  	data.correspondence.showBar = data.pref.clockBar;
  }

  if (cfg.game.moves) data.game.moves = data.game.moves.split(' ');
  else data.game.moves = [];

  return data;
};
<|endoftext|>


<commit_before>var miso = require('../modules/miso.util.js');

//	Header MVC
var headerMVC = {
	models: {
		header: function(){
			var me = this;
			me.text = m.p("Header");
			me.isMenuShown = m.p(false);
			me.toggleMenu = function(e){
				e.preventDefault();
				me.isMenuShown(!me.isMenuShown());
				var el = document.body;
				el.className = "";
				if(me.isMenuShown()) {
					el.className = "menu-active";
				}
			};
			me.scrollOffset = m.p();
		}
	},
	controller: function() {
		//	Expose the header model
		var model = this.model = misoGlobal.header = new headerMVC.models.header();

		//	Check for the offset
		if(!miso.isServer()) {
			//	Ref: http://stackoverflow.com/a/3464890
			var doc = document.documentElement,
				top = (window.pageYOffset || doc.scrollTop)  - (doc.clientTop || 0);
			var setOffset = function(){
				top = (window.pageYOffset || doc.scrollTop)  - (doc.clientTop || 0);
				//console.log('so', top);
				model.scrollOffset(top);
			}
			setInterval(setOffset, 300);
		}

		return this;
	},
	view: function(ctrl) {
		var o = ctrl.model;
		with(sugartags){
			return m("SECTION", {className: "miso-header" + (o.scrollOffset() > 400? " scrolled": "")},
				m("div", [
					(o.backLink()?
						A({href: o.backLink(), config: m.route}, [
							SPAN({className: "button-back"}, I({className: "fa fa-arrow-left"})),
							SPAN(m.trust(o.text()))
						])
					: SPAN(m.trust(o.text()))),
	  				A({href: "#", class: "button-menu", onclick: o.toggleMenu},
	  					SPAN(I({className: "fa fa-bars"}))
	  				)
				])
			);
		}
	}
};

m.mount(document.getElementsByClassName("miso-header--surround")[0], headerMVC);<commit_msg>Fix backlink issue<commit_after>var miso = require('../modules/miso.util.js');

//	Header MVC
var headerMVC = {
	models: {
		header: function(){
			var me = this;
			me.text = m.p("Header");
			me.isMenuShown = m.p(false);
			me.toggleMenu = function(e){
				if(e){
					e.preventDefault();
				}
				me.isMenuShown(!me.isMenuShown());
				var el = document.body;
				el.className = "";
				if(me.isMenuShown()) {
					el.className = "menu-active";
				}
			};
			me.scrollOffset = m.p();
		}
	},
	controller: function() {
		//	Expose the header model
		var model = this.model = misoGlobal.header = new headerMVC.models.header();

		//	Check for the offset
		if(!miso.isServer()) {
			//	Ref: http://stackoverflow.com/a/3464890
			var doc = document.documentElement,
				top = (window.pageYOffset || doc.scrollTop)  - (doc.clientTop || 0);
			var setOffset = function(){
				top = (window.pageYOffset || doc.scrollTop)  - (doc.clientTop || 0);
				//console.log('so', top);
				model.scrollOffset(top);
			}
			setInterval(setOffset, 300);
		}

		return this;
	},
	view: function(ctrl) {
		var o = ctrl.model;
		with(sugartags){
			return m("SECTION", {className: "miso-header" + (o.scrollOffset() > 400? " scrolled": "")},
				m("div", [
					(typeof o.backLink !== "undefined" && o.backLink()?
						A({href: o.backLink(), config: m.route}, [
							SPAN({className: "button-back"}, I({className: "fa fa-arrow-left"})),
							SPAN(m.trust(o.text()))
						])
					: SPAN(m.trust(o.text()))),
	  				A({href: "#", class: "button-menu", onclick: o.toggleMenu},
	  					SPAN(I({className: "fa fa-bars"}))
	  				)
				])
			);
		}
	}
};

m.mount(document.getElementsByClassName("miso-header--surround")[0], headerMVC);
<|endoftext|>


<commit_before>const HtmlWebpackPlugin = require('html-webpack-plugin')
const webpack = require('webpack')

module.exports = {
  mode: 'development',
  output: {
    filename: 'static/[name].js',
    publicPath: '/',
  },
  module: {
    rules: [
      {
        test: /\.elm$/,
        exclude: [/elm-stuff/, /node_modules/],
        use: [
          { loader: 'elm-hot-webpack-loader' },
          {
            loader: 'elm-webpack-loader',
            options: {
              debug: true
            },
          },
        ],
      },
      {
        test: /\.css$/,
        exclude: [/node_modules/],
        loader: ['style-loader', 'css-loader'],
      },
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: 'public/index.html',
      favicon: 'public/favicon.png',
    }),
    new webpack.HotModuleReplacementPlugin(),
  ],
  devServer: {
    inline: true,
    hot: true,
    stats: { colors: true },
    proxy: [{
      context: ['/api', '/debug', '/serve'],
      target: 'http://localhost:9000',
      ws: true,
    }],
  },
};
<commit_msg>ui: Enable compile-error dev server overlay, SPA routing<commit_after>const HtmlWebpackPlugin = require('html-webpack-plugin')
const webpack = require('webpack')

module.exports = {
  mode: 'development',
  output: {
    filename: 'static/[name].js',
    publicPath: '/',
  },
  module: {
    rules: [
      {
        test: /\.elm$/,
        exclude: [/elm-stuff/, /node_modules/],
        use: [
          { loader: 'elm-hot-webpack-loader' },
          {
            loader: 'elm-webpack-loader',
            options: {
              debug: true
            },
          },
        ],
      },
      {
        test: /\.css$/,
        exclude: [/node_modules/],
        loader: ['style-loader', 'css-loader'],
      },
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: 'public/index.html',
      favicon: 'public/favicon.png',
    }),
    new webpack.HotModuleReplacementPlugin(),
  ],
  devServer: {
    inline: true,
    historyApiFallback: true,
    hot: true,
    stats: { colors: true },
    overlay: true,
    open: true,
    proxy: [{
      context: ['/api', '/debug', '/serve'],
      target: 'http://localhost:9000',
      ws: true,
    }],
    watchOptions: {
      ignored: /node_modules/,
    },
  },
};
<|endoftext|>


<commit_before>/* eslint-disable no-extra-boolean-cast */
// <nowiki>
// Some UI code adapted from [[User:Mr. Stradivarius/gadgets/Draftify.js]]
// Adapted from https://en.wikipedia.org/wiki/User:MusikAnimal/userRightsManager.js
(function() {
	var pagePermissions = {
		'Wikipedia:權限申請/申請IP封禁例外權': 'ipblock-exempt',
		'Wikipedia:權限申請/申請巡查權': 'patroller',
		'Wikipedia:權限申請/申請回退權': 'rollbacker',
		'Wikipedia:權限申請/申請巡查豁免權': 'autoreviewer',
		'Wikipedia:權限申請/申請確認用戶權': 'confirmed',
		'Wikipedia:權限申請/申請大量訊息發送權': 'massmessage-sender',
		'Wikipedia:權限申請/申請大量帳號建立權': 'accountcreator',
		'Wikipedia:權限申請/申請檔案移動權': 'filemover',
		'Wikipedia:權限申請/申請跨維基導入權': 'transwiki',
		'Wikipedia:權限申請/申請模板編輯員': 'templateeditor',
	}

	var pageName = mw.config.get('wgPageName');
	var permission = pagePermissions[pageName];

	if (!permission) {
		return;
	}

	var permissionNames = {
		'ipblock-exempt': wgULS('IP封禁豁免', 'IP封鎖例外'),
		'patroller': '巡查員',
		'rollbacker': '回退員',
		'autoreviewer': '巡查豁免者',
		'confirmed': '已確認的使用者',
		'massmessage-sender': '大量訊息傳送者',
		'accountcreator': '大量帳號建立者',
		'filemover': '檔案移動員',
		'transwiki': '跨維基匯入者',
		'templateeditor': '模板編輯員',
	};

	var templates = {
		'ipblock-exempt': 'Ipexemptgranted',
		'patroller': 'Patrolgranted',
		'rollbacker': 'Rollbackgranted',
		'autoreviewer': 'Autopatrolgranted',
		'massmessage-sender': 'MMSgranted',
		'templateeditor': 'Template editor granted',
	};

	var api,
		tagLine = '（使用[[User:Xiplus/js/userRightsManager|userRightsManager]]）',
		permaLink, userName, dialog;

	mw.loader.using(['oojs-ui', 'mediawiki.api', 'mediawiki.widgets.SelectWithInputWidget', 'mediawiki.widgets.expiry'], function() {
		api = new mw.Api();
		$('.perm-assign-permissions a').on('click', function(e) {
			if (permission === 'AutoWikiBrowser') return true;
			e.preventDefault();
			userName = mw.util.getParamValue('user', $(this).attr('href'));
			showDialog();
		});
	});

	/* 修改自 https://zh.wikipedia.org/w/index.php?title=MediaWiki:Gadget-site-lib.js&oldid=36816755 */
	function wgULS(hans, hant, cn, tw, hk, sg, zh, mo, my) {
		var wg = mw.config.get('wgUserLanguage');
		var ret = {
			'zh': zh || hans || hant || cn || tw || hk || sg || mo || my,
			'zh-hans': hans || cn || sg || my,
			'zh-hant': hant || tw || hk || mo,
			'zh-cn': cn || hans || sg || my,
			'zh-sg': sg || hans || cn || my,
			'zh-tw': tw || hant || hk || mo,
			'zh-hk': hk || hant || mo || tw,
			'zh-mo': mo || hant || hk || tw
		}
		return ret[wg] || zh || hans || hant || cn || tw || hk || sg || mo || my;
	}

	function showDialog() {
		var Dialog = function(config) {
			Dialog.super.call(this, config);
		};
		OO.inheritClass(Dialog, OO.ui.ProcessDialog);
		Dialog.static.name = 'user-rights-manager';
		Dialog.static.title = '授予' + permissionNames[permission] + wgULS('给', '給') + userName;
		Dialog.static.actions = [
			{ action: 'submit', label: wgULS('授权', '授權'), flags: ['primary', 'progressive'] },
			{ label: '取消', flags: 'safe' }
		];
		Dialog.prototype.getApiManager = function() {
			return this.apiManager;
		};
		Dialog.prototype.getBodyHeight = function() {
			return 208;
		};
		Dialog.prototype.initialize = function() {
			Dialog.super.prototype.initialize.call(this);
			this.editFieldset = new OO.ui.FieldsetLayout({
				classes: ['container']
			});
			this.editPanel = new OO.ui.PanelLayout({
				expanded: false
			});
			this.editPanel.$element.append(this.editFieldset.$element);
			this.rightsChangeSummaryInput = new OO.ui.TextInputWidget({
				value: '',
				placeholder: '可留空'
			});
			this.expiryInput = new mw.widgets.ExpiryWidget({
				$overlay: $('.oo-ui-window'),
				RelativeInputClass: mw.widgets.SelectWithInputWidget,
				relativeInput: {
					or: true,
					dropdowninput: {
						options: [
							{ data: '1 day', label: '1天' },
							{ data: '1 week', label: '1週' },
							{ data: '1 month', label: '1個月' },
							{ data: '3 months', label: '3個月' },
							{ data: '6 months', label: '6個月' },
							{ data: '1 year', label: '1年' },
							{ data: 'infinite', label: '沒有期限' },
							{ data: 'other', label: '其他時間' },
						],
						value: 'infinite',
					},
					textinput: {
						required: true,
					}
				}
			});
			this.closingRemarksInput = new OO.ui.TextInputWidget({
				value: '{{done}} ~~~~'
			});
			this.watchTalkPageCheckbox = new OO.ui.CheckboxInputWidget({
				selected: false
			});
			var formElements = [
				new OO.ui.FieldLayout(this.rightsChangeSummaryInput, {
					label: wgULS('授权原因', '授權原因')
				}),
				new OO.ui.FieldLayout(this.expiryInput, {
					label: wgULS('结束时间', '結束時間')
				}),
				new OO.ui.FieldLayout(this.closingRemarksInput, {
					label: wgULS('关闭请求留言', '關閉請求留言')
				})
			];
			if (!!templates[permission]) {
				formElements.push(
					new OO.ui.FieldLayout(this.watchTalkPageCheckbox, {
						label: wgULS('监视用户讨论页', '監視使用者討論頁')
					})
				);
			}
			this.editFieldset.addItems(formElements);
			this.submitPanel = new OO.ui.PanelLayout({
				$: this.$,
				expanded: false
			});
			this.submitFieldset = new OO.ui.FieldsetLayout({
				classes: ['container']
			});
			this.submitPanel.$element.append(this.submitFieldset.$element);
			this.changeRightsProgressLabel = new OO.ui.LabelWidget();
			this.changeRightsProgressField = new OO.ui.FieldLayout(this.changeRightsProgressLabel);
			this.markAsDoneProgressLabel = new OO.ui.LabelWidget();
			this.markAsDoneProgressField = new OO.ui.FieldLayout(this.markAsDoneProgressLabel);
			this.issueTemplateProgressLabel = new OO.ui.LabelWidget();
			this.issueTemplateProgressField = new OO.ui.FieldLayout(this.issueTemplateProgressLabel);
			this.stackLayout = new OO.ui.StackLayout({
				items: [this.editPanel, this.submitPanel],
				padded: true
			});
			this.$body.append(this.stackLayout.$element);
		};

		Dialog.prototype.onSubmit = function() {
			var self = this, promiseCount = !!templates[permission] ? 3 : 2;

			self.actions.setAbilities({ submit: false });

			var addPromise = function(field, promise) {
				self.pushPending();
				promise.done(function() {
					field.$field.append($('<span>')
						.text('完成！')
						.prop('style', 'position:relative; top:0.5em; color: #009000; font-weight: bold')
					);
				}).fail(function(obj) {
					if (obj && obj.error && obj.error.info) {
						field.$field.append($('<span>')
							.text('錯誤：' + obj.error.info)
							.prop('style', 'position:relative; top:0.5em; color: #cc0000; font-weight: bold')
						);
					} else {
						field.$field.append($('<span>')
							.text('發生未知錯誤。')
							.prop('style', 'position:relative; top:0.5em; color: #cc0000; font-weight: bold')
						);
					}
				}).always(function() {
					promiseCount--; // FIXME: maybe we could use a self.isPending() or something
					self.popPending();

					if (promiseCount === 0) {
						setTimeout(function() {
							location.reload(true);
						}, 1000);
					}
				});

				return promise;
			};

			self.markAsDoneProgressField.setLabel('標記請求為已完成...');
			self.submitFieldset.addItems([self.markAsDoneProgressField]);
			self.changeRightsProgressField.setLabel('授予權限...');
			self.submitFieldset.addItems([self.changeRightsProgressField]);

			if (!!templates[permission]) {
				self.issueTemplateProgressField.setLabel('發送通知...');
				self.submitFieldset.addItems([self.issueTemplateProgressField]);
			}

			addPromise(
				self.markAsDoneProgressField,
				markAsDone('\n:' + this.closingRemarksInput.getValue())
			).then(function(data) {
				addPromise(
					self.changeRightsProgressField,
					assignPermission(
						this.rightsChangeSummaryInput.getValue(),
						data.edit.newrevid,
						this.expiryInput.getValue()
					)
				).then(function() {
					if (!!templates[permission]) {
						addPromise(
							self.issueTemplateProgressField,
							issueTemplate(this.watchTalkPageCheckbox.isSelected())
						);
					}
				}.bind(this));
			}.bind(this));

			self.stackLayout.setItem(self.submitPanel);
		};

		Dialog.prototype.getActionProcess = function(action) {
			return Dialog.super.prototype.getActionProcess.call(this, action).next(function() {
				if (action === 'submit') {
					return this.onSubmit();
				} else {
					return Dialog.super.prototype.getActionProcess.call(this, action);
				}
			}, this);
		};

		dialog = new Dialog({
			size: 'medium'
		});

		var windowManager = new OO.ui.WindowManager();
		$('body').append(windowManager.$element);
		windowManager.addWindows([dialog]);
		windowManager.openWindow(dialog);
	}

	function assignPermission(summary, revId, expiry) {
		permaLink = '[[Special:PermaLink/' + revId + '#User:' + userName + '|權限申請]]';
		var fullSummary = '+' + permissionNames[permission] + '；' + permaLink;
		if (summary !== '') {
			fullSummary += '；' + summary;
		}
		fullSummary += tagLine;

		return api.postWithToken('userrights', {
			action: 'userrights',
			format: 'json',
			user: userName.replace(/ /g, '_'),
			add: permission,
			reason: fullSummary,
			expiry: expiry === '' ? 'infinity' : expiry
		});
	}

	function markAsDone(closingRemarks) {
		var sectionNode = document.getElementById('User:' + userName.replace(/"/g, '.22').replace(/ /g, '_')),
			sectionNumber = $(sectionNode).siblings('.mw-editsection').find("a:not('.mw-editsection-visualeditor')").prop('href').match(/section=(\d+)/)[1];

		var basetimestamp, curtimestamp, page, revision, content;

		return api.get({
			action: 'query',
			prop: 'revisions',
			rvprop: ['content', 'timestamp'],
			titles: [pageName],
			rvsection: sectionNumber,
			formatversion: '2',
			curtimestamp: true
		})
			.then(function(data) {
				if (!data.query || !data.query.pages) {
					return $.Deferred().reject('unknown');
				}
				page = data.query.pages[0];
				if (!page || page.invalid) {
					return $.Deferred().reject('invalidtitle');
				}
				if (page.missing) {
					return $.Deferred().reject('nocreate-missing');
				}
				revision = page.revisions[0];
				basetimestamp = revision.timestamp;
				curtimestamp = data.curtimestamp;
				content = revision.content;
			})
			.then(function() {
				content = content.trim();
				content = content.replace(/:{{rfp\/status\|(.+?)}}/, ':{{rfp/status|+}}');
				content += closingRemarks;

				return api.postWithEditToken({
					action: 'edit',
					title: pageName,
					section: sectionNumber,
					text: content,
					summary: '/* User:' + userName + ' */ 完成' + tagLine,
					formatversion: '2',

					assert: mw.config.get('wgUserName') ? 'user' : undefined,
					basetimestamp: basetimestamp,
					starttimestamp: curtimestamp,
					nocreate: true
				});
			});
	}

	function issueTemplate(watch) {
		var talkPage = 'User talk:' + userName.replace(/ /g, '_');
		return api.postWithToken('edit', {
			format: 'json',
			action: 'edit',
			title: talkPage,
			summary: '根據' + permaLink + '授予' + permissionNames[permission] + tagLine,
			appendtext: '\n\n{{subst:' + templates[permission] + '}}',
			watchlist: watch ? 'watch' : 'unwatch'
		});
	}
})();
// </nowiki>
<commit_msg>Show rights log<commit_after>/* global Morebits */
/* eslint-disable no-extra-boolean-cast */
// <nowiki>
// Some UI code adapted from [[User:Mr. Stradivarius/gadgets/Draftify.js]]
// Adapted from https://en.wikipedia.org/wiki/User:MusikAnimal/userRightsManager.js
(function() {
	var pagePermissions = {
		'Wikipedia:權限申請/申請IP封禁例外權': 'ipblock-exempt',
		'Wikipedia:權限申請/申請巡查權': 'patroller',
		'Wikipedia:權限申請/申請回退權': 'rollbacker',
		'Wikipedia:權限申請/申請巡查豁免權': 'autoreviewer',
		'Wikipedia:權限申請/申請確認用戶權': 'confirmed',
		'Wikipedia:權限申請/申請大量訊息發送權': 'massmessage-sender',
		'Wikipedia:權限申請/申請大量帳號建立權': 'accountcreator',
		'Wikipedia:權限申請/申請檔案移動權': 'filemover',
		'Wikipedia:權限申請/申請跨維基導入權': 'transwiki',
		'Wikipedia:權限申請/申請模板編輯員': 'templateeditor',
	}

	var pageName = mw.config.get('wgPageName');
	var permission = pagePermissions[pageName];

	if (!permission) {
		return;
	}

	var permissionNames = {
		'ipblock-exempt': wgULS('IP封禁豁免', 'IP封鎖例外'),
		'patroller': '巡查員',
		'rollbacker': '回退員',
		'autoreviewer': '巡查豁免者',
		'confirmed': '已確認的使用者',
		'massmessage-sender': '大量訊息傳送者',
		'accountcreator': '大量帳號建立者',
		'filemover': '檔案移動員',
		'transwiki': '跨維基匯入者',
		'templateeditor': '模板編輯員',
	};

	var templates = {
		'ipblock-exempt': 'Ipexemptgranted',
		'patroller': 'Patrolgranted',
		'rollbacker': 'Rollbackgranted',
		'autoreviewer': 'Autopatrolgranted',
		'massmessage-sender': 'MMSgranted',
		'templateeditor': 'Template editor granted',
	};

	var api,
		tagLine = '（使用[[User:Xiplus/js/userRightsManager|userRightsManager]]）',
		permaLink, userName, dialog;

	mw.loader.using(['oojs-ui', 'mediawiki.api', 'mediawiki.widgets.SelectWithInputWidget', 'mediawiki.widgets.expiry', 'ext.gadget.morebits'], function() {
		api = new mw.Api();
		$('.perm-assign-permissions a').on('click', function(e) {
			if (permission === 'AutoWikiBrowser') return true;
			e.preventDefault();
			userName = mw.util.getParamValue('user', $(this).attr('href'));
			showDialog();
		});
	});

	/* 修改自 https://zh.wikipedia.org/w/index.php?title=MediaWiki:Gadget-site-lib.js&oldid=36816755 */
	function wgULS(hans, hant, cn, tw, hk, sg, zh, mo, my) {
		var wg = mw.config.get('wgUserLanguage');
		var ret = {
			'zh': zh || hans || hant || cn || tw || hk || sg || mo || my,
			'zh-hans': hans || cn || sg || my,
			'zh-hant': hant || tw || hk || mo,
			'zh-cn': cn || hans || sg || my,
			'zh-sg': sg || hans || cn || my,
			'zh-tw': tw || hant || hk || mo,
			'zh-hk': hk || hant || mo || tw,
			'zh-mo': mo || hant || hk || tw
		}
		return ret[wg] || zh || hans || hant || cn || tw || hk || sg || mo || my;
	}

	function showDialog() {
		var Dialog = function(config) {
			Dialog.super.call(this, config);
		};
		OO.inheritClass(Dialog, OO.ui.ProcessDialog);
		Dialog.static.name = 'user-rights-manager';
		Dialog.static.title = '授予' + permissionNames[permission] + wgULS('给', '給') + userName;
		Dialog.static.actions = [
			{ action: 'submit', label: wgULS('授权', '授權'), flags: ['primary', 'progressive'] },
			{ label: '取消', flags: 'safe' }
		];
		Dialog.prototype.getApiManager = function() {
			return this.apiManager;
		};
		Dialog.prototype.getBodyHeight = function() {
			return 208;
		};
		Dialog.prototype.initialize = function() {
			Dialog.super.prototype.initialize.call(this);
			this.editFieldset = new OO.ui.FieldsetLayout({
				classes: ['container']
			});
			this.editPanel = new OO.ui.PanelLayout({
				expanded: false
			});
			this.editPanel.$element.append(this.editFieldset.$element);

			var rightLogWapper = $('<span>');
			var url = mw.util.getUrl('Special:Log/rights', { type: 'rights', page: 'User:' + userName });
			$('<a>').text('最近權限日誌').attr({ 'href': url, 'target': '_blank' }).appendTo(rightLogWapper);
			rightLogWapper.append('：');
			var rightLogText = $('<span>').text('取得中').appendTo(rightLogWapper);
			this.rightLog = new OO.ui.LabelWidget({
				label: rightLogWapper
			});

			api.get({
				action: 'query',
				format: 'json',
				list: 'logevents',
				leaction: 'rights/rights',
				letitle: 'User:' + userName,
				lelimit: '1'
			}).done(function(data) {
				var logs = data.query.logevents;
				if (logs.length === 0) {
					rightLogText.text('沒有任何日誌');
				} else {
					var timestamp = new Morebits.date(logs[0].timestamp).calendar();
					var rights = logs[0].params.newgroups.join('、') || '（無）';
					rightLogText.text(timestamp + ' ' + logs[0].user + '將使用者群組改為' + rights);
				}
			});

			this.rightsChangeSummaryInput = new OO.ui.TextInputWidget({
				value: '',
				placeholder: '可留空'
			});
			this.expiryInput = new mw.widgets.ExpiryWidget({
				$overlay: $('.oo-ui-window'),
				RelativeInputClass: mw.widgets.SelectWithInputWidget,
				relativeInput: {
					or: true,
					dropdowninput: {
						options: [
							{ data: '1 day', label: '1天' },
							{ data: '1 week', label: '1週' },
							{ data: '1 month', label: '1個月' },
							{ data: '3 months', label: '3個月' },
							{ data: '6 months', label: '6個月' },
							{ data: '1 year', label: '1年' },
							{ data: 'infinite', label: '沒有期限' },
							{ data: 'other', label: '其他時間' },
						],
						value: 'infinite',
					},
					textinput: {
						required: true,
					}
				}
			});
			this.closingRemarksInput = new OO.ui.TextInputWidget({
				value: '{{done}} ~~~~'
			});
			this.watchTalkPageCheckbox = new OO.ui.CheckboxInputWidget({
				selected: false
			});
			this.editFieldset.addItems(this.rightLog);
			var formElements = [
				new OO.ui.FieldLayout(this.rightsChangeSummaryInput, {
					label: wgULS('授权原因', '授權原因')
				}),
				new OO.ui.FieldLayout(this.expiryInput, {
					label: wgULS('结束时间', '結束時間')
				}),
				new OO.ui.FieldLayout(this.closingRemarksInput, {
					label: wgULS('关闭请求留言', '關閉請求留言')
				})
			];
			if (!!templates[permission]) {
				formElements.push(
					new OO.ui.FieldLayout(this.watchTalkPageCheckbox, {
						label: wgULS('监视用户讨论页', '監視使用者討論頁')
					})
				);
			}
			this.editFieldset.addItems(formElements);
			this.submitPanel = new OO.ui.PanelLayout({
				$: this.$,
				expanded: false
			});
			this.submitFieldset = new OO.ui.FieldsetLayout({
				classes: ['container']
			});
			this.submitPanel.$element.append(this.submitFieldset.$element);
			this.changeRightsProgressLabel = new OO.ui.LabelWidget();
			this.changeRightsProgressField = new OO.ui.FieldLayout(this.changeRightsProgressLabel);
			this.markAsDoneProgressLabel = new OO.ui.LabelWidget();
			this.markAsDoneProgressField = new OO.ui.FieldLayout(this.markAsDoneProgressLabel);
			this.issueTemplateProgressLabel = new OO.ui.LabelWidget();
			this.issueTemplateProgressField = new OO.ui.FieldLayout(this.issueTemplateProgressLabel);
			this.stackLayout = new OO.ui.StackLayout({
				items: [this.editPanel, this.submitPanel],
				padded: true
			});
			this.$body.append(this.stackLayout.$element);
		};

		Dialog.prototype.onSubmit = function() {
			var self = this, promiseCount = !!templates[permission] ? 3 : 2;

			self.actions.setAbilities({ submit: false });

			var addPromise = function(field, promise) {
				self.pushPending();
				promise.done(function() {
					field.$field.append($('<span>')
						.text('完成！')
						.prop('style', 'position:relative; top:0.5em; color: #009000; font-weight: bold')
					);
				}).fail(function(obj) {
					if (obj && obj.error && obj.error.info) {
						field.$field.append($('<span>')
							.text('錯誤：' + obj.error.info)
							.prop('style', 'position:relative; top:0.5em; color: #cc0000; font-weight: bold')
						);
					} else {
						field.$field.append($('<span>')
							.text('發生未知錯誤。')
							.prop('style', 'position:relative; top:0.5em; color: #cc0000; font-weight: bold')
						);
					}
				}).always(function() {
					promiseCount--; // FIXME: maybe we could use a self.isPending() or something
					self.popPending();

					if (promiseCount === 0) {
						setTimeout(function() {
							location.reload(true);
						}, 1000);
					}
				});

				return promise;
			};

			self.markAsDoneProgressField.setLabel('標記請求為已完成...');
			self.submitFieldset.addItems([self.markAsDoneProgressField]);
			self.changeRightsProgressField.setLabel('授予權限...');
			self.submitFieldset.addItems([self.changeRightsProgressField]);

			if (!!templates[permission]) {
				self.issueTemplateProgressField.setLabel('發送通知...');
				self.submitFieldset.addItems([self.issueTemplateProgressField]);
			}

			addPromise(
				self.markAsDoneProgressField,
				markAsDone('\n:' + this.closingRemarksInput.getValue())
			).then(function(data) {
				addPromise(
					self.changeRightsProgressField,
					assignPermission(
						this.rightsChangeSummaryInput.getValue(),
						data.edit.newrevid,
						this.expiryInput.getValue()
					)
				).then(function() {
					if (!!templates[permission]) {
						addPromise(
							self.issueTemplateProgressField,
							issueTemplate(this.watchTalkPageCheckbox.isSelected())
						);
					}
				}.bind(this));
			}.bind(this));

			self.stackLayout.setItem(self.submitPanel);
		};

		Dialog.prototype.getActionProcess = function(action) {
			return Dialog.super.prototype.getActionProcess.call(this, action).next(function() {
				if (action === 'submit') {
					return this.onSubmit();
				} else {
					return Dialog.super.prototype.getActionProcess.call(this, action);
				}
			}, this);
		};

		dialog = new Dialog({
			size: 'medium'
		});

		var windowManager = new OO.ui.WindowManager();
		$('body').append(windowManager.$element);
		windowManager.addWindows([dialog]);
		windowManager.openWindow(dialog);
	}

	function assignPermission(summary, revId, expiry) {
		permaLink = '[[Special:PermaLink/' + revId + '#User:' + userName + '|權限申請]]';
		var fullSummary = '+' + permissionNames[permission] + '；' + permaLink;
		if (summary !== '') {
			fullSummary += '；' + summary;
		}
		fullSummary += tagLine;

		return api.postWithToken('userrights', {
			action: 'userrights',
			format: 'json',
			user: userName.replace(/ /g, '_'),
			add: permission,
			reason: fullSummary,
			expiry: expiry === '' ? 'infinity' : expiry
		});
	}

	function markAsDone(closingRemarks) {
		var sectionNode = document.getElementById('User:' + userName.replace(/"/g, '.22').replace(/ /g, '_')),
			sectionNumber = $(sectionNode).siblings('.mw-editsection').find("a:not('.mw-editsection-visualeditor')").prop('href').match(/section=(\d+)/)[1];

		var basetimestamp, curtimestamp, page, revision, content;

		return api.get({
			action: 'query',
			prop: 'revisions',
			rvprop: ['content', 'timestamp'],
			titles: [pageName],
			rvsection: sectionNumber,
			formatversion: '2',
			curtimestamp: true
		})
			.then(function(data) {
				if (!data.query || !data.query.pages) {
					return $.Deferred().reject('unknown');
				}
				page = data.query.pages[0];
				if (!page || page.invalid) {
					return $.Deferred().reject('invalidtitle');
				}
				if (page.missing) {
					return $.Deferred().reject('nocreate-missing');
				}
				revision = page.revisions[0];
				basetimestamp = revision.timestamp;
				curtimestamp = data.curtimestamp;
				content = revision.content;
			})
			.then(function() {
				content = content.trim();
				content = content.replace(/:{{rfp\/status\|(.+?)}}/, ':{{rfp/status|+}}');
				content += closingRemarks;

				return api.postWithEditToken({
					action: 'edit',
					title: pageName,
					section: sectionNumber,
					text: content,
					summary: '/* User:' + userName + ' */ 完成' + tagLine,
					formatversion: '2',

					assert: mw.config.get('wgUserName') ? 'user' : undefined,
					basetimestamp: basetimestamp,
					starttimestamp: curtimestamp,
					nocreate: true
				});
			});
	}

	function issueTemplate(watch) {
		var talkPage = 'User talk:' + userName.replace(/ /g, '_');
		return api.postWithToken('edit', {
			format: 'json',
			action: 'edit',
			title: talkPage,
			summary: '根據' + permaLink + '授予' + permissionNames[permission] + tagLine,
			appendtext: '\n\n{{subst:' + templates[permission] + '}}',
			watchlist: watch ? 'watch' : 'unwatch'
		});
	}
})();
// </nowiki>
<|endoftext|>


<commit_before>import FeedParser from 'feedparser'
import request from 'request'
import mongoose from 'mongoose'
import process from 'process'
import config from '../config/config'
import FeedModel from '../models/feed'
import PostModel from '../models/post'
import UserFeedModel from '../models/userFeed'

mongoose.connect(`mongodb://${config.MONGODB.HOST}:${config.MONGODB.PORT}/${config.MONGODB.NAME}`)
mongoose.Promise = require('bluebird')
global.Promise = require('bluebird')
/**
 * 定时更新订阅源
 */
async function update() {
  const items = await FeedModel.find({}, {
    absurl: 1,
    _id:    1,
  })
  const starttime = Date.now()
  let updateCount = 0
  let newCount = 0
  let equalCount = 0
  const promises = items.map(item => new Promise(resolve => {
    const req = request({
      url:     item.absurl,
      headers: {
        'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36',
      },
      timeout: 10000,
    })
    const feedparser = new FeedParser()
    FeedModel.update({
      _id: item._id,
    }, {
      recent_update: Date.now(),
    })
    req.on('response', res => {
      if (res.statusCode !== 200) {
        console.log(`#1 ${res.statusCode} -- ${item.absurl}`)
        resolve()
      } else {
        res.pipe(feedparser)
        feedparser.on('error', err => {
          console.log(`#2 ${err} -- ${item.absurl}`)
          resolve()
        })
      }
    })
    req.on('error', err => {
      console.log(`#3 ${err} -- ${item.absurl}`)
      resolve()
    })
    feedparser.on('readable', async function () {
      let result
      // eslint-disable-next-line
      while (result = this.read()) {
        // Use guid to identify...
        const origin = await PostModel.findOne({
          guid:    result.guid,
          feed_id: item._id,
        })
        if (origin && origin._id) {
          if (origin.link && (origin.link.toString() === result.link.toString())) {
            equalCount++
          } else {
            Object.assign(origin, result)
            origin.save()
            updateCount++
          }
        } else {
          const post = new PostModel(Object.assign(result, {
            feed_id: item._id,
          }))
          newCount++
          post.save()
          UserFeedModel.update({
            feed_id: item._id,
          }, {
            $inc: {
              unread: 1,
            },
          })
        }
      }
    })
    feedparser.on('end', () => {
      resolve()
    })
  }))
  Promise.all(promises).then(() => {
    setTimeout(() => {
      console.log('\r\n************* OK *************')
      console.log(Date().toLocaleString())
      console.log(`FeedNum: ${items.length}`)
      console.log(`TimeUsed: ${(Date.now() - starttime) / 1000} s`)
      console.log(`Equal: ${equalCount}`)
      console.log(`Update: ${updateCount}`)
      console.log(`New: ${newCount}`)
      console.log('************* OK *************\r\n')
      process.exit()
    }, 100)
  }).catch(err => {
    console.log(err)
  })
}
update()
<commit_msg>:bug: fix fetch_posts.js<commit_after>import FeedParser from 'feedparser'
import request from 'request'
import mongoose from 'mongoose'
import process from 'process'
import config from '../config/config'
import FeedModel from '../models/feed'
import PostModel from '../models/post'
import UserFeedModel from '../models/userFeed'

mongoose.connect(`mongodb://${config.MONGODB.USER}:${config.MONGODB.PASSWORD}@${config.MONGODB.HOST}:${config.MONGODB.PORT}/${config.MONGODB.NAME}`)
mongoose.Promise = require('bluebird')
global.Promise = require('bluebird')
/**
 * 定时更新订阅源
 */
async function update() {
  const items = await FeedModel.find({}, {
    absurl: 1,
    _id:    1,
  })
  const starttime = Date.now()
  let updateCount = 0
  let newCount = 0
  let equalCount = 0
  const promises = items.map(item => new Promise(resolve => {
    const req = request({
      url:     item.absurl,
      headers: {
        'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36',
      },
      timeout: 10000,
    })
    const feedparser = new FeedParser()
    FeedModel.update({
      _id: item._id,
    }, {
      recent_update: Date.now(),
    })
    req.on('response', res => {
      if (res.statusCode !== 200) {
        console.log(`#1 ${res.statusCode} -- ${item.absurl}`)
        resolve()
      } else {
        res.pipe(feedparser)
        feedparser.on('error', err => {
          console.log(`#2 ${err} -- ${item.absurl}`)
          resolve()
        })
      }
    })
    req.on('error', err => {
      console.log(`#3 ${err} -- ${item.absurl}`)
      resolve()
    })
    feedparser.on('readable', async function () {
      let result
      // eslint-disable-next-line
      while (result = this.read()) {
        // Use guid to identify...
        const origin = await PostModel.findOne({
          guid:    result.guid,
          feed_id: item._id,
        })
        if (origin && origin._id) {
          if (origin.link && (origin.link.toString() === result.link.toString())) {
            equalCount++
          } else {
            Object.assign(origin, result)
            origin.save()
            updateCount++
          }
        } else {
          // TODO: Invalid Date Cast failed
          if (Object.prototype.toString.call(result.pubdate) !== '[object Date]') {
            result.pubdate = null
          }
          if (Object.prototype.toString.call(result.date) !== '[object Date]') {
            result.date = null
          }
          const post = new PostModel(Object.assign(result, {
            feed_id: item._id,
          }))
          newCount++
          post.save()
          UserFeedModel.update({
            feed_id: item._id,
          }, {
            $inc: {
              unread: 1,
            },
          })
        }
      }
    })
    feedparser.on('end', () => {
      resolve()
    })
  }))
  Promise.all(promises).then(() => {
    setTimeout(() => {
      console.log('\r\n************* OK *************')
      console.log(Date().toLocaleString())
      console.log(`FeedNum: ${items.length}`)
      console.log(`TimeUsed: ${(Date.now() - starttime) / 1000} s`)
      console.log(`Equal: ${equalCount}`)
      console.log(`Update: ${updateCount}`)
      console.log(`New: ${newCount}`)
      console.log('************* OK *************\r\n')
      process.exit()
    }, 100)
  }).catch(err => {
    console.log(err)
  })
}
update()
<|endoftext|>


<commit_before>// Copyright (c) 2015 Uber Technologies, Inc.

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

'use strict';

var bufrw = require('bufrw');
var WriteResult = bufrw.WriteResult;
var ReadResult = bufrw.ReadResult;
var TypedError = require('error/typed');
var Frame = require('./frame');
var Tracing = require('./tracing');

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

// TODO: enforce message ID of this frame is Frame.NullId when
// errorBody.code.ProtocolError = ErrorResponse.Codes.ProtocolError

// code:1 tracing:25 message~2
function ErrorResponse(code, tracing, message) {
    var self = this;
    self.code = code || 0;
    self.tracing = tracing || Tracing.emptyTracing;
    self.type = ErrorResponse.TypeCode;
    self.message = message || '';
}

ErrorResponse.TypeCode = 0xff;

var Codes = Object.create(null);
// 0x00 not a valid value for "code", do not use.
Codes.Timeout = 0x01;
Codes.Cancelled = 0x02;
Codes.Busy = 0x03;
Codes.Declined = 0x04;
Codes.UnexpectedError = 0x05;
Codes.BadRequest = 0x06;
Codes.NetworkError = 0x07;
Codes.Unhealthy = 0x08;
Codes.ProtocolError = 0xff;

var CodeNames = Object.create(null);
CodeNames[Codes.Timeout] = 'Timeout';
CodeNames[Codes.Cancelled] = 'Cancelled';
CodeNames[Codes.Busy] = 'Busy';
CodeNames[Codes.Declined] = 'Declined';
CodeNames[Codes.UnexpectedError] = 'UnexpectedError';
CodeNames[Codes.BadRequest] = 'BadRequest';
CodeNames[Codes.NetworkError] = 'NetworkError';
CodeNames[Codes.ProtocolError] = 'ProtocolError';
CodeNames[Codes.Unhealthy] = 'Unhealthy';

var CodeErrors = Object.create(null);
CodeErrors[Codes.Timeout] = TypedError({
    type: 'tchannel.timeout',
    message: 'TChannel timeout',
    isErrorFrame: true,
    codeName: 'Timeout',
    errorCode: Codes.Timeout,
    originalId: null
});
CodeErrors[Codes.Cancelled] = TypedError({
    type: 'tchannel.cancelled',
    message: 'TChannel cancelled',
    isErrorFrame: true,
    codeName: 'Cancelled',
    errorCode: Codes.Cancelled,
    originalId: null
});
CodeErrors[Codes.Busy] = TypedError({
    type: 'tchannel.busy',
    message: 'TChannel busy',
    isErrorFrame: true,
    codeName: 'Busy',
    errorCode: Codes.Busy,
    originalId: null
});
CodeErrors[Codes.Declined] = TypedError({
    type: 'tchannel.declined',
    message: 'TChannel declined',
    isErrorFrame: true,
    codeName: 'Declined',
    errorCode: Codes.Declined,
    originalId: null
});
CodeErrors[Codes.UnexpectedError] = TypedError({
    type: 'tchannel.unexpected',
    message: 'TChannel unexpected error',
    isErrorFrame: true,
    codeName: 'UnexpectedError',
    errorCode: Codes.UnexpectedError,
    originalId: null
});
CodeErrors[Codes.BadRequest] = TypedError({
    type: 'tchannel.bad-request',
    message: 'TChannel bad request',
    isErrorFrame: true,
    codeName: 'BadRequest',
    errorCode: Codes.BadRequest,
    originalId: null
});
CodeErrors[Codes.NetworkError] = TypedError({
    type: 'tchannel.network',
    message: 'TChannel network error',
    isErrorFrame: true,
    codeName: 'NetworkError',
    errorCode: Codes.NetworkError,
    originalId: null
});
CodeErrors[Codes.ProtocolError] = TypedError({
    type: 'tchannel.protocol',
    message: 'TChannel protocol error',
    isErrorFrame: true,
    codeName: 'ProtocolError',
    errorCode: Codes.ProtocolError,
    originalId: null
});
CodeErrors[Codes.Unhealthy] = TypedError({
    type: 'tchannel.unhealthy',
    message: 'TChannel unhealthy',
    isErrorFrame: true,
    codeName: 'Unhealthy',
    errorCode: Codes.Unhealthy,
    originalId: null
});

ErrorResponse.Codes = Codes;
ErrorResponse.CodeNames = CodeNames;
ErrorResponse.CodeErrors = CodeErrors;

ErrorResponse.RW = bufrw.Struct(ErrorResponse, [
    {call: {writeInto: function writeGuard(body, buffer, offset) {
        if (CodeNames[body.code] === undefined) {
            return WriteResult.error(errors.InvalidErrorCodeError({
                errorCode: body.code,
                tracing: body.tracing
            }), offset);
        }
        return WriteResult.just(offset);
    }}},
    {name: 'code', rw: bufrw.UInt8},    // code:1
    {name: 'tracing', rw: Tracing.RW},  // tracing:25
    {name: 'message', rw: bufrw.str2},  // message~2
    {call: {writeInto: function writeGuard(body, buffer, offset) {
        if (CodeNames[body.code] === undefined) {
            return ReadResult.error(errors.InvalidErrorCodeError({
                errorCode: body.code,
                tracing: body.tracing,
            }), offset);
        }
        return ReadResult.just(offset);
    }}},
]);

ErrorResponse.RW.lazy = {};

ErrorResponse.RW.lazy.isFrameTerminal = function isFrameTerminal() {
    return true;
};

ErrorResponse.RW.lazy.codeOffset = Frame.Overhead;
ErrorResponse.RW.lazy.readCode = function readCode(frame) {
    // code:1
    return bufrw.UInt8.readFrom(frame.buffer, ErrorResponse.RW.lazy.codeOffset);
};

ErrorResponse.RW.lazy.tracingOffset = ErrorResponse.RW.lazy.codeOffset + 1;
ErrorResponse.RW.lazy.readTracing = function readTracing(frame) {
    // tracing:25
    return Tracing.RW.readFrom(frame.buffer, ErrorResponse.RW.lazy.tracingOffset);
};

ErrorResponse.RW.lazy.mesasgeOffset = ErrorResponse.RW.lazy.tracingOffset + 25;
ErrorResponse.RW.lazy.readMessage = function readMessage(frame) {
    // mesasge~2
    return bufrw.str2.readFrom(frame.buffer, ErrorResponse.RW.lazy.mesasgeOffset);
};

module.exports = ErrorResponse;
<commit_msg>v2/error_response: collect and separate error types from CodeErrors collection<commit_after>// Copyright (c) 2015 Uber Technologies, Inc.

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

'use strict';

var bufrw = require('bufrw');
var WriteResult = bufrw.WriteResult;
var ReadResult = bufrw.ReadResult;
var TypedError = require('error/typed');
var Frame = require('./frame');
var Tracing = require('./tracing');

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

// TODO: enforce message ID of this frame is Frame.NullId when
// errorBody.code.ProtocolError = ErrorResponse.Codes.ProtocolError

// code:1 tracing:25 message~2
function ErrorResponse(code, tracing, message) {
    var self = this;
    self.code = code || 0;
    self.tracing = tracing || Tracing.emptyTracing;
    self.type = ErrorResponse.TypeCode;
    self.message = message || '';
}

ErrorResponse.TypeCode = 0xff;

var Codes = Object.create(null);
// 0x00 not a valid value for "code", do not use.
Codes.Timeout = 0x01;
Codes.Cancelled = 0x02;
Codes.Busy = 0x03;
Codes.Declined = 0x04;
Codes.UnexpectedError = 0x05;
Codes.BadRequest = 0x06;
Codes.NetworkError = 0x07;
Codes.Unhealthy = 0x08;
Codes.ProtocolError = 0xff;

var CodeNames = Object.create(null);
CodeNames[Codes.Timeout] = 'Timeout';
CodeNames[Codes.Cancelled] = 'Cancelled';
CodeNames[Codes.Busy] = 'Busy';
CodeNames[Codes.Declined] = 'Declined';
CodeNames[Codes.UnexpectedError] = 'UnexpectedError';
CodeNames[Codes.BadRequest] = 'BadRequest';
CodeNames[Codes.NetworkError] = 'NetworkError';
CodeNames[Codes.ProtocolError] = 'ProtocolError';
CodeNames[Codes.Unhealthy] = 'Unhealthy';

var TimeoutError = TypedError({
    type: 'tchannel.timeout',
    message: 'TChannel timeout',
    isErrorFrame: true,
    codeName: 'Timeout',
    errorCode: Codes.Timeout,
    originalId: null
});

var CancelledError = TypedError({
    type: 'tchannel.cancelled',
    message: 'TChannel cancelled',
    isErrorFrame: true,
    codeName: 'Cancelled',
    errorCode: Codes.Cancelled,
    originalId: null
});

var BusyError = TypedError({
    type: 'tchannel.busy',
    message: 'TChannel busy',
    isErrorFrame: true,
    codeName: 'Busy',
    errorCode: Codes.Busy,
    originalId: null
});

var DeclinedError = TypedError({
    type: 'tchannel.declined',
    message: 'TChannel declined',
    isErrorFrame: true,
    codeName: 'Declined',
    errorCode: Codes.Declined,
    originalId: null
});

var UnexpectedErrorError = TypedError({
    type: 'tchannel.unexpected',
    message: 'TChannel unexpected error',
    isErrorFrame: true,
    codeName: 'UnexpectedError',
    errorCode: Codes.UnexpectedError,
    originalId: null
});

var BadRequestError = TypedError({
    type: 'tchannel.bad-request',
    message: 'TChannel bad request',
    isErrorFrame: true,
    codeName: 'BadRequest',
    errorCode: Codes.BadRequest,
    originalId: null
});

var NetworkErrorError = TypedError({
    type: 'tchannel.network',
    message: 'TChannel network error',
    isErrorFrame: true,
    codeName: 'NetworkError',
    errorCode: Codes.NetworkError,
    originalId: null
});

var ProtocolErrorError = TypedError({
    type: 'tchannel.protocol',
    message: 'TChannel protocol error',
    isErrorFrame: true,
    codeName: 'ProtocolError',
    errorCode: Codes.ProtocolError,
    originalId: null
});

var UnhealthyError = TypedError({
    type: 'tchannel.unhealthy',
    message: 'TChannel unhealthy',
    isErrorFrame: true,
    codeName: 'Unhealthy',
    errorCode: Codes.Unhealthy,
    originalId: null
});

var CodeErrors = Object.create(null);
CodeErrors[Codes.Timeout] = TimeoutError;
CodeErrors[Codes.Cancelled] = CancelledError;
CodeErrors[Codes.Busy] = BusyError;
CodeErrors[Codes.Declined] = DeclinedError;
CodeErrors[Codes.UnexpectedError] = UnexpectedErrorError;
CodeErrors[Codes.BadRequest] = BadRequestError;
CodeErrors[Codes.NetworkError] = NetworkErrorError;
CodeErrors[Codes.ProtocolError] = ProtocolErrorError;
CodeErrors[Codes.Unhealthy] = UnhealthyError;

ErrorResponse.Codes = Codes;
ErrorResponse.CodeNames = CodeNames;
ErrorResponse.CodeErrors = CodeErrors;

ErrorResponse.RW = bufrw.Struct(ErrorResponse, [
    {call: {writeInto: function writeGuard(body, buffer, offset) {
        if (CodeNames[body.code] === undefined) {
            return WriteResult.error(errors.InvalidErrorCodeError({
                errorCode: body.code,
                tracing: body.tracing
            }), offset);
        }
        return WriteResult.just(offset);
    }}},
    {name: 'code', rw: bufrw.UInt8},    // code:1
    {name: 'tracing', rw: Tracing.RW},  // tracing:25
    {name: 'message', rw: bufrw.str2},  // message~2
    {call: {writeInto: function writeGuard(body, buffer, offset) {
        if (CodeNames[body.code] === undefined) {
            return ReadResult.error(errors.InvalidErrorCodeError({
                errorCode: body.code,
                tracing: body.tracing,
            }), offset);
        }
        return ReadResult.just(offset);
    }}},
]);

ErrorResponse.RW.lazy = {};

ErrorResponse.RW.lazy.isFrameTerminal = function isFrameTerminal() {
    return true;
};

ErrorResponse.RW.lazy.codeOffset = Frame.Overhead;
ErrorResponse.RW.lazy.readCode = function readCode(frame) {
    // code:1
    return bufrw.UInt8.readFrom(frame.buffer, ErrorResponse.RW.lazy.codeOffset);
};

ErrorResponse.RW.lazy.tracingOffset = ErrorResponse.RW.lazy.codeOffset + 1;
ErrorResponse.RW.lazy.readTracing = function readTracing(frame) {
    // tracing:25
    return Tracing.RW.readFrom(frame.buffer, ErrorResponse.RW.lazy.tracingOffset);
};

ErrorResponse.RW.lazy.mesasgeOffset = ErrorResponse.RW.lazy.tracingOffset + 25;
ErrorResponse.RW.lazy.readMessage = function readMessage(frame) {
    // mesasge~2
    return bufrw.str2.readFrom(frame.buffer, ErrorResponse.RW.lazy.mesasgeOffset);
};

module.exports = ErrorResponse;
<|endoftext|>


<commit_before>function broadcast(componentName, eventName, params) {
    this.$children.forEach((child) => {
        const name = child.$options.name;

        if (name === componentName) {
            child.$emit(eventName, ...params);
        } else {
            broadcast.apply(child, [componentName, eventName].concat([params]));
        }
    });
}
export default {
    methods: {
        dispatch(componentName, eventName, params) {
            let parent = this.$parent || this.$root;
            let name = parent.$options.name;

            while (parent && (!name || name !== componentName)) {
                parent = parent.$parent;

                if (parent) {
                    name = parent.$options.name;
                }
            }
            if (parent) {
                parent.$emit(eventName, ...params);
            }
        },
        broadcast(componentName, eventName, params) {
            broadcast.call(this, componentName, eventName, params);
        },
    },
};
<commit_msg>emitter:修复发射时的参数传递<commit_after>function broadcast(componentName, eventName, params) {
    for (const child of this.$children) {
        const name = child.$options.name;

        if (name === componentName) {
            child.$emit(...[eventName].concat(params));
        } else {
            broadcast.apply(child, [componentName, eventName].concat([params]));
        }
    }
}
export default {
    methods: {
        dispatch(componentName, eventName, params) {
            let parent = this.$parent || this.$root;
            let name = parent.$options.name;

            while (parent && (!name || name !== componentName)) {
                parent = parent.$parent;

                if (parent) {
                    name = parent.$options.name;
                }
            }
            if (parent) {
                parent.$emit(...[eventName].concat(params));
            }
        },
        broadcast(componentName, eventName, params) {
            broadcast.call(this, componentName, eventName, params);
        },
    },
};
<|endoftext|>


<commit_before>backupApp.controller('ExportController', function($scope, $routeParams, AppService, DialogService, gettextCatalog) {
    $scope.ExportType = 'file';
    $scope.ExportPasswords = true;
    $scope.Connecting = false;
    $scope.BackupID = $routeParams.backupid;
    $scope.Completed = false;

    $scope.doExport = function() {
        // Helper function(s)
        function warnUnencryptedPasswords(continuation) {
            if ($scope.ExportType == 'file' && $scope.ExportPasswords && !$scope.fileEncrypted) {
                DialogService.dialog(gettextCatalog.getString('Not using encryption'), gettextCatalog.getString('The configuration should be kept safe. Are you sure you want to save an unencrypted file containing your passwords?'), [gettextCatalog.getString('Cancel'), gettextCatalog.getString('Yes, I understand the risk')], function(ix) {
                    if (ix == 0)
                            $scope.CurrentStep = 0;
                        else
                            continuation();
                });
            } else {
                continuation();
            }

        }

        // The actual export function to call after all checks pass
        function getExport() {
            if ($scope.ExportType == 'commandline') {
                $scope.Connecting = true;
                AppService.get('/backup/' + $scope.BackupID + '/export?cmdline=true&export-passwords=' + encodeURIComponent($scope.ExportPasswords)).then(
                    function(resp) {
                        $scope.Connecting = false;
                        $scope.Completed = true;
                        $scope.CommandLine = resp.data.Command;
                    },
                    function(resp) {
                        $scope.Connecting = false;
                        var message = resp.statusText;
                        if (resp.data != null && resp.data.Message != null)
                            message = resp.data.Message;

                        DialogService.dialog(gettextCatalog.getString('Error'), gettextCatalog.getString('Failed to connect: {{message}}', { message: message }));
                    }
                );
            } else {
                $scope.DownloadURL = AppService.get_export_url($scope.BackupID, $scope.UseEncryption ? $scope.Passphrase : null, $scope.ExportPasswords);
                $scope.Completed = true;
            }

        };

        // Make checks that do not require user input
        $scope.fileEncrypted = false;
        if ($scope.UseEncryption && $scope.ExportType == 'file') {
            if (($scope.Passphrase || '').trim().length == 0) {
                DialogService.dialog(gettextCatalog.getString('No passphrase entered'), gettextCatalog.getString('To export without a passphrase, uncheck the "Encrypt file" box'));
                return;
            }
            else {
               $scope.fileEncrypted = true;
            }
        }

        // Chain various checks that require user input
        warnUnencryptedPasswords(function() { getExport(); });
    }
});
<commit_msg>made some curly brace adjustments (Codacy)<commit_after>backupApp.controller('ExportController', function($scope, $routeParams, AppService, DialogService, gettextCatalog) {
    $scope.ExportType = 'file';
    $scope.ExportPasswords = true;
    $scope.Connecting = false;
    $scope.BackupID = $routeParams.backupid;
    $scope.Completed = false;

    $scope.doExport = function() {
        // Helper function(s)
        function warnUnencryptedPasswords(continuation) {
            if ($scope.ExportType == 'file' && $scope.ExportPasswords && !$scope.fileEncrypted) {
                DialogService.dialog(gettextCatalog.getString('Not using encryption'), gettextCatalog.getString('The configuration should be kept safe. Are you sure you want to save an unencrypted file containing your passwords?'), [gettextCatalog.getString('Cancel'), gettextCatalog.getString('Yes, I understand the risk')], function(ix) {
                    if (ix == 0) {
                        $scope.CurrentStep = 0;
                    } else {
                        continuation();
                    }
                });
            } else {
                continuation();
            }

        }

        // The actual export function to call after all checks pass
        function getExport() {
            if ($scope.ExportType == 'commandline') {
                $scope.Connecting = true;
                AppService.get('/backup/' + $scope.BackupID + '/export?cmdline=true&export-passwords=' + encodeURIComponent($scope.ExportPasswords)).then(
                    function(resp) {
                        $scope.Connecting = false;
                        $scope.Completed = true;
                        $scope.CommandLine = resp.data.Command;
                    },
                    function(resp) {
                        $scope.Connecting = false;
                        var message = resp.statusText;
                        if (resp.data != null && resp.data.Message != null) {
                            message = resp.data.Message;
                        }

                        DialogService.dialog(gettextCatalog.getString('Error'), gettextCatalog.getString('Failed to connect: {{message}}', { message: message }));
                    }
                );
            } else {
                $scope.DownloadURL = AppService.get_export_url($scope.BackupID, $scope.UseEncryption ? $scope.Passphrase : null, $scope.ExportPasswords);
                $scope.Completed = true;
            }

        }

        // Make checks that do not require user input
        $scope.fileEncrypted = false;
        if ($scope.UseEncryption && $scope.ExportType == 'file') {
            if (($scope.Passphrase || '').trim().length == 0) {
                DialogService.dialog(gettextCatalog.getString('No passphrase entered'), gettextCatalog.getString('To export without a passphrase, uncheck the "Encrypt file" box'));
                return;
            } else {
               $scope.fileEncrypted = true;
            }
        }

        // Chain various checks that require user input
        warnUnencryptedPasswords(function() { getExport(); });
    }
});
<|endoftext|>


<commit_before>const fs = require('fs');

const mysql_real_escape_string = (str) => {
    return str.replace(/[\0\x08\x09\x1a\n\r"'\\\%]/g, function(char) {
        switch (char) {
            case "\0":
                return "\\0";
            case "\x08":
                return "\\b";
            case "\x09":
                return "\\t";
            case "\x1a":
                return "\\z";
            case "\n":
                return "\\n";
            case "\r":
                return "\\r";
            case "\"":
            case "'":
            case "\\":
            case "%":
                return "\\" + char; // prepends a backslash to backslash, percent,
                // and double/single quotes
        }
    });
};

module.exports = (x) => {
    let flat = [{
            "name": "ns_vid",
            "value": x.ns_vid || null,
            "type": "string"
        },
        {
            "name": "ns_utc",
            "value": x.ns_utc || null,
            "type": "number"
        },
        {
            "name": "date",
            "value": x.date || null,
            "type": "string"
        },
        // {
        //     "name": "agent",
        //     "value": x.agent || null,
        //     "type": "string"
        // },
        {
            "name": "ip",
            "value": x.ip || null,
            "type": "string"
        },
        {
            "name": "screen_resolution",
            "value": x.screen_resolution || null,
            "type": "string"
        },
        {
            "name": "ns_v_platform",
            "value": x.ns_v_platform || null,
            "type": "string"
        },
        {
            "name": "ns_jspageurl",
            "value": x.ns_jspageurl || null,
            "type": "string"
        },
        {
            "name": "referrer",
            "value": x.referrer || null,
            "type": "string"
        },
        {
            "name": "type",
            "value": x.type || null,
            "type": "string"
        },
        {
            "name": "bbc_name",
            "value": x.name || null,
            "type": "string"
        },
        {
            "name": "bbc_section",
            "value": x.section || null,
            "type": "string"
        },
        {
            "name": "bbc_page_type",
            "value": x.page_type || null,
            "type": "string"
        },
        {
            "name": "bbc_site_type",
            "value": x.app_type || null,
            "type": "string"
        },
        {
            "name": "bbc_site_name",
            "value": x.app_name || null,
            "type": "string"
        },
        {
            "name": "bbc_service_name",
            "value": x.bbc_site || null,
            "type": "string"
        },
        {
            "name": "bbc_referring_object",
            "value": x.referring_object || null,
            "type": "string"
        },
        {
            "name": "bbc_action_name",
            "value": x.action_name || null,
            "type": "string"
        },
        {
            "name": "bbc_action_type",
            "value": x.action_type || null,
            "type": "string"
        },
        {
            "name": "bbc_postid",
            "value": x.postID || null,
            "type": "string"
        },
        {
            "name": "bbc_ocid",
            "value": x.ocid || null,
            "type": "string"
        },
        {
            "name": "bbc_cps_asset_id",
            "value": x.cps_asset_id || null,
            "type": "string"
        },
        {
            "name": "bbc_app_name",
            "value": x.app && x.app.name || null,
            "type": "string"
        },
        {
            "name": "bbc_app_major",
            "value": x.app && x.app.major || null,
            "type": "number"
        },
        {
            "name": "bbc_app_minor",
            "value": x.app && x.app.minor || null,
            "type": "number"
        },
        {
            "name": "loc_range_lat",
            "value": x.loc && x.loc.ll[0] || null,
            "type": "number"
        },
        {
            "name": "loc_range_long",
            "value": x.loc && x.loc.ll[1] || null,
            "type": "number"
        },
        {
            "name": "loc_country",
            "value": x.loc && x.loc.country || null,
            "type": "string"
        },
        {
            "name": "loc_region",
            "value": x.loc && x.loc.region || null,
            "type": "string"
        },
        {
            "name": "loc_city",
            "value": x.loc && x.loc.city || null,
            "type": "string"
        },
        {
            "name": "loc_cont",
            "value": x.loc && x.loc.cont || null,
            "type": "string"
        },
        {
            "name": "ua_family",
            "value": x.ua && x.ua.family || null,
            "type": "string"
        },
        {
            "name": "ua_major",
            "value": x.ua && x.ua.major || null,
            "type": "number"
        },
        {
            "name": "ua_minor",
            "value": x.ua && x.ua.minor || null,
            "type": "number"
        },
        {
            "name": "ua_patch",
            "value": x.ua && x.ua.patch || null,
            "type": "number"
        },
        {
            "name": "ua_device_family",
            "value": x.ua && x.ua.device && x.ua.device.family || null,
            "type": "string"
        },
        {
            "name": "ua_device_major",
            "value": x.ua && x.ua.device && x.ua.device.major || null,
            "type": "number"
        },
        {
            "name": "ua_device_minor",
            "value": x.ua && x.ua.device && x.ua.device.minor || null,
            "type": "number"
        },
        {
            "name": "ua_device_patch",
            "value": x.ua && x.ua.device && x.ua.device.patch || null,
            "type": "number"
        },
        {
            "name": "ua_os_family",
            "value": x.ua && x.ua.os && x.ua.os.family || null,
            "type": "string"
        },
        {
            "name": "ua_os_major",
            "value": x.ua && x.ua.os && x.ua.os.major || null,
            "type": "number"
        },
        {
            "name": "ua_os_minor",
            "value": x.ua && x.ua.os && x.ua.os.minor || null,
            "type": "number"
        },
        {
            "name": "ua_os_patch",
            "value": x.ua && x.ua.os && x.ua.os.patch || null,
            "type": "number"
        },
        {
            "name": "rp_type",
            "value": x.rp && x.rp.type || null,
            "type": "string"
        },
        {
            "name": "rp_name",
            "value": x.rp && x.rp.name || null,
            "type": "string"
        },
        {
            "name": "rp_host",
            "value": x.rp && x.rp.host || null,
            "type": "string"
        },
        {
            "name": "rp_page",
            "value": x.rp && x.rp.page || null,
            "type": "string"
        },
        {
            "name": "rp_search",
            "value": x.rp && x.rp.search || null,
            "type": "string"
        }
    ];

    let line = '';
    let i = 0;
    for (let row in flat) {
        if (i === 0) {
            if (flat[row].value === null) {
                line += 'NULL';
            } else if (flat[row].value !== undefined && flat[row].type === 'string') {
                line += "'" + mysql_real_escape_string(flat[row].value) + "'";
            } else {
                line += Number(flat[row].value);
                let num = Number(flat[row].value);
                if (num !== 'NaN') {
                    line += num;
                } else {
                    line += '0';
                }
            }
        } else {
            if (flat[row].value === null) {
                line += ', NULL';
            } else if (flat[row].value !== undefined && flat[row].type === 'string') {
                line += ", '" + mysql_real_escape_string(flat[row].value) + "'";
            } else {
                let num = Number(flat[row].value);
                if (num !== 'NaN') {
                    line += ', ' + num;
                } else {
                    line += ', 0';
                }
            }
        }
        i++;
    }
    line += '\n';
    fs.appendFileSync('./temp.csv', line);
    return null;
};<commit_msg>idiot<commit_after>const fs = require('fs');

const mysql_real_escape_string = (str) => {
    return str.replace(/[\0\x08\x09\x1a\n\r"'\\\%]/g, function(char) {
        switch (char) {
            case "\0":
                return "\\0";
            case "\x08":
                return "\\b";
            case "\x09":
                return "\\t";
            case "\x1a":
                return "\\z";
            case "\n":
                return "\\n";
            case "\r":
                return "\\r";
            case "\"":
            case "'":
            case "\\":
            case "%":
                return "\\" + char; // prepends a backslash to backslash, percent,
                // and double/single quotes
        }
    });
};

module.exports = (x) => {
    let flat = [{
            "name": "ns_vid",
            "value": x.ns_vid || null,
            "type": "string"
        },
        {
            "name": "ns_utc",
            "value": x.ns_utc || null,
            "type": "number"
        },
        {
            "name": "date",
            "value": x.date || null,
            "type": "string"
        },
        // {
        //     "name": "agent",
        //     "value": x.agent || null,
        //     "type": "string"
        // },
        {
            "name": "ip",
            "value": x.ip || null,
            "type": "string"
        },
        {
            "name": "screen_resolution",
            "value": x.screen_resolution || null,
            "type": "string"
        },
        {
            "name": "ns_v_platform",
            "value": x.ns_v_platform || null,
            "type": "string"
        },
        {
            "name": "ns_jspageurl",
            "value": x.ns_jspageurl || null,
            "type": "string"
        },
        {
            "name": "referrer",
            "value": x.referrer || null,
            "type": "string"
        },
        {
            "name": "type",
            "value": x.type || null,
            "type": "string"
        },
        {
            "name": "bbc_name",
            "value": x.name || null,
            "type": "string"
        },
        {
            "name": "bbc_section",
            "value": x.section || null,
            "type": "string"
        },
        {
            "name": "bbc_page_type",
            "value": x.page_type || null,
            "type": "string"
        },
        {
            "name": "bbc_site_type",
            "value": x.app_type || null,
            "type": "string"
        },
        {
            "name": "bbc_site_name",
            "value": x.app_name || null,
            "type": "string"
        },
        {
            "name": "bbc_service_name",
            "value": x.bbc_site || null,
            "type": "string"
        },
        {
            "name": "bbc_referring_object",
            "value": x.referring_object || null,
            "type": "string"
        },
        {
            "name": "bbc_action_name",
            "value": x.action_name || null,
            "type": "string"
        },
        {
            "name": "bbc_action_type",
            "value": x.action_type || null,
            "type": "string"
        },
        {
            "name": "bbc_postid",
            "value": x.postID || null,
            "type": "string"
        },
        {
            "name": "bbc_ocid",
            "value": x.ocid || null,
            "type": "string"
        },
        {
            "name": "bbc_cps_asset_id",
            "value": x.cps_asset_id || null,
            "type": "string"
        },
        {
            "name": "bbc_app_name",
            "value": x.app && x.app.name || null,
            "type": "string"
        },
        {
            "name": "bbc_app_major",
            "value": x.app && x.app.major || null,
            "type": "number"
        },
        {
            "name": "bbc_app_minor",
            "value": x.app && x.app.minor || null,
            "type": "number"
        },
        {
            "name": "loc_range_lat",
            "value": x.loc && x.loc.ll[0] || null,
            "type": "number"
        },
        {
            "name": "loc_range_long",
            "value": x.loc && x.loc.ll[1] || null,
            "type": "number"
        },
        {
            "name": "loc_country",
            "value": x.loc && x.loc.country || null,
            "type": "string"
        },
        {
            "name": "loc_region",
            "value": x.loc && x.loc.region || null,
            "type": "string"
        },
        {
            "name": "loc_city",
            "value": x.loc && x.loc.city || null,
            "type": "string"
        },
        {
            "name": "loc_cont",
            "value": x.loc && x.loc.cont || null,
            "type": "string"
        },
        {
            "name": "ua_family",
            "value": x.ua && x.ua.family || null,
            "type": "string"
        },
        {
            "name": "ua_major",
            "value": x.ua && x.ua.major || null,
            "type": "number"
        },
        {
            "name": "ua_minor",
            "value": x.ua && x.ua.minor || null,
            "type": "number"
        },
        {
            "name": "ua_patch",
            "value": x.ua && x.ua.patch || null,
            "type": "number"
        },
        {
            "name": "ua_device_family",
            "value": x.ua && x.ua.device && x.ua.device.family || null,
            "type": "string"
        },
        {
            "name": "ua_device_major",
            "value": x.ua && x.ua.device && x.ua.device.major || null,
            "type": "number"
        },
        {
            "name": "ua_device_minor",
            "value": x.ua && x.ua.device && x.ua.device.minor || null,
            "type": "number"
        },
        {
            "name": "ua_device_patch",
            "value": x.ua && x.ua.device && x.ua.device.patch || null,
            "type": "number"
        },
        {
            "name": "ua_os_family",
            "value": x.ua && x.ua.os && x.ua.os.family || null,
            "type": "string"
        },
        {
            "name": "ua_os_major",
            "value": x.ua && x.ua.os && x.ua.os.major || null,
            "type": "number"
        },
        {
            "name": "ua_os_minor",
            "value": x.ua && x.ua.os && x.ua.os.minor || null,
            "type": "number"
        },
        {
            "name": "ua_os_patch",
            "value": x.ua && x.ua.os && x.ua.os.patch || null,
            "type": "number"
        },
        {
            "name": "rp_type",
            "value": x.rp && x.rp.type || null,
            "type": "string"
        },
        {
            "name": "rp_name",
            "value": x.rp && x.rp.name || null,
            "type": "string"
        },
        {
            "name": "rp_host",
            "value": x.rp && x.rp.host || null,
            "type": "string"
        },
        {
            "name": "rp_page",
            "value": x.rp && x.rp.page || null,
            "type": "string"
        },
        {
            "name": "rp_search",
            "value": x.rp && x.rp.search || null,
            "type": "string"
        }
    ];

    let line = '';
    let i = 0;
    for (let row in flat) {
        if (i === 0) {
            if (flat[row].value === null) {
                line += 'NULL';
            } else if (flat[row].value !== undefined && flat[row].type === 'string') {
                line += "'" + mysql_real_escape_string(flat[row].value) + "'";
            } else {
                let num = Number(flat[row].value);
                if (num !== 'NaN') {
                    line += num;
                } else {
                    line += '0';
                }
            }
        } else {
            if (flat[row].value === null) {
                line += ', NULL';
            } else if (flat[row].value !== undefined && flat[row].type === 'string') {
                line += ", '" + mysql_real_escape_string(flat[row].value) + "'";
            } else {
                let num = Number(flat[row].value);
                if (num !== 'NaN') {
                    line += ', ' + num;
                } else {
                    line += ', 0';
                }
            }
        }
        i++;
    }
    line += '\n';
    fs.appendFileSync('./temp.csv', line);
    return null;
};<|endoftext|>