<commit_before>/*
 * Paper.js
 *
 * This file is part of Paper.js, a JavaScript Vector Graphics Library,
 * based on Scriptographer.org and designed to be largely API compatible.
 * http://paperjs.org/
 * http://scriptographer.org/
 *
 * Copyright (c) 2011, Juerg Lehni & Jonathan Puckey
 * http://lehni.org/ & http://jonathanpuckey.com/
 *
 * Distributed under the MIT license. See LICENSE file for details.
 *
 * All rights reserved.
 */

module('HitResult');

test('hitting a filled shape', function() {
	var path = new Path.Circle([50, 50], 50);

	var hitResult = path.hitTest([75, 75]);
	equals(function() {
		return hitResult == null;
	}, true, 'Since the path is not filled, the hit-test should return null');

	path.fillColor = 'red';
	hitResult = path.hitTest([75, 75]);
	equals(function() {
		return hitResult.type == 'fill';
	}, true);
	equals(function() {
		return hitResult.item == path;
	}, true);
});

test('the item on top should be returned', function() {
	var path = new Path.Circle([50, 50], 50);
	path.fillColor = 'red';

	// The cloned path is lying above the path:
	var copy = path.clone();

	var hitResult = paper.project.hitTest([75, 75]);
	equals(function() {
		return hitResult.item == copy;
	}, true);
});

test('hitting a stroked path', function() {
	var path = new Path([0, 0], [50, 0]);

	// We are hit testing with an offset of 5pt on a path with a stroke width
	// of 10:

	var hitResult = paper.project.hitTest([25, 5]);
	equals(function() {
		return hitResult == null;
	}, true, 'Since the path is not stroked yet, the hit-test should return null');

	path.strokeColor = 'black';
	path.strokeWidth = 10;
	hitResult = path.hitTest([25, 5]);
	equals(function() {
		return hitResult.type == 'stroke';
	}, true);
	equals(function() {
		return hitResult.item == path;
	}, true);
});

test('hitting a selected path', function() {
	var path = new Path.Circle([50, 50], 50);
	path.fillColor = 'red';

	var hitResult = paper.project.hitTest([75, 75], {
		selected: true
	});
	equals(function() {
		return hitResult == null;
	}, true, 'Since the path is not selected, the hit-test should return null');

	path.selected = true;
	hitResult = paper.project.hitTest([75, 75]);
	equals(function() {
		return hitResult.type == 'fill';
	}, true);
	equals(function() {
		return hitResult.item == path;
	}, true);
});

test('hitting path segments', function() {
	var path = new Path([0, 0], [10, 10], [20, 0]);

	var hitResult = paper.project.hitTest([10, 10]);

	equals(function() {
		return !!hitResult;
	}, true, 'A HitResult should be returned.');

	if (hitResult) {
		equals(function() {
			return hitResult.type;
		}, 'segment');

		equals(function() {
			return hitResult.item == path;
		}, true);
	}
});

test('hitting the center of a path', function() {
	var path = new Path([0, 0], [100, 100], [200, 0]);
	path.closed = true;

	var hitResult = paper.project.hitTest(path.position, {
		center: true
	});

	equals(function() {
		return !!hitResult;
	}, true, 'A HitResult should be returned.');

	if (hitResult) {
		equals(function() {
			return hitResult.point.toString();
		}, path.position.toString());

		equals(function() {
			return hitResult.type;
		}, 'center');
		equals(function() {
			return hitResult.item !== paper.project.activeLayer;
		}, true, 'We should not be hitting the active layer.');

		equals(function() {
			return hitResult.item == path;
		}, true, 'We should be hitting the path.');
	}
});

test('hitting the center of a path with tolerance', function() {
	var path = new Path([0, 0], [100, 100], [200, 0]);
	path.closed = true;
	var hitResult = paper.project.hitTest(path.position.add(1, 1), {
		center: true
	});

	equals(function() {
		return !!hitResult;
	}, true, 'A HitResult should be returned.');

	if (hitResult) {
		equals(function() {
			return !!hitResult.point;
		}, true, 'HitResult#point should not be empty');

		if (hitResult.point) {
			equals(function() {
				return hitResult.point.toString();
			}, path.position.toString());
		}

		equals(function() {
			return hitResult.type;
		}, 'center');

		equals(function() {
			return hitResult.item !== paper.project.activeLayer;
		}, true, 'We should not be hitting the active layer.');

		equals(function() {
			return hitResult.item == path;
		}, true, 'We should be hitting the path.');
	}
});

test('hitting path handles', function() {
	var path = new Path.Circle(new Point(), 10);
	path.firstSegment.handleIn = [-50, 0];
	path.firstSegment.handleOut = [50, 0];
	var firstPoint = path.firstSegment.point;
	var hitResult = paper.project.hitTest(firstPoint.add(50, 0), {
		handles: true
	});

	equals(function() {
		return !!hitResult;
	}, true, 'A HitResult should be returned (1)');

	if (hitResult) {
		equals(function() {
			return hitResult.type;
		}, 'handle-out');

		equals(function() {
			return hitResult.item == path;
		}, true);
	}

	var hitResult = paper.project.hitTest(firstPoint.add(-50, 0), {
		handles: true
	});

	equals(function() {
		return !!hitResult;
	}, true, 'A HitResult should be returned (2)');

	if (hitResult) {
		equals(function() {
			return hitResult.type;
		}, 'handle-in');

		equals(function() {
			return hitResult.item == path;
		}, true);
	}
});

test('hitting path handles (2)', function() {
	var path = new Path(new Segment({
		point: [0, 0],
		handleIn: [-50, -50],
		handleOut: [50, 50]
	}));

	var hitResult = paper.project.hitTest([50, 50], {
		handles: true
	});

	equals(function() {
		return !!hitResult;
	}, true, 'A HitResult should be returned (1)');

	if (hitResult) {
		equals(function() {
			return hitResult.type;
		}, 'handle-out');

		equals(function() {
			return hitResult.item == path;
		}, true);
	}

	var hitResult = paper.project.hitTest([-50, -50], {
		handles: true
	});

	equals(function() {
		return !!hitResult;
	}, true, 'A HitResult should be returned (2)');

	if (hitResult) {
		equals(function() {
			return hitResult.type;
		}, 'handle-in');

		equals(function() {
			return hitResult.item == path;
		}, true);
	}
});

test('hitting path ends', function() {
	var path = new Path([0, 0], [50, 50], [100, 0]);
	path.closed = true;

	equals(function() {
		return !paper.project.hitTest(path.firstSegment.point, {
			ends: true
		});
	}, true, 'No hitresult should be returned, because the path is closed.');

	path.closed = false;

	var hitResult = paper.project.hitTest(path.lastSegment.point, {
		ends: true
	});

	equals(function() {
		return !!hitResult;
	}, true, 'A HitResult should be returned (1)');

	if (hitResult) {
		equals(function() {
			return hitResult.type;
		}, 'segment');

		equals(function() {
			return hitResult.segment == path.lastSegment;
		}, true);
	}

	equals(function() {
		return !paper.project.hitTest(path.segments[1].point, {
			ends: true
		});
	}, true, 'No HitResult should be returned, since the second segment is not an end');
});

test('When a path is closed, the end of a path cannot be hit.', function() {
	var path = new Path([0, 0], [50, 50], [100, 0]);
	path.closed = true;

	var hitResult = paper.project.hitTest([0, 0], {
		ends: true
	});
	equals(function() {
		return !hitResult;
	}, true, 'When a path is closed, the end of a path cannot be hit.');
});

test('hitting path bounding box', function() {
	var path = new Path.Circle(new Point(100, 100), 50);

	var hitResult = paper.project.hitTest(path.bounds.topLeft, {
		bounds: true
	});

	equals(function() {
		return !!hitResult;
	}, true, 'A HitResult should be returned (1)');

	if (hitResult) {
		equals(function() {
			return hitResult.type;
		}, 'bounds');

		equals(function() {
			return hitResult.name;
		}, 'top-left');

		equals(function() {
			return hitResult.point.toString();
		},path.bounds.topLeft.toString());
	}
});

test('hitting guides', function() {
	var path = new Path.Circle(new Point(100, 100), 50);
	path.fillColor = 'red';

	var copy = path.clone();

	var hitResult = paper.project.hitTest(path.position);

	equals(function() {
		return !!hitResult;
	}, true, 'A HitResult should be returned (1)');

	if (hitResult) {
		equals(function() {
			return hitResult.item == copy;
		}, true, 'The copy is returned, because it is on top.');
	}

	path.guide = true;

	var hitResult = paper.project.hitTest(path.position, {
		guides: true,
		fill: true
	});

	equals(function() {
		return !!hitResult;
	}, true, 'A HitResult should be returned (2)');

	if (hitResult) {
		equals(function() {
			return hitResult.item == path;
		}, true, 'The path is returned, because it is a guide.');
	}
});

// TODO: project.hitTest(point, {type: AnItemType});<commit_msg>Add failing HitResult test.<commit_after>/*
 * Paper.js
 *
 * This file is part of Paper.js, a JavaScript Vector Graphics Library,
 * based on Scriptographer.org and designed to be largely API compatible.
 * http://paperjs.org/
 * http://scriptographer.org/
 *
 * Copyright (c) 2011, Juerg Lehni & Jonathan Puckey
 * http://lehni.org/ & http://jonathanpuckey.com/
 *
 * Distributed under the MIT license. See LICENSE file for details.
 *
 * All rights reserved.
 */

module('HitResult');

test('hitting a filled shape', function() {
	var path = new Path.Circle([50, 50], 50);

	var hitResult = path.hitTest([75, 75]);
	equals(function() {
		return hitResult == null;
	}, true, 'Since the path is not filled, the hit-test should return null');

	path.fillColor = 'red';
	hitResult = path.hitTest([75, 75]);
	equals(function() {
		return hitResult.type == 'fill';
	}, true);
	equals(function() {
		return hitResult.item == path;
	}, true);
});

test('the item on top should be returned', function() {
	var path = new Path.Circle([50, 50], 50);
	path.fillColor = 'red';

	// The cloned path is lying above the path:
	var copy = path.clone();

	var hitResult = paper.project.hitTest([75, 75]);
	equals(function() {
		return hitResult.item == copy;
	}, true);
});

test('hitting a stroked path', function() {
	var path = new Path([0, 0], [50, 0]);

	// We are hit testing with an offset of 5pt on a path with a stroke width
	// of 10:

	var hitResult = paper.project.hitTest([25, 5]);
	equals(function() {
		return hitResult == null;
	}, true, 'Since the path is not stroked yet, the hit-test should return null');

	path.strokeColor = 'black';
	path.strokeWidth = 10;
	hitResult = path.hitTest([25, 5]);
	equals(function() {
		return hitResult.type == 'stroke';
	}, true);
	equals(function() {
		return hitResult.item == path;
	}, true);
});

test('hitting a selected path', function() {
	var path = new Path.Circle([50, 50], 50);
	path.fillColor = 'red';

	var hitResult = paper.project.hitTest([75, 75], {
		selected: true
	});
	equals(function() {
		return hitResult == null;
	}, true, 'Since the path is not selected, the hit-test should return null');

	path.selected = true;
	hitResult = paper.project.hitTest([75, 75]);
	equals(function() {
		return hitResult.type == 'fill';
	}, true);
	equals(function() {
		return hitResult.item == path;
	}, true);
});

test('hitting path segments', function() {
	var path = new Path([0, 0], [10, 10], [20, 0]);

	var hitResult = paper.project.hitTest([10, 10]);

	equals(function() {
		return !!hitResult;
	}, true, 'A HitResult should be returned.');

	if (hitResult) {
		equals(function() {
			return hitResult.type;
		}, 'segment');

		equals(function() {
			return hitResult.item == path;
		}, true);
	}
});

