<commit_before>import { mat4, vec2, vec3 } from 'gl-matrix';
import requestAnimationFrame from 'raf';
import Input from './Input';
import Shader from './Shader';

class Renderer {
  constructor() {
    const hints = {
      alpha: false,
      antialias: true,
    };
    this.canvas = document.createElement('canvas');
    document.body.appendChild(this.canvas);
    this.context = this.canvas.getContext('webgl', hints) || this.canvas.getContext('experimental-webgl', hints);
    const GL = this.context;
    GL.extensions = {
      VAO: GL.getExtension('OES_vertex_array_object'),
    };
    GL.clearColor(0.9, 0.9, 0.9, 1);
    this.shader = new Shader(GL, 'standard');
    GL.useProgram(this.shader.program);
    this.bounds = {
      min: vec2.create(),
      max: vec2.create(),
    };
    this.viewport = vec2.create();
    this.center = vec2.create();
    this.scale = 0.00001;
    this.renderWireframe = false;
    this.meshes = [];
    window.addEventListener('resize', this.onResize.bind(this));
    this.onResize();
    this.onAnimationFrame = this.onAnimationFrame.bind(this);
    this.onAnimationFrame();
    this.input = new Input(this);
  }
  onResize() {
    const { canvas, context: GL, scale } = this;
    const width = window.innerWidth;
    const height = window.innerHeight;
    const pixelRatio = window.devicePixelRatio || 1;
    canvas.width = width * pixelRatio;
    canvas.height = height * pixelRatio;
    canvas.style.width = `${width}px`;
    canvas.style.height = `${height}px`;
    GL.viewport(0, 0, GL.drawingBufferWidth, GL.drawingBufferHeight);
    this.setScale(scale);
  }
  onAnimationFrame() {
    requestAnimationFrame(this.onAnimationFrame);
    if (!this.needsUpdate) return;
    this.needsUpdate = false;
    this.render();
  }
  toggleWireframe() {
    this.renderWireframe = !this.renderWireframe;
    this.needsUpdate = true;
  }
  render() {
    const { context: GL, meshes, renderWireframe, shader } = this;
    GL.clear(GL.COLOR_BUFFER_BIT);
    meshes.forEach(({ VAO, count, view, albedo, bounds }) => {
      if (!this.isOnBounds(bounds)) return;
      GL.uniformMatrix4fv(shader.uniform('model'), false, view);
      GL.uniform3fv(shader.uniform('albedo'), albedo);
      GL.extensions.VAO.bindVertexArrayOES(VAO);
      GL.drawElements(renderWireframe ? GL.LINE_STRIP : GL.TRIANGLES, count, GL.UNSIGNED_SHORT, 0);
      GL.extensions.VAO.bindVertexArrayOES(null);
    });
  }
  setCenter(center) {
    const { context: GL, shader } = this;
    vec2.copy(this.center, center);
    const view = mat4.fromTranslation(
      mat4.create(),
      vec3.fromValues(-center[0], -center[1], 0)
    );
    GL.uniformMatrix4fv(shader.uniform('view'), false, view);
    this.updateBounds();
    this.needsUpdate = true;
  }
  setScale(scale) {
    const { context: GL, shader, viewport } = this;
    this.scale = scale;
    vec2.set(viewport, GL.drawingBufferWidth * 0.5 * scale, GL.drawingBufferHeight * 0.5 * scale);
    const projection = mat4.ortho(
      mat4.create(),
      viewport[0] * -1.0, viewport[0],
      viewport[1] * -1.0, viewport[1],
      0, 1
    );
    GL.uniformMatrix4fv(shader.uniform('projection'), false, projection);
    this.updateBounds();
    this.needsUpdate = true;
  }
  updateBounds() {
    const { bounds, center, viewport } = this;
    vec2.sub(bounds.min, center, viewport);
    vec2.add(bounds.max, center, viewport);
  }
  isOnBounds(mesh) {
    const { bounds: { min, max } } = this;
    if (min[0] > mesh.max[0]) return false;
    if (min[1] > mesh.max[1]) return false;
    if (max[0] < mesh.min[0]) return false;
    if (max[1] < mesh.min[1]) return false;
    return true;
  }
  addMeshes(meshes, preprocess) {
    meshes.forEach(mesh => this.addMesh(mesh, preprocess));
  }
  addMesh({ vertices, indices, bounds, position, properties }, preprocess = mesh => mesh) {
    const { context: GL, meshes, shader } = this;
    // TODO: [Incomplete] This should be a class?
    const mesh = {
      VAO: GL.extensions.VAO.createVertexArrayOES(),
      vertices: GL.createBuffer(),
      index: GL.createBuffer(),
      count: indices.length,
      view: mat4.fromTranslation(
        mat4.create(),
        vec3.fromValues(position[0], position[1], 0)
      ),
      albedo: vec3.create(),
      bounds,
    };
    GL.extensions.VAO.bindVertexArrayOES(mesh.VAO);
    GL.bindBuffer(GL.ARRAY_BUFFER, mesh.vertices);
    GL.bufferData(GL.ARRAY_BUFFER, vertices, GL.STATIC_DRAW);
    GL.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, mesh.index);
    GL.bufferData(GL.ELEMENT_ARRAY_BUFFER, indices, GL.STATIC_DRAW);
    GL.vertexAttribPointer(
      shader.attribute('position'), 2, GL.FLOAT, false,
      Float32Array.BYTES_PER_ELEMENT * 2, 0
    );
    GL.enableVertexAttribArray(shader.attribute('position'));
    GL.extensions.VAO.bindVertexArrayOES(null);
    meshes.push(preprocess(mesh, properties));
    this.needsUpdate = true;
  }
}

export default new Renderer();
<commit_msg>HighDPI bugfix<commit_after>import { mat4, vec2, vec3 } from 'gl-matrix';
import requestAnimationFrame from 'raf';
import Input from './Input';
import Shader from './Shader';

class Renderer {
  constructor() {
    const hints = {
      alpha: false,
      antialias: true,
    };
    this.canvas = document.createElement('canvas');
    document.body.appendChild(this.canvas);
    this.context = this.canvas.getContext('webgl', hints) || this.canvas.getContext('experimental-webgl', hints);
    const GL = this.context;
    GL.extensions = {
      VAO: GL.getExtension('OES_vertex_array_object'),
    };
    GL.clearColor(0.9, 0.9, 0.9, 1);
    this.shader = new Shader(GL, 'standard');
    GL.useProgram(this.shader.program);
    this.bounds = {
      min: vec2.create(),
      max: vec2.create(),
    };
    this.viewport = vec2.create();
    this.center = vec2.create();
    this.scale = 0.00001;
    this.renderWireframe = false;
    this.meshes = [];
    window.addEventListener('resize', this.onResize.bind(this));
    this.onResize();
    this.onAnimationFrame = this.onAnimationFrame.bind(this);
    this.onAnimationFrame();
    this.input = new Input(this);
  }
  onResize() {
    this.width = window.innerWidth;
    this.height = window.innerHeight;
    const { canvas, context: GL, width, height, scale } = this;
    const pixelRatio = window.devicePixelRatio || 1;
    canvas.width = width * pixelRatio;
    canvas.height = height * pixelRatio;
    canvas.style.width = `${width}px`;
    canvas.style.height = `${height}px`;
    GL.viewport(0, 0, GL.drawingBufferWidth, GL.drawingBufferHeight);
    this.setScale(scale);
  }
  onAnimationFrame() {
    requestAnimationFrame(this.onAnimationFrame);
    if (!this.needsUpdate) return;
    this.needsUpdate = false;
    this.render();
  }
  toggleWireframe() {
    this.renderWireframe = !this.renderWireframe;
    this.needsUpdate = true;
  }
  render() {
    const { context: GL, meshes, renderWireframe, shader } = this;
    GL.clear(GL.COLOR_BUFFER_BIT);
    meshes.forEach(({ VAO, count, view, albedo, bounds }) => {
      if (!this.isOnBounds(bounds)) return;
      GL.uniformMatrix4fv(shader.uniform('model'), false, view);
      GL.uniform3fv(shader.uniform('albedo'), albedo);
      GL.extensions.VAO.bindVertexArrayOES(VAO);
      GL.drawElements(renderWireframe ? GL.LINE_STRIP : GL.TRIANGLES, count, GL.UNSIGNED_SHORT, 0);
      GL.extensions.VAO.bindVertexArrayOES(null);
    });
  }
  setCenter(center) {
    const { context: GL, shader } = this;
    vec2.copy(this.center, center);
    const view = mat4.fromTranslation(
      mat4.create(),
      vec3.fromValues(-center[0], -center[1], 0)
    );
    GL.uniformMatrix4fv(shader.uniform('view'), false, view);
    this.updateBounds();
    this.needsUpdate = true;
  }
  setScale(scale) {
    const { context: GL, shader, viewport, width, height } = this;
    this.scale = scale;
    vec2.set(viewport, width * 0.5 * scale, height * 0.5 * scale);
    const projection = mat4.ortho(
      mat4.create(),
      viewport[0] * -1.0, viewport[0],
      viewport[1] * -1.0, viewport[1],
      0, 1
    );
    GL.uniformMatrix4fv(shader.uniform('projection'), false, projection);
    this.updateBounds();
    this.needsUpdate = true;
  }
  updateBounds() {
    const { bounds, center, viewport } = this;
    vec2.sub(bounds.min, center, viewport);
    vec2.add(bounds.max, center, viewport);
  }
  isOnBounds(mesh) {
    const { bounds: { min, max } } = this;
    if (min[0] > mesh.max[0]) return false;
    if (min[1] > mesh.max[1]) return false;
    if (max[0] < mesh.min[0]) return false;
    if (max[1] < mesh.min[1]) return false;
    return true;
  }
  addMeshes(meshes, preprocess) {
    meshes.forEach(mesh => this.addMesh(mesh, preprocess));
  }
  addMesh({ vertices, indices, bounds, position, properties }, preprocess = mesh => mesh) {
    const { context: GL, meshes, shader } = this;
    // TODO: [Incomplete] This should be a class?
    const mesh = {
      VAO: GL.extensions.VAO.createVertexArrayOES(),
      vertices: GL.createBuffer(),
      index: GL.createBuffer(),
      count: indices.length,
      view: mat4.fromTranslation(
        mat4.create(),
        vec3.fromValues(position[0], position[1], 0)
      ),
      albedo: vec3.create(),
      bounds,
    };
    GL.extensions.VAO.bindVertexArrayOES(mesh.VAO);
    GL.bindBuffer(GL.ARRAY_BUFFER, mesh.vertices);
    GL.bufferData(GL.ARRAY_BUFFER, vertices, GL.STATIC_DRAW);
    GL.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, mesh.index);
    GL.bufferData(GL.ELEMENT_ARRAY_BUFFER, indices, GL.STATIC_DRAW);
    GL.vertexAttribPointer(
      shader.attribute('position'), 2, GL.FLOAT, false,
      Float32Array.BYTES_PER_ELEMENT * 2, 0
    );
    GL.enableVertexAttribArray(shader.attribute('position'));
    GL.extensions.VAO.bindVertexArrayOES(null);
    meshes.push(preprocess(mesh, properties));
    this.needsUpdate = true;
  }
}

