<commit_before>'use strict';

const
	$C = require('collection.js'),
	Sugar = require('sugar');

const
	fs = require('fs'),
	vinyl = require('vinyl-fs'),
	path = require('path'),
	isPathInside = require('is-path-inside'),
	glob = require('glob-promise');

const
	resolve = require('./resolve'),
	Declaration = require('./declaration'),
	{blockTypeList} = /** @type {{blockTypeList: Array<string>}} */ require('./validators');

const
	filesCache = Object.create(null),
	blockCache = Object.create(null);

/**
 * Validates a file by the specified path and return meta information
 *
 * @param {string} path
 * @param {!Object} cache - cache object
 * @returns {{mtime: !Object, fromCache: boolean}}
 */
function validateCache(path, cache) {
	const
		{mtime} = fs.statSync(path);

	return {
		mtime,
		fromCache: Boolean(cache[path] && Sugar.Date.is(mtime, cache[path].mtime))
	};
}

/**
 * Returns a file content by the specified path
 *
 * @param {string} path
 * @returns {string}
 */
function getFile(path) {
	const
		cache = validateCache(path, filesCache);

	if (!cache.fromCache) {
		filesCache[path] = {
			mtime: cache.mtime,
			content: fs.readFileSync(path, 'utf-8')
		};
	}

	return filesCache[path].content;
}

/**
 * Throws block not found error by the specified name
 * @param {string} name
 */
function blockNotFound(name) {
	throw new Error(`Block "${name}" is not defined`);
}

class Block {
	/**
	 * Returns a block manifest file by the specified name
	 *
	 * @param {string} name
	 * @returns {!Promise<Block>}
	 */
	static async get(name) {
		const
			blockPath = path.join(await resolve.block(name), 'index.js'),
			cache = validateCache(blockPath, blockCache);

		if (cache.fromCache) {
			return new this(blockPath, blockCache[blockPath].decl);
		}

		async function getDecl(url) {
			return new Declaration(getFile(path.join(await url, 'index.js')));
		}

		const
			decl = await getDecl(resolve.block(name));

		if (decl.mixin) {
			let
				skip = 1,
				parent;

			while ((parent = await resolve.block(decl.name, skip))) {
				const
					parentDecl = await getDecl(parent.path);

				if (!decl.parent && parentDecl.parent) {
					decl.parent = parentDecl.parent;
				}

				decl.dependencies = [...new Set(decl.dependencies.concat(parentDecl.dependencies))];
				decl.libs = [...new Set(decl.libs.concat(parentDecl.libs))];

				if (parentDecl.mixin) {
					skip = parent.from;

				} else {
					break;
				}
			}
		}

		blockCache[blockPath] = {
			mtime: cache.mtime,
			decl
		};

		return new this(blockPath, decl);
	}

	/**
	 * Returns block manifests file by the specified names
	 *
	 * @param {Array<string>=} [names]
	 * @returns {!Promise<!Map<string, !Block>>}
	 */
	static async getAll(names) {
		if (!names) {
			const
				b = `@(${blockTypeList.join('|')})-*`,
				components = `/**/${b}/index.js`,
				virtualComponents = `/**/${b}.index.js`;

			names = await $C([await resolve.block(), ...resolve.dependencies])
				.parallel()
				.to(Object.create(null))
				.reduce(async (map, root) => {
					const src = [
						path.join(root, components),
						path.join(root, virtualComponents)
					];

					if (!map[src]) {
						map[src] = $C(vinyl.src(src, {read: false}))
							.async
							.to([])
							.map((file) => {
								file.base = root;
								return path.dirname(file.relative);
							});
					}

					return map;
				});
		}

		const
			set = Object.create(null);

		const blocks = await $C(names)
			.parallel()
			.to([])
			.reduce(async (res, el) => {
				const i = res.push([]) - 1;
				await $C([].concat(await el)).parallel().forEach(async (nm, j) => {
					if (set[nm]) {
						return;
					}

					set[nm] = true;

					const
						block = await this.get(nm);

					if (block) {
						res[i][j] = block;
					}
				});

				return res;
			});

		return $C(Sugar.Array.flatten(blocks)).to(new Map()).reduce((map, decl) => map.set(decl.name, decl));
	}

	/**
	 * Returns a path to the logic file
	 * @returns {!Promise<?string>}
	 */
	get logic() {
		return resolve.block(`${this.name}/${this.name}.logic`);
	}

	/**
	 * Returns a path to the template file
	 * @returns {!Promise<?string>}
	 */
	get tpl() {
		return resolve.block(`${this.name}/${this.name}.ss`);
	}

	/**
	 * Returns a path to the ess template file
	 * @returns {!Promise<?string>}
	 */
	get etpl() {
		return resolve.block(`${this.name}/${this.name}.ess`);
	}

	/**
	 * Returns paths to the style files
	 * @returns {!Promise<!Array<string>>}
	 */
	get styles() {
		return (async () => {
			const
				root = await resolve.block(),
				style = await resolve.block(`${this.name}/${this.name}.styl`),
				styles = [].concat(style || []);

			if (this.mixin && !isPathInside(style, root)) {
				styles.push(...await glob(path.join(root, `/**/${this.name}/${this.name}_*.styl`)));
			}

			return styles;
		})();
	}

	/**
	 * Block name
	 * @returns {string}
	 */
	get name() {
		return this.declaration.name;
	}

	/**
	 * Block type
	 * @returns {string}
	 */
	get type() {
		return this.declaration.type;
	}

	/**
	 * Block parent
	 * @returns {?string}
	 */
	get parent() {
		return this.declaration.parent;
	}

	/**
	 * Block mixin status
	 * @returns {boolean}
	 */
	get mixin() {
		return this.declaration.mixin;
	}

	/**
	 * Block dependencies
	 * @returns {!Array<string>}
	 */
	get dependencies() {
		return this.declaration.dependencies;
	}

	/**
	 * Block libraries
	 * @returns {!Array<string>}
	 */
	get libs() {
		return this.declaration.libs;
	}

	/**
	 * @param index - block index src
	 * @param declaration - block declaration
	 */
	constructor(index, declaration) {
		this.index = index;
		this.declaration = declaration;
	}

	/**
	 * Returns the block parent manifest
	 *
	 * @param {Map<string, !Block>=} [cache] - optional cache object with predefined blocks
	 * @returns {!Promise<Block>}
	 */
	async getParent({cache} = {}) {
		if (!this.parent) {
			return null;
		}

		const
			block = cache ? cache.get(this.parent) : await this.constructor.get(this.parent);

		if (!block) {
			blockNotFound(this.parent);
		}

		return block;
	}

	/**
	 * Returns manifests of all block dependencies
	 *
	 * @param {boolean=} [onlyOwn] - if true parent dependencies also included
	 * @param {Map<string, !Block>=} [cache] - optional cache object with predefined blocks
	 * @returns {!Promise<!Map<string, !Block>>}
	 */
	async getDependencies({onlyOwn, cache} = {}) {
		let
			names = this.dependencies.slice();

		if (!onlyOwn) {
			let
				parent = await this.getParent({cache});

			while (parent) {
				names = [...parent.dependencies, ...names];
				parent = await parent.getParent({cache});
			}
		}

		if (cache) {
			return $C(names).to(new Map()).reduce((map, name) => {
				const
					block = cache.get(name);

				if (!block) {
					blockNotFound(name);
				}

				return map.set(name, block);
			});
		}

		return this.constructor.getAll([...new Set(names)]);
	}

	/**
	 * Returns manifests of all block libraries
	 *
	 * @param {boolean=} [onlyOwn] - if true parent libraries also included
	 * @param {Map<string, !Block>=} [cache] - optional cache object with predefined blocks
	 * @returns {!Promise<!Set<string>>}
	 */
	async getLibs({onlyOwn, cache} = {}) {
		let
			libs = this.libs.slice();

		if (!onlyOwn) {
			let
				parent = await this.getParent({cache});

			while (parent) {
				libs = [...parent.libs, ...libs];
				parent = await parent.getParent({cache});
			}
		}

		return new Set(libs);
	}

	/**
	 * Returns an object with block runtime dependencies
	 *
	 * @param {Map<string, !Block>=} [cache] - optional cache object with predefined blocks
	 * @returns {!Promise<{runtime: !Map<string, !Block>, parents: !Map<string, !Block>, libs: !Set<string>}>}
	 */
	async getRuntimeDependencies({cache} = {}) {
		const get = async (name, isParent, runtime = new Map(), parents = new Map()) => {
			const
				block = name === this.name ? this : cache ? cache.get(name) : await this.constructor.get(name);

			if (!block) {
				blockNotFound(name);
			}

			runtime = new Map([[name, block], ...runtime.entries()]);
			if (!isParent && parents.has(name)) {
				parents.delete(name);
			}

			await $C(block.getDependencies({onlyOwn: true, cache})).async.forEach(async (block) => {
				runtime = new Map([[block.name, block], ...runtime.entries()]);
				await get(block.name, false, runtime, parents);
			});

			const
				parentName = block.parent;

			if (parentName) {
				const
					parent = await block.getParent({cache});

				if (!runtime.has(parentName)) {
					parents = new Map([[parentName, parent], ...parents.entries()]);
					runtime = new Map([[parentName, parent], ...runtime.entries()]);
				}

				await get(parentName, true, runtime, parents);
			}

			return {
				runtime,
				parents
			};
		};

		return Object.assign(await get(this.name), {libs: await this.getLibs({cache})});
	}
}

module.exports = Block;
<commit_msg>:wrench: await .getDependencies<commit_after>'use strict';

const
	$C = require('collection.js'),
	Sugar = require('sugar');

const
	fs = require('fs'),
	vinyl = require('vinyl-fs'),
	path = require('path'),
	isPathInside = require('is-path-inside'),
	glob = require('glob-promise');

const
	resolve = require('./resolve'),
	Declaration = require('./declaration'),
	{blockTypeList} = /** @type {{blockTypeList: Array<string>}} */ require('./validators');

const
	filesCache = Object.create(null),
	blockCache = Object.create(null);

/**
 * Validates a file by the specified path and return meta information
 *
 * @param {string} path
 * @param {!Object} cache - cache object
 * @returns {{mtime: !Object, fromCache: boolean}}
 */
function validateCache(path, cache) {
	const
		{mtime} = fs.statSync(path);

	return {
		mtime,
		fromCache: Boolean(cache[path] && Sugar.Date.is(mtime, cache[path].mtime))
	};
}

/**
 * Returns a file content by the specified path
 *
 * @param {string} path
 * @returns {string}
 */
function getFile(path) {
	const
		cache = validateCache(path, filesCache);

	if (!cache.fromCache) {
		filesCache[path] = {
			mtime: cache.mtime,
			content: fs.readFileSync(path, 'utf-8')
		};
	}

	return filesCache[path].content;
}

/**
 * Throws block not found error by the specified name
 * @param {string} name
 */
function blockNotFound(name) {
	throw new Error(`Block "${name}" is not defined`);
}

class Block {
	/**
	 * Returns a block manifest file by the specified name
	 *
	 * @param {string} name
	 * @returns {!Promise<Block>}
	 */
	static async get(name) {
		const
			blockPath = path.join(await resolve.block(name), 'index.js'),
			cache = validateCache(blockPath, blockCache);

		if (cache.fromCache) {
			return new this(blockPath, blockCache[blockPath].decl);
		}

		async function getDecl(url) {
			return new Declaration(getFile(path.join(await url, 'index.js')));
		}

		const
			decl = await getDecl(resolve.block(name));

		if (decl.mixin) {
			let
				skip = 1,
				parent;

			while ((parent = await resolve.block(decl.name, skip))) {
				const
					parentDecl = await getDecl(parent.path);

				if (!decl.parent && parentDecl.parent) {
					decl.parent = parentDecl.parent;
				}

				decl.dependencies = [...new Set(decl.dependencies.concat(parentDecl.dependencies))];
				decl.libs = [...new Set(decl.libs.concat(parentDecl.libs))];

				if (parentDecl.mixin) {
					skip = parent.from;

				} else {
					break;
				}
			}
		}

		blockCache[blockPath] = {
			mtime: cache.mtime,
			decl
		};

		return new this(blockPath, decl);
	}

