text:
//global for tracking open and focused toolbar panels on refresh
var openGroups = [];
var focusedEl = null;

//backbutton and hash bookmarks support
var hash = {
	storedHash: '',
	currentTabHash: '', //The hash that's only stored on a tab switch
	cache: '',
	interval: null,
	listen: true, // listen to hash changes?

	 // start listening again
	startListening: function() {
		setTimeout(function(){hash.listen = true;}, 600);
	},
	 // stop listening to hash changes
	stopListening:function(){hash.listen = false;},
	//check if hash has changed
	checkHashChange:function(){
		var locStr = hash.currHash();
		if(hash.storedHash != locStr) {
			if(hash.listen == true) hash.refreshToHash(); ////update was made by back button
			hash.storedHash = locStr;
		}
		if(!hash.interval) hash.interval = setInterval(hash.checkHashChange, 500);
	},

	//refresh to a certain hash
	refreshToHash: function(locStr) {
		if(locStr) var newHash = true;
		locStr = locStr || hash.currHash();
		frmUpdateCSS(locStr);
		// remember which groups are open
		openGroups = [];
		jQuery('div.theme-group-content').each(function(i){
			if(jQuery(this).is(':visible')){openGroups.push(i);}
		});

		// remember any focused element
		focusedEl = null;
		jQuery('form input, form select, form .texturePicker').each(function(i){
			if(jQuery(this).is('.focus')){focusedEl = i;}
		});

		// if the hash is passed
		if(newHash){ hash.updateHash(locStr, true); }
	},

	updateHash: function(locStr, ignore) {
		if(ignore == true){ hash.stopListening(); }
		window.location.hash = locStr;
		if(ignore == true){
			hash.storedHash = locStr;
			hash.startListening();
		}

	},

	clean: function(locStr){return locStr.replace(/%23/g, "").replace(/[\?#]+/g, "");},

	currHash: function(){return hash.clean(window.location.hash);},

	currSearch: function(){return hash.clean(window.location.search);},

	init: function(){
		hash.storedHash = '';
		hash.checkHashChange();
	}
};

jQuery.fn.spinDown = function() {
	return this.click(function() {
		var $this = jQuery(this);
		$this.next().slideToggle(100);
		$this.parent().siblings().children('.state-active').click(); //close open tabs
		$this.prev().toggleClass('not-active');
		$this.find('.icon').toggleClass('icon-triangle-1-s').end().toggleClass('state-active');
		//jQuery('li.ui-state-default .ui-state-active').removeClass('ui-state-active');
		$this.find('.ui-icon').toggleClass('ui-icon-triangle-1-s').end().toggleClass('ui-state-active');
		if($this.is('.corner-all')) { $this.removeClass('corner-all').addClass('corner-top'); }
		else if($this.is('.corner-top')) { $this.removeClass('corner-top').addClass('corner-all'); }
		if($this.is('.ui-corner-all')) { $this.removeClass('ui-corner-all').addClass('ui-corner-top'); }
		else if($this.is('.ui-corner-top')) { $this.removeClass('ui-corner-top').addClass('ui-corner-all'); }
		return false;
	});
};

// validation for hex inputs
jQuery.fn.validHex = function() {
	return this.each(function() {
		var value = jQuery(this).val();
		value = value.replace(/[^#a-fA-F0-9]/g, ''); // non [#a-f0-9]
		if(value.match(/#/g) && value.match(/#/g).length > 1) value = value.replace(/#/g, ''); // ##
		if(value.indexOf('#') == -1) value = '#'+value; // no #
		if(value.length > 7) value = value.substr(0,7); // too many chars
		jQuery(this).val(value);
	});
};

//color pickers setup (sets bg color of inputs)
jQuery.fn.applyFarbtastic = function() {
	return this.each(function() {
		jQuery('
').farbtastic(this).remove();
	});
};

//function called after a change event in the form
function formChange(){
	var locStr = jQuery('.frm_settings_page input, .frm_settings_page select, .frm_settings_page textarea').serialize();
	locStr = hash.clean(locStr);
	frmUpdateCSS(locStr);
	hash.updateHash(locStr, true);
};

jQuery(document).ready(function($){
    // hover class toggles in app panel
    jQuery('.state-default').hover(
    	function(){ jQuery(this).addClass('state-hover'); },
    	function(){ jQuery(this).removeClass('state-hover'); }
    );

    $('div.theme-group .theme-group-header').addClass('corner-all').spinDown();

    // focus and blur classes in form
	$('input, select').focus(function(){
		$('input.focus, select.focus').removeClass('focus');
		$(this).addClass('focus');
	}).blur(function(){ $(this).removeClass('focus');});

	// change event in form
	$('form[name="frm_settings_form"] .styling_settings').bind('change', function() {
		formChange();
		return false;
	});

	// hex inputs
	$('input.hex').validHex().keyup(function() {$(this).validHex();})
		.click(function(){
			$(this).addClass('focus');
			$('#picker').remove();
			$('div.picker-on').removeClass('picker-on');
			$('div.texturePicker ul:visible').hide(0).parent().css('position', 'static');
			$(this).after('

').parent().addClass('picker-on');
			$('#picker').farbtastic(this);
			return false;
		})
		.wrap('

')
		.applyFarbtastic();

	$('body').click(function() {
		$('div.picker-on').removeClass('picker-on');
		$('#picker').remove();
		$('input.focus, select.focus').removeClass('focus');
		$('div.texturePicker ul:visible').hide().parent().css('position', 'static');
	});

	// texture pickers from select menus
		$('select.texture').each(function() {

			$(this).after('

');
			var texturePicker = $(this).next();
			var a = texturePicker.find('a');
			var ul = texturePicker.find('ul');
			var sIndex = texturePicker.prev().get(0).selectedIndex;

			// scrape options
			$(this).find('option').each(function(){
				ul.append('
'+ $(this).text() +'
');
				if($(this).get(0).index == sIndex){texturePicker.attr('title',$(this).text()).css('background', '#FFF url('+$(this).attr('value')+') 50% 50% no-repeat');}
			});

			ul.find('li').click(function() {
				texturePicker.prev().get(0).selectedIndex = texturePicker.prev().find('option[value="'+ $(this).attr('class') +'"]').get(0).index;
				texturePicker.attr('title',$(this).text()).css('background', '#FFF url('+$(this).attr('class')+')  50% 50% no-repeat');
				$('.frm_error_style img').attr('src',$(this).attr('class'));
				//ul.fadeOut(100);
				formChange();
				return false;
			});

			// hide the menu and select el
			ul.hide();

			// show/hide of menus
			texturePicker.click(function() {
				$(this).addClass('focus');
				$('#picker').remove();
				var showIt;
				if(ul.is(':hidden')){showIt = true;}
				$('div.texturePicker ul:visible').hide().parent().css('position', 'static');
				if(showIt == true){
					texturePicker.css('position', 'relative');
					ul.show();
				}
				return false;
			});
		});
});

// $Id: farbtastic.js,v 1.2 2007/01/08 22:53:01 unconed Exp $
// Farbtastic 1.2

jQuery.fn.farbtastic = function (callback) {
jQuery.farbtastic(this, callback);
return this;
};

jQuery.farbtastic = function (container, callback) {
var container = jQuery(container).get(0);
return container.farbtastic || (container.farbtastic = new jQuery._farbtastic(container, callback));
};

jQuery._farbtastic = function (container, callback) {
// Store farbtastic object
var fb = this;

// Insert markup
jQuery(container).html('

');
var e = jQuery('.farbtastic', container);
fb.wheel = jQuery('.wheel', container).get(0);
// Dimensions
fb.radius = 84;
fb.square = 100;
fb.width = 194;

// Fix background PNGs in IE6
if (navigator.appVersion.match(/MSIE [0-6]\./)) {
jQuery('*', e).each(function () {
if (this.currentStyle.backgroundImage != 'none') {
var image = this.currentStyle.backgroundImage;
image = this.currentStyle.backgroundImage.substring(5, image.length - 2);
jQuery(this).css({
'backgroundImage': 'none',
'filter': "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='" + image + "')"
});
}
});
}

/**
* Link to the given element(s) or callback.
*/
fb.linkTo = function (callback) {
// Unbind previous nodes
if (typeof fb.callback == 'object'){jQuery(fb.callback).unbind('keyup', fb.updateValue);}

// Reset color
fb.color = null;

// Bind callback or elements
if (typeof callback == 'function'){fb.callback = callback;}
else if (typeof callback == 'object' || typeof callback == 'string') {
fb.callback = jQuery(callback);
fb.callback.bind('keyup', fb.updateValue);
if (fb.callback.get(0).value){fb.setColor(fb.callback.get(0).value);}
}
return this;
};
fb.updateValue = function (event) {
if (this.value && this.value != fb.color){fb.setColor(this.value);}
};

/**
* Change color with HTML syntax #123456
*/
fb.setColor = function (color) {
var unpack = fb.unpack(color);
if (fb.color != color && unpack) {
fb.color = color;
fb.rgb = unpack;
fb.hsl = fb.RGBToHSL(fb.rgb);
fb.updateDisplay();
}
return this;
};

/**
* Change color with HSL triplet [0..1, 0..1, 0..1]
*/
fb.setHSL = function (hsl) {
fb.hsl = hsl;
fb.rgb = fb.HSLToRGB(hsl);
fb.color = fb.pack(fb.rgb);
fb.updateDisplay();
return this;
};

/////////////////////////////////////////////////////

/**
* Retrieve the coordinates of the given event relative to the center
* of the widget.
*/
fb.widgetCoords = function (event) {
var x, y;
var el = event.target || event.srcElement;
var reference = fb.wheel;

if (typeof event.offsetX != 'undefined') {
// Use offset coordinates and find common offsetParent
var pos = { x: event.offsetX, y: event.offsetY };

// Send the coordinates upwards through the offsetParent chain.
var e = el;
while (e) {
e.mouseX = pos.x;
e.mouseY = pos.y;
pos.x += e.offsetLeft;
pos.y += e.offsetTop;
e = e.offsetParent;
};

// Look for the coordinates starting from the wheel widget.
var e = reference;
var offset = { x: 0, y: 0 };
while (e) {
if (typeof e.mouseX != 'undefined') {
x = e.mouseX - offset.x;
y = e.mouseY - offset.y;
break;
}
offset.x += e.offsetLeft;
offset.y += e.offsetTop;
e = e.offsetParent;
}

// Reset stored coordinates
e = el;
while (e) {
e.mouseX = undefined;
e.mouseY = undefined;
e = e.offsetParent;
}
}
else {
// Use absolute coordinates
var pos = fb.absolutePosition(reference);
x = (event.pageX || 0*(event.clientX + jQuery('html').get(0).scrollLeft)) - pos.x;
y = (event.pageY || 0*(event.clientY + jQuery('html').get(0).scrollTop)) - pos.y;
}
// Subtract distance to middle
return { x: x - fb.width / 2, y: y - fb.width / 2 };
};

/**
* Mousedown handler
*/
fb.mousedown = function (event) {
// Capture mouse
if (!document.dragging) {
jQuery(document).bind('mousemove', fb.mousemove).bind('mouseup', fb.mouseup);
document.dragging = true;
};

// Check which area is being dragged
var pos = fb.widgetCoords(event);
fb.circleDrag = Math.max(Math.abs(pos.x), Math.abs(pos.y)) * 2 > fb.square;

// Process
fb.mousemove(event);
return false;
};

/**
* Mousemove handler
*/
fb.mousemove = function (event) {
// Get coordinates relative to color picker center
var pos = fb.widgetCoords(event);

// Set new HSL parameters
if (fb.circleDrag) {
var hue = Math.atan2(pos.x, -pos.y) / 6.28;
if (hue < 0) hue += 1;
fb.setHSL([hue, fb.hsl[1], fb.hsl[2]]);
}else{
var sat = Math.max(0, Math.min(1, -(pos.x / fb.square) + .5));
var lum = Math.max(0, Math.min(1, -(pos.y / fb.square) + .5));
fb.setHSL([fb.hsl[0], sat, lum]);
}
return false;
};

/**
* Mouseup handler
*/
fb.mouseup = function () {
// Uncapture mouse
jQuery(document).unbind('mousemove', fb.mousemove);
jQuery(document).unbind('mouseup', fb.mouseup);
document.dragging = false;
formChange();
};

/**
* Update the markers and styles
*/
fb.updateDisplay = function () {
// Markers
var angle = fb.hsl[0] * 6.28;
jQuery('.h-marker', e).css({
left: Math.round(Math.sin(angle) * fb.radius + fb.width / 2) + 'px',
top: Math.round(-Math.cos(angle) * fb.radius + fb.width / 2) + 'px'
});

jQuery('.sl-marker', e).css({
left: Math.round(fb.square * (.5 - fb.hsl[1]) + fb.width / 2) + 'px',
top: Math.round(fb.square * (.5 - fb.hsl[2]) + fb.width / 2) + 'px'
});

// Saturation/Luminance gradient
jQuery('.color', e).css('backgroundColor', fb.pack(fb.HSLToRGB([fb.hsl[0], 1, 0.5])));

// Linked elements or callback
if (typeof fb.callback == 'object') {
// Set background/foreground color
jQuery(fb.callback).css({
backgroundColor: fb.color,
color: fb.hsl[2] > 0.5 ? '#000' : '#fff'
});

// Change linked value
jQuery(fb.callback).each(function() {
if (this.value && this.value != fb.color){this.value = fb.color;}
});
}else if (typeof fb.callback == 'function'){fb.callback.call(fb, fb.color);}
};

/**
* Get absolute position of element
*/
fb.absolutePosition = function (el) {
var r = { x: el.offsetLeft, y: el.offsetTop };
// Resolve relative to offsetParent
if (el.offsetParent) {
var tmp = fb.absolutePosition(el.offsetParent);
r.x += tmp.x;
r.y += tmp.y;
}
return r;
};

/* Various color utility functions */
fb.pack = function (rgb) {
var r = Math.round(rgb[0] * 255);
var g = Math.round(rgb[1] * 255);
var b = Math.round(rgb[2] * 255);
return '#' + (r < 16 ? '0' : '') + r.toString(16) +
(g < 16 ? '0' : '') + g.toString(16) +
(b < 16 ? '0' : '') + b.toString(16);
};

fb.unpack = function (color) {
if (color.length == 7) {
return [parseInt('0x' + color.substring(1, 3)) / 255,
parseInt('0x' + color.substring(3, 5)) / 255,
parseInt('0x' + color.substring(5, 7)) / 255];
}
else if (color.length == 4) {
return [parseInt('0x' + color.substring(1, 2)) / 15,
parseInt('0x' + color.substring(2, 3)) / 15,
parseInt('0x' + color.substring(3, 4)) / 15];
}
};

fb.HSLToRGB = function (hsl) {
var m1, m2, r, g, b;
var h = hsl[0], s = hsl[1], l = hsl[2];
m2 = (l <= 0.5) ? l * (s + 1) : l + s - l*s;
m1 = l * 2 - m2;
return [this.hueToRGB(m1, m2, h+0.33333),
this.hueToRGB(m1, m2, h),
this.hueToRGB(m1, m2, h-0.33333)];
};

fb.hueToRGB = function (m1, m2, h) {
h = (h < 0) ? h + 1 : ((h > 1) ? h - 1 : h);
if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
if (h * 2 < 1) return m2;
if (h * 3 < 2) return m1 + (m2 - m1) * (0.66666 - h) * 6;
return m1;
};

fb.RGBToHSL = function (rgb) {
var min, max, delta, h, s, l;
var r = rgb[0], g = rgb[1], b = rgb[2];
min = Math.min(r, Math.min(g, b));
max = Math.max(r, Math.max(g, b));
delta = max - min;
l = (min + max) / 2;
s = 0;
if (l > 0 && l < 1) {
s = delta / (l < 0.5 ? (2 * l) : (2 - 2 * l));
}
h = 0;
if (delta > 0) {
if (max == r && max != g) h += (g - b) / delta;
if (max == g && max != b) h += (2 + (b - r) / delta);
if (max == b && max != r) h += (4 + (r - g) / delta);
h /= 6;
}
return [h, s, l];
};

// Install mousedown handler (the others are set on the document on-demand)
jQuery('*', e).mousedown(fb.mousedown);

// Init color
fb.setColor('#000000');

// Set linked elements/callback
if (callback) {
fb.linkTo(callback);
}
};


text:
import re
import os, sys
sys.path.insert(0, os.getcwd())
from code.common import logging, dict_get, run_command, args_to_string
import code.common.arguments as common_args

scenario_result_regex = {
    "SingleStream": r"([0-9]+th percentile latency \(ns\) +: [0-9\.]+)",
    "MultiStream": r"(Samples per query : [0-9\.]+)",
    "Offline": r"(Samples per second: [0-9\.]+)",
    "Server": r"(Scheduled samples per second +: [0-9\.]+)",
}

class GNMTHarness():

    def __init__(self, args, name=""):
        print (args)
        self.args = args
        self.name = name
        self.verbose = dict_get(args, "verbose", default=None)
        if self.verbose:
            logging.info("===== Harness arguments for {:} =====".format(name))
            for key in args:
                logging.info("{:}={:}".format(key, args[key]))

        self.system_id = args["system_id"]
        self.scenario = args["scenario"]
        self.engine_dir = "./build/engines/{:}/{:}/{:}".format(self.system_id, self.name, self.scenario)
        self.precision = args["precision"]

        self.has_gpu = dict_get(args, "gpu_batch_size", default=None) is not None
        self.has_dla = dict_get(args, "dla_batch_size", default=None) is not None

        self.enumerate_engines()

    def check_dir_exists(self, d):
        if not os.path.isdir(d):
            raise RuntimeError("Directory {:} does not exist.".format(d))

    def enumerate_engines(self):
        self.engines = []

        if self.scenario == "Server":
            batch_sizes = self.args["batch_sizes"]
        else:
            batch_sizes = [ self.args["gpu_batch_size"] ]

        for batch_size in batch_sizes:
            engine_name = self._get_engine_name("gpu", batch_size)
            self.check_dir_exists(engine_name)
            self.engines.append(engine_name)

    def _get_engine_name(self, device_type, batch_size):
        return "{:}/{:}-{:}-{:}-b{:}-{:}.plan".format(self.engine_dir, self.name, self.scenario,
                device_type, batch_size, self.precision)

    def build_default_flags(self, custom_args):
        flag_dict = {}
        flag_dict["verbose"] = self.verbose

        # Generate flags for logfile names.
        log_dir = os.path.join(self.args["log_dir"], self.system_id, self.name, self.scenario)
        if not os.path.exists(log_dir):
            os.makedirs(log_dir)
        flag_dict["logfile_outdir"] = log_dir
        flag_dict["logfile_prefix"] = "mlperf_log_"

        # Handle custom arguments
        for arg in custom_args:
            val = dict_get(self.args, arg, None)
            if val is not None:
                flag_dict[arg] = val

        return flag_dict

    def build_configs(self, flag_dict):
        # ideally, these values would be in mlperf.conf.  since they aren't, write them into user.conf using these values.
        # QSL Seed:      0x2b7e 1516 28ae d2a6
        # Schedule Seed: 0x3243 f6a8 885a 308d
        # Sample Seed:   0x093c 467e 37db 0c7a
        seeds_map = {
            "qsl_rng_seed": "3133965575612453542",
            "sample_index_rng_seed": "665484352860916858",
            "schedule_rng_seed": "3622009729038561421",
        }

        # required settings for each scenario
        required_settings_map = {
            "SingleStream": ["qsl_rng_seed", "sample_index_rng_seed", "schedule_rng_seed"], # "single_stream_expected_latency_ns", See: https://github.com/mlperf/inference/issues/471
            "Offline": ["offline_expected_qps", "qsl_rng_seed", "sample_index_rng_seed", "schedule_rng_seed"],
            "MultiStream": ["multi_stream_samples_per_query", "qsl_rng_seed", "sample_index_rng_seed", "schedule_rng_seed"],
            "Server": ["server_target_qps", "qsl_rng_seed", "sample_index_rng_seed", "schedule_rng_seed"],
        }

        # optional settings that we support overriding
        optional_settings_map = {
            "SingleStream": [ "single_stream_target_latency_percentile", "min_query_count" ],
            "Offline": [ "min_query_count" ],
            "MultiStream": [ "multi_stream_target_qps", "multi_stream_target_latency_ns", "multi_stream_max_async_queries", "multi_stream_target_latency_percentile", "min_query_count" ],
            "Server": [ "server_target_latency_percentile", "server_target_latency_ns", "min_query_count" ],
        }

        # option name to config file map
        options_map = {
            "single_stream_expected_latency_ns": "target_latency",
            "offline_expected_qps": "target_qps",
            "multi_stream_samples_per_query": "samples_per_query",
            "server_target_qps": "target_qps",
        }

        parameter_scaling_map = {
            "target_latency": 1 / 1000000.0,
            "target_latency_percentile": 100.0,
        }

        system = self.system_id
        benchmark = self.name
        scenario = self.scenario

        mlperf_conf_path = "measurements/{:}/{:}/{:}/mlperf.conf".format(system, benchmark, scenario)
        user_conf_path = "measurements/{:}/{:}/{:}/user.conf".format(system, benchmark, scenario)

        # setup paths
        if "mlperf_conf_path" not in flag_dict:
            flag_dict["mlperf_conf_path"] = mlperf_conf_path
        if "user_conf_path" not in flag_dict:
            flag_dict["user_conf_path"] = user_conf_path

        # assign seed values
        for name, value in seeds_map.items():
            if name not in flag_dict:
                flag_dict[name] = value

        # auto-generate user.conf
        with open(user_conf_path, "w") as f:
            for param in required_settings_map[scenario]:
                param_name = param
                if param in options_map:
                    param_name = options_map[param]
                value = flag_dict[param]
                if param_name in parameter_scaling_map:
                    value = value * parameter_scaling_map[param_name]
                f.write("*.{:}.{:} = {:}\n".format(scenario, param_name, value))
                flag_dict[param] = None
            for param in optional_settings_map[scenario]:
                if param not in flag_dict: continue
                param_name = param
                if param in options_map:
                    param_name = options_map[param]
                value = flag_dict[param]
                if param_name in parameter_scaling_map:
                    value = value * parameter_scaling_map[param_name]
                f.write("*.{:}.{:} = {:}\n".format(scenario, param_name, value))
                flag_dict[param] = None

    def run_harness(self):
        executable = "./build/bin/harness_gnmt_default"
        harness_args = common_args.GNMT_HARNESS_ARGS

        self.check_file_exists(executable)
        flag_dict = self.build_default_flags(harness_args)

        # Scenario based arguments
        if self.scenario == "Offline":
            scenario_args = common_args.OFFLINE_PARAMS
        elif self.scenario == "SingleStream":
            scenario_args = common_args.SINGLE_STREAM_PARAMS
        else:
            scenario_args = []

        for key in scenario_args:
            flag_dict[key] = dict_get(self.args, "gpu_"+key, None)

        engine_flag = "engine" if len(self.engines) == 1 else "engines"
        flag_dict[engine_flag] = ",".join(self.engines)

        # Remove the batch size flags
        flag_dict["batch_sizes"] = None
        flag_dict["gpu_batch_size"] = None

        # Choose input file based on test mode
        if ((flag_dict.get("test_mode", None) == "PerformanceOnly" or flag_dict.get("test_mode", None) is None)
            and flag_dict.get("input_file_performance", None) is not None):
            flag_dict["input_file"] = flag_dict["input_file_performance"]
        elif flag_dict.get("input_file_accuracy", None) is not None:
            flag_dict["input_file"] = flag_dict["input_file_accuracy"]
        flag_dict["input_file_performance"] = None
        flag_dict["input_file_accuracy"] = None

        # Handle configurations
        self.build_configs(flag_dict)

        argstr = args_to_string(flag_dict)
        cmd = "{:} {:}".format(executable, argstr)
        output = run_command(cmd, get_output=True)

        # Return harness result.
        return self.harness_get_result(output, scenario_result_regex[self.scenario])

    def harness_get_result(self, output, regex):
        # All harness outputs should have a result string
        result_regex = re.compile(regex)
        result_string = ""

        # All but the server harness should have an output with a validity message
        valid_regex = re.compile(r"(Result is : (VALID|INVALID))")
        valid_string = ""

        # Iterate through the harness output
        for line in output:
            # Check for the result string
            result_match = result_regex.match(line)
            if not result_match is None:
                result_string = result_match.group(1)
                break

        for line in output:
            # Check for the validity string
            valid_match = valid_regex.match(line)
            if not valid_match is None:
                valid_string = valid_match.group(1)
                break

        if result_string == "":
            return "Cannot find performance result. Maybe you are running in AccuracyOnly mode."
        elif valid_string == "":
            return result_string + " but cannot find validity result."
        else:
            return result_string + " and " + valid_string

    def check_file_exists(self, f):
        if not os.path.isfile(f):
            raise RuntimeError("File {:} does not exist.".format(f))

redpajama_set_name: RedPajamaGithub


text:
<!doctype html>

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">

    <link rel="prefetch" href="../../../../ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js">

    <meta name="application-name" content="Python.org">
    <meta name="msapplication-tooltip" content="The official home of the Python Programming Language">
    <meta name="apple-mobile-web-app-title" content="Python.org">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="HandheldFriendly" content="True">
    <meta name="format-detection" content="telephone=no">
    <meta http-equiv="cleartype" content="on">
    <meta http-equiv="imagetoolbar" content="false">

    <link href="../../../static/stylesheets/style.css" rel="stylesheet" type="text/css" title="default" />
    <link href="../../../static/stylesheets/mq.css" rel="stylesheet" type="text/css" media="not print, braille, embossed, speech, tty" />

    <link rel="icon" type="image/x-icon" href="https://www.python.org/static/favicon.ico">
    <link rel="apple-touch-icon-precomposed" sizes="144x144" href="../../../static/apple-touch-icon-144x144-precomposed.png">
    <link rel="apple-touch-icon-precomposed" sizes="114x114" href="../../../static/apple-touch-icon-114x114-precomposed.png">
    <link rel="apple-touch-icon-precomposed" sizes="72x72" href="../../../static/apple-touch-icon-72x72-precomposed.png">
    <link rel="apple-touch-icon-precomposed" href="../../../static/apple-touch-icon-precomposed.png">
    <link rel="apple-touch-icon" href="../../../static/apple-touch-icon-precomposed.png">

    <meta name="msapplication-TileImage" content="/static/metro-icon-144x144-precomposed.png">
    <meta name="msapplication-TileColor" content="#3673a5">
    <meta name="msapplication-navbutton-color" content="#3673a5">

    <meta property="og:site_name" content="Python.org">
    <meta property="og:type" content="website">

    <title>PEP 0430 -- Migrating to Python 3 as the default online documentation | Python.org</title>
    <meta property="og:title" content="Welcome to Python.org">

    <meta name="description" content="The official home of the Python Programming Language">
    <meta name="og:description" content="The official home of the Python Programming Language">
    <meta name="keywords" content="Python programming language object oriented web free open source software license documentation download community">
    <meta property="og:tag" content="Python programming language object oriented web free open source software license documentation download community">
    <meta property="og:published_time" content="">
    <meta property="og:modified_time" content="">
    <meta property="og:author" content="">
    <meta property="og:section" content="">
    <meta property="og:url" content="">
    <meta property="og:image" content="">
    <meta property="og:video" content="">

    <link rel="author" href="https://www.python.org/static/humans.txt">

Notice: While Javascript is not essential for this website, your interaction with the content will be limited. Please turn Javascript on for the full experience.

                    Skip to content

                    ▼ Close

        Python

        PSF

        Docs

        PyPI

        Jobs

        Community

                    ▲ The Python Network

                    ≡ Menu<form class="search-the-site" action="https://www.python.org/search/" method="get">
                        <fieldset title="Search Python.org">

                            Search This Site
                            <input id="id-search-field" name="q" type="search" role="textbox" class="search-field" placeholder="Search" value="" tabindex="1">

                            <button type="submit" name="submit" id="submit" class="search-button" title="Submit this Search" tabindex="3">
                                GO
                            </button>

                        </fieldset>
                    </form>

                                A A

Smaller

Larger

Reset

                                Socialize

Google+

Facebook

Twitter

Chat on IRC

                                Sign In

Sign Up / Register

Sign In

        About

Applications

Quotes

Getting Started

Help

        Downloads

All releases

Source code

Windows

Mac OS X

Other Platforms

License

Alternative Implementations

        Documentation

Docs

Audio/Visual Talks

Beginner's Guide

Developer's Guide

FAQ

Non-English Docs

PEP Index

Python Books

        Community

Diversity

IRC

Mailing Lists

Python Conferences

Special Interest Groups

Python Wiki

Python Logo

Merchandise

Community Awards

        Success Stories

Arts

Business

Education

Engineering

Government

Scientific

Software Development

        News

Python News

Community News

PSF News

PyCon News

        Events

Python Events

User Group Events

Python Events Archive

User Group Events Archive

Submit an Event

        Python>>>

        Python Developer's Guide>>>

        PEP Index>>>

PEP 0430 -- Migrating to Python 3 as the default online documentation

PEP 0430 -- Migrating to Python 3 as the default online documentation

   <col class="field-name">
   </col>
   <col class="field-body">
   </col>

      PEP:

      430

      Title:

      Migrating to Python 3 as the default online documentation

      Author:

      Nick Coghlan <ncoghlan at gmail.com>

      BDFL-Delegate:

      Georg Brandl

      Status:

      Final

      Type:

      Informational

      Created:

      27-Oct-2012

    Contents

      Abstract

      Background

      Key Concerns

        Don't Confuse Beginners

        Don't Break Useful Resources

      Proposal

        Presented URLs

      Rationale

      Implementation

      References

      Copyright

     Abstract

    This PEP proposes a strategy for migrating the default version of the
Python documentation presented to users of Python when accessing
docs.python.org from 2.7 to Python 3.3.

    It proposes a backwards compatible scheme that preserves the meaning of
existing deep links in to the Python 2 documentation, while still
presenting the Python 3 documentation by default, and presenting the
Python 2 and 3 documentation in a way that avoids making the Python 3
documentation look like a second-class citizen.

     Background

    With the transition of the overall Python ecosystem from Python 2 to Python 3
still in progress, one question which arises periodically [

     1

    ,

     2

    ] is when
and how to handle the change from providing the Python 2 documentation as
the default version displayed at the docs.python.org root URL to providing
the Python 3 documentation.

     Key Concerns

    There are a couple of key concerns that any migration proposal needs to
address.

      Don't Confuse Beginners

     Many beginners learn Python through third party resources. These resources,
not all of which are online resources, may reference in to the python.org
online documentation for additional background and details.

     Importantly, even when the online documentation is updated, the "version
added" and "version changed" tags usually provide enough information for
users to adjust appropriately for the specific version they are using.

     While deep links in to the python.org documentation may occasionally break
within the Python 2 series, this is very rare.

     Migrating to Python 3 is a very different matter. Many links would break due
to renames and removals, and the "version added" and "version changed"
information for the Python 2 series is completely absent.

      Don't Break Useful Resources

     There are many useful Python resources out there, such as the mailing list
archives on python.org and question-and-answer sites like Stack Overflow,
where links are highly unlikely to be updated, no matter how much notice
is provided.

     Old posts and answers to questions all currently link to docs.python.org
expecting to get the Python 2 documentation at unqualified URLs. Links from
answers that relate to Python 3 are explicitly qualified with
     <tt class="docutils literal">
      /py3k/
     </tt>
     in
the path component.

     Proposal

    This PEP (based on an idea originally put forward back in May [

     3

    ]) is to

     not migrate

    the Python 2 specific deep links at all, and instead adopt a
scheme where all URLs presented to users on docs.python.org are qualified
appropriately with the relevant release series.

    Visitors to the root URL at
    <tt class="docutils literal">

      http://docs.python.org

    </tt>
    will be automatically
redirected to
    <tt class="docutils literal">

      http://docs.python.org/3/

    </tt>
    , but links deeper in
the version-specific hierarchy, such as to
    <tt class="docutils literal">

      http://docs.python.org/library/os

    </tt>
    , will instead be redirected to
a Python 2 specific link such as
    <tt class="docutils literal">

      http://docs.python.org/2/library/os

    </tt>
    .

    The specific subpaths which will be redirected to explicitly qualified
paths for the Python 2 docs are:

     <tt class="docutils literal">

       /c-api/

     </tt>

     <tt class="docutils literal">
      /distutils/
     </tt>

     <tt class="docutils literal">
      /extending/
     </tt>

     <tt class="docutils literal">
      /faq/
     </tt>

     <tt class="docutils literal">
      /howto/
     </tt>

     <tt class="docutils literal">
      /library/
     </tt>

     <tt class="docutils literal">
      /reference/
     </tt>

     <tt class="docutils literal">
      /tutorial/
     </tt>

     <tt class="docutils literal">
      /using/
     </tt>

     <tt class="docutils literal">
      /whatsnew/
     </tt>

     <tt class="docutils literal">
      /about.html
     </tt>

     <tt class="docutils literal">
      /bugs.html
     </tt>

     <tt class="docutils literal">
      /contents.html
     </tt>

     <tt class="docutils literal">
      /copyright.html
     </tt>

     <tt class="docutils literal">
      /license.html
     </tt>

     <tt class="docutils literal">
      /genindex.html
     </tt>

     <tt class="docutils literal">
      /glossary.html
     </tt>

     <tt class="docutils literal">

       /py-modindex.html

     </tt>

     <tt class="docutils literal">
      /search.html
     </tt>

    The existing
    <tt class="docutils literal">
     /py3k/
    </tt>
    subpath will be redirected to the new
    <tt class="docutils literal">
     /3/
    </tt>
    subpath.

      Presented URLs

     With this scheme, the following URLs would be presented to users after
resolution of any aliasing and rewriting rules:

      <tt class="docutils literal">

        http://docs.python.org/x/*

      </tt>

      <tt class="docutils literal">

        http://docs.python.org/x.y/*

      </tt>

      <tt class="docutils literal">

        http://docs.python.org/dev/*

      </tt>

      <tt class="docutils literal">

        http://docs.python.org/release/x.y.z/*

      </tt>

      <tt class="docutils literal">

        http://docs.python.org/devguide

      </tt>

     The
     <tt class="docutils literal">
      /x/
     </tt>
     URLs mean "give me the latest documentation for a released
version in this release series". It will draw the documentation from the
relevant maintenance branch in source control (this will always be the
2.7 branch for Python 2 and is currently 3.3 for Python 3). Differences
relative to previous versions in the release series will be available
through "version added" and "version changed" markers.

     The
     <tt class="docutils literal">
      /x.y/
     </tt>
     URLs mean "give me the latest documentation for this release".
It will draw the documentation from the relevant maintenance branch in
source control (or the default branch for the currently in development
version). It differs from the status quo in that the URLs will
actually remain available in the user's browser for easy copy and pasting.
(Currently, references to specific versions that are not the latest in their
release series will resolve to a stable URL for a specific maintenance
version in the "release" hierarchy, while the current latest version in the
release series resolves to the release series URL. This makes it hard to get
a "latest version specific URL", since it is always necessary to construct
them manually).

     The
     <tt class="docutils literal">
      /dev/
     </tt>
     URL means the documentation for the default branch in source
control.

     The
     <tt class="docutils literal">
      /release/x.y.x/
     </tt>
     URLs will refer to the documentation of those
releases, exactly as it was at the time of the release.

     The developer's guide is not version specific, and thus retains its own
stable
     <tt class="docutils literal">
      /devguide/
     </tt>
     URL.

     Rationale

    There is some desire to switch the unqualified references to mean Python 3
as a sign of confidence in Python 3. Such a move would either break a lot of
things, or else involve an awful lot of work to

     avoid

    breaking things.

    I believe we can get much the same effect without breaking the world by:

     Deprecating the use of unqualified references to the online
documentation (while promising to preserve the meaning of such
references indefinitely)

     Updating all python.org and python-dev controlled links to use
qualified references (excluding archived email)

     Redirecting visitors to the root of
     <tt class="docutils literal">

       http://docs.python.org

     </tt>
     to
     <tt class="docutils literal">

       http://docs.python.org/3.x

     </tt>

    Most importantly, because this scheme doesn't alter the behaviour of any
existing deep links, it could be implemented with a significantly shorter
warning period than would be required for a scheme that risked breaking
deep links, or started to redirect unqualified links to Python 3. The
only part of the scheme which would require any warning at all is the
step of redirecting the "

     http://docs.python.org/

    " landing page to the
Python 3.3 documentation.

    Namespaces are one honking great idea - let's do more of those.

    Note that the approach described in this PEP gives two ways to access the
content of the default branch: as
    <tt class="docutils literal">
     /dev/
    </tt>
    or using the appropriate
    <tt class="docutils literal">
     /x.y/
    </tt>
    reference. This is deliberate, as the default branch is referenced
for two different purposes:

     to provide additional information when discussing an upcoming feature of
the next release (a
     <tt class="docutils literal">
      /x.y/
     </tt>
     URL is appropriate)

     to provide a stable destination for developers to access the documentation
of the next feature release, regardless of the version (a
     <tt class="docutils literal">
      /dev/
     </tt>
     URL is
appropriate)

     Implementation

    The URLs on docs.python.org are controlled by the python.org infrastructure
team rather than through the CPython source repo, so acceptance and
implementation of the ideas in this PEP will be up to the team.

     References

    <colgroup>
     <col class="label">
     </col>
     <col>
     </col>
    </colgroup>

       [1]

       May 2012 discussion
(

        http://mail.python.org/pipermail/python-dev/2012-May/119524.html

       )

    <colgroup>
     <col class="label">
     </col>
     <col>
     </col>
    </colgroup>

       [2]

       October 2012 discussion
(

        http://mail.python.org/pipermail/python-ideas/2012-October/017406.html

       )

    <colgroup>
     <col class="label">
     </col>
     <col>
     </col>
    </colgroup>

       [3]

       Using a "/latest/" path prefix
(

        http://mail.python.org/pipermail/python-dev/2012-May/119567.html

       )

     Copyright

    This document has been placed in the public domain.

Source: https://hg.python.org/peps/file/tip/pep-0430.txt

        Tweets by @ThePSF

The PSF

The Python Software Foundation is the organization behind Python. Become a member of the PSF and help advance the software and our mission.

                    ▲ Back to Top

        About

Applications

Quotes

Getting Started

Help

        Downloads

All releases

Source code

Windows

Mac OS X

Other Platforms

License

Alternative Implementations

        Documentation

Docs

Audio/Visual Talks

Beginner's Guide

Developer's Guide

FAQ

Non-English Docs

PEP Index

Python Books

        Community

Diversity

IRC

Mailing Lists

Python Conferences

Special Interest Groups

Python Wiki

Python Logo

Merchandise

Community Awards

        Success Stories

Arts

Business

Education

Engineering

Government

Scientific

Software Development

        News

Python News

Community News

PSF News

PyCon News

        Events

Python Events

User Group Events

Python Events Archive

User Group Events Archive

Submit an Event

        Contributing

Developer's Guide

Issue Tracker

python-dev list

Core Mentorship

                    ▲ Back to Top

Help & General Contact

Diversity Initiatives

Submit Website Bug

                            Copyright ©2001-2015.
                             Python Software Foundation
                             Legal Statements
                             Privacy Policy


text:
package org.xdevs23.animation;

import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.view.View;

import org.xdevs23.general.ExtendedAndroidClass;
import org.xdevs23.threads.Sleeper;

public class ColorFader extends ExtendedAndroidClass {

    public int startColor, endColor;
    public float speed;
    public View animatingView;

    private Handler handler;

    private boolean isAnimating = false;

    public ColorFader(int startColor, int endColor,
                      Context context, View view,
                      float speed,
                      Handler handler) {
        super(context);
        this.handler    = handler;
        this.startColor = startColor;
        this.endColor   = endColor;
        this.speed      = speed;
        animatingView   = view;
    }

    private Runnable setColor(final int r, final int g, final int b) {
        return new Runnable() {
            @Override
            public void run() {
                animatingView.setBackgroundColor(
                        Color.argb(255, r, g, b)
                );
            }
        };
    }

    public void animate() {
        if(!isAnimating) {
            Runnable coloringRunnable = new Runnable() {
                @Override
                public void run() {
                    isAnimating = true;
                    int
                            r, g, b,

                            or, og, ob,

                            er, eg, eb;

                    or = Color.red(startColor);
                    og = Color.green(startColor);
                    ob = Color.blue(startColor);

                    er = Color.red(endColor);
                    eg = Color.green(endColor);
                    eb = Color.blue(endColor);

                    r = or;
                    g = og;
                    b = ob;

                    while (r != er || g != eg || b != eb) {
                        if (r != er) {
                            if (or < er) r++;
                            else r--;
                        }
                        if (g != eg) {
                            if (og < eg) g++;
                            else g--;
                        }
                        if (b != eb) {
                            if (ob < eb) b++;
                            else b--;
                        }
                        handler.post(setColor(r, g, b));
                        if (speed <= 1.0f)
                            Sleeper.sleep((int) (100 - (speed * 100) + (speed != 1f ? 0 : 1)));
                        else if (speed < 10.0f)
                            Sleeper.sleep(0, (int) (1_000_000 - (speed * 100_000)));
                        else Sleeper.sleep(0, 1);
                    }
                    handler.post(setColor(er, eg, eb));
                    isAnimating = false;
                }
            };
            Thread coloringThread = new Thread(coloringRunnable, "XD_" + this.getClass().getSimpleName());
            coloringThread.start();
        }
    }

    public static ColorFader createAnimation(int startColor, int endColor,
                                             Context context, View view,
                                             float speed,
                                             Handler handler) {
        return new ColorFader(startColor, endColor, context, view, speed, handler);
    }

    public static ColorFader createAnimation(Drawable startColor, int endColor,
                                             Context context, View view,
                                             float speed,
                                             Handler handler) {
        ColorDrawable colorDrawable = (ColorDrawable) startColor;
        return new ColorFader(colorDrawable.getColor(), endColor, context, view, speed, handler);
    }

    public static void animate(int startColor, int endColor,
                               Context context, View view,
                               float speed,
                               Handler handler) {
        createAnimation(startColor, endColor, context, view, speed, handler).animate();
    }

}


text:
/*
 * reserved comment block
 * DO NOT REMOVE OR ALTER!
 */

/*
 * Copyright  1999-2004 The Apache Software Foundation.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */
package com.sun.org.apache.xml.internal.security.transforms;

import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException;

/**
 *
 * @author Christian Geuer-Pollmann
 */
public class TransformationException extends XMLSecurityException {

   /**
         *
         */
        private static final long serialVersionUID = 1L;

   /**
    * Constructor TransformationException
    *
    */
   public TransformationException() {
      super();
   }

   /**
    * Constructor TransformationException
    *
    * @param _msgID
    */
   public TransformationException(String _msgID) {
      super(_msgID);
   }

   /**
    * Constructor TransformationException
    *
    * @param _msgID
    * @param exArgs
    */
   public TransformationException(String _msgID, Object exArgs[]) {
      super(_msgID, exArgs);
   }

   /**
    * Constructor TransformationException
    *
    * @param _msgID
    * @param _originalException
    */
   public TransformationException(String _msgID, Exception _originalException) {
      super(_msgID, _originalException);
   }

   /**
    * Constructor TransformationException
    *
    * @param _msgID
    * @param exArgs
    * @param _originalException
    */
   public TransformationException(String _msgID, Object exArgs[],
                                  Exception _originalException) {
      super(_msgID, exArgs, _originalException);
   }
}


text:
import spliceString from './util/spliceString';
import parseNumber from './util/parseNumber';
import escapeRegExp from './util/escapeRegExp';
import indexOfLastDigit from './util/indexOfLastDigit';
import invariant from 'invariant';
import nextPosition from './nextPosition';
import isFinite from 'lodash.isfinite';

function indexOfDigit(str, start, direction) {
  let pos = start;
  while (str.charAt(pos).match(/\D/)) pos += direction;
  return pos;
}

const BACKSPACE = 8;
const TAB = 9;
const ENTER = 13;
const DELETE = 46;

function justDigits(str) {
  return str.replace(/\D/g, '');
}

function isNegative(formattedNumber) {
  return !!formattedNumber.match(/-/);
}

export default function createAbstractNumberFormatInput(numberFormat) {
  const {maximumFractionDigits, style} = numberFormat.resolvedOptions();
  const allowsFractionDigits = maximumFractionDigits > 0;
  const isPercent = style === 'percent';
  const decimalChar = allowsFractionDigits ? numberFormat.format(0.1).match(/\d(\D+)\d/)[1] : null;

  const fractionRegExp = allowsFractionDigits ? new RegExp(escapeRegExp(decimalChar) + '\\d*\\b') : null;
  const fractionPlaceholder = allowsFractionDigits ? (decimalChar + Array(maximumFractionDigits + 1).join('0')) : null;

  function parse(formattedNumber) {
    if (formattedNumber === '') return null;
    const number = parseNumber(formattedNumber, decimalChar);
    return isPercent ? number / 100 : number;
  }

  function addTrailingZeros(formattedNumber) {
    if (!allowsFractionDigits) return formattedNumber;

    const match = fractionRegExp.exec(formattedNumber);
    const existingFractionLength = match ? match[0].length : 0;
    const placeholder = fractionPlaceholder.slice(existingFractionLength);
    return spliceString(formattedNumber, indexOfLastDigit(formattedNumber) + 1, 0, placeholder);
  }

  function format(number) {
    if (number === null || number === undefined) return '';
    if (typeof number === 'string') return format(parse(number));
    invariant(isFinite(number), `Illegal number value: ${JSON.stringify(number)}`);
    return addTrailingZeros(numberFormat.format(number));
  }

  function placeDecimalInDigits(digits) {
    if (!allowsFractionDigits) return digits;

    const extraDigits = digits.length - maximumFractionDigits;
    const leadingFractionZerosNeeded = Math.max(0, -extraDigits);
    const integerDigits = Math.max(0, extraDigits);
    const decimalAndLeadingZeros = fractionPlaceholder.slice(0, 1 + leadingFractionZerosNeeded);

    return spliceString(digits, integerDigits, 0, decimalAndLeadingZeros);
  }

  function fixupSplice(editedStr) {
    const _temp = justDigits(editedStr);
    if (!_temp.length) return null;
    const digits = _temp.length ? _temp : '0';
    const digitsWithDecimal = placeDecimalInDigits(digits);
    const sign = isNegative(editedStr) ? '-' : '';
    return parse(sign + digitsWithDecimal);
  }

  function splice(formattedNumber, position, deleteCount, insertDigits = '') {
    return fixupSplice(spliceString(formattedNumber, position, deleteCount, justDigits(insertDigits)));
  }

  function flipSign(formattedNumber) {
    return -parse(formattedNumber);
  }

  function ensureLength(nextValue, oldValue, maxLength) {
    // Revert to oldValue if nextValue does not fit in input's maxLength.
    // We force nextValue to be negative to ensure there's always room for a minus sign.
    return format(-Math.abs(nextValue)).length > maxLength ? oldValue : nextValue;
  }

  // TODO(dbrans): Needs tests.
  function handlePaste({pasteText, selection, value, maxLength}) {
    const {start, end} = selection;
    const [preventDefault, stopPropagation] = [true, true];
    const nextValue = ensureLength(splice(value, start, end - start, pasteText), parse(value), maxLength);
    const position = nextPosition({start, end}, value, format(nextValue));
    return {selection: {start: position, end: position}, value: nextValue, preventDefault, stopPropagation};
  }

  // TODO(dbrans): Needs tests.
  function handleCut({selection, value}) {
    const {start, end} = selection;
    const [preventDefault, stopPropagation] = [true, false];
    const nextValue = splice(value, start, end - start);
    const position = nextPosition({start, end}, value, format(nextValue));
    const clipboardText = value.slice(start, end);
    return {selection: {start: position, end: position}, value: nextValue, preventDefault, stopPropagation, clipboardText};
  }

  function handleKeyPress({charCode, metaKey, altKey, ctrlKey, selection, value, maxLength}) {
    const {start, end} = selection;
    const char = String.fromCharCode(charCode);
    const oldValue = parse(value);
    let nextValue = oldValue;
    let [preventDefault, stopPropagation] = [false, false];

    if (char === '-' || char === '+') {
      if (char === '-' || char === '+' && isNegative(value)) nextValue = flipSign(value);
      [preventDefault, stopPropagation] = [true, true];
    } else if (char.match(/\d/)) { // DIGIT
      nextValue = ensureLength(splice(value, start, end - start, char), oldValue, maxLength);
      [preventDefault, stopPropagation] = [true, true];
    } else if (charCode === ENTER || charCode === TAB || metaKey || altKey || ctrlKey) {
      // Allow ENTER and TAB event to do its thing on a form (submit and change focus).
      [preventDefault, stopPropagation] = [false, false];
    } else {
      // Any other key preventDefault but don't stopPropagation.
      [preventDefault, stopPropagation] = [true, false];
    }
    const position = nextPosition({start, end}, value, format(nextValue));

    return {selection: {start: position, end: position}, value: nextValue, preventDefault, stopPropagation};
  }

  function handleKeyDown({charCode, selection, value}) {
    const passThrough = {selection, value: parse(value), preventDefault: false, stopPropagation: false};
    if (charCode !== DELETE && charCode !== BACKSPACE) return passThrough;

    let {start, end} = selection;
    if (start === end) {
      // No significant digits, when user presses DELETE or backspace we clear the input.
      if (parse(value) === 0) return {selection: {start: 0, end: 0}, value: null};
      // No selection: backspace and delete behave differently.
      const pos =
          charCode === DELETE ? indexOfDigit(value, start, 1) : indexOfDigit(value, start - 1, -1);
      if (pos >= 0 && pos < value.length) [start, end] = [pos, pos + 1];
    }

    const nextValue = splice(value, start, end - start);
    const position = nextPosition({start, end}, value, format(nextValue));

    return {
      selection: {start: position, end: position},
      value: nextValue,
      stopPropagation: true,
      preventDefault: true,
    };
  }

  return { parse, format, splice, flipSign, isNegative, handleKeyDown, handleKeyPress, handleCut, handlePaste};
}


text:
package allbegray.slack.webapi.method;

import java.util.List;
import java.util.Map;

import allbegray.slack.validation.Problem;
import allbegray.slack.validation.ValidationError;
import allbegray.slack.webapi.SlackWebApiConstants;

public abstract class AbstractPagingMethod extends AbstractMethod {

	protected Integer count;
	protected Integer page;

	public Integer getCount() {
		return count;
	}

	public void setCount(Integer count) {
		this.count = count;
	}

	public Integer getPage() {
		return page;
	}

	public void setPage(Integer page) {
		this.page = page;
	}

	@Override
	public void validate(List<ValidationError> errors) {
		if (count != null && count < 1) {
			addError(errors, "count", Problem.PATTERN_NOT_MATCH, "\"count\" must be greater than 0.");
		}
		if (page != null && page < 1) {
			addError(errors, "page", Problem.PATTERN_NOT_MATCH, "\"page\" must be greater than 0.");
		}
	}

	@Override
	protected void createParameters(Map<String, String> parameters) {
		parameters.put("count", count != null ? String.valueOf(count) : String.valueOf(SlackWebApiConstants.DEFAULT_COUNT));
		parameters.put("page", page != null ? String.valueOf(page) : String.valueOf(SlackWebApiConstants.DEFAULT_PAGE));
	}

}


text:
package io.astefanutti.metrics.cdi.se;

import javax.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class UnnamedHealthCheckBean extends HealthCheckBean {
}


text:
class CreateBlogSettings < ActiveRecord::Migration
  def change
    create_table :blog_settings do |t|
      t.string :key
      t.string :value
      t.string :description
      t.timestamps
    end

    add_index :blog_settings, :key, :unique => true
  end
end


text:
<?php

use yii\db\Schema;
use yii\db\Migration;

class m160116_195002_create_users_table extends Migration
{
    public function up()
    {
        $this->createTable('users',[
            'id' => $this->primaryKey(),
            'name' => $this->string(255)->notNull(),
            'login' => $this->string(255)->notNull()->unique(),
            'password_hash' => $this->string(255)->notNull(),
        ]);
    }

    public function down()
    {
        $this->dropTable('users');

        return true;
    }
}


text:
package com.github.xsocket.geak.interceptor;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import org.springframework.web.util.WebUtils;

import com.github.xsocket.geak.entity.Member;
import com.github.xsocket.geak.service.MemberService;
import com.github.xsocket.geak.util.GeakUtils;

public class AuthenticateInterceptor extends HandlerInterceptorAdapter {

  private static final Logger LOGGER = LoggerFactory.getLogger(AuthenticateInterceptor.class);

  // geak_member_openid
  public static final String COOKIE_MEMBER_OPENID = "_gmo_";

  private static final String REDIRECT_URL =
      "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=http://%s/&response_type=code&scope=snsapi_userinfo#wechat_redirect";

  @Autowired
  private MemberService service;
  @Value("${webapp.host}")
  private String host;
  @Value("${wechat.appid}")
  private String appId;

  private String redirectUrl = null;

  public String getOAuth2RedirectUrl() {
    if(redirectUrl == null) {
      redirectUrl = String.format(REDIRECT_URL, appId, host);
    }
    return redirectUrl;
  }

  @Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

    // 测试环境
    //Cookie token = new Cookie(COOKIE_MEMBER_OPENID, "oAWv4jklauWMMBAsssCVBqJ2YzFg");
    Cookie token = WebUtils.getCookie(request, COOKIE_MEMBER_OPENID);
    if(token == null) {
      // TODO 登陆后自动跳转到上次请求的页面
      LOGGER.debug("Could not found member openId, need oauth2 check first.");
      response.sendRedirect(String.format(REDIRECT_URL, appId, host));
      return false;
    } else {
      String openId = token.getValue();
      Member member = service.loadMemberByOpenId(openId, null);
      GeakUtils.setCurrentMember(member);
      // 设置cookie
      token = new Cookie(AuthenticateInterceptor.COOKIE_MEMBER_OPENID, openId);
      token.setPath("/");
      token.setMaxAge(3600 * 24 * 30);
      //token.setMaxAge(360);
      response.addCookie(token);
      return true;
    }
  }

  @Override
  public void postHandle(HttpServletRequest request, HttpServletResponse response,
      Object handler, ModelAndView mv) throws Exception {
    //为模型加入用户信息
    if(mv != null) {
      mv.addObject("member", GeakUtils.getCurrentMember());
    }
  }

  @Override
  public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
      throws Exception {
    //LOGGER.debug("完成拦截");

  }
}


text:
module.exports = {
  entryPoints: ["src/index.ts"],
  categorizeByGroup: false,
  readme: "none",
  plugin: ["none"],
  out: "dist/docs"
};


text:
#include <json_cgi.h> /* for log_message */
#include "village-bus-radius.h"

void print_customer(const char* username, const char* cleartext_password, const char* max_prepaid_session)
{
  printf("{ ");
  printf("\"username\" : \"%s\", ", username);
  if (max_prepaid_session) {
    printf("\"type\" : \"prepaid\", ");
    printf("\"seconds\" : %s", max_prepaid_session);
  } else {
    printf("\"type\" : \"flatrate\"");
  }
  printf(" }");
}

void radius_list_mysql()
{
  MYSQL* connection = NULL;
  MYSQL_RES* result  = NULL;
  MYSQL_ROW  row    = NULL;

  /* query user attributes */
  if (mysql(&connection, "SELECT username, attribute, op, value FROM radcheck WHERE username != 'chillispot' ORDER BY username") != 0) {
    return;
  }
  result = mysql_use_result(connection);

  char* username    = NULL;
  char* cleartext_password = NULL;
  char* max_prepaid_session = NULL;
  while ((row = mysql_fetch_row(result)) != NULL) {
    if (username && strcasecmp(username, row[0]) != 0) {
      print_customer(username, cleartext_password, max_prepaid_session);
      printf(", ");
      cleartext_password = NULL;
      max_prepaid_session = NULL;
    }
    username = strdup(row[0]);
    if (strcasecmp("ClearText-Password", row[1]) == 0) {
      cleartext_password = strdup(row[3]);
    } else if (strcasecmp("Max-Prepaid-Session", row[1]) == 0) {
      max_prepaid_session = strdup(row[3]);
    } else {
      log_message("Unknown attribute: %s %s %s %s\n", row[0], row[1], row[2], row[3]);
    }
  }
  if (username) { /* don't forget the last one */
    print_customer(username, cleartext_password, max_prepaid_session);
  }

  /* release memory used to store results and close connection */
  if (result != NULL) {
    mysql_free_result(result);
  }
  if (connection != NULL) {
    mysql_close(connection);
  }
}


text:
<!doctype html>

	<meta charset="utf-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<title>IBreakingTokenResult | Typesetter</title>
	<meta name="description" content="">
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<link rel="stylesheet" href="../assets/css/main.css">

						Search
						<input id="tsd-search-field" type="text" />

Preparing search index...

The search index is not available

					Typesetter

						Options

								All

Public

Public/Protected

All

							<input type="checkbox" id="tsd-filter-inherited" checked />
							Inherited
							<input type="checkbox" id="tsd-filter-externals" checked />
							Externals
							<input type="checkbox" id="tsd-filter-only-exported" />
							Only exported

					Menu

					Globals

					IBreakingTokenResult

Interface IBreakingTokenResult

Hierarchy

						IBreakingTokenResult

Index

Properties

break<wbr>Word

line

remaining<wbr>Token

Properties

break<wbr>Word

break<wbr>Word: boolean

Defined in wrappers/wrapper.ts:28

line

line: string

Defined in wrappers/wrapper.ts:29

remaining<wbr>Token

remaining<wbr>Token: string

Defined in wrappers/wrapper.ts:27

						Globals

						Abstract<wbr>Measurer

						Cache

						Cache<wbr>Character<wbr>Measurer

						Cache<wbr>Measurer

						Canvas<wbr>Context

						Character<wbr>Measurer

						Html<wbr>Context

						Html<wbr>Utils

						Measurer

						Methods

						Single<wbr>Line<wbr>Wrapper

						String<wbr>Methods

						Svg<wbr>Context

						Svg<wbr>Utils

						Tokenizer

						Typesetter

						Wrapper

						Writer

						IBreaking<wbr>Token<wbr>Result

								break<wbr>Word

								line

								remaining<wbr>Token

						ICanvas<wbr>Font<wbr>Style

						IDimensions

						IEllipsis<wbr>Result

						IIterative<wbr>Wrapping<wbr>State

						IPen

						IPen<wbr>Factory<wbr>Context

						IRuler<wbr>Factory<wbr>Context

						ITemporary<wbr>Text<wbr>Element<wbr>Harness

						ITransform

						ITypesetter<wbr>Context

						IWrapping<wbr>Result

						IWrite<wbr>Options

						IAnchor

						IPen<wbr>Factory

						IRuler

						IRuler<wbr>Factory

						IXAlign

						IYAlign

						DEFAULT_<wbr>FILL_<wbr>COLOR

						DEFAULT_<wbr>WRITE_<wbr>OPTIONS

Legend

Module

Object literal

Variable

Function

Function with type parameter

Index signature

Type alias

Enumeration

Enumeration member

Property

Method

Interface

Interface with type parameter

Constructor

Property

Method

Index signature

Class

Class with type parameter

Constructor

Property

Method

Accessor

Index signature

Inherited constructor

Inherited property

Inherited method

Inherited accessor

Protected property

Protected method

Protected accessor

Private property

Private method

Private accessor

Static property

Static method

Generated using TypeDoc


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

public class SortingArrayB
{
    public static void Main()
    {
        // *Zero tests
        int[] integers = { 2, 4, -5, -1, 2, 4, -5, 6 };

        // int[] integers = { 3, 4, 5, 7, 12, 14, 15, 15 };
        // int[] integers = { 2, 1, -5, -1, 2, 4, -5, 6 };
        // For manual entering you can uncomment this code:
        // Console.WriteLine("Enter the length of the array:");
        // int len=int.Parse(Console.ReadLine());
        // Console.WriteLine("Enter the array:");
        // int[] integers=new int[len];
        // for (int i=0;i<len;i++)
        // {
        //     integers[i] = int.Parse(Console.ReadLine());
        // }
        int[] intsClone = integers.Clone() as int[];
        int[] sortedArrayDescending = SortDescending(integers);
        int[] sortedArrayAscending = SortAscending(intsClone);
        Console.WriteLine("Sorted array:");
        Console.WriteLine("{0}", string.Join(", ", sortedArrayDescending));
        Console.WriteLine("{0}", string.Join(", ", sortedArrayAscending));
    }

    public static int[] SortDescending(int[] arrayOfIntsDesc)
    {
        int start = 0;
        int maxValueIndex = 0;
        int maxValue = int.MinValue;
        for (int i = 0; i < arrayOfIntsDesc.Length; i++)
        {
            for (int j = start; j < arrayOfIntsDesc.Length; j++)
            {
                if (arrayOfIntsDesc[j] > maxValue)
                {
                    maxValue = arrayOfIntsDesc[j];
                    maxValueIndex = j;
                }

                if (j == arrayOfIntsDesc.Length - 1)
                {
                    int temp = arrayOfIntsDesc[i];
                    arrayOfIntsDesc[i] = maxValue;
                    arrayOfIntsDesc[maxValueIndex] = temp;
                    maxValue = int.MinValue;
                    start++;
                }
            }
        }

        return arrayOfIntsDesc;
    }

    public static int[] SortAscending(int[] arrayOfIntsAsc)
    {
        int start = 0;
        int minValueIndex = 0;
        int minValue = int.MaxValue;
        for (int i = 0; i < arrayOfIntsAsc.Length; i++)
        {
            for (int j = start; j < arrayOfIntsAsc.Length; j++)
            {
                if (arrayOfIntsAsc[j] < minValue)
                {
                    minValue = arrayOfIntsAsc[j];
                    minValueIndex = j;
                }

                if (j == arrayOfIntsAsc.Length - 1)
                {
                    int temp = arrayOfIntsAsc[i];
                    arrayOfIntsAsc[i] = minValue;
                    arrayOfIntsAsc[minValueIndex] = temp;
                    minValue = int.MaxValue;
                    start++;
                }
            }
        }

        return arrayOfIntsAsc;
    }
}


text:
class CFWL_CaretTP : public CFWL_WidgetTP {
 public:
  CFWL_CaretTP();
  ~CFWL_CaretTP() override;

  // CFWL_WidgetTP
  void DrawBackground(CFWL_ThemeBackground* pParams) override;

 protected:
  void DrawCaretBK(CFX_Graphics* pGraphics,
                   uint32_t dwStates,
                   const CFX_RectF* pRect,
                   CFX_Color* crFill,
                   CFX_Matrix* pMatrix = nullptr);
};

#endif  // XFA_FWL_THEME_CFWL_CARETTP_H_


text:
license: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

           http://www.apache.org/licenses/LICENSE-2.0

         Unless required by applicable law or agreed to in writing,
         software distributed under the License is distributed on an
         "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
         KIND, either express or implied.  See the License for the
         specific language governing permissions and limitations

   under the License.
---

# Windows 8 のコマンド ライン ツール

`cordova`コマンド ライン ユーティリティは、一度にいくつかのプラットフォームでアプリケーションをビルドすることができます高度なツールです。 コルドバ フレームワークの古いバージョンをそれぞれのプラットフォームに固有のコマンド ライン ツールのセットを提供します。 CLI に代わるものとしてそれらを使用するには[cordova.apache.org][1]からコルドバのこのバージョンをダウンロードする必要があります。 ダウンロードには、プラットフォームごとに別々 のアーカイブが含まれています。 ターゲットにするプラットフォームを展開します。 ここで説明したツールは、最上位レベルでふつう利用できる `bin` ディレクトリ、それ以外の場合より詳細な方向の**README**ファイルを参照してください。

 [1]: http://cordova.apache.org

## Windows 8

Windows 8 のコマンド ライン ツールのみサポートして新しいプロジェクトを作成します。Cmd または powershell プロンプトからコマンドを実行する必要があります。

## プロジェクトを作成します。

実行、 `create` コマンドで、次のパラメーター。

*   新しいコルドバ Windows 8 プロジェクトへのパス

*   パッケージ名は、逆ドメイン スタイル大会に続きます。これは、既定の Namespace なります。

*   プロジェクト名


text:
// [AUTO_HEADER]

using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace TakaoPreference
{
    partial class PanelSimplex : UserControl
    {
        private Dictionary<string, string> m_simplexDictionary;
        private Button u_applyButton;
        public PanelSimplex(Dictionary<string, string> dictionary, Button button)
        {
            InitializeComponent();
            this.m_simplexDictionary = dictionary;
            this.u_applyButton = button;
            this.InitUI();
        }
        #region Init
        /// <summary>
        /// Initializing the user interface for Cangjie input method settings.
        /// </summary>
        private void InitUI()
        {
            string buffer;
            this.m_simplexDictionary.TryGetValue("ClearReadingBufferAtCompositionError", out buffer);
            if (buffer == "true")
                this.u_clearIfErrorCheckBox.Checked = true;
            else
                this.u_clearIfErrorCheckBox.Checked = false;

            this.m_simplexDictionary.TryGetValue("ComposeWhenTyping", out buffer);
            if (buffer == "true")
                this.u_autoComposeCheckbox.Checked = true;
            else
                this.u_autoComposeCheckbox.Checked = false;

            this.m_simplexDictionary.TryGetValue("UseCharactersSupportedByEncoding", out buffer);
            if (buffer == "")
                this.u_nonBig5CheckBox.Checked = true;
            else
                this.u_nonBig5CheckBox.Checked = false;
        }
        #endregion
        #region Event handlers

        /// <summary>
        /// Handle enabling or disabling the ShouldCommitAsPhrase option.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        private void ToggleClearRadicalsIfError(object sender, EventArgs e)
        {
            try
			{

                this.m_simplexDictionary.Remove("ClearReadingBufferAtCompositionError");
			}
            catch { }

            if (this.u_clearIfErrorCheckBox.Checked == true)
            {
                this.m_simplexDictionary.Add("ClearReadingBufferAtCompositionError", "true");
                if (this.u_autoComposeCheckbox.Checked == true)
                {
                    this.u_autoComposeCheckbox.Checked = false;
                    this.ToggleAutoComposeWhenTyping(sender, e);
                }
            }
            else
            {
                this.m_simplexDictionary.Add("ClearReadingBufferAtCompositionError", "false");
            }
            this.u_applyButton.Enabled = true;
        }

        private void ToggleAutoComposeWhenTyping(object sender, EventArgs e)
        {
            try
            {
                this.m_simplexDictionary.Remove("ComposeWhenTyping");
            }
            catch { }

            if (this.u_autoComposeCheckbox.Checked == true)
            {
                this.m_simplexDictionary.Add("ComposeWhenTyping", "true");
                if (u_clearIfErrorCheckBox.Checked == true)
                {
                    this.u_clearIfErrorCheckBox.Checked = false;
                    this.ToggleClearRadicalsIfError(sender, e);
                }
            }
            else
            {
                this.m_simplexDictionary.Add("ComposeWhenTyping", "false");
            }
            this.u_applyButton.Enabled = true;
        }

        private void ToggleShouldUseAllUnicodePlanes(object sender, EventArgs e)
        {
            try
            {
                this.m_simplexDictionary.Remove("UseCharactersSupportedByEncoding");
            }
            catch { }

            if (this.u_nonBig5CheckBox.Checked == true)
                this.m_simplexDictionary.Add("UseCharactersSupportedByEncoding", "");
            else
                this.m_simplexDictionary.Add("UseCharactersSupportedByEncoding", "BIG-5");

            this.u_applyButton.Enabled = true;
        }
        #endregion
    }
}


text:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	   xmlns:cache="http://www.springframework.org/schema/cache"
	   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">

	<cache:annotation-driven mode="aspectj"/>

	<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
		<property name="caches">
			<set>
				<ref bean="defaultCache"/>
				<bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean">
					<property name="name" value="primary"/>
				</bean>
				<bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean">
					<property name="name" value="secondary"/>
				</bean>
				<bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean">
					<property name="name" value="exception"/>
				</bean>
			</set>
		</property>
	</bean>

	<bean id="defaultCache"
		  class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean">
		<property name="name" value="default"/>
	</bean>

	<bean id="cacheableService" class="org.springframework.cache.config.AnnotatedJCacheableService">
		<constructor-arg ref="defaultCache"/>
	</bean>

</beans>


text:
/**
 * This file is part of the CernVM File System.
 */
#include "cvmfs_config.h"
#include "catalog_virtual.h"

#include <algorithm>
#include <cassert>
#include <cstdlib>

#include "catalog_mgr_rw.h"
#include "compression.h"
#include "history.h"
#include "logging.h"
#include "swissknife_history.h"
#include "swissknife_sync.h"
#include "util/pointer.h"
#include "util/posix.h"
#include "util/string.h"
#include "xattr.h"

using namespace std;  // NOLINT

namespace catalog {

const char *VirtualCatalog::kVirtualPath = ".cvmfs";
const char *VirtualCatalog::kSnapshotDirectory = "snapshots";
const unsigned VirtualCatalog::kActionNone              = 0x00;
const unsigned VirtualCatalog::kActionGenerateSnapshots = 0x01;
const unsigned VirtualCatalog::kActionRemove            = 0x02;

void VirtualCatalog::CreateBaseDirectory() {
  // Add /.cvmfs as a nested catalog
  DirectoryEntryBase entry_dir;
  entry_dir.name_ = NameString(string(kVirtualPath));
  entry_dir.mode_ = S_IFDIR |
                    S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
  entry_dir.uid_ = 0;
  entry_dir.gid_ = 0;
  entry_dir.size_ = 97;
  entry_dir.mtime_ = time(NULL);
  catalog_mgr_->AddDirectory(entry_dir, "");
  WritableCatalog *parent_catalog =
    catalog_mgr_->GetHostingCatalog(kVirtualPath);
  catalog_mgr_->CreateNestedCatalog(kVirtualPath);
  WritableCatalog *virtual_catalog =
    catalog_mgr_->GetHostingCatalog(kVirtualPath);
  assert(parent_catalog != virtual_catalog);

  // Set hidden flag in parent catalog
  DirectoryEntry entry_parent;
  bool retval = parent_catalog->LookupPath(
    PathString("/" + string(kVirtualPath)), &entry_parent);
  assert(retval);
  entry_parent.set_is_hidden(true);
  parent_catalog->UpdateEntry(entry_parent, "/" + string(kVirtualPath));

  // Set hidden flag in nested catalog
  DirectoryEntry entry_virtual;
  retval = virtual_catalog->LookupPath(PathString("/" + string(kVirtualPath)),
                                       &entry_virtual);
  assert(retval);
  entry_virtual.set_is_hidden(true);
  virtual_catalog->UpdateEntry(entry_virtual, "/" + string(kVirtualPath));
}

void VirtualCatalog::CreateNestedCatalogMarker() {
  DirectoryEntryBase entry_marker;
  // Note that another entity needs to ensure that the object of an empty
  // file is in the repository!  It is currently done by the sync_mediator.
  shash::Algorithms algorithm = catalog_mgr_->spooler_->GetHashAlgorithm();
  shash::Any file_hash(algorithm);
  void *empty_compressed;
  uint64_t sz_empty_compressed;
  bool retval = zlib::CompressMem2Mem(
    NULL, 0, &empty_compressed, &sz_empty_compressed);
  assert(retval);
  shash::HashMem(static_cast<unsigned char *>(empty_compressed),
                 sz_empty_compressed, &file_hash);
  free(empty_compressed);
  entry_marker.name_ = NameString(".cvmfscatalog");
  entry_marker.mode_ = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH;
  entry_marker.checksum_ = file_hash;
  entry_marker.mtime_ = time(NULL);
  entry_marker.uid_ = 0;
  entry_marker.gid_ = 0;
  XattrList xattrs;
  catalog_mgr_->AddFile(entry_marker, xattrs, kVirtualPath);
}

void VirtualCatalog::CreateSnapshotDirectory() {
  DirectoryEntryBase entry_dir;
  entry_dir.name_ = NameString(string(kSnapshotDirectory));
  entry_dir.mode_ = S_IFDIR |
                    S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
  entry_dir.uid_ = 0;
  entry_dir.gid_ = 0;
  entry_dir.size_ = 97;
  entry_dir.mtime_ = time(NULL);
  catalog_mgr_->AddDirectory(entry_dir, kVirtualPath);
}

/**
 * Checks for the top-level /.cvmfs directory and creates it as a nested catalog
 * if necessary.
 */
void VirtualCatalog::EnsurePresence() {
  DirectoryEntry e;
  bool retval = catalog_mgr_->LookupPath("/" + string(kVirtualPath),
                                        kLookupSole, &e);
  if (!retval) {
    LogCvmfs(kLogCatalog, kLogDebug, "creating new virtual catalog");
    CreateBaseDirectory();
    CreateNestedCatalogMarker();
    CreateSnapshotDirectory();
  }
  assert(catalog_mgr_->IsTransitionPoint(kVirtualPath));
}

void VirtualCatalog::Generate(int actions) {
  if (actions & kActionGenerateSnapshots) {
    GenerateSnapshots();
  }
  if (actions & kActionRemove) {
    Remove();
  }
}

void VirtualCatalog::GenerateSnapshots() {
  LogCvmfs(kLogCvmfs, kLogStdout, "Creating virtual snapshots");
  EnsurePresence();

  vector<TagId> tags_history;
  vector<TagId> tags_catalog;
  GetSortedTagsFromHistory(&tags_history);
  GetSortedTagsFromCatalog(&tags_catalog);
  // Add artifical end markers to both lists
  tags_history.push_back(TagId("", shash::Any()));
  tags_catalog.push_back(TagId("", shash::Any()));

  // Walk through both sorted lists concurrently and determine change set
  unsigned i_history = 0, i_catalog = 0;
  unsigned last_history = tags_history.size() - 1;
  unsigned last_catalog = tags_catalog.size() - 1;
  while ((i_history < last_history) || (i_catalog < last_catalog)) {
    TagId t_history = tags_history[i_history];
    TagId t_catalog = tags_catalog[i_catalog];

    // Both the same, nothing to do
    if (t_history == t_catalog) {
      i_history++;
      i_catalog++;
      continue;
    }

    // Same tag name for different hash, re-insert
    if (t_history.name == t_catalog.name) {
      RemoveSnapshot(t_catalog);
      InsertSnapshot(t_history);
      i_history++;
      i_catalog++;
      continue;
    }

    // New tag that's missing
    if ((t_history.name < t_catalog.name) || t_catalog.name.empty()) {
      InsertSnapshot(t_history);
      i_history++;
      continue;
    }

    // A tag was removed but it is still present in the catalog
    assert((t_history.name > t_catalog.name) || t_history.name.empty());
    RemoveSnapshot(t_catalog);
    i_catalog++;
  }
}

bool VirtualCatalog::ParseActions(
  const string &action_desc,
  unsigned *actions)
{
  *actions = kActionNone;
  if (action_desc.empty())
    return true;

  vector<string> action_tokens = SplitString(action_desc, ',');
  for (unsigned i = 0; i < action_tokens.size(); ++i) {
    if (action_tokens[i] == "snapshots") {
      *actions |= kActionGenerateSnapshots;
    } else if (action_tokens[i] == "remove") {
      *actions |= kActionRemove;
    } else {
      return false;
    }
  }
  return true;
}

void VirtualCatalog::GetSortedTagsFromHistory(vector<TagId> *tags) {
  UniquePtr<history::History> history(
    assistant_.GetHistory(swissknife::Assistant::kOpenReadOnly));
  vector<history::History::Tag> tags_history;
  bool retval = history->List(&tags_history);
  assert(retval);
  for (unsigned i = 0, l = tags_history.size(); i < l; ++i) {
    if ((tags_history[i].name == swissknife::CommandTag::kHeadTag) ||
        (tags_history[i].name == swissknife::CommandTag::kPreviousHeadTag))
    {
      continue;
    }
    tags->push_back(TagId(tags_history[i].name, tags_history[i].root_hash));
  }
  std::sort(tags->begin(), tags->end());
}

void VirtualCatalog::GetSortedTagsFromCatalog(vector<TagId> *tags) {
  WritableCatalog *virtual_catalog =
    catalog_mgr_->GetHostingCatalog(kVirtualPath);
  assert(virtual_catalog != NULL);
  Catalog::NestedCatalogList nested_catalogs =
    virtual_catalog->ListNestedCatalogs();
  for (unsigned i = 0, l = nested_catalogs.size(); i < l; ++i) {
    tags->push_back(TagId(GetFileName(nested_catalogs[i].mountpoint).ToString(),
                          nested_catalogs[i].hash));
  }
  std::sort(tags->begin(), tags->end());
}

void VirtualCatalog::InsertSnapshot(TagId tag) {
  LogCvmfs(kLogCatalog, kLogDebug, "add snapshot %s (%s) to virtual catalog",
           tag.name.c_str(), tag.hash.ToString().c_str());
  UniquePtr<Catalog> catalog(assistant_.GetCatalog(tag.hash,
                             swissknife::Assistant::kOpenReadOnly));
  assert(catalog.IsValid());
  assert(catalog->root_prefix().IsEmpty());
  DirectoryEntry entry_root;
  bool retval = catalog->LookupPath(PathString(""), &entry_root);
  assert(retval);

  // Add directory entry
  DirectoryEntryBase entry_dir = entry_root;
  entry_dir.name_ = NameString(tag.name);
  catalog_mgr_->AddDirectory(
    entry_dir, string(kVirtualPath) + "/" + string(kSnapshotDirectory));

  // Set "bind mount" flag
  WritableCatalog *virtual_catalog =
    catalog_mgr_->GetHostingCatalog(kVirtualPath);
  assert(virtual_catalog != NULL);
  string mountpoint =
    "/" + string(kVirtualPath) + "/" + string(kSnapshotDirectory) + "/" +
    tag.name;
  DirectoryEntry entry_bind_mountpoint(entry_dir);
  entry_bind_mountpoint.set_is_bind_mountpoint(true);
  virtual_catalog->UpdateEntry(entry_bind_mountpoint, mountpoint);

  // Register nested catalog
  uint64_t catalog_size = GetFileSize(catalog->database_path());
  assert(catalog_size > 0);
  virtual_catalog->InsertBindMountpoint(mountpoint, tag.hash, catalog_size);
}

void VirtualCatalog::Remove() {
  LogCvmfs(kLogCvmfs, kLogStdout, "Removing .cvmfs virtual catalog");

  // Safety check, make sure we don't remove the entire repository
  WritableCatalog *virtual_catalog =
    catalog_mgr_->GetHostingCatalog(kVirtualPath);
  assert(!virtual_catalog->IsRoot());
  DirectoryEntry entry_virtual;
  bool retval = catalog_mgr_->LookupPath(
    PathString("/" + string(kVirtualPath)), kLookupSole, &entry_virtual);
  assert(retval);
  assert(entry_virtual.IsHidden());

  RemoveRecursively(kVirtualPath);
  catalog_mgr_->RemoveNestedCatalog(kVirtualPath);
  catalog_mgr_->RemoveDirectory(kVirtualPath);
}

void VirtualCatalog::RemoveRecursively(const string &directory) {
  DirectoryEntryList listing;
  bool retval = catalog_mgr_->Listing(PathString("/" + directory), &listing);
  assert(retval);
  for (unsigned i = 0; i < listing.size(); ++i) {
    string this_path = directory + "/" + listing[i].name().ToString();
    if (listing[i].IsDirectory()) {
      if (!listing[i].IsBindMountpoint())
        RemoveRecursively(this_path);
      catalog_mgr_->RemoveDirectory(this_path);
    } else if (listing[i].IsRegular()) {
      assert(listing[i].name().ToString() == ".cvmfscatalog");
      catalog_mgr_->RemoveFile(this_path);
    } else {
      abort();
    }
  }
}

void VirtualCatalog::RemoveSnapshot(TagId tag) {
  LogCvmfs(kLogCatalog, kLogDebug,
           "remove snapshot %s (%s) from virtual catalog",
           tag.name.c_str(), tag.hash.ToString().c_str());
  string tag_dir =
    string(kVirtualPath) + "/" + string(kSnapshotDirectory) + "/" + tag.name;
  catalog_mgr_->RemoveDirectory(tag_dir);

  WritableCatalog *virtual_catalog =
    catalog_mgr_->GetHostingCatalog(kVirtualPath);
  assert(virtual_catalog != NULL);
  virtual_catalog->RemoveBindMountpoint("/" + tag_dir);
}

VirtualCatalog::VirtualCatalog(
  manifest::Manifest *m,
  download::DownloadManager *d,
  catalog::WritableCatalogManager *c,
  SyncParameters *p)
  : catalog_mgr_(c)
  , assistant_(d, m, p->stratum0, p->dir_temp)
{ }

}  // namespace catalog


text:
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <item name="auth_token_loader" type="id" />

</resources>


text:
"""Upload the contents of your Downloads folder to Dropbox.

This is an example app for API v2.
"""

from __future__ import print_function

import argparse
import contextlib
import datetime
import os
import six
import sys
import time
import unicodedata

if sys.version.startswith('2'):
    input = raw_input  # noqa: E501,F821; pylint: disable=redefined-builtin,undefined-variable,useless-suppression

import dropbox

# OAuth2 access token.  TODO: login etc.
TOKEN = ''

parser = argparse.ArgumentParser(description='Sync ~/Downloads to Dropbox')
parser.add_argument('folder', nargs='?', default='Downloads',
                    help='Folder name in your Dropbox')
parser.add_argument('rootdir', nargs='?', default='~/Downloads',
                    help='Local directory to upload')
parser.add_argument('--token', default=TOKEN,
                    help='Access token '
                    '(see https://www.dropbox.com/developers/apps)')
parser.add_argument('--yes', '-y', action='store_true',
                    help='Answer yes to all questions')
parser.add_argument('--no', '-n', action='store_true',
                    help='Answer no to all questions')
parser.add_argument('--default', '-d', action='store_true',
                    help='Take default answer on all questions')

def main():
    """Main program.

    Parse command line, then iterate over files and directories under
    rootdir and upload all files.  Skips some temporary files and
    directories, and avoids duplicate uploads by comparing size and
    mtime with the server.
    """
    args = parser.parse_args()
    if sum([bool(b) for b in (args.yes, args.no, args.default)]) > 1:
        print('At most one of --yes, --no, --default is allowed')
        sys.exit(2)
    if not args.token:
        print('--token is mandatory')
        sys.exit(2)

    folder = args.folder
    rootdir = os.path.expanduser(args.rootdir)
    print('Dropbox folder name:', folder)
    print('Local directory:', rootdir)
    if not os.path.exists(rootdir):
        print(rootdir, 'does not exist on your filesystem')
        sys.exit(1)
    elif not os.path.isdir(rootdir):
        print(rootdir, 'is not a folder on your filesystem')
        sys.exit(1)

    dbx = dropbox.Dropbox(args.token)

    for dn, dirs, files in os.walk(rootdir):
        subfolder = dn[len(rootdir):].strip(os.path.sep)
        listing = list_folder(dbx, folder, subfolder)
        print('Descending into', subfolder, '...')

        # First do all the files.
        for name in files:
            fullname = os.path.join(dn, name)
            if not isinstance(name, six.text_type):
                name = name.decode('utf-8')
            nname = unicodedata.normalize('NFC', name)
            if name.startswith('.'):
                print('Skipping dot file:', name)
            elif name.startswith('@') or name.endswith('~'):
                print('Skipping temporary file:', name)
            elif name.endswith('.pyc') or name.endswith('.pyo'):
                print('Skipping generated file:', name)
            elif nname in listing:
                md = listing[nname]
                mtime = os.path.getmtime(fullname)
                mtime_dt = datetime.datetime(*time.gmtime(mtime)[:6])
                size = os.path.getsize(fullname)
                if (isinstance(md, dropbox.files.FileMetadata) and
                        mtime_dt == md.client_modified and size == md.size):
                    print(name, 'is already synced [stats match]')
                else:
                    print(name, 'exists with different stats, downloading')
                    res = download(dbx, folder, subfolder, name)
                    with open(fullname) as f:
                        data = f.read()
                    if res == data:
                        print(name, 'is already synced [content match]')
                    else:
                        print(name, 'has changed since last sync')
                        if yesno('Refresh %s' % name, False, args):
                            upload(dbx, fullname, folder, subfolder, name,
                                   overwrite=True)
            elif yesno('Upload %s' % name, True, args):
                upload(dbx, fullname, folder, subfolder, name)

        # Then choose which subdirectories to traverse.
        keep = []
        for name in dirs:
            if name.startswith('.'):
                print('Skipping dot directory:', name)
            elif name.startswith('@') or name.endswith('~'):
                print('Skipping temporary directory:', name)
            elif name == '__pycache__':
                print('Skipping generated directory:', name)
            elif yesno('Descend into %s' % name, True, args):
                print('Keeping directory:', name)
                keep.append(name)
            else:
                print('OK, skipping directory:', name)
        dirs[:] = keep

def list_folder(dbx, folder, subfolder):
    """List a folder.

    Return a dict mapping unicode filenames to
    FileMetadata|FolderMetadata entries.
    """
    path = '/%s/%s' % (folder, subfolder.replace(os.path.sep, '/'))
    while '//' in path:
        path = path.replace('//', '/')
    path = path.rstrip('/')
    try:
        with stopwatch('list_folder'):
            res = dbx.files_list_folder(path)
    except dropbox.exceptions.ApiError as err:
        print('Folder listing failed for', path, '-- assumed empty:', err)
        return {}
    else:
        rv = {}
        for entry in res.entries:
            rv[entry.name] = entry
        return rv

def download(dbx, folder, subfolder, name):
    """Download a file.

    Return the bytes of the file, or None if it doesn't exist.
    """
    path = '/%s/%s/%s' % (folder, subfolder.replace(os.path.sep, '/'), name)
    while '//' in path:
        path = path.replace('//', '/')
    with stopwatch('download'):
        try:
            md, res = dbx.files_download(path)
        except dropbox.exceptions.HttpError as err:
            print('*** HTTP error', err)
            return None
    data = res.content
    print(len(data), 'bytes; md:', md)
    return data

def upload(dbx, fullname, folder, subfolder, name, overwrite=False):
    """Upload a file.

    Return the request response, or None in case of error.
    """
    path = '/%s/%s/%s' % (folder, subfolder.replace(os.path.sep, '/'), name)
    while '//' in path:
        path = path.replace('//', '/')
    mode = (dropbox.files.WriteMode.overwrite
            if overwrite
            else dropbox.files.WriteMode.add)
    mtime = os.path.getmtime(fullname)
    with open(fullname, 'rb') as f:
        data = f.read()
    with stopwatch('upload %d bytes' % len(data)):
        try:
            res = dbx.files_upload(
                data, path, mode,
                client_modified=datetime.datetime(*time.gmtime(mtime)[:6]),
                mute=True)
        except dropbox.exceptions.ApiError as err:
            print('*** API error', err)
            return None
    print('uploaded as', res.name.encode('utf8'))
    return res

def yesno(message, default, args):
    """Handy helper function to ask a yes/no question.

    Command line arguments --yes or --no force the answer;
    --default to force the default answer.

    Otherwise a blank line returns the default, and answering
    y/yes or n/no returns True or False.

    Retry on unrecognized answer.

    Special answers:
    - q or quit exits the program
    - p or pdb invokes the debugger
    """
    if args.default:
        print(message + '? [auto]', 'Y' if default else 'N')
        return default
    if args.yes:
        print(message + '? [auto] YES')
        return True
    if args.no:
        print(message + '? [auto] NO')
        return False
    if default:
        message += '? [Y/n] '
    else:
        message += '? [N/y] '
    while True:
        answer = input(message).strip().lower()
        if not answer:
            return default
        if answer in ('y', 'yes'):
            return True
        if answer in ('n', 'no'):
            return False
        if answer in ('q', 'quit'):
            print('Exit')
            raise SystemExit(0)
        if answer in ('p', 'pdb'):
            import pdb
            pdb.set_trace()
        print('Please answer YES or NO.')

@contextlib.contextmanager
def stopwatch(message):
    """Context manager to print how long a block of code took."""
    t0 = time.time()
    try:
        yield
    finally:
        t1 = time.time()
        print('Total elapsed time for %s: %.3f' % (message, t1 - t0))

if __name__ == '__main__':
    main()