export default new Renderer();
<|endoftext|>


<commit_before>function Window2(title){

	var win = Ti.UI.createWindow({
		title: title
	});

	// base view
	var view = Ti.UI.createView({
		layout: 'vertical'
	});
	/* 場所指定
	var ebisu = Ti.Map.createAnnotation({
		latitude: 35.645,
		longitude: 139.71,
		title: "Ebisu",
		animate: true
	});
	*/
	// マップエリア
	var map = Ti.Map.createView({
		mapType: Ti.Map.STANDARD_TYPE,
		region: {latitude: 35.645, longitutde: 139.71, latitudeDelta:0.01, longitudeDelta:0.01},
		animate: true,
		regionFit: false,
		top: 0,
		width: 'auto',
		height: '100%'
	});
	// サーチエリア
	var view_search = Ti.UI.createView({
		layout: 'vertical',
		top: 0,
		height: '30%',
		width: '100%',
		backgroundColor: '#000',
		opacity: 0.5
	});
	// 現在地のテキストフィールド
	var tfPresent = Ti.UI.createTextField({
		color: "#333",
		hintText: "現在地",
		height: 'auto',
		width: '60%',
		top: 10,
		borderStyle: Ti.UI.INPUT_BORDERSTYLE_ROUNDED
	});
	// 目的地のテキストフィールド
	var tfDestination = Ti.UI.createTextField({
		color: "#333",
		hintText: "目的地",
		height: 'auto',
		width: '60%',
		borderStyle: Ti.UI.INPUT_BORDERSTYLE_ROUNDED
	});
	// ヘルプボタン
	var sbmbutton = Ti.UI.createButton({
		title: "HELP!",
		width: '100%',
		height: 'auto'
	});
	// アラート
	var alert = Ti.UI.createAlertDialog({
		title: "HELP?",
		message: "近くの人に助けを求めますか？",
		buttonNames: ["OK","Cancel"],
		cancel: 1
	});
	sbmbutton.addEventListener("click",function(e){
		alert.show();
	});

	view.add(map);
	map.add(view_search);
	view_search.add(tfPresent);
	view_search.add(tfDestination);
	view_search.add(sbmbutton);

	win.add(view);

	return win;
}

module.exports = Window2;<commit_msg>Set line-height of textfield<commit_after>function Window2(title){

	var win = Ti.UI.createWindow({
		title: title
	});

	// base view
	var view = Ti.UI.createView({
		layout: 'vertical'
	});
	/* 場所指定
	var ebisu = Ti.Map.createAnnotation({
		latitude: 35.645,
		longitude: 139.71,
		title: "Ebisu",
		animate: true
	});
	*/
	// マップエリア
	var map = Ti.Map.createView({
		mapType: Ti.Map.STANDARD_TYPE,
		region: {latitude: 35.645, longitutde: 139.71, latitudeDelta:0.01, longitudeDelta:0.01},
		animate: true,
		regionFit: false,
		top: 0,
		width: 'auto',
		height: '100%'
	});
	// サーチエリア
	var view_search = Ti.UI.createView({
		layout: 'vertical',
		top: 0,
		height: '30%',
		width: '100%',
		backgroundColor: '#000',
		opacity: 0.5
	});
	// 現在地のテキストフィールド
	var tfPresent = Ti.UI.createTextField({
		color: "#333",
		hintText: "現在地",
		height: 'auto',
		width: '60%',
		top: 10,
		borderStyle: Ti.UI.INPUT_BORDERSTYLE_ROUNDED
	});
	// 目的地のテキストフィールド
	var tfDestination = Ti.UI.createTextField({
		color: "#333",
		hintText: "目的地",
		height: 'auto',
		width: '60%',
		top: 10,
		borderStyle: Ti.UI.INPUT_BORDERSTYLE_ROUNDED
	});
	// ヘルプボタン
	var sbmbutton = Ti.UI.createButton({
		title: "HELP!",
		width: '100%',
		height: 'auto'
	});
	// アラート
	var alert = Ti.UI.createAlertDialog({
		title: "HELP?",
		message: "近くの人に助けを求めますか？",
		buttonNames: ["OK","Cancel"],
		cancel: 1
	});
	sbmbutton.addEventListener("click",function(e){
		alert.show();
	});

	view.add(map);
	map.add(view_search);
	view_search.add(tfPresent);
	view_search.add(tfDestination);
	view_search.add(sbmbutton);

	win.add(view);

	return win;
}

module.exports = Window2;<|endoftext|>