	/**
	 * Returns block manifests file by the specified names
	 *
	 * @param {Array<string>=} [names]
	 * @returns {!Promise<!Map<string, !Block>>}
	 */
	static async getAll(names) {
		if (!names) {
			const
				b = `@(${blockTypeList.join('|')})-*`,
				components = `/**/${b}/index.js`,
				virtualComponents = `/**/${b}.index.js`;

			names = await $C([await resolve.block(), ...resolve.dependencies])
				.parallel()
				.to(Object.create(null))
				.reduce(async (map, root) => {
					const src = [
						path.join(root, components),
						path.join(root, virtualComponents)
					];

					if (!map[src]) {
						map[src] = $C(vinyl.src(src, {read: false}))
							.async
							.to([])
							.map((file) => {
								file.base = root;
								return path.dirname(file.relative);
							});
					}

					return map;
				});
		}

		const
			set = Object.create(null);

		const blocks = await $C(names)
			.parallel()
			.to([])
			.reduce(async (res, el) => {
				const i = res.push([]) - 1;
				await $C([].concat(await el)).parallel().forEach(async (nm, j) => {
					if (set[nm]) {
						return;
					}

					set[nm] = true;

					const
						block = await this.get(nm);

					if (block) {
						res[i][j] = block;
					}
				});

				return res;
			});

		return $C(Sugar.Array.flatten(blocks)).to(new Map()).reduce((map, decl) => map.set(decl.name, decl));
	}

	/**
	 * Returns a path to the logic file
	 * @returns {!Promise<?string>}
	 */
	get logic() {
		return resolve.block(`${this.name}/${this.name}.logic`);
	}

	/**
	 * Returns a path to the template file
	 * @returns {!Promise<?string>}
	 */
	get tpl() {
		return resolve.block(`${this.name}/${this.name}.ss`);
	}

	/**
	 * Returns a path to the ess template file
	 * @returns {!Promise<?string>}
	 */
	get etpl() {
		return resolve.block(`${this.name}/${this.name}.ess`);
	}

	/**
	 * Returns paths to the style files
	 * @returns {!Promise<!Array<string>>}
	 */
	get styles() {
		return (async () => {
			const
				root = await resolve.block(),
				style = await resolve.block(`${this.name}/${this.name}.styl`),
				styles = [].concat(style || []);

			if (this.mixin && !isPathInside(style, root)) {
				styles.push(...await glob(path.join(root, `/**/${this.name}/${this.name}_*.styl`)));
			}

			return styles;
		})();
	}

	/**
	 * Block name
	 * @returns {string}
	 */
	get name() {
		return this.declaration.name;
	}

	/**
	 * Block type
	 * @returns {string}
	 */
	get type() {
		return this.declaration.type;
	}

	/**
	 * Block parent
	 * @returns {?string}
	 */
	get parent() {
		return this.declaration.parent;
	}

	/**
	 * Block mixin status
	 * @returns {boolean}
	 */
	get mixin() {
		return this.declaration.mixin;
	}

	/**
	 * Block dependencies
	 * @returns {!Array<string>}
	 */
	get dependencies() {
		return this.declaration.dependencies;
	}

	/**
	 * Block libraries
	 * @returns {!Array<string>}
	 */
	get libs() {
		return this.declaration.libs;
	}

	/**
	 * @param index - block index src
	 * @param declaration - block declaration
	 */
	constructor(index, declaration) {
		this.index = index;
		this.declaration = declaration;
	}

	/**
	 * Returns the block parent manifest
	 *
	 * @param {Map<string, !Block>=} [cache] - optional cache object with predefined blocks
	 * @returns {!Promise<Block>}
	 */
	async getParent({cache} = {}) {
		if (!this.parent) {
			return null;
		}

		const
			block = cache ? cache.get(this.parent) : await this.constructor.get(this.parent);

		if (!block) {
			blockNotFound(this.parent);
		}

		return block;
	}

	/**
	 * Returns manifests of all block dependencies
	 *
	 * @param {boolean=} [onlyOwn] - if true parent dependencies also included
	 * @param {Map<string, !Block>=} [cache] - optional cache object with predefined blocks
	 * @returns {!Promise<!Map<string, !Block>>}
	 */
	async getDependencies({onlyOwn, cache} = {}) {
		let
			names = this.dependencies.slice();

		if (!onlyOwn) {
			let
				parent = await this.getParent({cache});

			while (parent) {
				names = [...parent.dependencies, ...names];
				parent = await parent.getParent({cache});
			}
		}

		if (cache) {
			return $C(names).to(new Map()).reduce((map, name) => {
				const
					block = cache.get(name);

				if (!block) {
					blockNotFound(name);
				}

				return map.set(name, block);
			});
		}

		return this.constructor.getAll([...new Set(names)]);
	}

	/**
	 * Returns manifests of all block libraries
	 *
	 * @param {boolean=} [onlyOwn] - if true parent libraries also included
	 * @param {Map<string, !Block>=} [cache] - optional cache object with predefined blocks
	 * @returns {!Promise<!Set<string>>}
	 */
	async getLibs({onlyOwn, cache} = {}) {
		let
			libs = this.libs.slice();

		if (!onlyOwn) {
			let
				parent = await this.getParent({cache});

			while (parent) {
				libs = [...parent.libs, ...libs];
				parent = await parent.getParent({cache});
			}
		}

		return new Set(libs);
	}

	/**
	 * Returns an object with block runtime dependencies
	 *
	 * @param {Map<string, !Block>=} [cache] - optional cache object with predefined blocks
	 * @returns {!Promise<{runtime: !Map<string, !Block>, parents: !Map<string, !Block>, libs: !Set<string>}>}
	 */
	async getRuntimeDependencies({cache} = {}) {
		const get = async (name, isParent, runtime = new Map(), parents = new Map()) => {
			const
				block = name === this.name ? this : cache ? cache.get(name) : await this.constructor.get(name);

			if (!block) {
				blockNotFound(name);
			}

			runtime = new Map([[name, block], ...runtime.entries()]);
			if (!isParent && parents.has(name)) {
				parents.delete(name);
			}

			await $C(await block.getDependencies({onlyOwn: true, cache})).async.forEach(async (block) => {
				runtime = new Map([[block.name, block], ...runtime.entries()]);
				await get(block.name, false, runtime, parents);
			});

			const
				parentName = block.parent;

			if (parentName) {
				const
					parent = await block.getParent({cache});

				if (!runtime.has(parentName)) {
					parents = new Map([[parentName, parent], ...parents.entries()]);
					runtime = new Map([[parentName, parent], ...runtime.entries()]);
				}

				await get(parentName, true, runtime, parents);
			}

			return {
				runtime,
				parents
			};
		};

		return Object.assign(await get(this.name), {libs: await this.getLibs({cache})});
	}
}

module.exports = Block;
<|endoftext|>


<commit_before>// triangulation using https://github.com/ironwallaby/delaunay

const TWO_PI = Math.PI * 2;
var WC_IMG, AD_IMG;
const DURATION = 1;
var vertices = [],
    indices = [],
    fragments = [];

var wc_cont = document.getElementById('wc_cont');
var ad_cont = document.getElementById('ad_cont');
var closeBtn = document.getElementById("close_btn");

function init() {
    window.onload = function () {

        window.addEventListener('resize', onReszie);

        WC_IMG = new Image();
        AD_IMG = new Image();

        WC_IMG.src = 'images/WC_1.png';
        AD_IMG.src = 'images/AU_1.jpg';
        //WC_IMG.width = wc_cont.style.width = window.innerWidth;
        AD_IMG.width = 768;
        AD_IMG.height = 485;
        ad_cont.style.width = AD_IMG.width + 'px';
        ad_cont.style.height = AD_IMG.height + 'px';

        resetAd();

    };
}

function addCloseBtn() {
    closeBtn.addEventListener("click", closeClicked);
    closeBtn.style.display = "block";
    document.body.appendChild(closeBtn);
};

function closeClicked() {

    ad_cont.removeChild(AD_IMG);

    //hide the image behind
    AD_IMG.style.display = "none";
    closeBtn.style.display = "none";

    //remove previous listeners
    WC_IMG.removeEventListener('click');
    closeBtn.removeEventListener('click');

    resetAd();
}

function resetAd() {
    TweenMax.set(wc_cont, {perspective:200, z:1});
    TweenMax.set(ad_cont, {scale:0.01});

    wc_cont.appendChild(WC_IMG);

    WC_IMG.addEventListener('click', initShatterObj);
    fade(WC_IMG, 0, 1); //fade the website back
    AD_IMG.style.display = "block";
}

function placeAd(clickPos) {
    fade(AD_IMG, 0, 1); // fade the ad in
    ad_cont.style.marginTop = 0;
    ad_cont.style.marginLeft = 0;
    ad_cont.style.marginRight = 0;
    ad_cont.style.marginBottom = 0;
    ad_cont.style.top = clickPos[1] - ad_cont.clientHeight / 2 + 'px';
    ad_cont.style.left = clickPos[0] - ad_cont.clientWidth / 2 + 'px';
    centerAd();
    zoomAd();
}

function centerAd() {
    TweenLite.to(ad_cont,3, {left: window.innerWidth / 2 - ad_cont.clientWidth / 2, top: window.innerHeight / 2 - ad_cont.clientHeight / 2});
}
function zoomAd() {
    TweenLite.to(ad_cont, 2, {scale:1});

}

function initShatterObj(event) {
    var clickPos = [];
    var box = WC_IMG.getBoundingClientRect(),
        top = box.top,
        left = box.left;

    clickPos[0] = event.clientX - left;
    clickPos[1] = event.clientY - top;

    ad_cont.appendChild(AD_IMG);

    triangulate(clickPos);
    shatter(clickPos);
    addCloseBtn();
    placeAd(clickPos);
    wc_cont.removeChild(WC_IMG);

}

function triangulate(clickPos) {
    var rings = [{
            r: 50,
            c: 10
        }, {
            r: 150,
            c: 10
        }, {
            r: 300,
            c: 10
        }, {
            r: 1200,
            c: 10
        },
        {
            r: 3200,
            c: 20
        }// very large in case of corner clicks
        ],
        x,
        y,
        centerX = clickPos[0],
        centerY = clickPos[1];

    //console.log("click: " + clickPos);

    vertices.push([centerX, centerY]);

    rings.forEach(function (ring) {
        var radius = ring.r,
            count = ring.c,
            variance = radius * 0.25;

        for (var i = 0; i < count; i++) {
            x = Math.cos((i / count) * TWO_PI) * radius + centerX + randomRange(-variance, variance);
            y = Math.sin((i / count) * TWO_PI) * radius + centerY + randomRange(-variance, variance);
            vertices.push([x, y]);
        }
    });

    vertices.forEach(function (v) {
        v[0] = clamp(v[0], 1, WC_IMG.width*2);
        v[1] = clamp(v[1],1, WC_IMG.height*2);
    });

    indices = Delaunay.triangulate(vertices);
}