test('hitting the center of a path', function() {
	var path = new Path([0, 0], [100, 100], [200, 0]);
	path.closed = true;

	var hitResult = paper.project.hitTest(path.position, {
		center: true
	});

	equals(function() {
		return !!hitResult;
	}, true, 'A HitResult should be returned.');

	if (hitResult) {
		equals(function() {
			return hitResult.point.toString();
		}, path.position.toString());

		equals(function() {
			return hitResult.type;
		}, 'center');
		equals(function() {
			return hitResult.item !== paper.project.activeLayer;
		}, true, 'We should not be hitting the active layer.');

		equals(function() {
			return hitResult.item == path;
		}, true, 'We should be hitting the path.');
	}
});

test('hitting the center of a path with tolerance', function() {
	var path = new Path([0, 0], [100, 100], [200, 0]);
	path.closed = true;
	var hitResult = paper.project.hitTest(path.position.add(1, 1), {
		center: true
	});

	equals(function() {
		return !!hitResult;
	}, true, 'A HitResult should be returned.');

	if (hitResult) {
		equals(function() {
			return !!hitResult.point;
		}, true, 'HitResult#point should not be empty');

		if (hitResult.point) {
			equals(function() {
				return hitResult.point.toString();
			}, path.position.toString());
		}

		equals(function() {
			return hitResult.type;
		}, 'center');

		equals(function() {
			return hitResult.item !== paper.project.activeLayer;
		}, true, 'We should not be hitting the active layer.');

		equals(function() {
			return hitResult.item == path;
		}, true, 'We should be hitting the path.');
	}
});

test('hitting path handles', function() {
	var path = new Path.Circle(new Point(), 10);
	path.firstSegment.handleIn = [-50, 0];
	path.firstSegment.handleOut = [50, 0];
	var firstPoint = path.firstSegment.point;
	var hitResult = paper.project.hitTest(firstPoint.add(50, 0), {
		handles: true
	});

	equals(function() {
		return !!hitResult;
	}, true, 'A HitResult should be returned (1)');

	if (hitResult) {
		equals(function() {
			return hitResult.type;
		}, 'handle-out');

		equals(function() {
			return hitResult.item == path;
		}, true);
	}

	var hitResult = paper.project.hitTest(firstPoint.add(-50, 0), {
		handles: true
	});

	equals(function() {
		return !!hitResult;
	}, true, 'A HitResult should be returned (2)');

	if (hitResult) {
		equals(function() {
			return hitResult.type;
		}, 'handle-in');

		equals(function() {
			return hitResult.item == path;
		}, true);
	}
});

test('hitting path handles (2)', function() {
	var path = new Path(new Segment({
		point: [0, 0],
		handleIn: [-50, -50],
		handleOut: [50, 50]
	}));

	var hitResult = paper.project.hitTest([50, 50], {
		handles: true
	});

	equals(function() {
		return !!hitResult;
	}, true, 'A HitResult should be returned (1)');

	if (hitResult) {
		equals(function() {
			return hitResult.type;
		}, 'handle-out');

		equals(function() {
			return hitResult.item == path;
		}, true);
	}

	var hitResult = paper.project.hitTest([-50, -50], {
		handles: true
	});

	equals(function() {
		return !!hitResult;
	}, true, 'A HitResult should be returned (2)');

	if (hitResult) {
		equals(function() {
			return hitResult.type;
		}, 'handle-in');

		equals(function() {
			return hitResult.item == path;
		}, true);
	}
});

test('hit testing stroke on segment point of a path', function() {
	var path = new Path([0, 0], [50, 50], [100, 0]);
	path.strokeColor = 'black';
	path.closed = true;

	var error = null;
	try {
		var hitResult = paper.project.hitTest(path.firstSegment.point, {
			stroke: true
		});
	} catch (e) {
		error = e;
	}
	var description = 'This hit test should not throw an error';
	if (error)
		description += ': ' + error;
	equals(error == null, true, description);
});

test('hitting path ends', function() {
	var path = new Path([0, 0], [50, 50], [100, 0]);
	path.closed = true;

	equals(function() {
		return !paper.project.hitTest(path.firstSegment.point, {
			ends: true
		});
	}, true, 'No hitresult should be returned, because the path is closed.');

	path.closed = false;

	var hitResult = paper.project.hitTest(path.lastSegment.point, {
		ends: true
	});

	equals(function() {
		return !!hitResult;
	}, true, 'A HitResult should be returned (1)');

	if (hitResult) {
		equals(function() {
			return hitResult.type;
		}, 'segment');

		equals(function() {
			return hitResult.segment == path.lastSegment;
		}, true);
	}

	equals(function() {
		return !paper.project.hitTest(path.segments[1].point, {
			ends: true
		});
	}, true, 'No HitResult should be returned, since the second segment is not an end');
});

test('When a path is closed, the end of a path cannot be hit.', function() {
	var path = new Path([0, 0], [50, 50], [100, 0]);
	path.closed = true;

	var hitResult = paper.project.hitTest([0, 0], {
		ends: true
	});
	equals(function() {
		return !hitResult;
	}, true, 'When a path is closed, the end of a path cannot be hit.');
});

test('hitting path bounding box', function() {
	var path = new Path.Circle(new Point(100, 100), 50);

	var hitResult = paper.project.hitTest(path.bounds.topLeft, {
		bounds: true
	});

	equals(function() {
		return !!hitResult;
	}, true, 'A HitResult should be returned (1)');

	if (hitResult) {
		equals(function() {
			return hitResult.type;
		}, 'bounds');

		equals(function() {
			return hitResult.name;
		}, 'top-left');

		equals(function() {
			return hitResult.point.toString();
		},path.bounds.topLeft.toString());
	}
});

test('hitting guides', function() {
	var path = new Path.Circle(new Point(100, 100), 50);
	path.fillColor = 'red';

	var copy = path.clone();

	var hitResult = paper.project.hitTest(path.position);

	equals(function() {
		return !!hitResult;
	}, true, 'A HitResult should be returned (1)');

	if (hitResult) {
		equals(function() {
			return hitResult.item == copy;
		}, true, 'The copy is returned, because it is on top.');
	}

	path.guide = true;

	var hitResult = paper.project.hitTest(path.position, {
		guides: true,
		fill: true
	});

	equals(function() {
		return !!hitResult;
	}, true, 'A HitResult should be returned (2)');

	if (hitResult) {
		equals(function() {
			return hitResult.item == path;
		}, true, 'The path is returned, because it is a guide.');
	}
});

// TODO: project.hitTest(point, {type: AnItemType});<|endoftext|>