<commit_before>module('lively.ast.StackReification').requires('lively.ast.AcornInterpreter').toRun(function() {

lively.Closure.subclass('lively.ast.RewrittenClosure',
'initializing', {

    initialize: function($super, func, varMapping, source) {
        $super(func, varMapping, source);
        this.ast = null;
    }

},
'accessing', {

    getRewrittenFunc: function() {
        // FIXME: should be:
        // return this.recreateFuncFromSource(this.getRewrittenSource());
        var func = eval(this.getRewrittenSource());
        func.livelyDebuggingEnabled = true;
        return func;
    },

    getRewrittenSource: function() {
        return this.ast && escodegen.generate(this.ast);
    },

    getOriginalFunc: function() {
        return this.addClosureInformation(this.getFunc());
    }
},
'rewriting', {

    rewrite: function(astRegistry) {
        var src = this.getFuncSource(),
            ast = lively.ast.acorn.parseFunction(src);
        return this.ast = lively.ast.Rewriting.rewriteFunction(ast, astRegistry);
    }

});

Object.extend(lively.ast.StackReification, {

    halt: function() {
        var frame = lively.ast.Interpreter.Frame.create();
        throw {isUnwindException: true, lastFrame: frame, topFrame: frame}
    },

    run: function(func, astRegistry) {
        if (!func.livelyDebuggingEnabled) func = func.stackCaptureMode(null, astRegistry);
        var result;
        try { return {isContinuation: false, returnValue: func()} } catch(e) {
            return e.isUnwindException ?
                lively.ast.Continuation.fromUnwindException(e) : e
        }
    }
});

Object.extend(Global, {
    catchUnwind: lively.ast.StackReification.run,
    halt: lively.ast.StackReification.halt,
    // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

    __createClosure: function(idx, scope, f) {
        f._cachedAst = lively.ast.Rewriting.getCurrentASTRegistry()[idx];
        f._cachedScope = scope;
        f.livelyDebuggingEnabled = true;
        return f;
    },

    __getClosure: function(idx) {
        return lively.ast.Rewriting.getCurrentASTRegistry()[idx];
    }
});

Object.extend(Function.prototype, {

    asRewrittenClosure: function(varMapping, astRegistry) {
        var closure = new lively.ast.RewrittenClosure(this, varMapping);
        closure.rewrite(astRegistry);
        return closure;
    },

    stackCaptureMode: function(varMapping, astRegistry) {
        var closure = this.asRewrittenClosure(varMapping, astRegistry),
            rewrittenFunc = closure.getRewrittenFunc();
        if (!rewrittenFunc) throw new Error('Cannot rewrite ' + this);
        return rewrittenFunc;
    },

    stackCaptureSource: function(varMapping, astRegistry) {
        return this.asRewrittenClosure(astRegistry).getRewrittenSource();
    }
});

Object.subclass('lively.ast.Continuation',
'settings', {
    isContinuation: true
},
'initializing', {
    initialize: function(frame) {
        this.currentFrame = frame; // the frame in which the the unwind was triggered
    },

    copy: function() {
        return new this.constructor(this.currentFrame.copy());
    }
},
'accessing', {
    frames: function() {
        var frame = this.currentFrame, result = [];
        do {
            if (frame.func)
                result.push(frame);
        } while (frame = frame.getContainingScope());
        return result;
    }
},
'resuming', {
    resume: function() {
        // FIXME: outer context usually does not have original AST
        // attaching the program node would possibly be right (otherwise the pc's context is missing)
        if (!this.currentFrame.getOriginalAst())
            throw new Error('Cannot resume because frame has no AST!');
        if (!this.currentFrame.pc)
            throw new Error('Cannot resume because frame has no pc!');

        var isComputed = false,
            interpreter = new lively.ast.AcornInterpreter.Interpreter();

        // go through all frames on the stack. beginning with the top most,
        // resume each of them
        return this.frames().reduce(function(result, frame) {
            var originalAst = frame.getOriginalAst(); // FIXME
            // frame.setComputedPC(isComputed);
            isComputed = true; // all outer scopes should not recompute
            if (isComputed) {
                frame.alreadyComputed[frame.pc.astIndex] = result;
            }
            // FIXME frames hold on to function ASTs but resuming from a
            // function is not supported right now. So we set the resumable
            // node to the functions body here as a quick fix
            var resumeNode = frame.getOriginalAst().body;
            return interpreter.runWithFrameAndResult(resumeNode, frame, result);
        }, undefined);
    }
});

Object.extend(lively.ast.Continuation, {
    fromUnwindException: function(e) {
        if (!e.isUnwindException) console.error("No unwind exception?");
        return new this(e.top);
    }
});

Object.subclass('lively.ast.Rewriting.UnwindException',
'settings', {
    isUnwindException: true
},
'initializing', {
    initialize: function(error) {
        this.error = error;
    }
},
'printing', {
    toString: function() {
        return '[UNWIND] ' + this.error.toString();
    }
},
'frames', {
    shiftFrame: function(thiz, frameState, lastNodeAstIndex, pointerToOriginalAst) {
        var alreadyComputed = frameState[0],
            varMapping = frameState[1],
            parentFrameState = frameState[2],
            parentScope = parentFrameState[1],
            parentFunc = null, // FIXME: determine AST parentFunc ... actually not necessary.
            frame = lively.ast.AcornInterpreter.Frame.create(
                __getClosure(pointerToOriginalAst), varMapping);
        frame.setThis(thiz);
        frame.setAlreadyComputed(alreadyComputed);
        if (!this.top) {
            this.top = this.last = frame;
            var pc = this.error && this.error.astIndex ?
                acorn.walk.findNodeByAstIndex(frame.getOriginalAst(), this.error.astIndex) :
                null;
            frame.setPC(pc);
            // FIXME: assemble real lexical scope -- Frame objects represent
            // call stack frames, not scopes!
            if (parentFrameState[2] !== Global)
                frame.setContainingScope(lively.ast.AcornInterpreter.Frame.create(parentFunc, parentScope));
        } else {
            // this.last.calledFrame = frameState;
            var pc = acorn.walk.findNodeByAstIndex(frame.getOriginalAst(), lastNodeAstIndex);
            frame.setPC(pc);
            this.last.setContainingScope(frame);
            this.last = frame;
        }
        return frame;
    }
});

}) // end of module
<commit_msg>debugging: when we have the result of an expression when unwinding then set the pc to the following node<commit_after>module('lively.ast.StackReification').requires('lively.ast.AcornInterpreter').toRun(function() {

lively.Closure.subclass('lively.ast.RewrittenClosure',
'initializing', {

    initialize: function($super, func, varMapping, source) {
        $super(func, varMapping, source);
        this.ast = null;
    }

},
'accessing', {

    getRewrittenFunc: function() {
        // FIXME: should be:
        // return this.recreateFuncFromSource(this.getRewrittenSource());
        var func = eval(this.getRewrittenSource());
        func.livelyDebuggingEnabled = true;
        return func;
    },

    getRewrittenSource: function() {
        return this.ast && escodegen.generate(this.ast);
    },

    getOriginalFunc: function() {
        return this.addClosureInformation(this.getFunc());
    }
},
'rewriting', {

    rewrite: function(astRegistry) {
        var src = this.getFuncSource(),
            ast = lively.ast.acorn.parseFunction(src);
        return this.ast = lively.ast.Rewriting.rewriteFunction(ast, astRegistry);
    }

});

Object.extend(lively.ast.StackReification, {

    halt: function() {
        var frame = lively.ast.Interpreter.Frame.create();
        throw {isUnwindException: true, lastFrame: frame, topFrame: frame}
    },

    run: function(func, astRegistry) {
        if (!func.livelyDebuggingEnabled) func = func.stackCaptureMode(null, astRegistry);
        var result;
        try { return {isContinuation: false, returnValue: func()} } catch(e) {
            return e.isUnwindException ?
                lively.ast.Continuation.fromUnwindException(e) : e
        }
    }
});

Object.extend(Global, {
    catchUnwind: lively.ast.StackReification.run,
    halt: lively.ast.StackReification.halt,
    // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

    __createClosure: function(idx, scope, f) {
        f._cachedAst = lively.ast.Rewriting.getCurrentASTRegistry()[idx];
        f._cachedScope = scope;
        f.livelyDebuggingEnabled = true;
        return f;
    },

    __getClosure: function(idx) {
        return lively.ast.Rewriting.getCurrentASTRegistry()[idx];
    }
});

Object.extend(Function.prototype, {

    asRewrittenClosure: function(varMapping, astRegistry) {
        var closure = new lively.ast.RewrittenClosure(this, varMapping);
        closure.rewrite(astRegistry);
        return closure;
    },

    stackCaptureMode: function(varMapping, astRegistry) {
        var closure = this.asRewrittenClosure(varMapping, astRegistry),
            rewrittenFunc = closure.getRewrittenFunc();
        if (!rewrittenFunc) throw new Error('Cannot rewrite ' + this);
        return rewrittenFunc;
    },

    stackCaptureSource: function(varMapping, astRegistry) {
        return this.asRewrittenClosure(astRegistry).getRewrittenSource();
    }
});

Object.subclass('lively.ast.Continuation',
'settings', {
    isContinuation: true
},
'initializing', {
    initialize: function(frame) {
        this.currentFrame = frame; // the frame in which the the unwind was triggered
    },

    copy: function() {
        return new this.constructor(this.currentFrame.copy());
    }
},
'accessing', {
    frames: function() {
        var frame = this.currentFrame, result = [];
        do {
            if (frame.func)
                result.push(frame);
        } while (frame = frame.getContainingScope());
        return result;
    }
},
'resuming', {
    resume: function() {
        // FIXME: outer context usually does not have original AST
        // attaching the program node would possibly be right (otherwise the pc's context is missing)
        if (!this.currentFrame.getOriginalAst())
            throw new Error('Cannot resume because frame has no AST!');
        if (!this.currentFrame.pc)
            throw new Error('Cannot resume because frame has no pc!');

        var isComputed = false,
            interpreter = new lively.ast.AcornInterpreter.Interpreter();

        // go through all frames on the stack. beginning with the top most,
        // resume each of them
        return this.frames().reduce(function(result, frame, i) {
            var originalAst = frame.getOriginalAst(); // FIXME
            // frame.setComputedPC(isComputed);
            isComputed = true; // all outer scopes should not recompute
            if (isComputed) {
                frame.alreadyComputed[frame.pc.astIndex] = result;
            }
            // FIXME frames hold on to function ASTs but resuming from a
            // function is not supported right now. So we set the resumable
            // node to the functions body here as a quick fix
            var resumeNode = frame.getOriginalAst().body;
            return interpreter.runWithFrameAndResult(resumeNode, frame, result);
        }, undefined);
    }
});

Object.extend(lively.ast.Continuation, {
    fromUnwindException: function(e) {
        if (!e.isUnwindException) console.error("No unwind exception?");
        return new this(e.top);
    }
});

Object.subclass('lively.ast.Rewriting.UnwindException',
'settings', {
    isUnwindException: true
},
'initializing', {
    initialize: function(error) {
        this.error = error;
    }
},
'printing', {
    toString: function() {
        return '[UNWIND] ' + this.error.toString();
    }
},
'frames', {
    shiftFrame: function(thiz, frameState, lastNodeAstIndex, pointerToOriginalAst) {
        var alreadyComputed = frameState[0],
            varMapping = frameState[1],
            parentFrameState = frameState[2],
            parentScope = parentFrameState[1],
            parentFunc = null, // FIXME: determine AST parentFunc ... actually not necessary.
            frame = lively.ast.AcornInterpreter.Frame.create(
                __getClosure(pointerToOriginalAst), varMapping);
        frame.setThis(thiz);
        frame.setAlreadyComputed(alreadyComputed);
        if (!this.top) {
            this.top = this.last = frame;
            var pc = this.error && this.error.astIndex ?
                acorn.walk.findNodeByAstIndex(frame.getOriginalAst(), this.error.astIndex) :
                null;
            frame.setPC(pc);
            // FIXME: assemble real lexical scope -- Frame objects represent
            // call stack frames, not scopes!
            if (parentFrameState[2] !== Global)
                frame.setContainingScope(lively.ast.AcornInterpreter.Frame.create(parentFunc, parentScope));
        } else {
            if (frame.isAlreadyComputed(lastNodeAstIndex)) lastNodeAstIndex++;
            var pc = acorn.walk.findNodeByAstIndex(frame.getOriginalAst(), lastNodeAstIndex);
            frame.setPC(pc);
            this.last.setContainingScope(frame);
            this.last = frame;
        }
        return frame;
    }
});

}) // end of module
<|endoftext|>


<commit_before>'use strict';