function shatter(clickPos) {
    var p0, p1, p2,
        fragment;

    var tl0 = new TimelineMax({
        onComplete: shatterCompleteHandler
    });

    for (var i = 0; i < indices.length; i += 3) {
        p0 = vertices[indices[i + 0]];
        p1 = vertices[indices[i + 1]];
        p2 = vertices[indices[i + 2]];

        fragment = new Fragment(p0, p1, p2);

        var dx = fragment.centroid[0] - clickPos[0],
            dy = fragment.centroid[1] - clickPos[1],
            d = Math.sqrt(dx * dx + dy * dy),
            rx = 30 * sign(dy),
            ry = 90 * -sign(dx),
            delay = d * 0.001 * randomRange(1, 1.1);
        fragment.canvas.style.zIndex = Math.floor(d).toString();

        var tl1 = new TimelineMax();

        tl1.to(fragment.canvas, 1, {
            z: -500,
            rotationX: 1,
            rotationY: 1,
            ease: Cubic.easeIn
        });
        tl1.to(fragment.canvas, 0.4, {alpha: 0}, 0.6);
        tl0.insert(tl1, delay);
        fragments.push(fragment);
        wc_cont.appendChild(fragment.canvas);
    }

}

function shatterCompleteHandler() {
    // add pooling?
    fragments.forEach(function (f) {
        wc_cont.removeChild(f.canvas);
    });
    fragments.length = 0;
    vertices.length = 0;
    indices.length = 0;
    //placeImage();
}

//////////////
// MATH UTILS
//////////////

function randomRange(min, max) {
    return min + (max - min) * Math.random();
}

function fade(component, from, to) {
    TweenLite.fromTo(component, DURATION, {opacity: from}, {opacity: to});
}
function clamp(x, min, max) {
    return x < min ? min : (x > max ? max : x);
}

function sign(x) {
    return x < 0 ? -1 : 1;
}

function onReszie() {
    var id;
    $(window).resize(function() {
        clearTimeout(id);
        id = setTimeout(doneResizing, 500);

    });

    function doneResizing(){
        cenlrAd();
    }
}

//////////////
// FRAGMENT
//////////////

function isRetina() {
    if (window.devicePixelRatio > 1) {
        return true;
    }
    else {
        return false;
    }
}

Fragment = function (v0, v1, v2) {
    this.v0 = v0;
    this.v1 = v1;
    this.v2 = v2;

    this.computeBoundingBox();
    this.computeCentroid();
    this.createCanvas();
    this.clip();
};
Fragment.prototype = {
    computeBoundingBox: function () {
        var xMin = Math.min(this.v0[0], this.v1[0], this.v2[0]),
            xMax = Math.max(this.v0[0], this.v1[0], this.v2[0]),
            yMin = Math.min(this.v0[1], this.v1[1], this.v2[1]),
            yMax = Math.max(this.v0[1], this.v1[1], this.v2[1]);

        this.box = {
            x: xMin,
            y: yMin,
            w: (xMax - xMin),
            h: (yMax - yMin)
        };

    },
    computeCentroid: function () {
        var x = (this.v0[0] + this.v1[0] + this.v2[0]) / 3,
            y = (this.v0[1] + this.v1[1] + this.v2[1]) / 3;

        this.centroid = [x, y];
    },
    createCanvas: function () {
        this.canvas = document.createElement('canvas');
        this.canvas.width = this.box.w;
        this.canvas.height = this.box.h;
        this.canvas.style.width = this.box.w + 'px';
        this.canvas.style.height = this.box.h + 'px';
        this.canvas.style.left = this.box.x + 'px';
        this.canvas.style.top = this.box.y + 'px';
        this.ctx = this.canvas.getContext('2d');

        //if (isRetina()){
          //  this.ctx.scale(0.75,0.75);
        //}

    },
    clip: function () {
        this.ctx.translate(-this.box.x, -this.box.y);
        this.ctx.beginPath();
        this.ctx.moveTo(this.v0[0], this.v0[1]);
        this.ctx.lineTo(this.v1[0], this.v1[1]);
        this.ctx.lineTo(this.v2[0], this.v2[1]);
        this.ctx.closePath();
        this.ctx.clip();
        this.ctx.drawImage(WC_IMG, 0, 0);
    }
};

//load ad
init();<commit_msg>removed extra append<commit_after>// triangulation using https://github.com/ironwallaby/delaunay

const TWO_PI = Math.PI * 2;
var WC_IMG, AD_IMG;
const DURATION = 1;
var vertices = [],
    indices = [],
    fragments = [];

var wc_cont = document.getElementById('wc_cont');
var ad_cont = document.getElementById('ad_cont');
var closeBtn = document.getElementById("close_btn");

function init() {
    window.onload = function () {

        window.addEventListener('resize', onReszie);

        WC_IMG = new Image();
        AD_IMG = new Image();

        WC_IMG.src = 'images/WC_1.png';
        AD_IMG.src = 'images/AU_1.jpg';
        //WC_IMG.width = wc_cont.style.width = window.innerWidth;
        AD_IMG.width = 768;
        AD_IMG.height = 485;
        ad_cont.style.width = AD_IMG.width + 'px';
        ad_cont.style.height = AD_IMG.height + 'px';

        resetAd();

    };
}

function addCloseBtn() {
    closeBtn.addEventListener("click", closeClicked);
    closeBtn.style.display = "block";
    document.body.appendChild(closeBtn);
};

function closeClicked() {

    ad_cont.removeChild(AD_IMG);

    //hide the image behind
    AD_IMG.style.display = "none";
    closeBtn.style.display = "none";

    //remove previous listeners
    WC_IMG.removeEventListener('click');
    closeBtn.removeEventListener('click');

    resetAd();
}

function resetAd() {
    TweenMax.set(wc_cont, {perspective:200, z:1});
    TweenMax.set(ad_cont, {scale:0.01});

    wc_cont.appendChild(WC_IMG);

    WC_IMG.addEventListener('click', initShatterObj);
    fade(WC_IMG, 0, 1); //fade the website back
    AD_IMG.style.display = "block";
}

function placeAd(clickPos) {
    fade(AD_IMG, 0, 1); // fade the ad in
    ad_cont.style.marginTop = 0;
    ad_cont.style.marginLeft = 0;
    ad_cont.style.marginRight = 0;
    ad_cont.style.marginBottom = 0;
    ad_cont.style.top = clickPos[1] - ad_cont.clientHeight / 2 + 'px';
    ad_cont.style.left = clickPos[0] - ad_cont.clientWidth / 2 + 'px';
    centerAd();
    zoomAd();
}

function centerAd() {
    TweenLite.to(ad_cont,3, {left: window.innerWidth / 2 - ad_cont.clientWidth / 2, top: window.innerHeight / 2 - ad_cont.clientHeight / 2});
}
function zoomAd() {
    TweenLite.to(ad_cont, 2, {scale:1});

}

function initShatterObj(event) {
    var clickPos = [];
    var box = WC_IMG.getBoundingClientRect(),
        top = box.top,
        left = box.left;

    clickPos[0] = event.clientX - left;
    clickPos[1] = event.clientY - top;

    ad_cont.appendChild(AD_IMG);

    triangulate(clickPos);
    shatter(clickPos);
    addCloseBtn();
    placeAd(clickPos);
    wc_cont.removeChild(WC_IMG);

}

function triangulate(clickPos) {
    var rings = [{
            r: 50,
            c: 10
        }, {
            r: 150,
            c: 10
        }, {
            r: 300,
            c: 10
        }, {
            r: 1200,
            c: 10
        },
        {
            r: 3200,
            c: 20
        }// very large in case of corner clicks
        ],
        x,
        y,
        centerX = clickPos[0],
        centerY = clickPos[1];

    //console.log("click: " + clickPos);

    vertices.push([centerX, centerY]);

    rings.forEach(function (ring) {
        var radius = ring.r,
            count = ring.c,
            variance = radius * 0.25;

        for (var i = 0; i < count; i++) {
            x = Math.cos((i / count) * TWO_PI) * radius + centerX + randomRange(-variance, variance);
            y = Math.sin((i / count) * TWO_PI) * radius + centerY + randomRange(-variance, variance);
            vertices.push([x, y]);
        }
    });

    vertices.forEach(function (v) {
        v[0] = clamp(v[0], 1, WC_IMG.width*2);
        v[1] = clamp(v[1],1, WC_IMG.height*2);
    });

    indices = Delaunay.triangulate(vertices);
}

function shatter(clickPos) {
    var p0, p1, p2,
        fragment;

    var tl0 = new TimelineMax({
        onComplete: shatterCompleteHandler
    });

    for (var i = 0; i < indices.length; i += 3) {
        p0 = vertices[indices[i + 0]];
        p1 = vertices[indices[i + 1]];
        p2 = vertices[indices[i + 2]];

        fragment = new Fragment(p0, p1, p2);

        var dx = fragment.centroid[0] - clickPos[0],
            dy = fragment.centroid[1] - clickPos[1],
            d = Math.sqrt(dx * dx + dy * dy),
            rx = 30 * sign(dy),
            ry = 90 * -sign(dx),
            delay = d * 0.001 * randomRange(1, 1.1);
        fragment.canvas.style.zIndex = Math.floor(d).toString();

        var tl1 = new TimelineMax();

        tl1.to(fragment.canvas, 1, {
            z: -500,
            rotationX: 1,
            rotationY: 1,
            ease: Cubic.easeIn
        });
        tl1.to(fragment.canvas, 0.4, {alpha: 0}, 0.6);
        tl0.insert(tl1, delay);
        fragments.push(fragment);
        wc_cont.appendChild(fragment.canvas);
    }

}

function shatterCompleteHandler() {
    // add pooling?
    fragments.forEach(function (f) {
        wc_cont.removeChild(f.canvas);
    });
    fragments.length = 0;
    vertices.length = 0;
    indices.length = 0;
    //placeImage();
}

//////////////
// MATH UTILS
//////////////

function randomRange(min, max) {
    return min + (max - min) * Math.random();
}

function fade(component, from, to) {
    TweenLite.fromTo(component, DURATION, {opacity: from}, {opacity: to});
}
function clamp(x, min, max) {
    return x < min ? min : (x > max ? max : x);
}

function sign(x) {
    return x < 0 ? -1 : 1;
}

function onReszie() {
    var id;
    $(window).resize(function() {
        clearTimeout(id);
        id = setTimeout(doneResizing, 500);

    });

    function doneResizing(){
        centerAd();
    }
}

//////////////
// FRAGMENT
//////////////

function isRetina() {
    if (window.devicePixelRatio > 1) {
        return true;
    }
    else {
        return false;
    }
}

Fragment = function (v0, v1, v2) {
    this.v0 = v0;
    this.v1 = v1;
    this.v2 = v2;

    this.computeBoundingBox();
    this.computeCentroid();
    this.createCanvas();
    this.clip();
};
Fragment.prototype = {
    computeBoundingBox: function () {
        var xMin = Math.min(this.v0[0], this.v1[0], this.v2[0]),
            xMax = Math.max(this.v0[0], this.v1[0], this.v2[0]),
            yMin = Math.min(this.v0[1], this.v1[1], this.v2[1]),
            yMax = Math.max(this.v0[1], this.v1[1], this.v2[1]);

        this.box = {
            x: xMin,
            y: yMin,
            w: (xMax - xMin),
            h: (yMax - yMin)
        };

    },
    computeCentroid: function () {
        var x = (this.v0[0] + this.v1[0] + this.v2[0]) / 3,
            y = (this.v0[1] + this.v1[1] + this.v2[1]) / 3;

        this.centroid = [x, y];
    },
    createCanvas: function () {
        this.canvas = document.createElement('canvas');
        this.canvas.width = this.box.w;
        this.canvas.height = this.box.h;
        this.canvas.style.width = this.box.w + 'px';
        this.canvas.style.height = this.box.h + 'px';
        this.canvas.style.left = this.box.x + 'px';
        this.canvas.style.top = this.box.y + 'px';
        this.ctx = this.canvas.getContext('2d');

        //if (isRetina()){
          //  this.ctx.scale(0.75,0.75);
        //}

    },
    clip: function () {
        this.ctx.translate(-this.box.x, -this.box.y);
        this.ctx.beginPath();
        this.ctx.moveTo(this.v0[0], this.v0[1]);
        this.ctx.lineTo(this.v1[0], this.v1[1]);
        this.ctx.lineTo(this.v2[0], this.v2[1]);
        this.ctx.closePath();
        this.ctx.clip();
        this.ctx.drawImage(WC_IMG, 0, 0);
    }
};