<commit_before>/*global Audit */
describe('Audit', function () {
	'use strict';
	var a;

	var mockRules = [{
		id: 'positive1',
		selector: 'input',
		checks: [{
			id: 'positive1-check1',
			evaluate: function () {
				return true;
			}
		}]
	}, {
		id: 'positive2',
		selector: '#monkeys',
		checks: [{
			id: 'positive2-check1',
			evaluate: function () {
				return true;
			}
		}]
	}, {
		id: 'negative1',
		selector: 'div',
		checks: [{
			id: 'negative1-check1',
			type: 'FAIL',
			evaluate: function () {
				return true;
			}
		}]
	}, {
		id: 'positive3',
		selector: 'blink',
		checks: [{
			id: 'positive3-check1',
			evaluate: function () {
				return true;
			}
		}]
	}];

	var fixture = document.getElementById('fixture');

	beforeEach(function () {
		a = new Audit();
		mockRules.forEach(function (rule) {
			a.addRule(rule);
		});
	});
	afterEach(function () {
		fixture.innerHTML = '';
	});

	it('should be a function', function () {
		assert.isFunction(Audit);
	});

	describe('document', function () {
		it('should create a document based on the current window.document', function () {
			var orig = window.DqDocument;
			var called = false;
			window.DqDocument = function () {
				called = true;
				assert.notEqual(this, window, 'invoked with `new`');
				return { bananas: 'monkeys' };
			};
			var a = new Audit({});

			assert.isTrue(called);
			assert.deepEqual(a.document, { bananas: 'monkeys' });
			window.DqDocument = orig;
		});
	});

	describe('Audit#run', function () {
		it('should work', function (done) {
			fixture.innerHTML = '<input type="text" aria-label="monkeys">' +
				'
bananas
' +
				'<input type="text" aria-labelledby="monkeys">' +
				'<blink>FAIL ME</blink>';
			a.run({ include: [fixture] }, {}, function () {
				assert.ok('yay');
				done();
			});
		});
		it('should run all the rules', function (done) {
			fixture.innerHTML = '<input aria-label="monkeys" type="text">' +
				'
bananas
' +
				'<input aria-labelledby="monkeys" type="text">' +
				'<blink>FAIL ME</blink>';

			a.run({ include: [fixture] }, {}, function (results) {
				var expected = [{
					id: 'positive1',
					result: 'NA',
					pageLevel: false,
					details: [{
						node: {
							selector: '#fixture > input:nth-of-type(1)',
							source: '<input aria-label="monkeys" type="text">',
							frames: []
						},
						checks: [{
							id: 'positive1-check1',
							type: 'PASS',
							result: true,
							data: null,
							error: null,
							relatedNodes: []
						}]
					}, {
						node: {
							selector: '#fixture > input:nth-of-type(2)',
							source: '<input aria-labelledby="monkeys" type="text">',
							frames: []
						},
						checks: [{
							id: 'positive1-check1',
							type: 'PASS',
							result: true,
							data: null,
							error: null,
							relatedNodes: []
						}]
					}]
				}, {
					id: 'positive2',
					result: 'NA',
					pageLevel: false,
					details: [{
						node: {
							selector: '#monkeys',
							source: '
bananas
',
							frames: []
						},
						checks: [{
							id: 'positive2-check1',
							type: 'PASS',
							result: true,
							data: null,
							error: null,
							relatedNodes: []
						}]
					}]
				}, {
					id: 'negative1',
					result: 'NA',
					pageLevel: false,
					details: [{
						node: {
							selector: '#monkeys',
							source: '
bananas
',
							frames: []
						},
						checks: [{
							id: 'negative1-check1',
							type: 'FAIL',
							result: true,
							data: null,
							error: null,
							relatedNodes: []
						}]
					}]
				}, {
					id: 'positive3',
					result: 'NA',
					pageLevel: false,
					details: [{
						node: {
							selector: '#fixture > blink',
							source: '<blink>FAIL ME</blink>',
							frames: []
						},
						checks: [{
							id: 'positive3-check1',
							type: 'PASS',
							result: true,
							data: null,
							error: null,
							relatedNodes: []
						}]
					}]
				}];
				assert.deepEqual(results, expected);
				done();
			});
		});
		it('should not run rules disabled by the options', function (done) {
			a.run({ include: [document] }, [{id: 'positive3', enabled: false}], function (results) {
				assert.equal(results.length, 3);
				done();
			});
		});
		it('should call the rule\'s run function', function (done) {
			var targetRule = mockRules[mockRules.length - 1],
				rule = utils.findBy(a.rules, 'id', targetRule.id),
				called = false,
				orig;

			fixture.innerHTML = 'link';
			orig = rule.run;
			rule.run = function (node, options, callback) {
				called = true;
				callback({});
			};
			a.run({ include: [document] }, {}, function () {
				assert.isTrue(called);
				rule.run = orig;
				done();
			});
		});
		it('should pass the option to the run function', function (done) {
			var targetRule = mockRules[mockRules.length - 1],
				rule = utils.findBy(a.rules, 'id', targetRule.id),
				passed = false,
				orig, options;

			fixture.innerHTML = 'link';
			orig = rule.run;
			rule.run = function (node, options, callback) {
				assert.ok(options);
				assert.equal(options.id, targetRule.id);
				assert.equal(options.data, 'monkeys');
				passed = true;
				callback({});
			};
			options = [{id: targetRule.id, data: 'monkeys'}];
			a.run({ include: [document] }, options, function () {
				assert.ok(passed);
				rule.run = orig;
				done();
			});
		});

		it('should skip pageLevel rules if context is not set to entire page', function () {
			var audit = new Audit();

			audit.addRule({
				pageLevel: true,
				enabled: true,
				evaluate: function () {
					assert.ok(false, 'Should not run');
				}
			});

			audit.run({ include: [ document.body ], page: false }, {}, function (results) {
				assert.deepEqual(results, []);
			});

		});
	});
	describe('Audit#after', function () {
		it('should run Rule#after on any rule whose result is passed in', function () {
			var audit = new Audit();
			var success = false;
			var options = [{ id: 'hehe', enabled: true, monkeys: 'bananas' }];
			var results = [{
				id: 'hehe',
				monkeys: 'bananas'
			}];
			audit.addRule({
				id: 'hehe',
				pageLevel: false,
				enabled: false
			});

			audit.rules[0].after = function (res, opts) {
				assert.equal(res, results[0]);
				assert.equal(opts, options[0]);
				success = true;
			};

			audit.after(results, options);
		});
	});

});
<commit_msg>IE being weird again<commit_after>/*global Audit */
describe('Audit', function () {
	'use strict';
	var a;

	var mockRules = [{
		id: 'positive1',
		selector: 'input',
		checks: [{
			id: 'positive1-check1',
			evaluate: function () {
				return true;
			}
		}]
	}, {
		id: 'positive2',
		selector: '#monkeys',
		checks: [{
			id: 'positive2-check1',
			evaluate: function () {
				return true;
			}
		}]
	}, {
		id: 'negative1',
		selector: 'div',
		checks: [{
			id: 'negative1-check1',
			type: 'FAIL',
			evaluate: function () {
				return true;
			}
		}]
	}, {
		id: 'positive3',
		selector: 'blink',
		checks: [{
			id: 'positive3-check1',
			evaluate: function () {
				return true;
			}
		}]
	}];

	var fixture = document.getElementById('fixture');

	beforeEach(function () {
		a = new Audit();
		mockRules.forEach(function (rule) {
			a.addRule(rule);
		});
	});
	afterEach(function () {
		fixture.innerHTML = '';
	});

	it('should be a function', function () {
		assert.isFunction(Audit);
	});

	describe('document', function () {
		it('should create a document based on the current window.document', function () {
			var orig = window.DqDocument;
			var called = false;
			window.DqDocument = function () {
				called = true;
				assert.notEqual(this, window, 'invoked with `new`');
				return { bananas: 'monkeys' };
			};
			var a = new Audit({});

			assert.isTrue(called);
			assert.deepEqual(a.document, { bananas: 'monkeys' });
			window.DqDocument = orig;
		});
	});

	describe('Audit#run', function () {
		it('should run all the rules', function (done) {
			fixture.innerHTML = '<input type="text" aria-label="monkeys">' +
				'
bananas
' +
				'<input aria-labelledby="monkeys" type="text">' +
				'<blink>FAIL ME</blink>';

			a.run({ include: [fixture] }, {}, function (results) {
				var expected = [{
					id: 'positive1',
					result: 'NA',
					pageLevel: false,
					details: [{
						node: {
							selector: '#fixture > input:nth-of-type(1)',
							source: '<input type="text" aria-label="monkeys">',
							frames: []
						},
						checks: [{
							id: 'positive1-check1',
							type: 'PASS',
							result: true,
							data: null,
							error: null,
							relatedNodes: []
						}]
					}, {
						node: {
							selector: '#fixture > input:nth-of-type(2)',
							source: '<input aria-labelledby="monkeys" type="text">',
							frames: []
						},
						checks: [{
							id: 'positive1-check1',
							type: 'PASS',
							result: true,
							data: null,
							error: null,
							relatedNodes: []
						}]
					}]
				}, {
					id: 'positive2',
					result: 'NA',
					pageLevel: false,
					details: [{
						node: {
							selector: '#monkeys',
							source: '
bananas
',
							frames: []
						},
						checks: [{
							id: 'positive2-check1',
							type: 'PASS',
							result: true,
							data: null,
							error: null,
							relatedNodes: []
						}]
					}]
				}, {
					id: 'negative1',
					result: 'NA',
					pageLevel: false,
					details: [{
						node: {
							selector: '#monkeys',
							source: '
bananas
',
							frames: []
						},
						checks: [{
							id: 'negative1-check1',
							type: 'FAIL',
							result: true,
							data: null,
							error: null,
							relatedNodes: []
						}]
					}]
				}, {
					id: 'positive3',
					result: 'NA',
					pageLevel: false,
					details: [{
						node: {
							selector: '#fixture > blink',
							source: '<blink>FAIL ME</blink>',
							frames: []
						},
						checks: [{
							id: 'positive3-check1',
							type: 'PASS',
							result: true,
							data: null,
							error: null,
							relatedNodes: []
						}]
					}]
				}];
				assert.deepEqual(results, expected);
				done();
			});
		});
		it('should not run rules disabled by the options', function (done) {
			a.run({ include: [document] }, [{id: 'positive3', enabled: false}], function (results) {
				assert.equal(results.length, 3);
				done();
			});
		});
		it('should call the rule\'s run function', function (done) {
			var targetRule = mockRules[mockRules.length - 1],
				rule = utils.findBy(a.rules, 'id', targetRule.id),
				called = false,
				orig;

			fixture.innerHTML = 'link';
			orig = rule.run;
			rule.run = function (node, options, callback) {
				called = true;
				callback({});
			};
			a.run({ include: [document] }, {}, function () {
				assert.isTrue(called);
				rule.run = orig;
				done();
			});
		});
		it('should pass the option to the run function', function (done) {
			var targetRule = mockRules[mockRules.length - 1],
				rule = utils.findBy(a.rules, 'id', targetRule.id),
				passed = false,
				orig, options;

			fixture.innerHTML = 'link';
			orig = rule.run;
			rule.run = function (node, options, callback) {
				assert.ok(options);
				assert.equal(options.id, targetRule.id);
				assert.equal(options.data, 'monkeys');
				passed = true;
				callback({});
			};
			options = [{id: targetRule.id, data: 'monkeys'}];
			a.run({ include: [document] }, options, function () {
				assert.ok(passed);
				rule.run = orig;
				done();
			});
		});

		it('should skip pageLevel rules if context is not set to entire page', function () {
			var audit = new Audit();

			audit.addRule({
				pageLevel: true,
				enabled: true,
				evaluate: function () {
					assert.ok(false, 'Should not run');
				}
			});

			audit.run({ include: [ document.body ], page: false }, {}, function (results) {
				assert.deepEqual(results, []);
			});

		});
	});
	describe('Audit#after', function () {
		it('should run Rule#after on any rule whose result is passed in', function () {
			var audit = new Audit();
			var success = false;
			var options = [{ id: 'hehe', enabled: true, monkeys: 'bananas' }];
			var results = [{
				id: 'hehe',
				monkeys: 'bananas'
			}];
			audit.addRule({
				id: 'hehe',
				pageLevel: false,
				enabled: false
			});

			audit.rules[0].after = function (res, opts) {
				assert.equal(res, results[0]);
				assert.equal(opts, options[0]);
				success = true;
			};

			audit.after(results, options);
		});
	});

});
<|endoftext|>


<commit_before>const expect = require('chai').expect;
const util = require('../../src/util');
const { Canvas } = require('@ali/g');
const View = require('../../src/chart/view');
const Coord = require('../../src/coord/index');

const div = document.createElement('div');
div.id = 'debug';
document.body.appendChild(div);

const canvas = new Canvas({
  containerId: 'debug',
  width: 500,
  height: 500
});

const coord = new Coord.Rect({
  start: {
    x: 80,
    y: 420
  },
  end: {
    x: 420,
    y: 80
  }
});

const data = [
  { a: 1, b: 2 },
  { a: 2, b: 5 },
  { a: 3, b: 4 }
];
describe('test view', function() {
const view = new View({
  viewContainer: canvas.addGroup({
    zIndex: 2
  }),
  canvas: canvas,
  coord,
  options: {
    scales: {
      e: {
        type: 'cat',
        values: ['a', 'b', 'c']
      },
      a: {
        min: 0
      },
      b: {
        min: 0
      }
    },
    axes: {
      a: {
        title: null
      },
      b: {
        grid: {
          position: 'center'
        }
      }
    }
  }
});

view.source(data);
view.scale({
  a: {
    min: 0
  },
  b: {
    min: 0
  }
});
view.axis('a', {
  title: {
    textStyle: {
      fill: 'red'
    }
  }
});

view.guide().line({
  start: {
    a: 1,
    b: 2
  },
  end: {
    a: 3,
    b: 4
  },
  text: {
    content: '辅助线的辅助文本',
    position: 0.3
  }
});
const line = view.line().position('a*b');

view.render();
canvas.sort();
canvas.draw();
});
<commit_msg>移除无用文件<commit_after><|endoftext|>