// Datacollectors controller
angular.module('datacollectors').controller('AdminController', ['$scope', '$http', '$stateParams', '$location', 'Authentication', 'Datacollectors',
    function($scope, $http, $stateParams, $location, Authentication, Datacollectors) {
        $scope.authentication = Authentication;

        $scope.users;

        $scope.roles;

        $scope.accessRequests;

        $scope.requestedRoles;

        $scope.userEmail;

        $scope.userDisplayName;

        $scope.selectedRoles = [];

        function getUsers(){
            $http({
                method: 'GET',
                url: '/users'
            }).success(function(data){
                $scope.users = data;
            }).error(function(){
                alert('error');
            });
        }

        function getRoles(){
            $http({
                method: 'GET',
                url: '/roles'
            }).success(function(data){
                $scope.roles = data;
            }).error(function(){
                alert('error');
            });
        }

        function getAccessRequests(){
            $http({
                method: 'GET',
                url: '/access_requests_listing'
            }).success(function(data){
                $scope.accessRequests = data;
            }).error(function(){
                alert('error');
            });
        }

        $scope.grantSelectedRolesToSelectedUsers = function(){
            if($scope.userDisplayName){
                $scope.selectedRoles.forEach(function(role){
                    var json = {
                        requestedRoles: $scope.selectedRoles,
                        userEmail:  $scope.userEmail
                    };
                    $http.post('/grant_requested_roles', json)
                        .success(function(data, status, headers, config) {

                        }).
                        error(function(data, status, headers, config) {
                            alert('Error while granting requested roles');
                        });
                })
            }
        };

        $scope.generatePlaycardsFromDcInventory = function(){
            $http.post('/generate_playcards', {})
                .success(function(data, status, headers, config) {

                }).
                error(function(data, status, headers, config) {
                    alert('Error while generating Playcards');
                });
        };

        $scope.grantRequestedRoles = function(){
          //alert('Granting roles: ' + $scope.requestedRoles + '  to  ' + $scope.userEmail);
            var json = {
                requestedRoles: $scope.requestedRoles,
                userEmail:  $scope.userEmail
            };
            $http.post('/grant_requested_roles', json)
                .success(function(data, status, headers, config) {

                }).
                error(function(data, status, headers, config) {
                    alert('Error while granting requested roles');
                });
        };

        $scope.removeSelectedAccessRequest = function(){
            if($scope.userEmail){
                var json = {email: $scope.userEmail};
                $http.post('/remove_access_request', json)
                    .success(function(data, status, headers, config) {
                        for(var i = 0; i < $scope.accessRequests.length; i++) {
                            if($scope.accessRequests[i].email == $scope.userEmail) {
                                $scope.accessRequests.splice(i, 1);
                                break;
                            }
                        }
                    }).
                    error(function(data, status, headers, config) {
                        alert('Error while granting requested roles');
                    });
            }
        };

        $scope.removeSelectedUsers = function(){
            if($scope.userEmail){
                var json = {email: $scope.userEmail};
                $http.post('/remove_users', json)
                    .success(function(data, status, headers, config) {
                        for(var i = 0; i < $scope.users.length; i++) {
                            if($scope.users[i].Email == $scope.userEmail) {
                                $scope.users.splice(i, 1);
                                break;
                            }
                        }
                    }).
                    error(function(data, status, headers, config) {
                        alert('Error while granting requested roles');
                    });
            }
        };

        getUsers();
        getRoles();
        getAccessRequests();

        $scope.usersGridOptions = {
            bindingOptions: {
                dataSource: 'users',
                columns: 'collectionDatafields'
            },
            grouping: {
                autoExpandAll: true
            },
            groupPanel: {
                visible: true
            },
            filterRow: {
                visible: true,
                applyFilter: 'auto'
            },
            searchPanel: {
                visible: true,
                width: 240,
                placeholder: 'Search...'
            },
            paging: {
                enabled: true,
                pageSize: 10
            },
            pager: {
                showPageSizeSelector: true,
                allowedPageSizes: [5, 10, 20]
            },
            rowAlternationEnabled: true,
            allowColumnReordering: true,
            allowColumnResizing: true,
            columnAutoWidth: true,
            columnChooser:  {
                enabled: true

            },
            selection: {
                mode: 'single'
            },
            onSelectionChanged: function (selecteditems) {
                var data = selecteditems.selectedRowsData;
                if (data.length > 0) {
                    $scope.userEmail = data[0].Email;
                    $scope.userDisplayName = data[0].DisplayName;
                }
                else {

                }
            }
        };

        $scope.rolesGridOptions = {
            bindingOptions: {
                dataSource: 'roles',
                columns: 'collectionDatafields'
            },
            grouping: {
                autoExpandAll: true
            },
            groupPanel: {
                visible: true
            },
            filterRow: {
                visible: true,
                applyFilter: 'auto'
            },
            searchPanel: {
                visible: true,
                width: 240,
                placeholder: 'Search...'
            },
            paging: {
                enabled: true,
                pageSize: 10
            },
            pager: {
                showPageSizeSelector: true,
                allowedPageSizes: [5, 10, 20]
            },
            rowAlternationEnabled: true,
            allowColumnReordering: true,
            allowColumnResizing: true,
            columnAutoWidth: true,
            columnChooser:  {
                enabled: true

            },
            selection: {
                mode: 'multiple'
            },
            onSelectionChanged: function (selecteditems) {
                var data = selecteditems.selectedRowsData;
                if (data.length > 0) {
                    $scope.selectedRoles.push(data[0].name);
                }
                else {

                }
            }
        };

        $scope.accessRequestsGridOptions = {
            bindingOptions: {
                dataSource: 'accessRequests',
                columns: 'collectionDatafields'
            },
            grouping: {
                autoExpandAll: true
            },
            groupPanel: {
                visible: true
            },
            filterRow: {
                visible: true,
                applyFilter: 'auto'
            },
            searchPanel: {
                visible: true,
                width: 240,
                placeholder: 'Search...'
            },
            paging: {
                enabled: true,
                pageSize: 10
            },
            pager: {
                showPageSizeSelector: true,
                allowedPageSizes: [5, 10, 20]
            },
            rowAlternationEnabled: true,
            allowColumnReordering: true,
            allowColumnResizing: true,
            columnAutoWidth: true,
            columnChooser:  {
                enabled: true

            },
            selection: {
                mode: 'multiple'
            },

            onSelectionChanged: function (selecteditems) {
                var data = selecteditems.selectedRowsData;
                if(data.length > 0){
                    //for(var prop in data[0]){
                    //    console.log('selected requests prop: ' + prop + '  selected requests value: ' + data[0][prop]);
                    //}

                    $scope.requestedRoles = data[0].RequestedRoles;
                    $scope.userEmail = data[0].email;

                }
                else {

                }

            }
        };
    }
]);

<commit_msg>added explicit notification of a succsessful role being granted<commit_after>'use strict';

// Datacollectors controller
angular.module('datacollectors').controller('AdminController', ['$scope', '$http', '$stateParams', '$location', 'Authentication', 'Datacollectors',
    function($scope, $http, $stateParams, $location, Authentication, Datacollectors) {
        $scope.authentication = Authentication;

        $scope.users;

        $scope.roles;

        $scope.accessRequests;

        $scope.requestedRoles;

        $scope.userEmail;

        $scope.userDisplayName;

        $scope.selectedRoles = [];

        function getUsers(){
            $http({
                method: 'GET',
                url: '/users'
            }).success(function(data){
                $scope.users = data;
            }).error(function(){
                alert('error');
            });
        }

        function getRoles(){
            $http({
                method: 'GET',
                url: '/roles'
            }).success(function(data){
                $scope.roles = data;
            }).error(function(){
                alert('error');
            });
        }

        function getAccessRequests(){
            $http({
                method: 'GET',
                url: '/access_requests_listing'
            }).success(function(data){
                $scope.accessRequests = data;
            }).error(function(){
                alert('error');
            });
        }

        $scope.grantSelectedRolesToSelectedUsers = function(){
            if($scope.userDisplayName){
                $scope.selectedRoles.forEach(function(role){
                    var json = {
                        requestedRoles: $scope.selectedRoles,
                        userEmail:  $scope.userEmail
                    };
                    $http.post('/grant_requested_roles', json)
                        .success(function(data, status, headers, config) {

                        }).
                        error(function(data, status, headers, config) {
                            alert('Error while granting requested roles');
                        });
                })
            }
        };

        $scope.generatePlaycardsFromDcInventory = function(){
            $http.post('/generate_playcards', {})
                .success(function(data, status, headers, config) {

                }).
                error(function(data, status, headers, config) {
                    alert('Error while generating Playcards');
                });
        };

        $scope.grantRequestedRoles = function(){
          //alert('Granting roles: ' + $scope.requestedRoles + '  to  ' + $scope.userEmail);
            var json = {
                requestedRoles: $scope.requestedRoles,
                userEmail:  $scope.userEmail
            };
            $http.post('/grant_requested_roles', json)
                .success(function(data, status, headers, config) {
                        alert('Requested roles have been successfully granted');
                    for(var i = 0; i < $scope.accessRequests.length; i++) {
                        if($scope.accessRequests[i].email == $scope.userEmail) {
                            $scope.accessRequests.splice(i, 1);
                            break;
                        }
                    }
                }).
                error(function(data, status, headers, config) {
                    alert('Error while granting requested roles');
                });
        };

        $scope.removeSelectedAccessRequest = function(){
            if($scope.userEmail){
                var json = {email: $scope.userEmail};
                $http.post('/remove_access_request', json)
                    .success(function(data, status, headers, config) {
                        for(var i = 0; i < $scope.accessRequests.length; i++) {
                            if($scope.accessRequests[i].email == $scope.userEmail) {
                                $scope.accessRequests.splice(i, 1);
                                break;
                            }
                        }
                    }).
                    error(function(data, status, headers, config) {
                        alert('Error while granting requested roles');
                    });
            }
        };

        $scope.removeSelectedUsers = function(){
            if($scope.userEmail){
                var json = {email: $scope.userEmail};
                $http.post('/remove_users', json)
                    .success(function(data, status, headers, config) {
                        for(var i = 0; i < $scope.users.length; i++) {
                            if($scope.users[i].Email == $scope.userEmail) {
                                $scope.users.splice(i, 1);
                                break;
                            }
                        }
                    }).
                    error(function(data, status, headers, config) {
                        alert('Error while granting requested roles');
                    });
            }
        };

        getUsers();
        getRoles();
        getAccessRequests();

        $scope.usersGridOptions = {
            bindingOptions: {
                dataSource: 'users',
                columns: 'collectionDatafields'
            },
            grouping: {
                autoExpandAll: true
            },
            groupPanel: {
                visible: true
            },
            filterRow: {
                visible: true,
                applyFilter: 'auto'
            },
            searchPanel: {
                visible: true,
                width: 240,
                placeholder: 'Search...'
            },
            paging: {
                enabled: true,
                pageSize: 10
            },
            pager: {
                showPageSizeSelector: true,
                allowedPageSizes: [5, 10, 20]
            },
            rowAlternationEnabled: true,
            allowColumnReordering: true,
            allowColumnResizing: true,
            columnAutoWidth: true,
            columnChooser:  {
                enabled: true

            },
            selection: {
                mode: 'single'
            },
            onSelectionChanged: function (selecteditems) {
                var data = selecteditems.selectedRowsData;
                if (data.length > 0) {
                    $scope.userEmail = data[0].Email;
                    $scope.userDisplayName = data[0].DisplayName;
                }
                else {

                }
            }
        };

        $scope.rolesGridOptions = {
            bindingOptions: {
                dataSource: 'roles',
                columns: 'collectionDatafields'
            },
            grouping: {
                autoExpandAll: true
            },
            groupPanel: {
                visible: true
            },
            filterRow: {
                visible: true,
                applyFilter: 'auto'
            },
            searchPanel: {
                visible: true,
                width: 240,
                placeholder: 'Search...'
            },
            paging: {
                enabled: true,
                pageSize: 10
            },
            pager: {
                showPageSizeSelector: true,
                allowedPageSizes: [5, 10, 20]
            },
            rowAlternationEnabled: true,
            allowColumnReordering: true,
            allowColumnResizing: true,
            columnAutoWidth: true,
            columnChooser:  {
                enabled: true

            },
            selection: {
                mode: 'multiple'
            },
            onSelectionChanged: function (selecteditems) {
                var data = selecteditems.selectedRowsData;
                if (data.length > 0) {
                    $scope.selectedRoles.push(data[0].name);
                }
                else {

                }
            }
        };

        $scope.accessRequestsGridOptions = {
            bindingOptions: {
                dataSource: 'accessRequests',
                columns: 'collectionDatafields'
            },
            grouping: {
                autoExpandAll: true
            },
            groupPanel: {
                visible: true
            },
            filterRow: {
                visible: true,
                applyFilter: 'auto'
            },
            searchPanel: {
                visible: true,
                width: 240,
                placeholder: 'Search...'
            },
            paging: {
                enabled: true,
                pageSize: 10
            },
            pager: {
                showPageSizeSelector: true,
                allowedPageSizes: [5, 10, 20]
            },
            rowAlternationEnabled: true,
            allowColumnReordering: true,
            allowColumnResizing: true,
            columnAutoWidth: true,
            columnChooser:  {
                enabled: true

            },
            selection: {
                mode: 'multiple'
            },

            onSelectionChanged: function (selecteditems) {
                var data = selecteditems.selectedRowsData;
                if(data.length > 0){
                    //for(var prop in data[0]){
                    //    console.log('selected requests prop: ' + prop + '  selected requests value: ' + data[0][prop]);
                    //}

                    $scope.requestedRoles = data[0].RequestedRoles;
                    $scope.userEmail = data[0].email;

                }
                else {

                }

            }
        };
    }
]);