//load ad
init();<|endoftext|>


<commit_before>// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt

frappe.provide("frappe.ui.form");

frappe.ui.form.save = function(frm, action, callback, btn) {
	$(btn).prop("disabled", true);

	// specified here because there are keyboard shortcuts to save
	var working_label = {
		"Save": __("Saving"),
		"Submit": __("Submitting"),
		"Update": __("Updating"),
		"Amend": __("Amending"),
		"Cancel": __("Cancelling")
	}[toTitle(action)];

	var freeze_message = working_label ? __(working_label) : "";

	var save = function() {
		check_name(function() {
			if(check_mandatory()) {
				_call({
					method: "frappe.desk.form.save.savedocs",
					args: { doc: frm.doc, action:action},
					callback: function(r) {
						$(document).trigger("save", [frm.doc]);
						callback(r);
					},
					btn: btn,
					freeze_message: freeze_message
				});
			} else {
				$(btn).prop("disabled", false);
			}
		});

	};

	var cancel = function() {
		var args = {
			doctype: frm.doc.doctype,
			name: frm.doc.name
		};

		// update workflow state value if workflow exists
		var workflow_state_fieldname = frappe.workflow.get_state_fieldname(frm.doctype);
		if(workflow_state_fieldname) {
			$.extend(args, {
				workflow_state_fieldname: workflow_state_fieldname,
				workflow_state: frm.doc[workflow_state_fieldname]

			});
		}

		_call({
			method: "frappe.desk.form.save.cancel",
			args: args,
			callback: function(r) {
				$(document).trigger("save", [frm.doc]);
				callback(r);
			},
			btn: btn,
			freeze_message: freeze_message
		});
	};

	var check_name = function(callback) {
		var doc = frm.doc;
		var meta = locals.DocType[doc.doctype];
		if(doc.__islocal && (meta && meta.autoname
				&& meta.autoname.toLowerCase()=='prompt')) {
			var d = frappe.prompt(__("Name"), function(values) {
				var newname = values.value;
				if(newname) {
					doc.__newname = strip(newname);
				} else {
					msgprint(__("Name is required"));
					throw "name required";
				}

				callback();

			}, __('Enter the name of the new {0}', [doc.doctype]), __("Create"));

			if(doc.__newname) {
				d.set_value("value", doc.__newname);
			}

			d.onhide = function() {
				$(btn).prop("disabled", false);
			}
		} else {
			callback();
		}
	};

	var check_mandatory = function() {
		var me = this;
		var has_errors = false;
		frm.scroll_set = false;

		if(frm.doc.docstatus==2) return true; // don't check for cancel

		$.each(frappe.model.get_all_docs(frm.doc), function(i, doc) {

			if(doc.parent && doc.__unedited) {
				frappe.model.remove_from_locals(doc.doctype, doc.name);
				return;
			}

			var error_fields = [];
			var folded = false;

			$.each(frappe.meta.docfield_list[doc.doctype] || [], function(i, docfield) {
				if(docfield.fieldname) {
					var df = frappe.meta.get_docfield(doc.doctype,
						docfield.fieldname, frm.doc.name);

					if(df.fieldtype==="Fold") {
						folded = frm.layout.folded;
					}

					if(df.reqd && !frappe.model.has_value(doc.doctype, doc.name, df.fieldname)) {
						has_errors = true;
						error_fields[error_fields.length] = __(df.label);

						// scroll to field
						if(!me.scroll_set) {
							scroll_to(doc.parentfield || df.fieldname);
						}

						if(folded) {
							frm.layout.unfold();
							folded = false;
						}
					}

				}
			});
			if(error_fields.length)
				msgprint(__('Mandatory fields required in {0}', [(doc.parenttype
					? (__(frappe.meta.docfield_map[doc.parenttype][doc.parentfield].label) + ' ('+ __("Table") + ')')
					: __(doc.doctype))]) + '\n' + error_fields.join('\n'));
		});

		return !has_errors;
	};

	var scroll_to = function(fieldname) {
		var f = cur_frm.fields_dict[fieldname];
		if(f) {
			$(document).scrollTop($(f.wrapper).offset().top - 60);
		}
		frm.scroll_set = true;
	};

	var _call = function(opts) {
		// opts = {
		// 	method: "some server method",
		// 	args: {args to be passed},
		// 	callback: callback,
		// 	btn: btn
		// }
		$(opts.btn).prop("disabled", true);

		if(frappe.ui.form.is_saving) {
			// this is likely to happen if the user presses the shortcut cmd+s for a longer duration or uses double click
			// no need to show this to user, as they can see "Saving" in freeze message
			console.log("Already saving. Please wait a few moments.")
			throw "saving";
		}
		frappe.ui.form.is_saving = true;

		return frappe.call({
			freeze: true,
			freeze_message: opts.freeze_message,
			method: opts.method,
			args: opts.args,
			btn: opts.btn,
			callback: function(r) {
				opts.callback && opts.callback(r);
			},
			always: function() {
				frappe.ui.form.is_saving = false;
				frappe.ui.form.update_calling_link(opts.args.doc.name);
			}
		})
	};

	if(action==="cancel") {
		cancel();
	} else {
		save();
	}
}

frappe.ui.form.update_calling_link = function(name) {
	if(frappe._from_link) {
		// set value
		frappe.model.set_value(frappe._from_link.doctype,
			frappe._from_link.docname, frappe._from_link.df.fieldname, name);

		// refresh field
		frappe._from_link.refresh();

		// if from form, switch
		if(frappe._from_link.frm) {
			frappe.set_route("Form", frappe._from_link.frm.doctype, frappe._from_link.frm.docname);
			setTimeout(function() { frappe.utils.scroll_to(frappe._from_link_scrollY); }, 100);
		}

		frappe._from_link = null;
	}
}

<commit_msg>Fixed issue in link field<commit_after>// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt

frappe.provide("frappe.ui.form");

frappe.ui.form.save = function(frm, action, callback, btn) {
	$(btn).prop("disabled", true);

	// specified here because there are keyboard shortcuts to save
	var working_label = {
		"Save": __("Saving"),
		"Submit": __("Submitting"),
		"Update": __("Updating"),
		"Amend": __("Amending"),
		"Cancel": __("Cancelling")
	}[toTitle(action)];

	var freeze_message = working_label ? __(working_label) : "";

	var save = function() {
		check_name(function() {
			if(check_mandatory()) {
				_call({
					method: "frappe.desk.form.save.savedocs",
					args: { doc: frm.doc, action:action},
					callback: function(r) {
						$(document).trigger("save", [frm.doc]);
						callback(r);
					},
					btn: btn,
					freeze_message: freeze_message
				});
			} else {
				$(btn).prop("disabled", false);
			}
		});

	};

	var cancel = function() {
		var args = {
			doctype: frm.doc.doctype,
			name: frm.doc.name
		};

		// update workflow state value if workflow exists
		var workflow_state_fieldname = frappe.workflow.get_state_fieldname(frm.doctype);
		if(workflow_state_fieldname) {
			$.extend(args, {
				workflow_state_fieldname: workflow_state_fieldname,
				workflow_state: frm.doc[workflow_state_fieldname]

			});
		}

		_call({
			method: "frappe.desk.form.save.cancel",
			args: args,
			callback: function(r) {
				$(document).trigger("save", [frm.doc]);
				callback(r);
			},
			btn: btn,
			freeze_message: freeze_message
		});
	};

	var check_name = function(callback) {
		var doc = frm.doc;
		var meta = locals.DocType[doc.doctype];
		if(doc.__islocal && (meta && meta.autoname
				&& meta.autoname.toLowerCase()=='prompt')) {
			var d = frappe.prompt(__("Name"), function(values) {
				var newname = values.value;
				if(newname) {
					doc.__newname = strip(newname);
				} else {
					msgprint(__("Name is required"));
					throw "name required";
				}

				callback();

			}, __('Enter the name of the new {0}', [doc.doctype]), __("Create"));

			if(doc.__newname) {
				d.set_value("value", doc.__newname);
			}

			d.onhide = function() {
				$(btn).prop("disabled", false);
			}
		} else {
			callback();
		}
	};

	var check_mandatory = function() {
		var me = this;
		var has_errors = false;
		frm.scroll_set = false;

		if(frm.doc.docstatus==2) return true; // don't check for cancel

		$.each(frappe.model.get_all_docs(frm.doc), function(i, doc) {

			if(doc.parent && doc.__unedited) {
				frappe.model.remove_from_locals(doc.doctype, doc.name);
				return;
			}

			var error_fields = [];
			var folded = false;

			$.each(frappe.meta.docfield_list[doc.doctype] || [], function(i, docfield) {
				if(docfield.fieldname) {
					var df = frappe.meta.get_docfield(doc.doctype,
						docfield.fieldname, frm.doc.name);

					if(df.fieldtype==="Fold") {
						folded = frm.layout.folded;
					}

					if(df.reqd && !frappe.model.has_value(doc.doctype, doc.name, df.fieldname)) {
						has_errors = true;
						error_fields[error_fields.length] = __(df.label);

						// scroll to field
						if(!me.scroll_set) {
							scroll_to(doc.parentfield || df.fieldname);
						}

						if(folded) {
							frm.layout.unfold();
							folded = false;
						}
					}

				}
			});
			if(error_fields.length)
				msgprint(__('Mandatory fields required in {0}', [(doc.parenttype
					? (__(frappe.meta.docfield_map[doc.parenttype][doc.parentfield].label) + ' ('+ __("Table") + ')')
					: __(doc.doctype))]) + '\n' + error_fields.join('\n'));
		});

		return !has_errors;
	};

	var scroll_to = function(fieldname) {
		var f = cur_frm.fields_dict[fieldname];
		if(f) {
			$(document).scrollTop($(f.wrapper).offset().top - 60);
		}
		frm.scroll_set = true;
	};

	var _call = function(opts) {
		// opts = {
		// 	method: "some server method",
		// 	args: {args to be passed},
		// 	callback: callback,
		// 	btn: btn
		// }
		$(opts.btn).prop("disabled", true);

		if(frappe.ui.form.is_saving) {
			// this is likely to happen if the user presses the shortcut cmd+s for a longer duration or uses double click
			// no need to show this to user, as they can see "Saving" in freeze message
			console.log("Already saving. Please wait a few moments.")
			throw "saving";
		}
		frappe.ui.form.is_saving = true;

		return frappe.call({
			freeze: true,
			freeze_message: opts.freeze_message,
			method: opts.method,
			args: opts.args,
			btn: opts.btn,
			callback: function(r) {
				opts.callback && opts.callback(r);
			},
			always: function(r) {
				frappe.ui.form.is_saving = false;

				var doc = r.docs && r.docs[0];
				if(doc) {
					frappe.ui.form.update_calling_link(doc.name);
				}
			}
		})
	};

	if(action==="cancel") {
		cancel();
	} else {
		save();
	}
}

frappe.ui.form.update_calling_link = function(name) {
	if(frappe._from_link) {
		// set value
		frappe.model.set_value(frappe._from_link.doctype,
			frappe._from_link.docname, frappe._from_link.df.fieldname, name);

		// refresh field
		frappe._from_link.refresh();

		// if from form, switch
		if(frappe._from_link.frm) {
			frappe.set_route("Form", frappe._from_link.frm.doctype, frappe._from_link.frm.docname);
			setTimeout(function() { frappe.utils.scroll_to(frappe._from_link_scrollY); }, 100);
		}

		frappe._from_link = null;
	}
}

<|endoftext|>


<commit_before>var instance = jsPlumb.getInstance({
    Endpoint: ["Dot", {radius: 2}],
    Connector: "StateMachine",
    HoverPaintStyle: {strokeStyle: "#f44336", lineWidth: 2},
    ConnectionOverlays: [
        ["Arrow", {
            location: 1,
            id: "arrow",
            length: 14,
            foldback: 0.8
        }]
    ],
    Container: "canvas"
});