<commit_before>const rafter = require('../../rafter/rController');
// const VolumeService = require('rafter').VolumeService;
// const nock = require('nock');
// VolumeService.list = function() { return promise.resolve({ json: () => Promise.resolve({ name: 'filename' }) }); };
describe('The Unit Test for Rafter', () => {

  // it('should login a rafter user', (done) => {
  //   nock('https://rafter.bi.vt.edu')
  //     .defaultReplyHeaders({
  //       'set-cookie':['cookie']
  //     })
  //     .post('/usersvc/login')
  //     .reply(301);
  //     const token = { token: '

' };
  //   nock('https://rafter.bi.vt.edu')
  //     .get('/usersvc/')
  //     .reply(200, token);
  //   const req = { body: { id:'yo', password: 'yo' } };
  //   const res = {
  //       json: (msg) => {
  //       expect(msg).to.equal('{"token":"

"}');
  //       done();
  //     }
  //   };
  //   rafter.rlogin(req, res);
  // });
  //
  // it('should not login a rafter user', (done) => {
  //   nock('https://rafter.bi.vt.edu')
  //     .defaultReplyHeaders({
  //       'set-cookie':['cookie']
  //     })
  //     .post('/usersvc/login')
  //     .reply(400);
  //   const token = { token: '

' };
  //   nock('https://rafter.bi.vt.edu')
  //     .get('/usersvc/')
  //     .reply(200, token);
  //   const req = { body: { id:'yo', password: 'yo' } };
  //   const res = {
  //     status: (code) => {
  //       expect(code).to.equal(400);
  //       done();
  //     }
  //   };
  //   rafter.rlogin(req, res);
  // });

  it('initializes the volume service', async() => {
    const req = { body: { command: 'ls', token: 'token', userName: 'yoyo', rafterFile: { path: '/yo' } } };
    const res = {
      status(code) { return { json() {} }; }
      //   expect(code).to.equal(200);
      // }
    };
    // const init = { list() { return Promise.reject(new Error('fail')); } };
    // req.body.init = init;
    await rafter.initVolS(req, res);
    // expect(res.status)
  });
  it('tries to lists the contents of a directory but has an error', async() => {
    const req = { body: { command: 'ls', token: 'token', userName: 'yoyo', rafterFile: { path: '/yo' } } };
    const res = {
      status: (code) => {
        // expect(code).to.equal(200);
      }
    };
    const init = { list() { return Promise.reject(new Error('fail')); } };
    req.body.init = init;
    await rafter.runVolumeService(req, res);
  });
  it('lists the contents of home directory', async() => {
    const req = { body: { command: 'ls', token: 'token', userName: 'yoyo', rafterFile: { path: '/yo' } } };
    const res = {
      json(item) {}
    };
    const init = { list() { return Promise.resolve({ name: 'filename' }); } };
    req.body.init = init;
    await rafter.runVolumeService(req, res);
  });
  it('creates a new file', async() => {
    const req = { body: { command: 'create', token: 'token', userName: 'yoyo', rafterFile: { name: 'filename', createType: 'file' } } };
    const res = {
      json(item) {},
      status: (code) => {
        expect(code).to.equal(200);
        return { json(item) {} };
      }
    };
    const init = { create() { return Promise.resolve({ name: 'filename' }); } };
    req.body.init = init;
    await rafter.runVolumeService(req, res);
  });
  it('creates a new file and puts the contents', async() => {
    const req = { body: { command: 'create', token: 'token', userName: 'yoyo', rafterFile: { name: 'filename', createType: 'file', content:'howdy' } } };
    const res = {
      json(item) {},
      status: (code) => {
        expect(code).to.equal(200);
        return { json(item) {} };
      }
    };
    const init = { create() { return Promise.resolve({ name: 'filename' }); },
    put() { return Promise.resolve({ name: 'filename' }); }
    };
    req.body.init = init;
    await rafter.runVolumeService(req, res);
  });
  it('creates a new file but has error on putting the contents', async() => {
    const req = { body: { command: 'create', token: 'token', userName: 'yoyo', rafterFile: { name: 'filename', createType: 'file', content:'howdy' } } };
    const res = {
      json(item) {},
      status: (code) => {
        // expect(code).to.equal(200);
        // return { json(item) {} };
      }
    };
    const init = { create() { return Promise.resolve({ name: 'filename' }); },
    put() { return Promise.reject(new Error('fail')); }
    };
    req.body.init = init;
    await rafter.runVolumeService(req, res);
  });
  it('tries to create a new file but has error', async() => {
    const req = { body: { command: 'create', token: 'token', userName: 'yoyo', rafterFile: { name: 'filename', createType: 'file' } } };
    const res = {
      json(item) {},
      status: (code) => {
        // expect(code).to.equal(400);
      }
    };
    const init = { create() { return Promise.reject(new Error('fail')); } };
    req.body.init = init;
    await rafter.runVolumeService(req, res);
  });
  it('prevents creating a new file without a file name', async() => {
    const req = { body: { command: 'create', token: 'token', userName: 'yoyo', rafterFile: { name: '', createType: 'file' } } };
    const res = {
      json(item) {},
      status: (code) => {
        expect(code).to.equal(400);
        return { json(item) {} };
      }
    };
    const init = { create() { return Promise.resolve({ name: '' }); } };
    req.body.init = init;
    await rafter.runVolumeService(req, res);
  });
  it('creates a new folder', async() => {
    const req = { body: { command: 'create', token: 'token', userName: 'yoyo', rafterFile: { name: 'filename', createType: 'folder' } } };
    const res = {
      json(item) {},
      status: (code) => {
        expect(code).to.equal(200);
        return { json(item) {} };
      }
    };
    const init = { mkdir() { return Promise.resolve({ name: 'filename' }); } };
    req.body.init = init;
    await rafter.runVolumeService(req, res);
  });
  it('catches error on create new folder', async() => {
    const req = { body: { command: 'create', token: 'token', userName: 'yoyo', rafterFile: { name: 'filename', createType: 'folder' } } };
    const res = {
      json(item) {},
      status: (code) => {
        // expect(code).to.equal(200);
        // return { json(item) {} };
      }
    };
    const init = { mkdir() { return Promise.reject({ error: 'you fail' }); } };
    req.body.init = init;
    await rafter.runVolumeService(req, res);
  });
  it('asks for a bogus volume service command', async() => {
    const req = { body: { command: 'bogas', token: 'token', userName: 'yoyo', rafterFile: { name: 'filename' } } };
    const res = {
      json(item) {},
      status: (code) => {
        expect(code).to.equal(400);
        return { json(item) {} };
      }
    };
    const init = { create() { return Promise.resolve({ error: 'you fail' }); } };
    req.body.init = init;
    await rafter.runVolumeService(req, res);
  });

  it('downloads a file', async() => {
    const req = { body: { command: 'get', token: 'token', userName: 'yoyo', fileID: '123' } };
    const res = {
      setHeader() {}
      // status: (code) => {
      //   expect(code).to.equal(200);
      //   return { json(item) {} };
      // }
    };
    const init = { get() { return Promise.resolve({ name: 'filename' }); } };
    req.body.init = init;
    await rafter.runVolumeService(req, res);
  });

  it('deletes a file', async() => {
    const req = { body: { command: 'remove', token: 'token', userName: 'yoyo', fileID: '123' } };
    const res = {
      json() {}
      // status: (code) => {
      //   expect(code).to.equal(200);
      //   return { json(item) {} };
      // }
    };
    const init = { remove() { return Promise.resolve(true); } };
    req.body.init = init;
    await rafter.runVolumeService(req, res);
  });

  it('catches error on delete a file', async() => {
    const req = { body: { command: 'remove', token: 'token', userName: 'yoyo', fileID: '123' } };
    const res = {
      json(err) {
      // status: (code) => {
      expect(err.message).to.be('you fail');
      }
      //   return { json(item) {} };
      // }
    };
    const init = { remove() { return Promise.reject(new Error({ message: 'you fail' })); } };
    req.body.init = init;
    await rafter.runVolumeService(req, res);
  });

});
<commit_msg>unit tests<commit_after>const rafter = require('../../rafter/rController');
// const VolumeService = require('rafter').VolumeService;
const nock = require('nock');
// VolumeService.list = function() { return promise.resolve({ json: () => Promise.resolve({ name: 'filename' }) }); };
describe('The Unit Test for Rafter', () => {

  it('initializes a rafter user (returns their token)', (done) => {
    const token = 'token';
    nock('https://rafter.bi.vt.edu')
      .defaultReplyHeaders({
        'set-cookie':['cookie']
      })
      .post('/usersvc/authenticate/123')
        .reply(200, token);
    // nock('https://rafter.bi.vt.edu')
    //   .get('/usersvc/')
    //   .reply(200, token);
    const req = { body: { id: '123', secret: 'howdy' } };
    const res = {
        json: (data) => {
        expect(data).to.equal('token');
        done();
      }
    };
    rafter.rinit(req, res);
  });

  it('sends error on rafter init)', (done) => {
    // const token = 'token';
    nock('https://rafter.bi.vt.edu')
      .defaultReplyHeaders({
        'set-cookie':['cookie']
      })
      .post('/usersvc/authenticate/123')
        .replyWithError({ status: 400 });
    // nock('https://rafter.bi.vt.edu')
    //   .get('/usersvc/')
    //   .reply(200, token);
    const req = { body: { id: '123', secret: 'howdy' } };
    const res = {
        json: (err) => {
        expect(err.status).to.equal(400);
        done();
      }
    };
    rafter.rinit(req, res);
  });

  // it('should login a rafter user', (done) => {
  //   nock('https://rafter.bi.vt.edu')
  //     .defaultReplyHeaders({
  //       'set-cookie':['cookie']
  //     })
  //     .post('/usersvc/login')
  //     .reply(301);
  //     const token = { token: '

' };
  //   nock('https://rafter.bi.vt.edu')
  //     .get('/usersvc/')
  //     .reply(200, token);
  //   const req = { body: { id:'yo', password: 'yo' } };
  //   const res = {
  //       json: (msg) => {
  //       expect(msg).to.equal('{"token":"

"}');
  //       done();
  //     }
  //   };
  //   rafter.rlogin(req, res);
  // });
  //
  // it('should not login a rafter user', (done) => {
  //   nock('https://rafter.bi.vt.edu')
  //     .defaultReplyHeaders({
  //       'set-cookie':['cookie']
  //     })
  //     .post('/usersvc/login')
  //     .reply(400);
  //   const token = { token: '

' };
  //   nock('https://rafter.bi.vt.edu')
  //     .get('/usersvc/')
  //     .reply(200, token);
  //   const req = { body: { id:'yo', password: 'yo' } };
  //   const res = {
  //     status: (code) => {
  //       expect(code).to.equal(400);
  //       done();
  //     }
  //   };
  //   rafter.rlogin(req, res);
  // });

  it('initializes the volume service', async() => {
    const req = { body: { command: 'ls', token: 'token', userName: 'yoyo', rafterFile: { path: '/yo' } } };
    const res = {
      status(code) { return { json() {} }; }
      //   expect(code).to.equal(200);
      // }
    };
    // const init = { list() { return Promise.reject(new Error('fail')); } };
    // req.body.init = init;
    await rafter.initVolS(req, res);
    // expect(res.status)
  });
  it('tries to lists the contents of a directory but has an error', async() => {
    const req = { body: { command: 'ls', token: 'token', userName: 'yoyo', rafterFile: { path: '/yo' } } };
    const res = {
      status: (code) => {
        // expect(code).to.equal(200);
      }
    };
    const init = { list() { return Promise.reject(new Error('fail')); } };
    req.body.init = init;
    await rafter.runVolumeService(req, res);
  });
  it('lists the contents of home directory', async() => {
    const req = { body: { command: 'ls', token: 'token', userName: 'yoyo', rafterFile: { path: '/yo' } } };
    const res = {
      json(item) {}
    };
    const init = { list() { return Promise.resolve({ name: 'filename' }); } };
    req.body.init = init;
    await rafter.runVolumeService(req, res);
  });
  it('creates a new file', async() => {
    const req = { body: { command: 'create', token: 'token', userName: 'yoyo', rafterFile: { name: 'filename', createType: 'file' } } };
    const res = {
      json(item) {},
      status: (code) => {
        expect(code).to.equal(200);
        return { json(item) {} };
      }
    };
    const init = { create() { return Promise.resolve({ name: 'filename' }); } };
    req.body.init = init;
    await rafter.runVolumeService(req, res);
  });
  it('creates a new file and puts the contents', async() => {
    const req = { body: { command: 'create', token: 'token', userName: 'yoyo', rafterFile: { name: 'filename', createType: 'file', content:'howdy' } } };
    const res = {
      json(item) {},
      status: (code) => {
        expect(code).to.equal(200);
        return { json(item) {} };
      }
    };
    const init = { create() { return Promise.resolve({ name: 'filename' }); },
    put() { return Promise.resolve({ name: 'filename' }); }
    };
    req.body.init = init;
    await rafter.runVolumeService(req, res);
  });
  it('creates a new file but has error on putting the contents', async() => {
    const req = { body: { command: 'create', token: 'token', userName: 'yoyo', rafterFile: { name: 'filename', createType: 'file', content:'howdy' } } };
    const res = {
      json(item) {},
      status: (code) => {
        // expect(code).to.equal(200);
        // return { json(item) {} };
      }
    };
    const init = { create() { return Promise.resolve({ name: 'filename' }); },
    put() { return Promise.reject(new Error('fail')); }
    };
    req.body.init = init;
    await rafter.runVolumeService(req, res);
  });
  it('tries to create a new file but has error', async() => {
    const req = { body: { command: 'create', token: 'token', userName: 'yoyo', rafterFile: { name: 'filename', createType: 'file' } } };
    const res = {
      json(item) {},
      status: (code) => {
        // expect(code).to.equal(400);
      }
    };
    const init = { create() { return Promise.reject(new Error('fail')); } };
    req.body.init = init;
    await rafter.runVolumeService(req, res);
  });
  it('prevents creating a new file without a file name', async() => {
    const req = { body: { command: 'create', token: 'token', userName: 'yoyo', rafterFile: { name: '', createType: 'file' } } };
    const res = {
      json(item) {},
      status: (code) => {
        expect(code).to.equal(400);
        return { json(item) {} };
      }
    };
    const init = { create() { return Promise.resolve({ name: '' }); } };
    req.body.init = init;
    await rafter.runVolumeService(req, res);
  });
  it('creates a new folder', async() => {
    const req = { body: { command: 'create', token: 'token', userName: 'yoyo', rafterFile: { name: 'filename', createType: 'folder' } } };
    const res = {
      json(item) {},
      status: (code) => {
        expect(code).to.equal(200);
        return { json(item) {} };
      }
    };
    const init = { mkdir() { return Promise.resolve({ name: 'filename' }); } };
    req.body.init = init;
    await rafter.runVolumeService(req, res);
  });
  it('catches error on create new folder', async() => {
    const req = { body: { command: 'create', token: 'token', userName: 'yoyo', rafterFile: { name: 'filename', createType: 'folder' } } };
    const res = {
      json(item) {},
      status: (code) => {
        // expect(code).to.equal(200);
        // return { json(item) {} };
      }
    };
    const init = { mkdir() { return Promise.reject({ error: 'you fail' }); } };
    req.body.init = init;
    await rafter.runVolumeService(req, res);
  });
  it('asks for a bogus volume service command', async() => {
    const req = { body: { command: 'bogas', token: 'token', userName: 'yoyo', rafterFile: { name: 'filename' } } };
    const res = {
      json(item) {},
      status: (code) => {
        expect(code).to.equal(400);
        return { json(item) {} };
      }
    };
    const init = { create() { return Promise.resolve({ error: 'you fail' }); } };
    req.body.init = init;
    await rafter.runVolumeService(req, res);
  });

  it('downloads a file', async() => {
    const req = { body: { command: 'get', token: 'token', userName: 'yoyo', fileID: '123' } };
    const res = {
      setHeader() {}
      // status: (code) => {
      //   expect(code).to.equal(200);
      //   return { json(item) {} };
      // }
    };
    const init = { get() { return Promise.resolve({ name: 'filename' }); } };
    req.body.init = init;
    await rafter.runVolumeService(req, res);
  });

  it('deletes a file', async() => {
    const req = { body: { command: 'remove', token: 'token', userName: 'yoyo', fileID: '123' } };
    const res = {
      json() {}
      // status: (code) => {
      //   expect(code).to.equal(200);
      //   return { json(item) {} };
      // }
    };
    const init = { remove() { return Promise.resolve(true); } };
    req.body.init = init;
    await rafter.runVolumeService(req, res);
  });

  it('catches error on delete a file', async() => {
    const req = { body: { command: 'remove', token: 'token', userName: 'yoyo', fileID: '123' } };
    const res = {
      json(err) {
      // status: (code) => {
      expect(err.message).to.be('you fail');
      }
      //   return { json(item) {} };
      // }
    };
    const init = { remove() { return Promise.reject(new Error({ message: 'you fail' })); } };
    req.body.init = init;
    await rafter.runVolumeService(req, res);
  });

});
<|endoftext|>