<|endoftext|>


<commit_before>Ti.include('/util.js');
Ti.UI.currentWindow.add(
	createClubTable()
);<commit_msg>on click > green<commit_after>Ti.include('/util.js');

var table = createClubTable();
table.addEventListener('click',function(e){
	e.rowData.backgroundColor = '#00FF00';
});
Ti.UI.currentWindow.add(table);
<|endoftext|>


<commit_before>//
/**
 * Created by tungtouch on 2/9/15.
 */

var cluster = require('cluster');
var numCPUs = require('os').cpus().length;
var colors = require('colors');
var dgram = require('dgram');
var message = new Buffer("Some bytes hello world bo bo bo world HEHEHEHE ahhaha hohoho hehe:");
var client = dgram.createSocket("udp4");
var async = require('async');

var max = 1000;
var serverUDP = "128.199.126.250"; //128.199.126.250
var port = 4343;
var numCluster = 100;
var maxReq = max * numCluster;
var arr = [];

for (var i = 0; i < max; i++) {
    arr.push(i);
}
var a = 0;

//[2GB]128.199.126.250 [8GB]128.199.109.202

if (cluster.isMaster) {

    // Keep track of http requests
    var numReqs = 0;
    var totalReqs = 0;
    var second = 0;

    setInterval(function() {
        console.log(
            colors.red("Gói tin/s: ", numReqs), " | ",
            colors.yellow("Tổng gói tin: ", totalReqs), " | ",
            colors.blue("Thời gian: ", second++ +"s"));
        numReqs = 0;
        if(totalReqs == maxReq) {
            console.log(colors.cyan("\n-------------------------------"));
            console.log("Tổng thời gian: ", second-1 + "s", " | Tổng số gói tin:", totalReqs);
            console.log(colors.cyan("Kết quả hệ thống: ", colors.bold(totalReqs / second)), " Thiết bị/giây ! \n");

            process.exit(1);
        }
    }, 1000);

    // Count requestes
    function messageHandler(msg) {
        if (msg.cmd && msg.cmd == 'notifyRequest') {
            numReqs += 1;
            totalReqs +=1;
        }
    }

    // Start workers and listen for messages containing notifyRequest

    for (var i = 0; i < numCluster; i++) {
        cluster.fork();
    }

    Object.keys(cluster.workers).forEach(function(id) {
        cluster.workers[id].on('message', messageHandler);
    });

} else {
    var q = async.queue(function(index, cb){
        //console.log("Index: ", index);
        setTimeout(function () {
            client.send(message, 0, message.length, port, serverUDP, function (err) {
                //console.log("Request : ", a++);
                process.send({ cmd: 'notifyRequest' });
                if(err){
                    console.log('ERROR :', err);
                }
                cb(err);
            });
        }, 10);
    });

    q.push(arr);

}<commit_msg>Update UDPefef<commit_after>//
/**
 * Created by tungtouch on 2/9/15.
 */

var cluster = require('cluster');
var numCPUs = require('os').cpus().length;
var colors = require('colors');
var dgram = require('dgram');
var message = new Buffer("Some bytes hello world bo bo bo world HEHEHEHE ahhaha hohoho hehe:");
var client = dgram.createSocket("udp4");
var async = require('async');

var max = 1000;
var serverUDP = "128.199.126.250"; //128.199.126.250
var port = 4343;
var numCluster = 150;
var maxReq = max * numCluster;
var arr = [];

for (var i = 0; i < max; i++) {
    arr.push(i);
}
var a = 0;

//[2GB]128.199.126.250 [8GB]128.199.109.202

if (cluster.isMaster) {

    // Keep track of http requests
    var numReqs = 0;
    var totalReqs = 0;
    var second = 0;

    setInterval(function() {
        console.log(
            colors.red("Gói tin/s: ", numReqs), " | ",
            colors.yellow("Tổng gói tin: ", totalReqs), " | ",
            colors.blue("Thời gian: ", second++ +"s"));
        numReqs = 0;
        if(totalReqs == maxReq) {
            console.log(colors.cyan("\n-------------------------------"));
            console.log("Tổng thời gian: ", second-1 + "s", " | Tổng số gói tin:", totalReqs);
            console.log(colors.cyan("Kết quả hệ thống: ", colors.bold(totalReqs / second)), " Thiết bị/giây ! \n");

            process.exit(1);
        }
    }, 1000);

    // Count requestes
    function messageHandler(msg) {
        if (msg.cmd && msg.cmd == 'notifyRequest') {
            numReqs += 1;
            totalReqs +=1;
        }
    }

    // Start workers and listen for messages containing notifyRequest

    for (var i = 0; i < numCluster; i++) {
        cluster.fork();
    }

    Object.keys(cluster.workers).forEach(function(id) {
        cluster.workers[id].on('message', messageHandler);
    });

} else {
    var q = async.queue(function(index, cb){
        //console.log("Index: ", index);
        setTimeout(function () {
            client.send(message, 0, message.length, port, serverUDP, function (err) {
                //console.log("Request : ", a++);
                process.send({ cmd: 'notifyRequest' });
                if(err){
                    console.log('ERROR :', err);
                }
                cb(err);
            });
        }, 10);
    });

    q.push(arr);

}<|endoftext|>


<commit_before>'use strict';

function Fraction(n, d) {
  if (n % d == 0) {
    this.n = n / d;
    this.d = 1;
    return;
  }

  // REVIEW
  // WHAT IS THIS???
  for (var i = d; i >= 2; i--) {
    if (n % i == 0 && d % i == 0) {
      this.n = n / i;
      this.d = d / i;
      return;
    }
  }

  this.n = n;
  this.d = d;
}

Fraction.prototype.numerator = function () {
  return this.n;
};

Fraction.prototype.denominator = function () {
  return this.d;
};

Fraction.prototype.add = function (fraction) {
  if (this.d === fraction.d) {
    return new Fraction(this.n + fraction.n, this.d);
  }

// TODO REVIEW
// NOT NECESSARY! Optimization
//   if (this.d % fraction.d == 0 || fraction.d % this.d == 0) {
//
//     if (this.d > fraction.d) {
//       return new Fraction(this.n + fraction.n * (this.d / fraction.d), this.d);
//     }
//     else {
//       return new Fraction(fraction.n + this.n * (fraction.d / this.d), fraction.d);
//     }
//   }

  return new Fraction(this.n * fraction.d
    + fraction.n * this.d,
    this.d * fraction.d);

};

module.exports = Fraction; <commit_msg>added biggestCommonDivisor function<commit_after>'use strict';

function findBiggestCommonDivisor(n, d) {
  for (var i = d; i >= 2; i--) {
    if (n % i == 0 && d % i == 0) {
      return i;
    }
  }
  return 0;
}

function Fraction(n, d) {
  if (n % d == 0) {
    this.n = n / d;
    this.d = 1;
    return;
  }

  var biggestCommonDivisor = findBiggestCommonDivisor(n,d);
  if (biggestCommonDivisor > 0){
      this.n = n / biggestCommonDivisor;
      this.d = d / biggestCommonDivisor;
      return;
  }

  this.n = n;
  this.d = d;
}

Fraction.prototype.numerator = function () {
  return this.n;
};

Fraction.prototype.denominator = function () {
  return this.d;
};