instance.registerConnectionType("basic", {anchor: "Continuous", connector: "StateMachine"});

window.jsp = instance;

var canvas = document.getElementById("canvas");
var windows = jsPlumb.getSelector(".statemachine-demo .w");

instance.bind("click", function (c) {
    instance.detach(c);
});

jsPlumb.fire("jsPlumbDemoLoaded", instance);

var initNode = function (el) {
    instance.draggable(el);
    instance.makeSource(el, {
        filter: ".ep",
        anchor: "Continuous",
        connectorStyle: {strokeStyle: "#26a69a", lineWidth: 2, outlineColor: "transparent", outlineWidth: 4},
        connectionType: "basic",
        extract: {
            "action": "the-action"
        }
    });
    instance.makeTarget(el, {
        dropOptions: {hoverClass: "dragHover"},
        anchor: "Continuous",
        allowLoopback: true
    });
};

var newNode = function (x, y, frontname, operation, subtype, fields) {
    var d = document.createElement("div");
    var id = jsPlumbUtil.uuid();
    d.className = "w";
    d.id = "box-" + subtype + "-" + id;

    var innerhtml = "";
    innerhtml += "
close
";
    innerhtml += "
";
    if (fields != null && fields.length > 0) {
        innerhtml += "
mode_edit
  ";
    }
    innerhtml += frontname;
    innerhtml += "
";
    if (fields != null && fields.length > 0) {
        innerhtml += "
";
        innerhtml += fields;
        innerhtml += "
";
    }
    innerhtml += "

";
    innerhtml += "

";

    d.innerHTML = innerhtml;
    d.style.left = x + "px";
    d.style.top = y + "px";
    d.setAttribute("data-operation", operation);
    d.setAttribute("data-subtype", subtype);

    document.getElementById("canvas").appendChild(d);
    initNode(d);

    if (fields != null && fields.length > 0) {
        $("#" + d.id + " > div > .btnSettings").click(function () {
            $("#" + d.id + " > .settings").toggle("slow");
        });
    }

    $("#" + d.id + " > .btnClose").click(function (e) {
        instance.remove($("#" + d.id));
        e.stopPropagation();
    });

    return d;
};

//init
for (var i = 0; i < windows.length; i++) {
    initNode(windows[i], true);
}

//add index
$("#btnAddIndex").click(function () {
    var option = $("#indextype option[value=" + $("#indextype").val() + "]");
    var frontname = option.text();
    var operation = option.data("operation");
    var subtype = option.data("subtype");
    var details = option.data("details");
    newNode(0, 0, frontname, operation, subtype, details);
});

//add operation
$("#btnAddOperation").click(function () {
    var option = $("#indexoperation option[value=" + $("#indexoperation").val() + "]");
    var frontname = option.text();
    var operation = option.data("operation");
    var subtype = option.data("subtype");
    var details = option.data("details");
    newNode(0, 0, frontname, operation, subtype, details);
});