<commit_before>/**
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * 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.
 */
'use strict';

// Initializes FriendlyChat.
function FriendlyChat() {
  this.checkSetup();

  // Shortcuts to DOM Elements.
  this.messageList = document.getElementById('messages');
  this.messageForm = document.getElementById('message-form');
  this.messageInput = document.getElementById('message');
  this.submitButton = document.getElementById('submit');
  this.submitImageButton = document.getElementById('submitImage');
  this.imageForm = document.getElementById('image-form');
  this.mediaCapture = document.getElementById('mediaCapture');
  this.userPic = document.getElementById('user-pic');
  this.userName = document.getElementById('user-name');
  this.signInButton = document.getElementById('sign-in');
  this.signOutButton = document.getElementById('sign-out');
  this.signInSnackbar = document.getElementById('must-signin-snackbar');

  // Saves message on form submit.
  this.messageForm.addEventListener('submit', this.saveMessage.bind(this));
  this.signOutButton.addEventListener('click', this.signOut.bind(this));
  this.signInButton.addEventListener('click', this.signIn.bind(this));

  // Toggle for the button.
  var buttonTogglingHandler = this.toggleButton.bind(this);
  this.messageInput.addEventListener('keyup', buttonTogglingHandler);
  this.messageInput.addEventListener('change', buttonTogglingHandler);

  // Events for image upload.
  this.submitImageButton.addEventListener('click', function() {
    this.mediaCapture.click();
  }.bind(this));
  this.mediaCapture.addEventListener('change', this.saveImageMessage.bind(this));

  this.initFirebase();
}

// Sets up shortcuts to Firebase features and initiate firebase auth.
FriendlyChat.prototype.initFirebase = function() {
  this.auth = firebase.auth();
  this.database = firebase.database();
  this.storage = firebase.storage();
  // Initiates Firebase auth and listen to auth state changes.
  this.auth.onAuthStateChanged(this.onAuthStateChanged.bind(this));
    // TODO(DEVELOPER): Initialize Firebase.
};

// Loads chat messages history and listens for upcoming ones.
FriendlyChat.prototype.loadMessages = function() {
  // Reference to the /messages/ database path.
  this.messagesRef = this.database.ref('messages');
  // Make sure we remove all previous listeners.
  this.messagesRef.off();

  // Loads the last 12 messages and listen for new ones.
  var setMessage = function(data) {
    var val = data.val();
    this.displayMessage(data.key, val.name, val.text, val.photoUrl, val.imageUrl);
  }.bind(this);
  this.messagesRef.limitToLast(12).on('child_added', setMessage);
  this.messagesRef.limitToLast(12).on('child_changed', setMessage);
  // TODO(DEVELOPER): Load and listens for new messages.
};

// Saves a new message on the Firebase DB.
FriendlyChat.prototype.saveMessage = function(e) {

  e.preventDefault();
  // Check that the user entered a message and is signed in.
  if (this.messageInput.value && this.checkSignedInWithMessage()) {
    var currentUser = this.auth.currentUser;
    // Add a new message entry to the Firebase Database.
    this.messagesRef.push({
      name: currentUser.displayName,
      text: this.messageInput.value,
      photoUrl: currentUser.photoURL || '/images/profile_placeholder.png'
    }).then(function() {
      // Clear message text field and SEND button state.
      FriendlyChat.resetMaterialTextfield(this.messageInput);
      this.toggleButton();
    }.bind(this)).catch(function(error) {
      console.error('Error writing new message to Firebase Database', error);
    });
  }
};

// Sets the URL of the given img element with the URL of the image stored in Firebase Storage.
FriendlyChat.prototype.setImageUrl = function(imageUri, imgElement) {
  imgElement.src = imageUri;

  // TODO(DEVELOPER): If image is on Firebase Storage, fetch image URL and set img element's src.
};

// Saves a new message containing an image URI in Firebase.
// This first saves the image in Firebase storage.
FriendlyChat.prototype.saveImageMessage = function(event) {
  var file = event.target.files[0];

  // Clear the selection in the file picker input.
  this.imageForm.reset();

  // Check if the file is an image.
  if (!file.type.match('image.*')) {
    var data = {
      message: 'You can only share images',
      timeout: 2000
    };
    this.signInSnackbar.MaterialSnackbar.showSnackbar(data);
    return;
  }
  // Check if the user is signed-in
  if (this.checkSignedInWithMessage()) {

    // TODO(DEVELOPER): Upload image to Firebase storage and add message.

  }
};

// Signs-in Friendly Chat.
FriendlyChat.prototype.signIn = function() {
    // Sign in Firebase using popup auth and Google as the identity provider.
  var provider = new firebase.auth.GoogleAuthProvider();
  this.auth.signInWithPopup(provider);
  // TODO(DEVELOPER): Sign in Firebase with credential from the Google user.
};

// Signs-out of Friendly Chat.
FriendlyChat.prototype.signOut = function() {
    // Sign out of Firebase.
  this.auth.signOut();
  // TODO(DEVELOPER): Sign out of Firebase.
};

// Triggers when the auth state change for instance when the user signs-in or signs-out.
FriendlyChat.prototype.onAuthStateChanged = function(user) {
  if (user) { // User is signed in!
    // Get profile pic and user's name from the Firebase user object.
    var profilePicUrl = user.photoURL; // Only change these two lines!
    var userName = user.displayName;   // Only change these two lines!

    // Set the user's profile pic and name.
    this.userPic.style.backgroundImage = 'url(' + profilePicUrl + ')';
    this.userName.textContent = userName;

    // Show user's profile and sign-out button.
    this.userName.removeAttribute('hidden');
    this.userPic.removeAttribute('hidden');
    this.signOutButton.removeAttribute('hidden');

    // Hide sign-in button.
    this.signInButton.setAttribute('hidden', 'true');

    // We load currently existing chant messages.
    this.loadMessages();
  } else { // User is signed out!
    // Hide user's profile and sign-out button.
    this.userName.setAttribute('hidden', 'true');
    this.userPic.setAttribute('hidden', 'true');
    this.signOutButton.setAttribute('hidden', 'true');

    // Show sign-in button.
    this.signInButton.removeAttribute('hidden');
  }
};

// Returns true if user is signed-in. Otherwise false and displays a message.
FriendlyChat.prototype.checkSignedInWithMessage = function() {

  if (this.auth.currentUser) {
    return true;
  }

  // Display a message to the user using a Toast.
  var data = {
    message: 'You must sign-in first',
    timeout: 2000
  };
  this.signInSnackbar.MaterialSnackbar.showSnackbar(data);
  return false;
};

// Resets the given MaterialTextField.
FriendlyChat.resetMaterialTextfield = function(element) {
  element.value = '';
  element.parentNode.MaterialTextfield.boundUpdateClassesHandler();
};

// Template for messages.
FriendlyChat.MESSAGE_TEMPLATE =
    '
' +
      '

' +
      '

' +
      '

' +
    '
';

// A loading image URL.
FriendlyChat.LOADING_IMAGE_URL = 'https://www.google.com/images/spin-32.gif';