Fraction.prototype.add = function (fraction) {
  if (this.d === fraction.d) {
    return new Fraction(this.n + fraction.n, this.d);
  }

// TODO REVIEW
// NOT NECESSARY! Optimization
//   if (this.d % fraction.d == 0 || fraction.d % this.d == 0) {
//
//     if (this.d > fraction.d) {
//       return new Fraction(this.n + fraction.n * (this.d / fraction.d), this.d);
//     }
//     else {
//       return new Fraction(fraction.n + this.n * (fraction.d / this.d), fraction.d);
//     }
//   }

  return new Fraction(this.n * fraction.d
    + fraction.n * this.d,
    this.d * fraction.d);

};

module.exports = Fraction; <|endoftext|>


<commit_before>import Ember from 'ember';
import config from './config/environment';

const Router = Ember.Router.extend({
  location: config.locationType
});

Router.map(function() {
  // Edit forms & list forms.
  this.route('ember-flexberry-dummy-application-user-list');
  this.route('ember-flexberry-dummy-application-user-edit', { path: 'ember-flexberry-dummy-application-user-edit/:id' });
  this.route('ember-flexberry-dummy-application-user-edit.new', { path: 'ember-flexberry-dummy-application-user-edit/new' });

  this.route('ember-flexberry-dummy-comment-edit', { path: 'ember-flexberry-dummy-comment-edit/:id' });
  this.route('ember-flexberry-dummy-comment-edit.new', { path: 'ember-flexberry-dummy-comment-edit/new' });

  this.route('ember-flexberry-dummy-comment-vote-edit', { path: 'ember-flexberry-dummy-comment-vote-edit/:id' });
  this.route('ember-flexberry-dummy-comment-vote-edit.new', { path: 'ember-flexberry-dummy-comment-vote-edit/new' });

  this.route('ember-flexberry-dummy-localization-list');
  this.route('ember-flexberry-dummy-localization-edit', { path: 'ember-flexberry-dummy-localization-edit/:id' });
  this.route('ember-flexberry-dummy-localization-edit.new', { path: 'ember-flexberry-dummy-localization-edit/new' });

  this.route('ember-flexberry-dummy-suggestion-list');
  this.route('ember-flexberry-dummy-suggestion-edit', { path: 'ember-flexberry-dummy-suggestion-edit/:id' });
  this.route('ember-flexberry-dummy-suggestion-edit.new', { path: 'ember-flexberry-dummy-suggestion-edit/new' });

  this.route('ember-flexberry-dummy-suggestion-type-list');
  this.route('ember-flexberry-dummy-suggestion-type-edit', { path: 'ember-flexberry-dummy-suggestion-type-edit/:id' });
  this.route('ember-flexberry-dummy-suggestion-type-edit.new', { path: 'ember-flexberry-dummy-suggestion-type-edit/new' });

  // Logging.
  this.route('i-i-s-caseberry-logging-objects-application-log-l');
  this.route('i-i-s-caseberry-logging-objects-application-log-e', { path: 'i-i-s-caseberry-logging-objects-application-log-e/:id' });
  this.route('i-i-s-caseberry-logging-objects-application-log-e.new', { path: 'i-i-s-caseberry-logging-objects-application-log-e/new' });
  this.route('log-service-examples/settings-example');

  // Locks.
  this.route('new-platform-flexberry-services-lock-list');
  this.route('new-platform-flexberry-services-lock-edit', { path: 'new-platform-flexberry-services-lock-edit/:id' });

  // Components examples routes (sorted by component's names).
  this.route('components-examples/flexberry-checkbox/settings-example');
  this.route('components-examples/flexberry-datepicker/settings-example');
  this.route('components-examples/flexberry-dropdown/settings-example');
  this.route('components-examples/flexberry-dropdown/conditional-render-example');
  this.route('components-examples/flexberry-dropdown/empty-value-example');
  this.route('components-examples/flexberry-dropdown/items-example');
  this.route('components-examples/flexberry-field/settings-example');
  this.route('components-examples/flexberry-file/settings-example');
  this.route('components-examples/flexberry-groupedit/settings-example');
  this.route('components-examples/flexberry-groupedit/model-update-example');
  this.route('components-examples/flexberry-groupedit/configurate-row-example');
  this.route('components-examples/flexberry-lookup/settings-example');
  this.route('components-examples/flexberry-lookup/customizing-window-example');
  this.route('components-examples/flexberry-lookup/limit-function-example');
  this.route('components-examples/flexberry-lookup/limit-function-through-dynamic-properties-example');
  this.route('components-examples/flexberry-lookup/lookup-block-form-example');
  this.route('components-examples/flexberry-lookup/lookup-in-modal');
  this.route('components-examples/flexberry-lookup/dropdown-mode-example');
  this.route('components-examples/flexberry-menu/settings-example');
  this.route('components-examples/flexberry-objectlistview/settings-example');
  this.route('components-examples/flexberry-objectlistview/toolbar-custom-buttons-example');
  this.route('components-examples/flexberry-objectlistview/limit-function-example');
  this.route('components-examples/flexberry-objectlistview/on-edit-form');
  this.route('components-examples/flexberry-objectlistview/on-edit-form/user', { path: 'components-examples/flexberry-objectlistview/on-edit-form/user/:id' });
  this.route('components-examples/flexberry-objectlistview/custom-filter');
  this.route('components-examples/flexberry-objectlistview/configurate-rows');
  this.route('components-examples/flexberry-objectlistview/selected-rows');

  this.route('components-examples/flexberry-simpleolv/settings-example');
  this.route('components-examples/flexberry-simpleolv/toolbar-custom-buttons-example');
  this.route('components-examples/flexberry-simpleolv/limit-function-example');
  this.route('components-examples/flexberry-simpleolv/on-edit-form');
  this.route('components-examples/flexberry-simpleolv/on-edit-form/user', { path: 'components-examples/flexberry-simpleolv/on-edit-form/user/:id' });
  this.route('components-examples/flexberry-simpleolv/custom-filter');
  this.route('components-examples/flexberry-simpleolv/configurate-rows');
  this.route('components-examples/flexberry-simpleolv/selected-rows');

  this.route('components-examples/flexberry-simpledatetime/settings-example');
  this.route('components-examples/flexberry-textarea/settings-example');
  this.route('components-examples/flexberry-textbox/settings-example');
  this.route('components-examples/flexberry-toggler/settings-example');

  // Integration examples routes.
  this.route('integration-examples/edit-form/readonly-mode');
  this.route('integration-examples/edit-form/validation');

  // User-setting forms.
  this.route('user-setting-forms/user-setting-delete');
});

export default Router;
<commit_msg>Add route<commit_after>import Ember from 'ember';
import config from './config/environment';

const Router = Ember.Router.extend({
  location: config.locationType
});

Router.map(function() {
  // Edit forms & list forms.
  this.route('ember-flexberry-dummy-application-user-list');
  this.route('ember-flexberry-dummy-application-user-edit', { path: 'ember-flexberry-dummy-application-user-edit/:id' });
  this.route('ember-flexberry-dummy-application-user-edit.new', { path: 'ember-flexberry-dummy-application-user-edit/new' });

  this.route('ember-flexberry-dummy-comment-edit', { path: 'ember-flexberry-dummy-comment-edit/:id' });
  this.route('ember-flexberry-dummy-comment-edit.new', { path: 'ember-flexberry-dummy-comment-edit/new' });

  this.route('ember-flexberry-dummy-comment-vote-edit', { path: 'ember-flexberry-dummy-comment-vote-edit/:id' });
  this.route('ember-flexberry-dummy-comment-vote-edit.new', { path: 'ember-flexberry-dummy-comment-vote-edit/new' });

  this.route('ember-flexberry-dummy-localization-list');
  this.route('ember-flexberry-dummy-localization-edit', { path: 'ember-flexberry-dummy-localization-edit/:id' });
  this.route('ember-flexberry-dummy-localization-edit.new', { path: 'ember-flexberry-dummy-localization-edit/new' });

  this.route('ember-flexberry-dummy-suggestion-list');
  this.route('ember-flexberry-dummy-suggestion-edit', { path: 'ember-flexberry-dummy-suggestion-edit/:id' });
  this.route('ember-flexberry-dummy-suggestion-edit.new', { path: 'ember-flexberry-dummy-suggestion-edit/new' });

  this.route('ember-flexberry-dummy-suggestion-type-list');
  this.route('ember-flexberry-dummy-suggestion-type-edit', { path: 'ember-flexberry-dummy-suggestion-type-edit/:id' });
  this.route('ember-flexberry-dummy-suggestion-type-edit.new', { path: 'ember-flexberry-dummy-suggestion-type-edit/new' });

  // Logging.
  this.route('i-i-s-caseberry-logging-objects-application-log-l');
  this.route('i-i-s-caseberry-logging-objects-application-log-e', { path: 'i-i-s-caseberry-logging-objects-application-log-e/:id' });
  this.route('i-i-s-caseberry-logging-objects-application-log-e.new', { path: 'i-i-s-caseberry-logging-objects-application-log-e/new' });
  this.route('log-service-examples/settings-example');

  // Locks.
  this.route('new-platform-flexberry-services-lock-list');
  this.route('new-platform-flexberry-services-lock-edit', { path: 'new-platform-flexberry-services-lock-edit/:id' });

  // Components examples routes (sorted by component's names).
  this.route('components-examples/flexberry-checkbox/settings-example');
  this.route('components-examples/flexberry-datepicker/settings-example');
  this.route('components-examples/flexberry-dropdown/settings-example');
  this.route('components-examples/flexberry-dropdown/conditional-render-example');
  this.route('components-examples/flexberry-dropdown/empty-value-example');
  this.route('components-examples/flexberry-dropdown/items-example');
  this.route('components-examples/flexberry-field/settings-example');
  this.route('components-examples/flexberry-file/settings-example');
  this.route('components-examples/flexberry-groupedit/settings-example');
  this.route('components-examples/flexberry-groupedit/model-update-example');
  this.route('components-examples/flexberry-groupedit/configurate-row-example');
  this.route('components-examples/flexberry-lookup/settings-example');
  this.route('components-examples/flexberry-lookup/customizing-window-example');
  this.route('components-examples/flexberry-lookup/limit-function-example');
  this.route('components-examples/flexberry-lookup/limit-function-through-dynamic-properties-example');
  this.route('components-examples/flexberry-lookup/lookup-block-form-example');
  this.route('components-examples/flexberry-lookup/lookup-in-modal');
  this.route('components-examples/flexberry-lookup/dropdown-mode-example');
  this.route('components-examples/flexberry-menu/settings-example');
  this.route('components-examples/flexberry-objectlistview/settings-example');
  this.route('components-examples/flexberry-objectlistview/toolbar-custom-buttons-example');
  this.route('components-examples/flexberry-objectlistview/limit-function-example');
  this.route('components-examples/flexberry-objectlistview/on-edit-form');
  this.route('components-examples/flexberry-objectlistview/on-edit-form/user', { path: 'components-examples/flexberry-objectlistview/on-edit-form/user/:id' });
  this.route('components-examples/flexberry-objectlistview/custom-filter');
  this.route('components-examples/flexberry-objectlistview/configurate-rows');
  this.route('components-examples/flexberry-objectlistview/selected-rows');

  this.route('components-examples/flexberry-simpleolv/settings-example');
  this.route('components-examples/flexberry-simpleolv/toolbar-custom-buttons-example');
  this.route('components-examples/flexberry-simpleolv/limit-function-example');
  this.route('components-examples/flexberry-simpleolv/on-edit-form');
  this.route('components-examples/flexberry-simpleolv/on-edit-form/user', { path: 'components-examples/flexberry-simpleolv/on-edit-form/user/:id' });
  this.route('components-examples/flexberry-simpleolv/custom-filter');
  this.route('components-examples/flexberry-simpleolv/configurate-rows');
  this.route('components-examples/flexberry-simpleolv/selected-rows');

  this.route('components-examples/flexberry-simpledatetime/settings-example');
  this.route('components-examples/flexberry-textarea/settings-example');
  this.route('components-examples/flexberry-textbox/settings-example');
  this.route('components-examples/flexberry-toggler/settings-example');

  // Integration examples routes.
  this.route('integration-examples/edit-form/readonly-mode');
  this.route('integration-examples/edit-form/validation');

  // User-setting forms.
  this.route('user-setting-forms/user-setting-delete');

  // Components acceptance tests forms.
  this.route('components-acceptance-tests/flexberry-groupedit/settings-example');
});