//submit operation
$("#btnSubmit").click(function () {
    if ($("#entityname").val().length === 0) {
        showAlert(" Please specify an entity.");
        return;
    }

    if ($("#query").val().length === 0) {
        showAlert(" Please specify a query vector.");
        return;
    }

    if ($("#column").val().length === 0) {
        showAlert(" Please specify an attribute.");
        return;
    }

    $("#btnSubmit").addClass('disabled');
    $("#btnSubmit").prop('disabled', true);

    $("#progress").show();

    $.ajax("/query/compound", {
        data: JSON.stringify(evaluate("box-start")),
        contentType: 'application/json',
        type: 'POST',
        success: function (data) {
            if (data.code === 200) {
                $.each(data.details.intermediate_responses, function (idx, val) {
                    if (val.id.length > 0) {
                        $("#" + val.id + " > .res").html("execution time: " + val.time + "ms" + "
" + "results: " + val.results.length);

                        var slicedData = val.results.slice(0, Math.min(150, val.results.length));
                        $("#" + val.id).data("results", slicedData);

                        $("#" + val.id).click(function () {
                            $("#resultbox").show();
                            var results = $("#" + val.id).data("results");

                            if (results.length > 0) {
                                var innerhtml = '';
                                innerhtml += '
';
                                innerhtml += '

';

                                $.each(results[0], function (key, value) {
                                    innerhtml += "" + key + "	"
                                });

                                innerhtml += '

';
                                innerhtml += '
';

                                $.each(results, function (key, value) {
                                    innerhtml += "
";
                                    $.each(value, function (attributekey, attributevalue) {
                                        innerhtml += "" + attributevalue + "	"
                                    });
                                    innerhtml += "
";
                                });

                                innerhtml += '
';

                                innerhtml += '
';
                            }

                            $("#results").html(innerhtml);
                        });
                    }
                });
            } else {
                showAlert("Error in request: " + data.message);
            }
            $("#progress").hide()
            $("#btnSubmit").removeClass('disabled');
            $("#btnSubmit").prop('disabled', false);
        },
        error: function () {
            $("#progress").hide()
            $("#btnSubmit").removeClass('disabled');
            $("#btnSubmit").prop('disabled', false);
            showAlert("Error in request.");
        }
    });
});

//evaluate canvas
var evaluate = function (id) {
    var operation = $("#" + id).data("operation");
    $("#" + id).data("results", null);

    var result = {};
    result.id = id;
    result.operation = operation;

    result.options = {};
    result.options.subtype = $("#" + id).data("subtype");

    result.options.entityname = $("#entityname").val();
    result.options.column = $("#column").val();
    result.options.query = $("#query").val();

    result.options.informationlevel = $("#informationlevel").val();

    if ($("#k").val().length > 0) {
        result.options.k = $("#k").val();
    }
    $("#" + id + " > .settings").find(":input").each(function () {
        if ($(this).val().length > 0) {
            result.options[$(this).attr('name')] = $(this).val();
        }
    });

    var targets = getTargets(id);
    if (targets.length > 0) {
        result.targets = $.map(targets, function (val, i) {
            clearRes(val)
            return evaluate(val)
        });
    }

    if (operation === "start") {
        clearRes("box-start");
    }

    return result;
};

var getTargets = function (id) {
    var connections = instance.getConnections({target: id});
    var targets = $.map(connections, function (val, i) {
        return val.sourceId
    });
    return targets;
};

var clearRes = function (id) {
    $('#' + id + ' > div.res').html("");
};

<commit_msg>result displayal in compound query<commit_after>var instance = jsPlumb.getInstance({
    Endpoint: ["Dot", {radius: 2}],
    Connector: "StateMachine",
    HoverPaintStyle: {strokeStyle: "#f44336", lineWidth: 2},
    ConnectionOverlays: [
        ["Arrow", {
            location: 1,
            id: "arrow",
            length: 14,
            foldback: 0.8
        }]
    ],
    Container: "canvas"
});

instance.registerConnectionType("basic", {anchor: "Continuous", connector: "StateMachine"});

window.jsp = instance;

var canvas = document.getElementById("canvas");
var windows = jsPlumb.getSelector(".statemachine-demo .w");

instance.bind("click", function (c) {
    instance.detach(c);
});

jsPlumb.fire("jsPlumbDemoLoaded", instance);

var initNode = function (el) {
    instance.draggable(el);
    instance.makeSource(el, {
        filter: ".ep",
        anchor: "Continuous",
        connectorStyle: {strokeStyle: "#26a69a", lineWidth: 2, outlineColor: "transparent", outlineWidth: 4},
        connectionType: "basic",
        extract: {
            "action": "the-action"
        }
    });
    instance.makeTarget(el, {
        dropOptions: {hoverClass: "dragHover"},
        anchor: "Continuous",
        allowLoopback: true
    });
};

var newNode = function (x, y, frontname, operation, subtype, fields) {
    var d = document.createElement("div");
    var id = jsPlumbUtil.uuid();
    d.className = "w";
    d.id = "box-" + subtype + "-" + id;

    var innerhtml = "";
    innerhtml += "
close
";
    innerhtml += "
";
    if (fields != null && fields.length > 0) {
        innerhtml += "
mode_edit
  ";
    }
    innerhtml += frontname;
    innerhtml += "
";
    if (fields != null && fields.length > 0) {
        innerhtml += "
";
        innerhtml += fields;
        innerhtml += "
";
    }
    innerhtml += "

";
    innerhtml += "

";

    d.innerHTML = innerhtml;
    d.style.left = x + "px";
    d.style.top = y + "px";
    d.setAttribute("data-operation", operation);
    d.setAttribute("data-subtype", subtype);

    document.getElementById("canvas").appendChild(d);
    initNode(d);

    if (fields != null && fields.length > 0) {
        $("#" + d.id + " > div > .btnSettings").click(function () {
            $("#" + d.id + " > .settings").toggle("slow");
        });
    }

    $("#" + d.id + " > .btnClose").click(function (e) {
        instance.remove($("#" + d.id));
        e.stopPropagation();
    });

    return d;
};

//init
for (var i = 0; i < windows.length; i++) {
    initNode(windows[i], true);
}

//add index
$("#btnAddIndex").click(function () {
    var option = $("#indextype option[value=" + $("#indextype").val() + "]");
    var frontname = option.text();
    var operation = option.data("operation");
    var subtype = option.data("subtype");
    var details = option.data("details");
    newNode(0, 0, frontname, operation, subtype, details);
});

//add operation
$("#btnAddOperation").click(function () {
    var option = $("#indexoperation option[value=" + $("#indexoperation").val() + "]");
    var frontname = option.text();
    var operation = option.data("operation");
    var subtype = option.data("subtype");
    var details = option.data("details");
    newNode(0, 0, frontname, operation, subtype, details);
});

//submit operation
$("#btnSubmit").click(function () {
    if ($("#entityname").val().length === 0) {
        showAlert(" Please specify an entity.");
        return;
    }

    if ($("#query").val().length === 0) {
        showAlert(" Please specify a query vector.");
        return;
    }

    if ($("#column").val().length === 0) {
        showAlert(" Please specify an attribute.");
        return;
    }

    $("#btnSubmit").addClass('disabled');
    $("#btnSubmit").prop('disabled', true);

    $("#progress").show();

    $.ajax("/query/compound", {
        data: JSON.stringify(evaluate("box-start")),
        contentType: 'application/json',
        type: 'POST',
        success: function (data) {
            if (data.code === 200) {
                $.each(data.details.intermediate_responses, function (idx, val) {
                    if (val.id.length > 0) {
                        $("#" + val.id + " > .res").html("execution time: " + val.time + "ms" + "
" + "results: " + val.results.length);

                        var slicedData = val.results.slice(0, Math.min(150, val.results.length));
                        $("#" + val.id).data("results", slicedData);

                        $("#" + val.id).click(function () {
                            $("#resultbox").show();
                            var results = $("#" + val.id).data("results");

                            var innerhtml = '';
                            if (results != null && results.length > 0) {
                                innerhtml += '
';
                                innerhtml += '

';

                                $.each(results[0], function (key, value) {
                                    innerhtml += "" + key + "	"
                                });

                                innerhtml += '

';
                                innerhtml += '
';

                                $.each(results, function (key, value) {
                                    innerhtml += "
";
                                    $.each(value, function (attributekey, attributevalue) {
                                        innerhtml += "" + attributevalue + "	"
                                    });
                                    innerhtml += "
";
                                });

                                innerhtml += '
';

                                innerhtml += '
';
                            }

                            $("#results").html(innerhtml);
                        });
                    }
                });
            } else {
                showAlert("Error in request: " + data.message);
            }
            $("#progress").hide()
            $("#btnSubmit").removeClass('disabled');
            $("#btnSubmit").prop('disabled', false);
        },
        error: function () {
            $("#progress").hide()
            $("#btnSubmit").removeClass('disabled');
            $("#btnSubmit").prop('disabled', false);
            showAlert("Error in request.");
        }
    });
});

//evaluate canvas
var evaluate = function (id) {
    var operation = $("#" + id).data("operation");
    $("#" + id).data("results", null);

    var result = {};
    result.id = id;
    result.operation = operation;

    result.options = {};
    result.options.subtype = $("#" + id).data("subtype");

    result.options.entityname = $("#entityname").val();
    result.options.column = $("#column").val();
    result.options.query = $("#query").val();

    result.options.informationlevel = $("#informationlevel").val();

    if ($("#k").val().length > 0) {
        result.options.k = $("#k").val();
    }
    $("#" + id + " > .settings").find(":input").each(function () {
        if ($(this).val().length > 0) {
            result.options[$(this).attr('name')] = $(this).val();
        }
    });

    var targets = getTargets(id);
    if (targets.length > 0) {
        result.targets = $.map(targets, function (val, i) {
            clearRes(val)
            return evaluate(val)
        });
    }

    if (operation === "start") {
        clearRes("box-start");
    }

    return result;
};

var getTargets = function (id) {
    var connections = instance.getConnections({target: id});
    var targets = $.map(connections, function (val, i) {
        return val.sourceId
    });
    return targets;
};

var clearRes = function (id) {
    $('#' + id + ' > div.res').html("");
};

<|endoftext|>


<commit_before>const React = require('react');
const parse = require('..');
const { data, render } = require('./helpers/');

describe('HTML to React', () => {
  describe('exports', () => {
    it('has default ES Module', () => {
      expect(parse.default).toBe(parse);
    });

    it('has domToReact', () => {
      expect(parse.domToReact).toBe(require('../lib/dom-to-react'));
    });

    it('has htmlToDOM', () => {
      expect(parse.htmlToDOM).toBe(require('html-dom-parser'));
    });
  });

  describe('parser', () => {
    it.each([undefined, null, {}, [], 0, 1, () => {}, new Date()])(
      'throws an error if first argument is %p',
      input => {
        expect(() => {
          parse(input);
        }).toThrow(TypeError);
      }
    );

    it('converts empty string to empty array', () => {
      expect(parse('')).toEqual([]);
    });

    it('returns string if it cannot be parsed as HTML', () => {
      expect(parse('foo')).toBe('foo');
    });

    it('converts single HTML element to React', () => {
      const html = data.html.single;
      const reactElement = parse(html);

      expect(render(reactElement)).toBe(html);
    });

    it('converts single HTML element and ignores comment', () => {
      const html = data.html.single;
      // comment should be ignored
      const reactElement = parse(html + data.html.comment);

      expect(render(reactElement)).toBe(html);
    });

    it('converts multiple HTML elements to React', () => {
      const html = data.html.multiple;
      const reactElements = parse(html);

      expect(
        render(React.createElement(React.Fragment, {}, reactElements))
      ).toBe(html);
    });

    it('converts complex HTML to React', () => {
      const html = data.html.complex;
      const reactElement = parse(data.html.doctype + html);

      expect(render(reactElement)).toBe(html);
    });

    it('converts empty ';
      const reactElement = parse(html);

      expect(render(reactElement)).toBe(html);
    });

    it('converts empty ';
      const reactElement = parse(html);

      expect(render(reactElement)).toBe(html);
    });

    it('converts SVG to React', () => {
      const svg = data.svg.complex;
      const reactElement = parse(svg);

      expect(render(reactElement)).toBe(svg);
    });

    it('decodes HTML entities', () => {
      const encodedEntities = 'asdf & ÿ ü '';
      const decodedEntities = "asdf & ÿ ü '";
      const reactElement = parse('' + encodedEntities + '');

      expect(reactElement.props.children).toBe(decodedEntities);
    });
  });

  describe('options', () => {
    describe('replace', () => {
      it('overrides the element if a valid React element is returned', () => {
        const html = data.html.complex;
        const reactElement = parse(html, {
          replace: node => {
            if (node.name === 'title') {
              return React.createElement('title', {}, 'Replaced Title');
            }
          }
        });

        expect(render(reactElement)).toBe(
          html.replace('<title>Title</title>', '<title>Replaced Title</title>')
        );
      });

      it('does not override the element if an invalid React element is returned', () => {
        const html = data.html.complex;
        const options = {
          replace: node => {
            if (node.attribs && node.attribs.id === 'header') {
              return {
                type: 'h1',
                props: { children: 'Heading' }
              };
            }
          }
        };
        const reactElement = parse(html, options);

        expect(render(reactElement)).toBe(html);
      });

      it('use attributesToProps to converts attributes to React props', () => {
        const { attributesToProps } = parse;
        const html = data.html.attributes;

        let props;
        const options = {
          replace: node => {
            if (node.attribs && node.name === 'hr') {
              props = attributesToProps(node.attribs);
              return {
                type: 'hr',
                props
              };
            }
          }
        };
        const reactElement = parse(html, options);

        expect(props).toEqual({
          id: 'foo',
          className: 'bar baz',
          style: {
            background: '#fff',
            textAlign: 'center'
          },
          ['data-foo']: 'bar'
        });
        expect(render(reactElement)).toBe(html);
      });
    });

    describe('library', () => {
      it('converts with Preact instead of React', () => {
        const Preact = require('preact');
        const html = data.html.single;
        const options = { library: Preact };
        const preactElement = parse(html, options);

        expect(preactElement).toEqual(Preact.createElement('p', {}, 'foo'));
      });
    });

    describe('htmlparser2', () => {
      it('parses XHTML with xmlMode enabled', () => {
        // using self-closing syntax (`/>`) for non-void elements is invalid
        // which causes elements to nest instead of being rendered correctly
        // enabling htmlparser2 option xmlMode resolves this issue
        const html = '

';
        const options = { htmlparser2: { xmlMode: true } };
        const reactElements = parse(html, options);

        expect(render(reactElements)).toBe('

');
      });
    });

    describe('trim', () => {
      it('preserves whitespace text nodes when disabled (default)', () => {
        const html = `

`;
        const reactElement = parse(html);

        expect(render(reactElement)).toBe(html);
      });

      it('removes whitespace text nodes when enabled', () => {
        const html = `

 text 	 	\t
\r
\n
`;
        const options = { trim: true };
        const reactElement = parse(html, options);

        expect(render(reactElement)).toBe(
          '

 text

'
        );
      });
    });
  });
});
<commit_msg>test(html-to-react): verify `attributesToProps` is on module exports<commit_after>const React = require('react');
const parse = require('..');
const { data, render } = require('./helpers/');

describe('HTML to React', () => {
  describe('exports', () => {
    it('has default ES Module', () => {
      expect(parse.default).toBe(parse);
    });

    it('has domToReact', () => {
      expect(parse.domToReact).toBe(require('../lib/dom-to-react'));
    });

    it('has htmlToDOM', () => {
      expect(parse.htmlToDOM).toBe(require('html-dom-parser'));
    });

    it('has attributesToProps', () => {
      expect(parse.attributesToProps).toBe(
        require('../lib/attributes-to-props')
      );
    });
  });

  describe('parser', () => {
    it.each([undefined, null, {}, [], 0, 1, () => {}, new Date()])(
      'throws an error if first argument is %p',
      input => {
        expect(() => {
          parse(input);
        }).toThrow(TypeError);
      }
    );

    it('converts empty string to empty array', () => {
      expect(parse('')).toEqual([]);
    });

    it('returns string if it cannot be parsed as HTML', () => {
      expect(parse('foo')).toBe('foo');
    });

    it('converts single HTML element to React', () => {
      const html = data.html.single;
      const reactElement = parse(html);

      expect(render(reactElement)).toBe(html);
    });

    it('converts single HTML element and ignores comment', () => {
      const html = data.html.single;
      // comment should be ignored
      const reactElement = parse(html + data.html.comment);

      expect(render(reactElement)).toBe(html);
    });

    it('converts multiple HTML elements to React', () => {
      const html = data.html.multiple;
      const reactElements = parse(html);

      expect(
        render(React.createElement(React.Fragment, {}, reactElements))
      ).toBe(html);
    });

    it('converts complex HTML to React', () => {
      const html = data.html.complex;
      const reactElement = parse(data.html.doctype + html);

      expect(render(reactElement)).toBe(html);
    });

    it('converts empty ';
      const reactElement = parse(html);

      expect(render(reactElement)).toBe(html);
    });

    it('converts empty ';
      const reactElement = parse(html);

      expect(render(reactElement)).toBe(html);
    });

    it('converts SVG to React', () => {
      const svg = data.svg.complex;
      const reactElement = parse(svg);

      expect(render(reactElement)).toBe(svg);
    });

    it('decodes HTML entities', () => {
      const encodedEntities = 'asdf & ÿ ü '';
      const decodedEntities = "asdf & ÿ ü '";
      const reactElement = parse('' + encodedEntities + '');

      expect(reactElement.props.children).toBe(decodedEntities);
    });
  });

  describe('options', () => {
    describe('replace', () => {
      it('overrides the element if a valid React element is returned', () => {
        const html = data.html.complex;
        const reactElement = parse(html, {
          replace: node => {
            if (node.name === 'title') {
              return React.createElement('title', {}, 'Replaced Title');
            }
          }
        });

        expect(render(reactElement)).toBe(
          html.replace('<title>Title</title>', '<title>Replaced Title</title>')
        );
      });

      it('does not override the element if an invalid React element is returned', () => {
        const html = data.html.complex;
        const options = {
          replace: node => {
            if (node.attribs && node.attribs.id === 'header') {
              return {
                type: 'h1',
                props: { children: 'Heading' }
              };
            }
          }
        };
        const reactElement = parse(html, options);

        expect(render(reactElement)).toBe(html);
      });

      it('use attributesToProps to converts attributes to React props', () => {
        const { attributesToProps } = parse;
        const html = data.html.attributes;

        let props;
        const options = {
          replace: node => {
            if (node.attribs && node.name === 'hr') {
              props = attributesToProps(node.attribs);
              return {
                type: 'hr',
                props
              };
            }
          }
        };
        const reactElement = parse(html, options);

        expect(props).toEqual({
          id: 'foo',
          className: 'bar baz',
          style: {
            background: '#fff',
            textAlign: 'center'
          },
          ['data-foo']: 'bar'
        });
        expect(render(reactElement)).toBe(html);
      });
    });

    describe('library', () => {
      it('converts with Preact instead of React', () => {
        const Preact = require('preact');
        const html = data.html.single;
        const options = { library: Preact };
        const preactElement = parse(html, options);

        expect(preactElement).toEqual(Preact.createElement('p', {}, 'foo'));
      });
    });

    describe('htmlparser2', () => {
      it('parses XHTML with xmlMode enabled', () => {
        // using self-closing syntax (`/>`) for non-void elements is invalid
        // which causes elements to nest instead of being rendered correctly
        // enabling htmlparser2 option xmlMode resolves this issue
        const html = '

';
        const options = { htmlparser2: { xmlMode: true } };
        const reactElements = parse(html, options);

        expect(render(reactElements)).toBe('

');
      });
    });

    describe('trim', () => {
      it('preserves whitespace text nodes when disabled (default)', () => {
        const html = `

`;
        const reactElement = parse(html);

        expect(render(reactElement)).toBe(html);
      });

      it('removes whitespace text nodes when enabled', () => {
        const html = `

 text 	 	\t
\r
\n
`;
        const options = { trim: true };
        const reactElement = parse(html, options);

        expect(render(reactElement)).toBe(
          '

 text

'
        );
      });
    });
  });
});
<|endoftext|>


<commit_before>var path = require('path');
var fs = require('fs');
var util = require('./util'); //必须第一个加载
var proxy = require('./lib');
var config = util.config;
var argvs = util.argvs;
var rulesUtil = require('./lib/rules/util');