// Displays a Message in the UI.
FriendlyChat.prototype.displayMessage = function(key, name, text, picUrl, imageUri) {
  var div = document.getElementById(key);
  // If an element for that message does not exists yet we create it.
  if (!div) {
    var container = document.createElement('div');
    container.innerHTML = FriendlyChat.MESSAGE_TEMPLATE;
    div = container.firstChild;
    div.setAttribute('id', key);
    this.messageList.appendChild(div);
  }
  if (picUrl) {
    div.querySelector('.pic').style.backgroundImage = 'url(' + picUrl + ')';
  }
  div.querySelector('.name').textContent = name;
  var messageElement = div.querySelector('.message');
  if (text) { // If the message is text.
    messageElement.textContent = text;
    // Replace all line breaks by
.
    messageElement.innerHTML = messageElement.innerHTML.replace(/\n/g, '
');
  } else if (imageUri) { // If the message is an image.
    var image = document.createElement('img');
    image.addEventListener('load', function() {
      this.messageList.scrollTop = this.messageList.scrollHeight;
    }.bind(this));
    this.setImageUrl(imageUri, image);
    messageElement.innerHTML = '';
    messageElement.appendChild(image);
  }
  // Show the card fading-in.
  setTimeout(function() {div.classList.add('visible')}, 1);
  this.messageList.scrollTop = this.messageList.scrollHeight;
  this.messageInput.focus();
};

// Enables or disables the submit button depending on the values of the input
// fields.
FriendlyChat.prototype.toggleButton = function() {
  if (this.messageInput.value) {
    this.submitButton.removeAttribute('disabled');
  } else {
    this.submitButton.setAttribute('disabled', 'true');
  }
};

// Checks that the Firebase SDK has been correctly setup and configured.
FriendlyChat.prototype.checkSetup = function() {
  if (!window.firebase || !(firebase.app instanceof Function) || !window.config) {
    window.alert('You have not configured and imported the Firebase SDK. ' +
        'Make sure you go through the codelab setup instructions.');
  } else if (config.storageBucket === '') {
    window.alert('Your Firebase Storage bucket has not been enabled. Sorry about that. This is ' +
        'actually a Firebase bug that occurs rarely. ' +
        'Please go and re-generate the Firebase initialisation snippet (step 4 of the codelab) ' +
        'and make sure the storageBucket attribute is not empty. ' +
        'You may also need to visit the Storage tab and paste the name of your bucket which is ' +
        'displayed there.');
  }
};

window.onload = function() {
  window.friendlyChat = new FriendlyChat();
};
<commit_msg>images<commit_after>/**
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * 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.
 */
'use strict';

// Initializes FriendlyChat.
function FriendlyChat() {
  this.checkSetup();

  // Shortcuts to DOM Elements.
  this.messageList = document.getElementById('messages');
  this.messageForm = document.getElementById('message-form');
  this.messageInput = document.getElementById('message');
  this.submitButton = document.getElementById('submit');
  this.submitImageButton = document.getElementById('submitImage');
  this.imageForm = document.getElementById('image-form');
  this.mediaCapture = document.getElementById('mediaCapture');
  this.userPic = document.getElementById('user-pic');
  this.userName = document.getElementById('user-name');
  this.signInButton = document.getElementById('sign-in');
  this.signOutButton = document.getElementById('sign-out');
  this.signInSnackbar = document.getElementById('must-signin-snackbar');

  // Saves message on form submit.
  this.messageForm.addEventListener('submit', this.saveMessage.bind(this));
  this.signOutButton.addEventListener('click', this.signOut.bind(this));
  this.signInButton.addEventListener('click', this.signIn.bind(this));

  // Toggle for the button.
  var buttonTogglingHandler = this.toggleButton.bind(this);
  this.messageInput.addEventListener('keyup', buttonTogglingHandler);
  this.messageInput.addEventListener('change', buttonTogglingHandler);

  // Events for image upload.
  this.submitImageButton.addEventListener('click', function() {
    this.mediaCapture.click();
  }.bind(this));
  this.mediaCapture.addEventListener('change', this.saveImageMessage.bind(this));

  this.initFirebase();
}

// Sets up shortcuts to Firebase features and initiate firebase auth.
FriendlyChat.prototype.initFirebase = function() {
  this.auth = firebase.auth();
  this.database = firebase.database();
  this.storage = firebase.storage();
  // Initiates Firebase auth and listen to auth state changes.
  this.auth.onAuthStateChanged(this.onAuthStateChanged.bind(this));
    // TODO(DEVELOPER): Initialize Firebase.
};

// Loads chat messages history and listens for upcoming ones.
FriendlyChat.prototype.loadMessages = function() {
  // Reference to the /messages/ database path.
  this.messagesRef = this.database.ref('messages');
  // Make sure we remove all previous listeners.
  this.messagesRef.off();

  // Loads the last 12 messages and listen for new ones.
  var setMessage = function(data) {
    var val = data.val();
    this.displayMessage(data.key, val.name, val.text, val.photoUrl, val.imageUrl);
  }.bind(this);
  this.messagesRef.limitToLast(12).on('child_added', setMessage);
  this.messagesRef.limitToLast(12).on('child_changed', setMessage);
  // TODO(DEVELOPER): Load and listens for new messages.
};

// Saves a new message on the Firebase DB.
FriendlyChat.prototype.saveMessage = function(e) {
  e.preventDefault();
  // Check that the user entered a message and is signed in.
  if (this.messageInput.value && this.checkSignedInWithMessage()) {
    var currentUser = this.auth.currentUser;
    // Add a new message entry to the Firebase Database.
    this.messagesRef.push({
      name: currentUser.displayName,
      text: this.messageInput.value,
      photoUrl: currentUser.photoURL || '/images/profile_placeholder.png'
    }).then(function() {
      // Clear message text field and SEND button state.
      FriendlyChat.resetMaterialTextfield(this.messageInput);
      this.toggleButton();
    }.bind(this)).catch(function(error) {
      console.error('Error writing new message to Firebase Database', error);
    });
  }
};

// Sets the URL of the given img element with the URL of the image stored in Firebase Storage.
FriendlyChat.prototype.setImageUrl = function(imageUri, imgElement) {
  imgElement.src = imageUri;
  // If the image is a Firebase Storage URI we fetch the URL.
  if (imageUri.startsWith('gs://')) {
    imgElement.src = FriendlyChat.LOADING_IMAGE_URL; // Display a loading image first.
    this.storage.refFromURL(imageUri).getMetadata().then(function(metadata) {
      imgElement.src = metadata.downloadURLs[0];
    });
  } else {
    imgElement.src = imageUri;
  }
  // TODO(DEVELOPER): If image is on Firebase Storage, fetch image URL and set img element's src.
};

// Saves a new message containing an image URI in Firebase.
// This first saves the image in Firebase storage.
FriendlyChat.prototype.saveImageMessage = function(event) {
  var file = event.target.files[0];

  // Clear the selection in the file picker input.
  this.imageForm.reset();

  // Check if the file is an image.
  if (!file.type.match('image.*')) {
    var data = {
      message: 'You can only share images',
      timeout: 2000
    };
    this.signInSnackbar.MaterialSnackbar.showSnackbar(data);
    return;
  }
  // Check if the user is signed-in
  if (this.checkSignedInWithMessage()) {

    // We add a message with a loading icon that will get updated with the shared image.
    var currentUser = this.auth.currentUser;
    this.messagesRef.push({
      name: currentUser.displayName,
      imageUrl: FriendlyChat.LOADING_IMAGE_URL,
      photoUrl: currentUser.photoURL || '/images/profile_placeholder.png'
    }).then(function(data) {

      // Upload the image to Firebase Storage.
      this.storage.ref(currentUser.uid + '/' + Date.now() + '/' + file.name)
          .put(file, {contentType: file.type})
          .then(function(snapshot) {
            // Get the file's Storage URI and update the chat message placeholder.
            var filePath = snapshot.metadata.fullPath;
            data.update({imageUrl: this.storage.ref(filePath).toString()});
          }.bind(this)).catch(function(error) {
        console.error('There was an error uploading a file to Firebase Storage:', error);
      });
    }.bind(this));
  }
};

// Signs-in Friendly Chat.
FriendlyChat.prototype.signIn = function() {
    // Sign in Firebase using popup auth and Google as the identity provider.
  var provider = new firebase.auth.GoogleAuthProvider();
  this.auth.signInWithPopup(provider);
  // TODO(DEVELOPER): Sign in Firebase with credential from the Google user.
};

// Signs-out of Friendly Chat.
FriendlyChat.prototype.signOut = function() {
    // Sign out of Firebase.
  this.auth.signOut();
  // TODO(DEVELOPER): Sign out of Firebase.
};

// Triggers when the auth state change for instance when the user signs-in or signs-out.
FriendlyChat.prototype.onAuthStateChanged = function(user) {
  if (user) { // User is signed in!
    // Get profile pic and user's name from the Firebase user object.
    var profilePicUrl = user.photoURL; // Only change these two lines!
    var userName = user.displayName;   // Only change these two lines!

    // Set the user's profile pic and name.
    this.userPic.style.backgroundImage = 'url(' + profilePicUrl + ')';
    this.userName.textContent = userName;

    // Show user's profile and sign-out button.
    this.userName.removeAttribute('hidden');
    this.userPic.removeAttribute('hidden');
    this.signOutButton.removeAttribute('hidden');

    // Hide sign-in button.
    this.signInButton.setAttribute('hidden', 'true');

    // We load currently existing chant messages.
    this.loadMessages();
  } else { // User is signed out!
    // Hide user's profile and sign-out button.
    this.userName.setAttribute('hidden', 'true');
    this.userPic.setAttribute('hidden', 'true');
    this.signOutButton.setAttribute('hidden', 'true');

    // Show sign-in button.
    this.signInButton.removeAttribute('hidden');
  }
};

// Returns true if user is signed-in. Otherwise false and displays a message.
FriendlyChat.prototype.checkSignedInWithMessage = function() {

  if (this.auth.currentUser) {
    return true;
  }

  // Display a message to the user using a Toast.
  var data = {
    message: 'You must sign-in first',
    timeout: 2000
  };
  this.signInSnackbar.MaterialSnackbar.showSnackbar(data);
  return false;
};

// Resets the given MaterialTextField.
FriendlyChat.resetMaterialTextfield = function(element) {
  element.value = '';
  element.parentNode.MaterialTextfield.boundUpdateClassesHandler();
};

// Template for messages.
FriendlyChat.MESSAGE_TEMPLATE =
    '
' +
      '

' +
      '

' +
      '

' +
    '
';

// A loading image URL.
FriendlyChat.LOADING_IMAGE_URL = 'https://www.google.com/images/spin-32.gif';

// Displays a Message in the UI.
FriendlyChat.prototype.displayMessage = function(key, name, text, picUrl, imageUri) {
  var div = document.getElementById(key);
  // If an element for that message does not exists yet we create it.
  if (!div) {
    var container = document.createElement('div');
    container.innerHTML = FriendlyChat.MESSAGE_TEMPLATE;
    div = container.firstChild;
    div.setAttribute('id', key);
    this.messageList.appendChild(div);
  }
  if (picUrl) {
    div.querySelector('.pic').style.backgroundImage = 'url(' + picUrl + ')';
  }
  div.querySelector('.name').textContent = name;
  var messageElement = div.querySelector('.message');
  if (text) { // If the message is text.
    messageElement.textContent = text;
    // Replace all line breaks by
.
    messageElement.innerHTML = messageElement.innerHTML.replace(/\n/g, '
');
  } else if (imageUri) { // If the message is an image.
    var image = document.createElement('img');
    image.addEventListener('load', function() {
      this.messageList.scrollTop = this.messageList.scrollHeight;
    }.bind(this));
    this.setImageUrl(imageUri, image);
    messageElement.innerHTML = '';
    messageElement.appendChild(image);
  }
  // Show the card fading-in.
  setTimeout(function() {div.classList.add('visible')}, 1);
  this.messageList.scrollTop = this.messageList.scrollHeight;
  this.messageInput.focus();
};

// Enables or disables the submit button depending on the values of the input
// fields.
FriendlyChat.prototype.toggleButton = function() {
  if (this.messageInput.value) {
    this.submitButton.removeAttribute('disabled');
  } else {
    this.submitButton.setAttribute('disabled', 'true');
  }
};

// Checks that the Firebase SDK has been correctly setup and configured.
FriendlyChat.prototype.checkSetup = function() {
  if (!window.firebase || !(firebase.app instanceof Function) || !window.config) {
    window.alert('You have not configured and imported the Firebase SDK. ' +
        'Make sure you go through the codelab setup instructions.');
  } else if (config.storageBucket === '') {
    window.alert('Your Firebase Storage bucket has not been enabled. Sorry about that. This is ' +
        'actually a Firebase bug that occurs rarely. ' +
        'Please go and re-generate the Firebase initialisation snippet (step 4 of the codelab) ' +
        'and make sure the storageBucket attribute is not empty. ' +
        'You may also need to visit the Storage tab and paste the name of your bucket which is ' +
        'displayed there.');
  }
};

window.onload = function() {
  window.friendlyChat = new FriendlyChat();
};
<|endoftext|>


<commit_before>var treeData = [
  {
    "name": "النبي صلى الله عليه وسلم",
    "parent": "null",
    "children": [//d.children are visible, d._children are hidden.
				 //on click, the data is switched between the 2 vars
      {//1
        "name": "ابو هريرة",
		'url':''
        ,"_children": [
          {//1
            "name": "ذكوان أبو صالح",
            "parent": "ابو هريرة",
			'url': '',
            "_children": [
              {//1
                "name":   "سهيل بن أبي صالح",
                 "url": ""
              },
			  {//2
				'name': 'الأعمش سليمان بن مهران',
				'url': ''
			  }

            ]
         },
          {//2
            "name": "أبو سلمة بن عبد الرحمان بن عوف",
			'url':''
            ,"_children": [
             {//1
                "name":   "ابن شهاب الزهري",
                 "url": ""
              },

              {//2
                "name":   "محمد بن عمرو بن علقمة",
                 "url": ""
              },
            ]
          },
          {//3
            "name": "عبد الرحمان الأعرج",
			'url': ''
            ,"_children": [
              {  //1
                "name":   "أبو الزناد",
                 "url": ""
              },
			  {//2
				'name': 'ابن شهاب الزهري',
				'url':''
			  }
            ]

          },
          {//4
            "name": "سعيد بن المسيب",
			'url': ''
            ,"_children": [
              {//1
                "name":   "ابن شهاب الزهري",
                 "url": ""
              },
			  {//2
				"name": "قتادة",
				'url':''
			  }

            ]

          },
          {//5
            "name": "سعيد المقبري",
			'url':''
            ,"_children": [
              { //1
                "name":   "عبيد الله بن عمر",
                 "url": ""
              }
              ,{  //2
                "name":   "الليث بن سعد",
                 "url": ""
              }
             ,{  //3
                "name":   "محمد بن عبد الرحمان بن أبي ذئب",
                 "url": ""
              },
              {  //4
                "name":   "محمد بن عجلان",
                 "url": ""
              }
            ]

          },
          {//6
            "name": "همام بن منبه",
			'url': ''
            ,"_children": [
              {  //1
                "name":   "معمر بن راشد",
                 "url": ""
              }

            ]

          },
          {//7
            "name": "محمد بن سرين",
			'url': ''
            ,"_children": [
              {
                "name":   "أيوب السختياني",
                 "url": ""
              },
			  {
				"name":"هشام بن حسان",
				"url":""
			  }

            ]

         }

        ]
      },
      {//2
        "name": "عبد الله بن عمر",
		"url":""
        ,"_children": [
          {//1
            "name": "نافع مولى ابن عمر",
			"url":""

            ,"_children": [
             {  //1
                "name":   "عبيد الله بن عمر",
                 "url": ""
              },

              ]
			}
		]
		}
	]
	}
]
;

<commit_msg>Added more narrators<commit_after>var treeData = [
  {
    "name": "النبي صلى الله عليه وسلم",
    "parent": "null",
    "children": [//d.children are visible, d._children are hidden.
				 //on click, the data is switched between the 2 vars
      {//1
        "name": "ابو هريرة",
		'url':''
        ,"_children": [
          {//1
            "name": "ذكوان أبو صالح",
            "parent": "ابو هريرة",
			'url': '',
            "_children": [
              {//1
                "name":   "سهيل بن أبي صالح",
                 "url": ""
              },
			  {//2
				'name': 'الأعمش سليمان بن مهران',
				'url': ''
			  }

            ]
         },
          {//2
            "name": "أبو سلمة بن عبد الرحمان بن عوف",
			'url':''
            ,"_children": [
             {//1
                "name":   "ابن شهاب الزهري",
                 "url": ""
              },

              {//2
                "name":   "محمد بن عمرو بن علقمة",
                 "url": ""
              },
            ]
          },
          {//3
            "name": "عبد الرحمان الأعرج",
			'url': ''
            ,"_children": [
              {  //1
                "name":   "أبو الزناد",
                 "url": ""
              },
			  {//2
				'name': 'ابن شهاب الزهري',
				'url':''
			  }
            ]

          },
          {//4
            "name": "سعيد بن المسيب",
			'url': ''
            ,"_children": [
              {//1
                "name":   "ابن شهاب الزهري",
                 "url": ""
              },
			  {//2
				"name": "قتادة",
				'url':''
			  }

            ]

          },
          {//5
            "name": "سعيد المقبري",
			'url':''
            ,"_children": [
              { //1
                "name":   "عبيد الله بن عمر",
                 "url": ""
              }
              ,{  //2
                "name":   "الليث بن سعد",
                 "url": ""
              }
             ,{  //3
                "name":   "محمد بن عبد الرحمان بن أبي ذئب",
                 "url": ""
              },
              {  //4
                "name":   "محمد بن عجلان",
                 "url": ""
              }
            ]

          },
          {//6
            "name": "همام بن منبه",
			'url': ''
            ,"_children": [
              {  //1
                "name":   "معمر بن راشد",
                 "url": ""
              }

            ]

          },
          {//7
            "name": "محمد بن سرين",
			'url': ''
            ,"_children": [
              {
                "name":   "أيوب السختياني",
                 "url": ""
              },
			  {
				"name":"هشام بن حسان",
				"url":""
			  }

            ]

         }

        ]
      },
      {//2
        "name": "عبد الله بن عمر",
		"url":""
        ,"_children": [
          {//1
            "name": "نافع مولى ابن عمر",
			"url":""

            ,"_children": [
             {  //1
                "name":   "عبيد الله بن عمر",
                 "url": ""
              },
			  {//2
				"name": "أيوب السختياني",
				"url": ""
			  },
			  {  //3
                "name":   "موسى بن عقبة",
                 "url": ""
              },
			  {//4
				"name": "مالك بن أنس",
				"url": ""
			  },
			  {//5
                "name":   "الليث بن سعد",
                 "url": ""
              },
              ]
			},
			{
				"name": "سالم بن عبد الله بن عمر",
				"url": "",

				"_children": [
					{
						"name": "ابن شهاب الزهري",
						"url": ""
					},
					{
						"name": "موسى بن عقبة",
						"url": ""
					}
				]
			},
			{
				"name": "عبد الله بن دينار",
				"url": "",

				"_children": [
					{
						"name": "مالك بن أنس",
						"url": ""
					},
					{
						"name": "إسماعيل بن جعفر",
						"url": ""
					},
					{
						"name": "سفيان الثوري",
						"url": ""
					}
				]
			}

		]
		}
	]
	}
]
;

<|endoftext|>


<commit_before>var Benchmark = require('benchmark');

var createGraph = require('../'),
    numberOfNodes = 10000;

var suite = new Benchmark.Suite();

var graphWithOutMap = createGraph();
var graphWithMap = createGraph({useMap: true});
for (var i = 0; i < numberOfNodes; ++i) {
  graphWithOutMap.addNode('hello' + i, i);
  graphWithMap.addNode('hello' + i, i);
}

var sum1 = 0;
var sum2 = 0;

// add tests
suite.add('graphWithOutMap', function() {
  var localSum = 0;
  graphWithOutMap.forEachNode(function (node) {
    localSum += node.data;
  });
  sum1 = localSum;
})
.add('graphWithMap', function() {
  var localSum = 0;
  graphWithMap.forEachNode(function (node) {
    localSum += node.data;
  });
  sum2 = localSum;
})
.on('cycle', function(event) {
  console.log(String(event.target));
})
.on('complete', function() {
   if (sum1 !== sum2) {
     throw new Error('Invalid test')
   }

   console.log('Fastest is ' + this.filter('fastest').map("name"));
})
// run async
.run({ 'async': true });
<commit_msg>update iteration test<commit_after>var Benchmark = require('benchmark');

var createGraph = require('../'),
    numberOfNodes = 10000;

var suite = new Benchmark.Suite();

var graph = createGraph();
for (var i = 0; i < numberOfNodes; ++i) {
  graph.addNode('hello' + i, i);
}

var sum = 0;

// add tests
suite.add('forEachNode', function() {
  var localSum = 0;
  graph.forEachNode(function (node) {
    localSum += node.data;
  });
  sum = localSum;
})
.on('cycle', function(event) {
  console.log(String(event.target));
})
.on('complete', function() {
   console.log(sum);
   console.log('Fastest is ' + this.filter('fastest').map("name"));
})
// run async
.run({ 'async': true });
<|endoftext|>


<commit_before>/*
Copyright 2015 The Kubernetes Authors All rights reserved.

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.
*/

var app = angular.module('PerfDashApp', ['ngMaterial', 'chart.js']);

var PerfDashApp = function(http, scope) {
    this.http = http;
    this.scope = scope;
    this.testNames = [];
    this.onClick = this.onClickInternal_.bind(this);
};

PerfDashApp.prototype.onClickInternal_ = function(data) {
    console.log(data);
    // Get location
    // TODO(random-liu): Make the URL configurable if we want to support more
    // buckets in the future.
    window.location = "http://kubekins.dls.corp.google.com/job/" + this.job + "/" + data[0].label + "/";
};

// Fetch data from the server and update the data to display
PerfDashApp.prototype.refresh = function() {
    this.http.get("api")
            .success(function(data) {
                this.testNames = Object.keys(data);
                this.testName = this.testNames[0];
                this.allData = data;
                this.testNameChanged();
            }.bind(this))
    .error(function(data) {
        console.log("error fetching result");
        console.log(data);
    });
};

// Update the data to graph, using selected labels
PerfDashApp.prototype.labelChanged = function() {
    this.seriesData = [];
    this.series = [];
    result = this.getData(this.selectedLabels);
    if (result.length <= 0) {
        return;
    }
    // All the unit should be the same
    this.options= {scaleLabel: "<%=value%> "+result[0].unit};
    angular.forEach(result[0].data, function(value, name) {
        this.seriesData.push(this.getStream(result, name));
        this.series.push(name);
    }, this);
};

// Update the data to graph, using the selected testName
PerfDashApp.prototype.testNameChanged = function() {
    this.data = this.allData[this.testName].builds;
    this.job = this.allData[this.testName].job;
    this.builds = this.getBuilds();
    this.labels = this.getLabels();
    this.labelChanged();
};

// Get all of the builds for the data set (e.g. build numbers)
PerfDashApp.prototype.getBuilds = function() {
    return Object.keys(this.data)
};

// Get the set of all labels (e.g. 'resources', 'verbs') in the data set
PerfDashApp.prototype.getLabels = function() {
    var set = {};
    angular.forEach(this.data, function(items, build) {
        angular.forEach(items, function(item) {
            angular.forEach(item.labels, function(label, name) {
                if (set[name] == undefined) {
                    set[name] = {}
                }
                set[name][label] = true
            });
        });
    });

    this.selectedLabels = {}
    var labels = {};
    angular.forEach(set, function(items, name) {
        labels[name] = [];
        angular.forEach(items, function(ignore, item) {
            if (this.selectedLabels[name] == undefined) {
              this.selectedLabels[name] = item;
            }
            labels[name].push(item)
        }, this);
    }, this);
    return labels;
};

// Extract a time series of data for specific labels
PerfDashApp.prototype.getData = function(labels) {
    var result = [];
    angular.forEach(this.data, function(items, build) {
        angular.forEach(items, function(item) {
            var match = true;
            angular.forEach(labels, function(label, name) {
                if (item.labels[name] != label) {
                    match = false;
                }
            });
            if (match) {
                result.push(item);
            }
        });
    });
    return result;
};

// Given a slice of data, turn it into a time series of numbers
// 'data' is an array of APICallLatency objects
// 'stream' is a selector for latency data, (e.g. 'Perc50')
PerfDashApp.prototype.getStream = function(data, stream) {
    var result = [];
    angular.forEach(data, function(value) {
        result.push(value.data[stream]);
    });
    return result;
};

app.controller('AppCtrl', ['$scope', '$http', '$interval', function($scope, $http, $interval) {
    $scope.controller = new PerfDashApp($http, $scope);
    $scope.controller.refresh();

    // Refresh every 5 min.  The data only refreshes every 10 minutes on the server
    $interval($scope.controller.refresh.bind($scope.controller), 300000)
}]);
<commit_msg>Make clicks work again.<commit_after>/*
Copyright 2015 The Kubernetes Authors All rights reserved.

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.
*/

var app = angular.module('PerfDashApp', ['ngMaterial', 'chart.js']);

var PerfDashApp = function(http, scope) {
    this.http = http;
    this.scope = scope;
    this.testNames = [];
    this.onClick = this.onClickInternal_.bind(this);
};

PerfDashApp.prototype.onClickInternal_ = function(data) {
    console.log(data);
    // Get location
    // TODO(random-liu): Make the URL configurable if we want to support more
    // buckets in the future.
    window.location = "https://k8s-gubernator.appspot.com/build/kubernetes-jenkins/logs/" + this.job + "/" + data[0].label + "/";
};

// Fetch data from the server and update the data to display
PerfDashApp.prototype.refresh = function() {
    this.http.get("api")
            .success(function(data) {
                this.testNames = Object.keys(data);
                this.testName = this.testNames[0];
                this.allData = data;
                this.testNameChanged();
            }.bind(this))
    .error(function(data) {
        console.log("error fetching result");
        console.log(data);
    });
};

// Update the data to graph, using selected labels
PerfDashApp.prototype.labelChanged = function() {
    this.seriesData = [];
    this.series = [];
    result = this.getData(this.selectedLabels);
    if (result.length <= 0) {
        return;
    }
    // All the unit should be the same
    this.options= {scaleLabel: "<%=value%> "+result[0].unit};
    angular.forEach(result[0].data, function(value, name) {
        this.seriesData.push(this.getStream(result, name));
        this.series.push(name);
    }, this);
};

// Update the data to graph, using the selected testName
PerfDashApp.prototype.testNameChanged = function() {
    this.data = this.allData[this.testName].builds;
    this.job = this.allData[this.testName].job;
    this.builds = this.getBuilds();
    this.labels = this.getLabels();
    this.labelChanged();
};

// Get all of the builds for the data set (e.g. build numbers)
PerfDashApp.prototype.getBuilds = function() {
    return Object.keys(this.data)
};

// Get the set of all labels (e.g. 'resources', 'verbs') in the data set
PerfDashApp.prototype.getLabels = function() {
    var set = {};
    angular.forEach(this.data, function(items, build) {
        angular.forEach(items, function(item) {
            angular.forEach(item.labels, function(label, name) {
                if (set[name] == undefined) {
                    set[name] = {}
                }
                set[name][label] = true
            });
        });
    });

    this.selectedLabels = {}
    var labels = {};
    angular.forEach(set, function(items, name) {
        labels[name] = [];
        angular.forEach(items, function(ignore, item) {
            if (this.selectedLabels[name] == undefined) {
              this.selectedLabels[name] = item;
            }
            labels[name].push(item)
        }, this);
    }, this);
    return labels;
};

// Extract a time series of data for specific labels
PerfDashApp.prototype.getData = function(labels) {
    var result = [];
    angular.forEach(this.data, function(items, build) {
        angular.forEach(items, function(item) {
            var match = true;
            angular.forEach(labels, function(label, name) {
                if (item.labels[name] != label) {
                    match = false;
                }
            });
            if (match) {
                result.push(item);
            }
        });
    });
    return result;
};

// Given a slice of data, turn it into a time series of numbers
// 'data' is an array of APICallLatency objects
// 'stream' is a selector for latency data, (e.g. 'Perc50')
PerfDashApp.prototype.getStream = function(data, stream) {
    var result = [];
    angular.forEach(data, function(value) {
        result.push(value.data[stream]);
    });
    return result;
};

app.controller('AppCtrl', ['$scope', '$http', '$interval', function($scope, $http, $interval) {
    $scope.controller = new PerfDashApp($http, $scope);
    $scope.controller.refresh();

    // Refresh every 5 min.  The data only refreshes every 10 minutes on the server
    $interval($scope.controller.refresh.bind($scope.controller), 300000)
}]);
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

const self = require("sdk/self");
const { when: unload } = require("sdk/system/unload");

const shield = require("./lib/shield/index");

const studyConfig = {
  name: self.addonId,
  days: 28,
  surveyUrls: {
  },
  variations: {
    "control": () => {},
    "securityOnboarding": () => {}
  }
};

class ContainersStudy extends shield.Study {
  isEligible () {
    // If the user already has testpilot-containers extension, they are in the
    // Test Pilot experiment, so exclude them.
    return super.isEligible();
  }
}

const thisStudy = new ContainersStudy(studyConfig);

if (self.id === "@shield-study-containers") {
  unload((reason) => thisStudy.shutdown(reason));
}

exports.study = thisStudy;
<commit_msg>add surveyUrl for shield study participants<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

const self = require("sdk/self");
const { when: unload } = require("sdk/system/unload");

const shield = require("./lib/shield/index");

const surveyUrl = "https://www.surveygizmo.com/s3/3621810/shield-txp-containers";

const studyConfig = {
  name: self.addonId,
  days: 28,
  surveyUrls: {
    "end-of-study": surveyUrl,
    "user-ended-study": surveyUrl,
    ineligible: null,
  },
  variations: {
    "control": () => {},
    "securityOnboarding": () => {}
  }
};

class ContainersStudy extends shield.Study {
  isEligible () {
    // If the user already has testpilot-containers extension, they are in the
    // Test Pilot experiment, so exclude them.
    return super.isEligible();
  }
}

const thisStudy = new ContainersStudy(studyConfig);

if (self.id === "@shield-study-containers") {
  unload((reason) => thisStudy.shutdown(reason));
}

exports.study = thisStudy;
<|endoftext|>


<commit_before>var sveta = function(hand, turn) {
    if (hand.four || hand.straight_flush || hand.full_house) {
        return 8;
    }

    if (hand.flush || hand.straight || hand.three || hand.two) {
        return 4;
    }

    else return 0;
};

module.exports = sveta;

//var hand_categories = {
//    "straight_flush": true,
//    "four": true,
//    "full_house": true,
//    "flush": true,
//    "straight": true,
//    "three": true,
//    "two": true
//}
<commit_msg>sveta 2<commit_after>var sveta = function(hand, turn) {
    switch(turn) {
        case 2: return twoCard(hand);
        case 5: return fiveCard(hand);
        case 6: return sixCard(hand);
        case 7: return sevenCard(hand);
    }

    console.log('&&SVETA ERROR');
    return twoCard(hand);
};

function twoCard(hand) {
    if (hand.two) {
        return 4;
    }

    else return 0;
}

function fiveCard(hand) {
    if (hand.four || hand.straight_flush || hand.full_house || hand.flush) {
        return 8;
    }

    if (hand.straight || hand.three || hand.two) {
        return 4;
    }

    else return 0;
}

function sixCard(hand) {
    if (hand.four || hand.straight_flush || hand.full_house || hand.flush) {
        return 8;
    }

    if (hand.straight || hand.three || hand.two) {
        return 4;
    }

    else return 0;
}

function sevenCard(hand) {
    if (hand.four || hand.straight_flush || hand.full_house || hand.flush) {
        return 8;
    }

    if (hand.straight || hand.three) {
        return 4;
    }

    else if (hand.two) {
        return 0;
    }

    else return 0;
}

module.exports = sveta;

//var hand_categories = {
//    "straight_flush": true,
//    "four": true,
//    "full_house": true,
//    "flush": true,
//    "straight": true,
//    "three": true,
//    "two": true
//}
<|endoftext|>


<commit_before>
import React from 'react';
import PureComponent from 'react-pure-render/component';
import ReactDOM from 'react-dom';

import Qustom from '../../src/index';

class App extends PureComponent {
    render() {
        return (

                <Qustom {...this.props} />

        );
    }
}

function getParameterByName(targetName) {
    const url = window.location.href;
    const name = targetName.replace(/[\[\]]/g, '\\$&');
    const regex = new RegExp(`[?&]${name}(=([^&#]*)|&|#|$)`);
    const results = regex.exec(url);
    if (!results) return null;
    if (!results[2]) return '';
    return decodeURIComponent(results[2].replace(/\+/g, ' '));
}

function initApp() {
    let view;
    if (!getParameterByName('accountid') && !getParameterByName('surveyid')) {
        view = (
Survey ID and Account ID are required!
);
    } else if (!getParameterByName('surveyid')) {
        view = (
Survey ID is required!
);
    } else if (!getParameterByName('accountid')) {
        view = (
Account ID is required!
);
    } else {
        // handle en to en-US
        let locale = getParameterByName('locale') || '';
        locale = locale === 'en' ? 'en-US' : locale;
        const props = {
            accountid: getParameterByName('accountid') || 'context.authorizer.principalId',
            surveyid: getParameterByName('surveyid') || '759e7930-3219-11e6-b8fc-ed3df7fb1eab',
            type: getParameterByName('type') || 'default', // type=default/embedded
            locale: locale, // sync with product or no need
            // preview mode does not send out feedback
            preview: getParameterByName('preview') || false
        };
        view = (<App {...props} />);
    }
    ReactDOM.render(
        view,
        document.getElementById('main')
    );
}

initApp();

if (module.hot) {
    module.hot.accept();
}
<commit_msg>Get clientid from parameter<commit_after>
import React from 'react';
import PureComponent from 'react-pure-render/component';
import ReactDOM from 'react-dom';

import Qustom from '../../src/index';

class App extends PureComponent {
    render() {
        return (

                <Qustom {...this.props} />

        );
    }
}

function getParameterByName(targetName) {
    const url = window.location.href;
    const name = targetName.replace(/[\[\]]/g, '\\$&');
    const regex = new RegExp(`[?&]${name}(=([^&#]*)|&|#|$)`);
    const results = regex.exec(url);
    if (!results) return null;
    if (!results[2]) return '';
    return decodeURIComponent(results[2].replace(/\+/g, ' '));
}

function initApp() {
    let view;
    if (!getParameterByName('accountid') && !getParameterByName('surveyid')) {
        view = (
Survey ID and Account ID are required!
);
    } else if (!getParameterByName('surveyid')) {
        view = (
Survey ID is required!
);
    } else if (!getParameterByName('accountid')) {
        view = (
Account ID is required!
);
    } else {
        // handle en to en-US
        let locale = getParameterByName('locale') || '';
        locale = locale === 'en' ? 'en-US' : locale;
        const props = {
            accountid: getParameterByName('accountid') || 'context.authorizer.principalId',
            surveyid: getParameterByName('surveyid') || '759e7930-3219-11e6-b8fc-ed3df7fb1eab',
            clientid: getParameterByName('clientid') || '',
            type: getParameterByName('type') || 'default', // type=default/embedded
            locale: locale, // sync with product or no need
            // preview mode does not send out feedback
            preview: getParameterByName('preview') || false
        };
        view = (<App {...props} />);
    }
    ReactDOM.render(
        view,
        document.getElementById('main')
    );
}

initApp();

if (module.hot) {
    module.hot.accept();
}
<|endoftext|>