export default Router;
<|endoftext|>


<commit_before>async function component( args ) {
/*
base_component_id("form_editor_component")
load_once_from_file(true)
*/

    //alert(JSON.stringify(args,null,2))
    var uid2 = uuidv4()
    var mm = null
    var texti = null
    if (args) {
        texti = args.text
    }
    var designMode = true
    Vue.component("form_editor_component",
    {
    //*** COPY_START ***//
      template: `

Form editor

MY FORM

{{field.text}}

{{field.label}}<input></input>

                                    <button class='xs-6'  v-if='design_mode' type=button class='btn btn-primary'      v-on:click='deleteField(field.id)'  > - </button>

                        <button  v-if='design_mode' type=button class='btn btn-primary'      v-on:click='addField()'  >+ field</button>

                     <slot v-if='text' :text2="text"></slot>

`
        ,

        mounted: function() {
            mm = this
            document.getElementById(uid2).style.width="100%"

            document.getElementById(uid2).style.height="45vh"

            if (texti) {
                var json2 = this.getJsonModelFromCode(  texti  )
                mm.model = json2
                mm.edited_app_component_id = saveHelper.getValueOfCodeString(texti, "base_component_id")

                this.generateCodeFromModel(  json2  )
             //alert(this.text)
         }

         //editor.getSession().on('change', function() {
            //mm.text = editor.getSession().getValue();
            //alert("changed text to : " + mm.text)
         //   });
     },
     methods: {
        addField() {
            mm.model.fields.push({   id: mm.model.next_id,   type: "input",   label: "DOB"   })
            mm.model.next_id ++
            this.generateCodeFromModel(  mm.model  )
            //alert("Added: " + JSON.stringify(mm.model,null,2))
        },
        deleteField(   fieldId   ) {
            var itemD = null
            for (var tt=0; tt < mm.model.fields.length ; tt++) {
                var ciurr = mm.model.fields[tt]
                if (ciurr.id == fieldId) {
                    itemD = ciurr
                }
            }
            if (itemD) {
                var index = mm.model.fields.indexOf(  itemD  );
                if (index > -1) {
                  mm.model.fields.splice(index, 1);
                }
            }

            this.generateCodeFromModel(  mm.model  )
            //alert("Added: " + JSON.stringify(mm.model,null,2))
        },
        getText: function() {
            return this.text
        },
        setText: function(textValue) {
            this.text =  textValue
            var json2 = this.getJsonModelFromCode(  textValue  )
            mm.model = json2
            this.generateCodeFromModel(  json2  )
        }
        ,
        getJsonModelFromCode: function(  codeV  ) {
            var json2 = saveHelper.getValueOfCodeString(codeV,"formEditor",")//formEditor")
            return json2
        }

        ,
        generateCodeFromModel: async function(  jsonModel  ) {
            var startIndex = this.text.indexOf("//** gen_" + "start **//")
            var endIndex = this.text.indexOf("//** gen_" + "end **//")

            //zzz
            var sql =    "select  cast(code as text)  as  code  from  system_code  where " +
                         "        base_component_id = 'form_editor_component'   and   code_tag = 'LATEST' "

            var results = await callApp({ driver_name:    "systemFunctions2",method_name:    "sql"},
                {   sql: sql  })

            var editorCode = results[0].code
            var stt = "//*** COPY_" + "START ***//"
            var editorCodeToCopyStart = editorCode.indexOf(stt) + stt.length
            var editorCodeToCopyEnd = editorCode.indexOf("//*** COPY_" + "END ***//")
            var editorCodeToCopy = editorCode.substring(editorCodeToCopyStart, editorCodeToCopyEnd)
            console.log(editorCodeToCopy)
            //alert(JSON.stringify(mm.model,null,2))

            this.text = this.text.substring(0,startIndex) +

                `//** gen_start **//
                var uid2 = uuidv4()
                var mm = null
                var texti = null
                var designMode = false
                Vue.component('${this.edited_app_component_id}', {`

                + editorCodeToCopy +

                `,
                data: function () {
                  return {
                      design_mode: designMode,
                      text: texti,
                      uid2: uid2,
                      model: `

                      + JSON.stringify(mm.model,null,2) +

                  `}
                }
              })`

              +
              this.text.substring(endIndex)
              //console.log(this.text)

              this.text = saveHelper.deleteCodeString(  this.text, "formEditor", ")//form" + "Editor")

              this.text = saveHelper.insertCodeString(  this.text,
                                                        "formEditor",
                                                        mm.model,
                                                        ")//form" + "Editor")
        }

     }
     //*** COPY_END ***//
     ,
     data: function () {
       return {
           design_mode: designMode,
           edited_app_component_id: null,
           text:        texti,
           uid2:        uid2,
           model:       {
                            next_id: 1,
                            fields: [
                                    ]
           }
       }
     }

    }
    )

}
<commit_msg>Slightly nicer form editor buttons<commit_after>async function component( args ) {
/*
base_component_id("form_editor_component")
load_once_from_file(true)
*/

    //alert(JSON.stringify(args,null,2))
    var uid2 = uuidv4()
    var mm = null
    var texti = null
    if (args) {
        texti = args.text
    }
    var designMode = true
    Vue.component("form_editor_component",
    {
    //*** COPY_START ***//
      template: `

Form editor

MY FORM

{{field.text}}

{{field.label}}<input></input>

                                    <button class='xs-4'  v-if='design_mode' type=button class='btn btn-sm btn-info'      v-on:click='deleteField(field.id)'  > - </button>

                        <button  v-if='design_mode' type=button class='btn btn-primary btn-lg'      v-on:click='addField()'  >+</button>

                     <slot v-if='text' :text2="text"></slot>

`
        ,

        mounted: function() {
            mm = this
            document.getElementById(uid2).style.width="100%"

            document.getElementById(uid2).style.height="45vh"

            if (texti) {
                var json2 = this.getJsonModelFromCode(  texti  )
                mm.model = json2
                mm.edited_app_component_id = saveHelper.getValueOfCodeString(texti, "base_component_id")

                this.generateCodeFromModel(  json2  )
             //alert(this.text)
         }

         //editor.getSession().on('change', function() {
            //mm.text = editor.getSession().getValue();
            //alert("changed text to : " + mm.text)
         //   });
     },
     methods: {
        addField() {
            mm.model.fields.push({   id: mm.model.next_id,   type: "input",   label: "DOB"   })
            mm.model.next_id ++
            this.generateCodeFromModel(  mm.model  )
            //alert("Added: " + JSON.stringify(mm.model,null,2))
        },
        deleteField(   fieldId   ) {
            var itemD = null
            for (var tt=0; tt < mm.model.fields.length ; tt++) {
                var ciurr = mm.model.fields[tt]
                if (ciurr.id == fieldId) {
                    itemD = ciurr
                }
            }
            if (itemD) {
                var index = mm.model.fields.indexOf(  itemD  );
                if (index > -1) {
                  mm.model.fields.splice(index, 1);
                }
            }

            this.generateCodeFromModel(  mm.model  )
            //alert("Added: " + JSON.stringify(mm.model,null,2))
        },
        getText: function() {
            return this.text
        },
        setText: function(textValue) {
            this.text =  textValue
            var json2 = this.getJsonModelFromCode(  textValue  )
            mm.model = json2
            this.generateCodeFromModel(  json2  )
        }
        ,
        getJsonModelFromCode: function(  codeV  ) {
            var json2 = saveHelper.getValueOfCodeString(codeV,"formEditor",")//formEditor")
            return json2
        }

        ,
        generateCodeFromModel: async function(  jsonModel  ) {
            var startIndex = this.text.indexOf("//** gen_" + "start **//")
            var endIndex = this.text.indexOf("//** gen_" + "end **//")

            //zzz
            var sql =    "select  cast(code as text)  as  code  from  system_code  where " +
                         "        base_component_id = 'form_editor_component'   and   code_tag = 'LATEST' "

            var results = await callApp({ driver_name:    "systemFunctions2",method_name:    "sql"},
                {   sql: sql  })

            var editorCode = results[0].code
            var stt = "//*** COPY_" + "START ***//"
            var editorCodeToCopyStart = editorCode.indexOf(stt) + stt.length
            var editorCodeToCopyEnd = editorCode.indexOf("//*** COPY_" + "END ***//")
            var editorCodeToCopy = editorCode.substring(editorCodeToCopyStart, editorCodeToCopyEnd)
            console.log(editorCodeToCopy)
            //alert(JSON.stringify(mm.model,null,2))

            this.text = this.text.substring(0,startIndex) +

                `//** gen_start **//
                var uid2 = uuidv4()
                var mm = null
                var texti = null
                var designMode = false
                Vue.component('${this.edited_app_component_id}', {`

                + editorCodeToCopy +

                `,
                data: function () {
                  return {
                      design_mode: designMode,
                      text: texti,
                      uid2: uid2,
                      model: `

                      + JSON.stringify(mm.model,null,2) +

                  `}
                }
              })`

              +
              this.text.substring(endIndex)
              //console.log(this.text)

              this.text = saveHelper.deleteCodeString(  this.text, "formEditor", ")//form" + "Editor")

              this.text = saveHelper.insertCodeString(  this.text,
                                                        "formEditor",
                                                        mm.model,
                                                        ")//form" + "Editor")
        }

     }
     //*** COPY_END ***//
     ,
     data: function () {
       return {
           design_mode: designMode,
           edited_app_component_id: null,
           text:        texti,
           uid2:        uid2,
           model:       {
                            next_id: 1,
                            fields: [
                                    ]
           }
       }
     }

    }
    )

}
<|endoftext|>