function parseHosts(hostsPath) {
	if (hostsPath) {
		try {
			rulesUtil.setPublicHosts(fs.readFileSync(path.resolve(hostsPath), {encoding: 'utf8'}));
		} catch(e) {}
	}

	rulesUtil.loadHosts();
}

function start(options) {
	var app = proxy(options.port, options.plugins);
	require('util')._extend(app, config);
	require('./biz/init')(app);
	return app;
}

function updateConfig(options) {
	if (options.plugins) {
		options.plugins = options.plugins.split(',').map(function(plugin) {
			return /[^\w-]/i.test(plugin) ? path.resolve(plugin.trim()) : plugin;
		});
	}

	for (var i in argvs) {
		config[i] = options[i] || config[i];
	}

	var port = config.port;
	if (Array.isArray(config.ports)) {
		config.ports.forEach(function(name) {
			config[name] = ++port;
		});
	}
}

module.exports = function init(options) {
	options = options || {};
	updateConfig(options);
	parseHosts(options.hosts);
	return start(options);
};<commit_msg>hosts file<commit_after>var path = require('path');
var fs = require('fs');
var util = require('./util'); //必须第一个加载
var proxy = require('./lib');
var config = util.config;
var argvs = util.argvs;
var rulesUtil = require('./lib/rules/util');

function parseHosts(hostsPath) {
	if (hostsPath) {
		try {
			rulesUtil.setPublicHosts(fs.readFileSync(path.resolve(hostsPath), {encoding: 'utf8'}));
			rulesUtil.enablePublicHosts();
		} catch(e) {}
	}

	rulesUtil.loadHosts();
}

function start(options) {
	var app = proxy(options.port, options.plugins);
	require('util')._extend(app, config);
	require('./biz/init')(app);
	return app;
}

function updateConfig(options) {
	if (options.plugins) {
		options.plugins = options.plugins.split(',').map(function(plugin) {
			return /[^\w-]/i.test(plugin) ? path.resolve(plugin.trim()) : plugin;
		});
	}

	for (var i in argvs) {
		config[i] = options[i] || config[i];
	}

	var port = config.port;
	if (Array.isArray(config.ports)) {
		config.ports.forEach(function(name) {
			config[name] = ++port;
		});
	}
}

module.exports = function init(options) {
	options = options || {};
	updateConfig(options);
	parseHosts(options.hosts);
	return start(options);
};<|endoftext|>


<commit_before>import template from './app.html';
import './app.scss';
import changelog from '../views/changelog-toaster-release.html';
import { isPhonePortrait } from './mediaQueries';
import _ from 'underscore';
import i18next from 'i18next';

export const AppComponent = {
  template: template,
  controller: AppComponentCtrl
};

function AppComponentCtrl(
  $scope,
  dimInfoService,
  dimSettingsService,
  $i18next,
  toaster,
  $timeout,
  hotkeys,
  dimState
) {
  'ngInject';

  this.$onInit = function() {
    this.reviewsEnabled = $featureFlags.reviewsEnabled;
    this.settings = dimSettingsService;
    this.featureFlags = {
      colorA11y: $featureFlags.colorA11y
    };

    this.settings = dimSettingsService;
    $scope.$watch(() => this.settings.itemSize, (size) => {
      if (!isPhonePortrait()) {
        document.querySelector('html').style.setProperty("--item-size", `${size}px`);
      }
    });
    $scope.$watch(() => this.settings.charCol, (cols) => {
      if (!isPhonePortrait()) {
        document.querySelector('html').style.setProperty("--character-columns", cols);
      }
    });
    $scope.$watch(() => this.settings.vaultMaxCol, (cols) => {
      document.querySelector('html').style.setProperty("--vault-max-columns", cols);
    });

    $scope.$watch(() => this.settings.charColMobile, (cols) => {
      if (isPhonePortrait()) {
        document.querySelector('html').style.setProperty("--character-columns", cols);
      }
    });

    // a watch on isPhonePortrait is needed when the user on mobile changes from portrait to landscape
    // or a user on desktop shrinks the browser window below isphoneportrait treshold value
    $scope.$watch(() => isPhonePortrait(), (isPhonePortrait) => {
      if (isPhonePortrait) {
        document.querySelector('html').style.setProperty("--character-columns", this.settings.charColMobile);
      } else {
        document.querySelector('html').style.setProperty("--character-columns", this.settings.charCol);
      }
    });

    hotkeys = hotkeys.bindTo($scope);

    hotkeys.add({
      combo: ['ctrl+alt+shift+d'],
      callback: function() {
        dimState.debug = true;
        console.log("***** DIM DEBUG MODE ENABLED *****");
      }
    });

    if ($featureFlags.colorA11y) {
      $scope.$watch(() => this.settings.colorA11y, (color) => {
        if (color && color !== '-') {
          document.querySelector('html').style.setProperty("--color-filter", `url(#${color.toLowerCase()})`);
        } else {
          document.querySelector('html').style.removeProperty("--color-filter");
        }
      });
    }

    // Show the changelog
    if ($featureFlags.changelogToaster) {
      $timeout(() => {
        dimInfoService.show(`changelogv${$DIM_VERSION.replace(/\./gi, '')}`, {
          title: $i18next.t('Help.Version', {
            version: $DIM_VERSION,
            context: $DIM_FLAVOR
          }),
          body: changelog
        });
      });
    }

    try {
      localStorage.setItem('test', 'true');
    } catch (e) {
      console.log('storage test', e);
      $timeout(() => {
        dimInfoService.show('no-storage', {
          title: $i18next.t('Help.NoStorage'),
          body: $i18next.t('Help.NoStorageMessage'),
          type: 'error',
          hideable: false
        }, 0);
      });
    }

    if (window.BroadcastChannel) {
      const updateChannel = new window.BroadcastChannel('precache-updates');

      const updateMessage = _.once(() => {
        $timeout(() => {
          dimInfoService.show('update-available', {
            title: $i18next.t('Help.UpdateAvailable'),
            body: $i18next.t('Help.UpdateAvailableMessage'),
            type: 'warn',
            hideable: false
          }, 0);
        });
      });

      const messageHandler = () => updateMessage();

      updateChannel.addEventListener('message', messageHandler);
      $scope.$on('$destroy', () => {
        updateChannel.removeEventListener('message', messageHandler);
      });
    }
  };

  $scope.$on('i18nextLanguageChange', () => {
    this.language = `lang-${i18next.language}`;
  });
}
<commit_msg>lint + adjustments<commit_after>import template from './app.html';
import './app.scss';
import changelog from '../views/changelog-toaster-release.html';
import { isPhonePortrait, isPhonePortraitStream } from './mediaQueries';
import _ from 'underscore';
import i18next from 'i18next';

export const AppComponent = {
  template: template,
  controller: AppComponentCtrl
};

function AppComponentCtrl(
  $scope,
  dimInfoService,
  dimSettingsService,
  $i18next,
  toaster,
  $timeout,
  hotkeys,
  dimState
) {
  'ngInject';

  this.$onInit = function() {
    this.reviewsEnabled = $featureFlags.reviewsEnabled;
    this.settings = dimSettingsService;
    this.featureFlags = {
      colorA11y: $featureFlags.colorA11y
    };

    this.settings = dimSettingsService;
    $scope.$watch(() => this.settings.itemSize, (size) => {
        document.querySelector('html').style.setProperty("--item-size", `${size}px`);
    });
    $scope.$watch(() => this.settings.charCol, (cols) => {
        document.querySelector('html').style.setProperty("--character-columns", cols);
    });
    $scope.$watch(() => this.settings.vaultMaxCol, (cols) => {
      document.querySelector('html').style.setProperty("--vault-max-columns", cols);
    });

    $scope.$watch(() => this.settings.charColMobile, (cols) => {
      // this check is needed so on start up/load this doesn't override the value set above on "normal" mode.
      if (isPhonePortrait()) {
        document.querySelector('html').style.setProperty("--character-columns", cols);
      }
    });
    // a subscribe on isPhonePortraitStream is needed when the user on mobile changes from portrait to landscape
    // or a user on desktop shrinks the browser window below isphoneportrait treshold value
    isPhonePortraitStream().subscribe((isPhonePortrait) => {
      if (isPhonePortrait) {
        document.querySelector('html').style.setProperty("--character-columns", this.settings.charColMobile);
      } else {
        document.querySelector('html').style.setProperty("--character-columns", this.settings.charCol);
      }
    });

    hotkeys = hotkeys.bindTo($scope);

    hotkeys.add({
      combo: ['ctrl+alt+shift+d'],
      callback: function() {
        dimState.debug = true;
        console.log("***** DIM DEBUG MODE ENABLED *****");
      }
    });

    if ($featureFlags.colorA11y) {
      $scope.$watch(() => this.settings.colorA11y, (color) => {
        if (color && color !== '-') {
          document.querySelector('html').style.setProperty("--color-filter", `url(#${color.toLowerCase()})`);
        } else {
          document.querySelector('html').style.removeProperty("--color-filter");
        }
      });
    }

    // Show the changelog
    if ($featureFlags.changelogToaster) {
      $timeout(() => {
        dimInfoService.show(`changelogv${$DIM_VERSION.replace(/\./gi, '')}`, {
          title: $i18next.t('Help.Version', {
            version: $DIM_VERSION,
            context: $DIM_FLAVOR
          }),
          body: changelog
        });
      });
    }

    try {
      localStorage.setItem('test', 'true');
    } catch (e) {
      console.log('storage test', e);
      $timeout(() => {
        dimInfoService.show('no-storage', {
          title: $i18next.t('Help.NoStorage'),
          body: $i18next.t('Help.NoStorageMessage'),
          type: 'error',
          hideable: false
        }, 0);
      });
    }

    if (window.BroadcastChannel) {
      const updateChannel = new window.BroadcastChannel('precache-updates');

      const updateMessage = _.once(() => {
        $timeout(() => {
          dimInfoService.show('update-available', {
            title: $i18next.t('Help.UpdateAvailable'),
            body: $i18next.t('Help.UpdateAvailableMessage'),
            type: 'warn',
            hideable: false
          }, 0);
        });
      });

      const messageHandler = () => updateMessage();

      updateChannel.addEventListener('message', messageHandler);
      $scope.$on('$destroy', () => {
        updateChannel.removeEventListener('message', messageHandler);
      });
    }
  };

  $scope.$on('i18nextLanguageChange', () => {
    this.language = `lang-${i18next.language}`;
  });
}
<|endoftext|>


<commit_before>import React, { PropTypes, Component } from 'react';
import { connect } from 'react-redux';
import {Card, CardHeader, CardText} from 'material-ui/Card';
import FlatButton from 'material-ui/FlatButton';
import AffichePrix from 'containers/CommandeEdit/components/components/AffichePrix';
import { createStructuredSelector } from 'reselect';
import {
    selectOffresDuProduit,
    selectTypesProduitsRelais,
    selectFournisseursRelais,
    selectProduitsRelaisByTypeProduit,
} from 'containers/Commande/selectors';

import styles from './styles.css';

class DetailOffres extends Component {
  static propTypes = {
    offres: PropTypes.array,
    produits: PropTypes.array.isRequired,
    typeProduits: PropTypes.array.isRequired,
    params: PropTypes.object.isRequired,
    fournisseurs: PropTypes.array,
  }

  static contextTypes = {
    muiTheme: PropTypes.object.isRequired,
  };

  constructor(props) {
    super(props);
    this.state = {
      viewOffre: true,
    };
  }

  render() {
    const { viewOffre } = this.state;
    const {
      offres,
      fournisseurs,
      produits,
      typeProduits,
      params,
    } = this.props;

    if (!offres || !typeProduits) return null;
    const { produitId, relaiId } = params;
    const produit = produits.find((pdt) => pdt.id === produitId);

    if (!produit) {
      return
Produit non trouvé
;
    }

    const fournisseur = fournisseurs.find((f) => f.id === produit.fournisseurId);
    const muiTheme = this.context.muiTheme;

    return (

          <div className={`col-md-12 ${styles.fournisseurSwitch}`}>
            <FlatButton
              onClick={() => this.setState((oldState) => ({ viewOffre: !oldState.viewOffre }))}
              primary
              label={viewOffre ? fournisseur.nom : 'Afficher les offres'}
            />

          {viewOffre && <div className={`${styles.produitTitre} col-md-12`}>{produit.nom.toUpperCase()}
}

                {viewOffre && <img src={`https://proxiweb.fr/${produit.photo}`} alt={produit.nom} style={{ width: '100%', height: 'auto', maxWidth: 200 }} />}
                {!viewOffre && <img src={`https://proxiweb.fr/${fournisseur.illustration}`} alt={produit.nom} style={{ width: '100%', height: 'auto', maxWidth: 200 }} />}

                {viewOffre &&
}
                {!viewOffre &&
}

        { viewOffre && offres.filter((o) => o.active && o.relaiId === relaiId).map((offre, idx) => {
          const typeProduit = typeProduits.find((typesPdt) => typesPdt.id === produit.typeProduitId);

          return (
            <div key={idx} className={`row ${styles.offre}`} style={{ backgroundColor: muiTheme.palette.groupColor, border: `solid 1px ${muiTheme.palette.groupColorBorder}` }}>

                <Card>
                  <CardHeader
                    actAsExpander
                    showExpandableButton
                    title={<AffichePrix offre={offre} typeProduit={typeProduit} />}
                  >
                  </CardHeader>
                  <CardText expandable>
                    lorem
                  </CardText>
                </Card>

);
        })}

    );
  }
}

const mapStateToProps = createStructuredSelector({
  typeProduits: selectTypesProduitsRelais(),
  offres: selectOffresDuProduit(),
  fournisseurs: selectFournisseursRelais(),
  produits: selectProduitsRelaisByTypeProduit(),
});

export default connect(mapStateToProps)(DetailOffres);
<commit_msg>suite mep catalogue<commit_after>import React, { PropTypes, Component } from 'react';
import { connect } from 'react-redux';
import {Card, CardHeader, CardText} from 'material-ui/Card';
import FlatButton from 'material-ui/FlatButton';
import AffichePrix, { prixAuKg, detailPrix } from 'containers/CommandeEdit/components/components/AffichePrix';
import { createStructuredSelector } from 'reselect';
import {
    selectOffresDuProduit,
    selectTypesProduitsRelais,
    selectFournisseursRelais,
    selectProduitsRelaisByTypeProduit,
} from 'containers/Commande/selectors';

import styles from './styles.css';

class DetailOffres extends Component {
  static propTypes = {
    offres: PropTypes.array,
    produits: PropTypes.array.isRequired,
    typeProduits: PropTypes.array.isRequired,
    params: PropTypes.object.isRequired,
    fournisseurs: PropTypes.array,
  }

  static contextTypes = {
    muiTheme: PropTypes.object.isRequired,
  };

  constructor(props) {
    super(props);
    this.state = {
      viewOffre: true,
    };
  }

  render() {
    const { viewOffre } = this.state;
    const {
      offres,
      fournisseurs,
      produits,
      typeProduits,
      params,
    } = this.props;

    if (!offres || !typeProduits) return null;
    const { produitId, relaiId } = params;
    const produit = produits.find((pdt) => pdt.id === produitId);

    if (!produit) {
      return
Produit non trouvé
;
    }

    const fournisseur = fournisseurs.find((f) => f.id === produit.fournisseurId);
    const muiTheme = this.context.muiTheme;

    return (

          <div className={`col-md-12 ${styles.fournisseurSwitch}`}>
            <FlatButton
              onClick={() => this.setState((oldState) => ({ viewOffre: !oldState.viewOffre }))}
              primary
              label={viewOffre ? fournisseur.nom : 'Afficher les offres'}
            />

          {viewOffre && <div className={`${styles.produitTitre} col-md-12`}>{produit.nom.toUpperCase()}
}

                {viewOffre && <img src={`https://proxiweb.fr/${produit.photo}`} alt={produit.nom} style={{ width: '100%', height: 'auto', maxWidth: 200 }} />}
                {!viewOffre && <img src={`https://proxiweb.fr/${fournisseur.illustration}`} alt={produit.nom} style={{ width: '100%', height: 'auto', maxWidth: 200 }} />}

                {viewOffre &&
}
                {!viewOffre &&
}

        { viewOffre && offres.filter((o) => o.active && o.relaiId === relaiId).map((offre, idx) => {
          const typeProduit = typeProduits.find((typesPdt) => typesPdt.id === produit.typeProduitId);

          return (
            <div key={idx} className={`row ${styles.offre}`} style={{ backgroundColor: muiTheme.palette.groupColor, border: `solid 1px ${muiTheme.palette.groupColorBorder}` }}>

                <Card>
                  <CardHeader
                    actAsExpander
                    showExpandableButton
                    title={<AffichePrix offre={offre} typeProduit={typeProduit} />}
                  >
                  </CardHeader>
                  <CardText expandable>
                    lorem
                  </CardText>
                </Card>

);
        })}

    );
  }
}

const mapStateToProps = createStructuredSelector({
  typeProduits: selectTypesProduitsRelais(),
  offres: selectOffresDuProduit(),
  fournisseurs: selectFournisseursRelais(),
  produits: selectProduitsRelaisByTypeProduit(),
});

export default connect(mapStateToProps)(DetailOffres);
<|endoftext|>


<commit_before>import React, {PropTypes} from "react";
import {connect} from "react-redux";
import {closeTriggerDialog} from "actions/BuildStepTriggerActions.es6";
import "../../../sass/buildStepTrigger.sass";
import R from "ramda";

export class TriggerDialog extends React.Component {

    constructor(props) {
        super(props);
    }

    haveParameter(){
        const {parameter} = this.props;
        return parameter && parameter.length > 0;
    }

    checkValidInput(){
        const getValues = R.map(param => document.getElementById(param.key).value);

        const inputValues = getValues(this.props.parameter);
        const filterValidValues = R.filter(value => value && value !== "");

        return inputValues.length === filterValidValues(inputValues).length;
    }

    executeTrigger(parameter, url) {
        const inputValues = R.map((param) => param.key + "=" + document.getElementById(param.key).value);
        const formatToUrlParm = R.pipe(inputValues, R.toString,R.replace("\", \"", "&"), R.replace("[\"", ""), R.replace("\"]", ""));

        let urlParameter = "";
        if (this.haveParameter()){
            urlParameter = formatToUrlParm(parameter);
        }
        /* eslint-disable */
        console.log("Request URL: " + url + "?" + urlParameter);
        /* eslint-enable */

        // TODO: execute
    }

    renderInputs() {
        if(!this.haveParameter()){
            return null;
        }
        const mapInputFields = R.map((prop) => {
            return

                {prop.name}
                <input type="text" name={prop.key} id={prop.key}/>

;
        });
        return mapInputFields(this.props.parameter);
    }

    renderButton() {
        const {parameter, url, closeTriggerDialog} = this.props;

        if(!this.haveParameter()){
            return null;
        }

        const clickExecute = () => {
            if(this.checkValidInput()){
                this.executeTrigger(parameter, url);
                closeTriggerDialog();
            } else{
                document.getElementById("triggerFailure").innerHTML = "No valid input!";
            }
        };

        return <button className="triggerBtn" onClick={clickExecute}>Start Trigger</button>;
    }

    render() {
        const {showTrigger, closeTriggerDialog, parameter, url} = this.props;

        if (!showTrigger) {
            return null;
        }

        const triggerDialog = (titleText) =>

{titleText}

                {this.renderInputs()}
                {this.renderButton()}

;

        if(!parameter || parameter.length === 0){
            this.executeTrigger(parameter, url);
            return

                {triggerDialog("Start Trigger...")}
                {setTimeout(closeTriggerDialog, 2000)}

;
        }

        return triggerDialog("Step Name");
    }
}

TriggerDialog.propTypes = {
    parameter: PropTypes.array,
    url: PropTypes.string,
    closeTriggerDialog: PropTypes.func.isRequired,
    showTrigger: PropTypes.bool
};

const mapStateToProps = (state) => {
    return state.triggerDialog;
};

const mapDispatchToProps = (dispatch) => {
    return {
        closeTriggerDialog: () => dispatch(closeTriggerDialog())
    };
};

export default connect(mapStateToProps, mapDispatchToProps)(TriggerDialog);<commit_msg>close trigger dialog on escape click<commit_after>import React, {PropTypes} from "react";
import {connect} from "react-redux";
import {closeTriggerDialog} from "actions/BuildStepTriggerActions.es6";
import "../../../sass/buildStepTrigger.sass";
import R from "ramda";

export class TriggerDialog extends React.Component {

    constructor(props) {
        super(props);
    }

    hasParameter(){
        const {parameter} = this.props;
        return parameter && parameter.length > 0;
    }

    closeOnEscClick(){
        document.onkeydown = (evt) => {
            evt = evt || window.event;
            let isEscape = false;
            if ("key" in evt) {
                isEscape = (evt.key === "Escape" || evt.key === "Esc");
            } else {
                isEscape = (evt.keyCode === 27);
            }
            if (isEscape) {
                this.props.closeTriggerDialog();
            }
        };
    }

    checkValidInput(){
        const getValues = R.map(param => document.getElementById(param.key).value);

        const inputValues = getValues(this.props.parameter);
        const filterValidValues = R.filter(value => value && value !== "");

        return inputValues.length === filterValidValues(inputValues).length;
    }

    executeTrigger(parameter, url) {
        const inputValues = R.map((param) => param.key + "=" + document.getElementById(param.key).value);
        const formatToUrlParm = R.pipe(inputValues, R.toString,R.replace("\", \"", "&"), R.replace("[\"", ""), R.replace("\"]", ""));

        let urlParameter = "";
        if (this.hasParameter()){
            urlParameter = formatToUrlParm(parameter);
        }
        /* eslint-disable */
        console.log("Request URL: " + url + "?" + urlParameter);
        /* eslint-enable */

        // TODO: execute
    }

    renderInputs() {
        if(!this.hasParameter()){
            return null;
        }
        const mapInputFields = R.map((prop) => {
            return

                {prop.name}
                <input type="text" name={prop.key} id={prop.key}/>

;
        });
        return mapInputFields(this.props.parameter);
    }

    renderButton() {
        const {parameter, url, closeTriggerDialog} = this.props;

        if(!this.hasParameter()){
            return null;
        }

        const clickExecute = () => {
            if(this.checkValidInput()){
                this.executeTrigger(parameter, url);
                closeTriggerDialog();
            } else{
                document.getElementById("triggerFailure").innerHTML = "No valid input!";
            }
        };

        return <button className="triggerBtn" onClick={clickExecute}>Start Trigger</button>;
    }

    render() {
        const {showTrigger, closeTriggerDialog, parameter, url} = this.props;

        if (!showTrigger) {
            return null;
        }

        this.closeOnEscClick();

        const triggerDialog = (titleText) =>

{titleText}

                {this.renderInputs()}
                {this.renderButton()}

;

        if(!parameter || parameter.length === 0){
            this.executeTrigger(parameter, url);
            return

                {triggerDialog("Start Trigger...")}
                {setTimeout(closeTriggerDialog, 2000)}

;
        }

        return triggerDialog("Step Name");
    }
}

TriggerDialog.propTypes = {
    parameter: PropTypes.array,
    url: PropTypes.string,
    closeTriggerDialog: PropTypes.func.isRequired,
    showTrigger: PropTypes.bool
};

const mapStateToProps = (state) => {
    return state.triggerDialog;
};

const mapDispatchToProps = (dispatch) => {
    return {
        closeTriggerDialog: () => dispatch(closeTriggerDialog())
    };
};

export default connect(mapStateToProps, mapDispatchToProps)(TriggerDialog);<|endoftext|>