<commit_before>

function Route(template, defaults) {
  this.template = template = template + '#';
  this.defaults = defaults || {};
  var urlParams = this.urlParams = {};
  forEach(template.split(/\W/), function(param){
    if (param && template.match(new RegExp(":" + param + "\\W"))) {
      urlParams[param] = true;
    }
  });
}

Route.prototype = {
  url: function(params) {
    var path = [];
    var self = this;
    var url = this.template;
    params = params || {};
    forEach(this.urlParams, function(_, urlParam){
      var value = params[urlParam] || self.defaults[urlParam] || "";
      url = url.replace(new RegExp(":" + urlParam + "(\\W)"), value + "$1");
    });
    url = url.replace(/\/?#$/, '');
    var query = [];
    forEachSorted(params, function(value, key){
      if (!self.urlParams[key]) {
        query.push(encodeURI(key) + '=' + encodeURI(value));
      }
    });
    url = url.replace(/\/*$/, '');
    return url + (query.length ? '?' + query.join('&') : '');
  }
};

function ResourceFactory(xhr) {
  this.xhr = xhr;
}

ResourceFactory.DEFAULT_ACTIONS = {
  'get':    {method:'GET'},
  'save':   {method:'POST'},
  'query':  {method:'GET', isArray:true},
  'remove': {method:'DELETE'},
  'delete': {method:'DELETE'}
};

ResourceFactory.prototype = {
  route: function(url, paramDefaults, actions){
    var self = this;
    var route = new Route(url);
    actions = extend({}, ResourceFactory.DEFAULT_ACTIONS, actions);
    function extractParams(data){
      var ids = {};
      forEach(paramDefaults || {}, function(value, key){
        ids[key] = value.charAt && value.charAt(0) == '@' ? getter(data, value.substr(1)) : value;
      });
      return ids;
    }

    function Resource(value){
      copy(value || {}, this);
    }

    forEach(actions, function(action, name){
      var isPostOrPut = action.method == 'POST' || action.method == 'PUT';
      Resource[name] = function (a1, a2, a3) {
        var params = {};
        var data;
        var callback = noop;
        switch(arguments.length) {
        case 3: callback = a3;
        case 2:
          if (isFunction(a2)) {
            callback = a2;
          } else {
            params = a1;
            data = a2;
            break;
          }
        case 1:
          if (isFunction(a1)) callback = a1;
          else if (isPostOrPut) data = a1;
          else params = a1;
          break;
        case 0: break;
        default:
          throw "Expected between 0-3 arguments [params, data, callback], got " + arguments.length + " arguments.";
        }

        var value = this instanceof Resource ? this : (action.isArray ? [] : new Resource(data));
        self.xhr(
          action.method,
          route.url(extend({}, action.params || {}, extractParams(data), params)),
          data,
          function(status, response, clear) {
            if (status == 200) {
              if (action.isArray) {
                value.length = 0;
                forEach(response, function(item){
                  value.push(new Resource(item));
                });
              } else {
                copy(response, value);
              }
              (callback||noop)(value);
            } else {
              throw {status: status, response:response, message: status + ": " + response};
            }
          },
          action.verifyCache);
        return value;
      };

      Resource.bind = function(additionalParamDefaults){
        return self.route(url, extend({}, paramDefaults, additionalParamDefaults), actions);
      };

      Resource.prototype['$' + name] = function(a1, a2){
        var params = extractParams(this);
        var callback = noop;
        switch(arguments.length) {
        case 2: params = a1; callback = a2;
        case 1: if (typeof a1 == $function) callback = a1; else params = a1;
        case 0: break;
        default:
          throw "Expected between 1-2 arguments [params, callback], got " + arguments.length + " arguments.";
        }
        var data = isPostOrPut ? this : _undefined;
        Resource[name].call(this, params, data, callback);
      };
    });
    return Resource;
  }
};
<commit_msg>adding a fallthrough comment<commit_after>

function Route(template, defaults) {
  this.template = template = template + '#';
  this.defaults = defaults || {};
  var urlParams = this.urlParams = {};
  forEach(template.split(/\W/), function(param){
    if (param && template.match(new RegExp(":" + param + "\\W"))) {
      urlParams[param] = true;
    }
  });
}

Route.prototype = {
  url: function(params) {
    var path = [];
    var self = this;
    var url = this.template;
    params = params || {};
    forEach(this.urlParams, function(_, urlParam){
      var value = params[urlParam] || self.defaults[urlParam] || "";
      url = url.replace(new RegExp(":" + urlParam + "(\\W)"), value + "$1");
    });
    url = url.replace(/\/?#$/, '');
    var query = [];
    forEachSorted(params, function(value, key){
      if (!self.urlParams[key]) {
        query.push(encodeURI(key) + '=' + encodeURI(value));
      }
    });
    url = url.replace(/\/*$/, '');
    return url + (query.length ? '?' + query.join('&') : '');
  }
};

function ResourceFactory(xhr) {
  this.xhr = xhr;
}

ResourceFactory.DEFAULT_ACTIONS = {
  'get':    {method:'GET'},
  'save':   {method:'POST'},
  'query':  {method:'GET', isArray:true},
  'remove': {method:'DELETE'},
  'delete': {method:'DELETE'}
};

ResourceFactory.prototype = {
  route: function(url, paramDefaults, actions){
    var self = this;
    var route = new Route(url);
    actions = extend({}, ResourceFactory.DEFAULT_ACTIONS, actions);
    function extractParams(data){
      var ids = {};
      forEach(paramDefaults || {}, function(value, key){
        ids[key] = value.charAt && value.charAt(0) == '@' ? getter(data, value.substr(1)) : value;
      });
      return ids;
    }

    function Resource(value){
      copy(value || {}, this);
    }

    forEach(actions, function(action, name){
      var isPostOrPut = action.method == 'POST' || action.method == 'PUT';
      Resource[name] = function (a1, a2, a3) {
        var params = {};
        var data;
        var callback = noop;
        switch(arguments.length) {
        case 3: callback = a3;
        case 2:
          if (isFunction(a2)) {
            callback = a2;
            //fallthrough
          } else {
            params = a1;
            data = a2;
            break;
          }
        case 1:
          if (isFunction(a1)) callback = a1;
          else if (isPostOrPut) data = a1;
          else params = a1;
          break;
        case 0: break;
        default:
          throw "Expected between 0-3 arguments [params, data, callback], got " + arguments.length + " arguments.";
        }

        var value = this instanceof Resource ? this : (action.isArray ? [] : new Resource(data));
        self.xhr(
          action.method,
          route.url(extend({}, action.params || {}, extractParams(data), params)),
          data,
          function(status, response, clear) {
            if (status == 200) {
              if (action.isArray) {
                value.length = 0;
                forEach(response, function(item){
                  value.push(new Resource(item));
                });
              } else {
                copy(response, value);
              }
              (callback||noop)(value);
            } else {
              throw {status: status, response:response, message: status + ": " + response};
            }
          },
          action.verifyCache);
        return value;
      };

      Resource.bind = function(additionalParamDefaults){
        return self.route(url, extend({}, paramDefaults, additionalParamDefaults), actions);
      };

      Resource.prototype['$' + name] = function(a1, a2){
        var params = extractParams(this);
        var callback = noop;
        switch(arguments.length) {
        case 2: params = a1; callback = a2;
        case 1: if (typeof a1 == $function) callback = a1; else params = a1;
        case 0: break;
        default:
          throw "Expected between 1-2 arguments [params, callback], got " + arguments.length + " arguments.";
        }
        var data = isPostOrPut ? this : _undefined;
        Resource[name].call(this, params, data, callback);
      };
    });
    return Resource;
  }
};
<|endoftext|>