<commit_before>'use strict';

/**
 * Height directive
 */

angular.module('b.directives.height', []).
    directive('resizeHeight', function ($window) {
        function endsWith(str, suffix) {
            return str.indexOf(suffix, str.length - suffix.length) !== -1;
        }

        function calculateHeight(windowHeight, offset) {
            if (!offset) return windowHeight;
            offset = offset.trim();
            if (endsWith(offset, "%")) {
                var ps = offset.substr(0, offset.length-1);
                return windowHeight - Math.round(windowHeight * parseInt(ps) / 100);
            }
            return windowHeight - parseInt(offset);
        }

        return {
            replace: false,
            restrict: 'EA',
            scope: {
                offset: "@"
            },
            link: function (scope, elem, attrs) {
                var handler = function () {
                    var windowHeight = $window.innerHeight;
                    elem.height(calculateHeight(windowHeight, scope.offset));
                };
                $($window).ready(_.debounce(handler, 50));
                $window.addEventListener('resize', _.debounce(handler, 50));
            }
        };
    });
<commit_msg>Better event management<commit_after>'use strict';

/**
 * Height directive
 */

angular.module('b.directives.height', []).
    directive('resizeHeight', function ($window) {
        function endsWith(str, suffix) {
            return str.indexOf(suffix, str.length - suffix.length) !== -1;
        }

        function calculateHeight(windowHeight, offset) {
            if (!offset) return windowHeight;
            offset = offset.trim();
            if (endsWith(offset, "%")) {
                var ps = offset.substr(0, offset.length - 1);
                return windowHeight - Math.round(windowHeight * parseInt(ps) / 100);
            }
            return windowHeight - parseInt(offset);
        }

        return {
            replace: false,
            restrict: 'EA',
            scope: {
                offset: "@"
            },
            link: function (scope, elem, attrs) {
                var win = angular.element($window);
                var handler = function () {
                    elem.height(calculateHeight(win.innerHeight(), scope.offset));
                };
                win.bind("resize", _.debounce(handler, 50));
                handler();
            }
        };
    });
<|endoftext|>


<commit_before>import { isQName } from "./qname";

import { seq, first, isSeq } from "./seq";

import { isVNode } from "./access";

// faux VNode
function vnode(inode,type,name,value){
	return {
		inode:inode,
		type:type,
		name:name,
		value:value,
		__is_VNode:true
	};
}

function _n(type, name, children){
	children = seq(children).concatMap(c => isSeq(c) ? c : isVNode(c) ? seq(c) : x(c));
	return vnode(function (parent, ref) {
		var ns;
		if(type == 1) {
			if(isQName(name)) {
				ns = name;
				name = name.name;
			} else if(/:/.test(name)){
				// TODO where are the namespaces?
			}
		}
		// convert to real VNode instance
		var node = parent.vnode(
			parent.emptyINode(type, name, type == 1 ? parent.emptyAttrMap() : undefined, ns),
			parent,
			parent.depth + 1,
			0,
			type
		);
		return children.concatMap(child => {
			return child.inode(node);
		}).reduce(function (node, child) {
			return node.modify(child, ref);
		}, node);
	}, type, name);
}

function _a(name, child) {
	if(isSeq(child)) {
		child = first(child);
	} else if(Array.isArray(child)){
		child = child[0];
	} else if(!child.__is_VNode) {
		child = x(child);
	}
	return vnode(function (parent) {
		var node = parent.vnode(parent.ituple(name, child), parent);
		// node is an attr node /w child as $val
		// push node to
		child = child.inode(node);
		//node.type = child.type;
		node = node.finalize();
		if (parent.type == 1) {
			// TODO conversion rules!
			parent.attr(name, node.value + "");
		} else if (parent.type == 6) {
			// tuple
			parent.push([node.inode.$name,node.inode.$value]);
		}
		return node;
	}, 2, name);
}

function _v(type,val) {
	return vnode(function (parent) {
		return seq(val).map(val => parent.vnode(parent.ivalue(type, val), parent));
	}, type, null, val);
}

/**
 * Create a provisional element VNode.
 * Once the VNode's inode function is called, the node is inserted into the parent at the specified index
 * @param  {[type]} name     [description]
 * @param  {[type]} children [description]
 * @return {[type]}          [description]
 */
export function e(name, children) {
	return seq(_n(1, name, children));
}

export function l(children) {
	return _n(5, null, children);
}

export function m(children){
	return _n(6, null, children);
}

export function a(name, value){
	return _a(name,value);
}

export function p(target, content){
	return _v(7, target+" "+content);
}

export function x(value = null) {
	return seq(_v(3, value));
}

export function c(value){
	return _v(8, value);
}
<commit_msg>seqify constructors<commit_after>import { isQName } from "./qname";

import { seq, first, isSeq, exactlyOne } from "./seq";

import { isVNode } from "./access";

// faux VNode
function vnode(inode,type,name,value){
	return {
		inode:inode,
		type:type,
		name:name,
		value:value,
		__is_VNode:true
	};
}

function _n(type, name, children){
	children = seq(children).concatMap(c => isSeq(c) ? c : isVNode(c) ? seq(c) : x(c));
	return vnode(function (parent, ref) {
		var ns;
		if(type == 1) {
			if(isQName(name)) {
				ns = name;
				name = name.name;
			} else if(/:/.test(name)){
				// TODO where are the namespaces?
			}
		}
		// convert to real VNode instance
		var node = parent.vnode(
			parent.emptyINode(type, name, type == 1 ? parent.emptyAttrMap() : undefined, ns),
			parent,
			parent.depth + 1,
			0,
			type
		);
		return children
			.concatMap(child => child.inode(node))
			.reduce((node, child) => node.modify(child, ref), node);
	}, type, name);
}

function _a(name, child) {
	child = exactlyOne(child).concatMap(c => isSeq(c) ? c : isVNode(c) ? seq(c) : x(c));
	return vnode(function (parent) {
		var node = parent.vnode(parent.ituple(name), parent);
		// node is an attr node /w child as $val
		return child
			.concatMap(child => child.inode(node))
			.reduce((node, child) => {
				if (parent.type == 1) {
					// TODO conversion rules!
					parent.attr(name, child.value + "");
				} else if (parent.type == 6) {
					// tuple
					parent.push([name, child.inode]);
				}
				return node.modify(child,name);
			}, node);
	}, 2, name);
}

function _v(type,val) {
	return vnode(function (parent) {
		return seq(val).map(val => parent.vnode(parent.ivalue(type, val), parent));
	}, type, null, val);
}

/**
 * Create a provisional element VNode.
 * Once the VNode's inode function is called, the node is inserted into the parent at the specified index
 * @param  {[type]} name     [description]
 * @param  {[type]} children [description]
 * @return {[type]}          [description]
 */
export function e(name, children) {
	return exactlyOne(name).map(name => _n(1, name, children));
}

export function l(children) {
	return seq(_n(5, null, children));
}

export function m(children){
	return seq(_n(6, null, children));
}

export function a(name, value){
	return exactlyOne(name).map(name => _a(name,value));
}

export function p(target, content){
	return _v(7, target+" "+content);
}

export function x(value = null) {
	return seq(_v(3, value));
}

export function c(value){
	return seq(_v(8, value));
}
<|endoftext|>


<commit_before>#!/usr/bin/env node

'use strict'

const fs = require('fs')
const { join, basename, relative } = require('path')
const glob = require('glob')
const toPascal = require('to-pascal-case')
const gaze = require('gaze')
const resolveModule = require('resolve')

module.exports = createComponentMap

if (require.main === module) {
  process.on('unhandledRejection', err => { throw err })
  main(require('minimist')(process.argv.slice(2)))
}

function main (args) {
  const dir = args._[0] || 'components'
  const output = args.output || args.o || '-'
  const browser = args.browser || args.b || false
  const watch = args.watch || args.w || false
  const initial = args.initial || args.i || false

  const pattern = join(dir, '*')
  const writer = createWriter({
    stream: createStreamFactory({ output }),
    pattern,
    output,
    browser
  })
  const resolver = createResolver({ pattern, browser })
  const generator = createGenerator({ resolver, writer })

  if (!watch) {
    generator()
  } else {
    if (initial) writer()
    gaze(pattern, function (err) {
      if (err) throw err
      this.on('added', generator)
      this.on('deleted', generator)
    })
    gaze('package.json', function (err) {
      if (err) throw err
      this.on('changed', generator)
    })
    generator()
  }
}

function createComponentMap ({ pattern = 'components/*', output = '-', browser = false }) {
  const writer = createWriter({
    stream: createStreamFactory({ output }),
    pattern,
    output,
    browser
  })
  const resolver = createResolver({ pattern, browser })
  const generator = createGenerator({ resolver, writer })
  return generator()
}

function createGenerator ({ resolver, writer }) {
  return function generate () {
    return resolver().then(writer)
  }
}

function createResolver ({ pattern, browser }) {
  return function () {
    return Promise.all([
      new Promise((resolve, reject) => {
        resolveModule('./package.json', { basedir: process.cwd() }, (err, res, pkg) => {
          if (err) return reject(err)
          const { penguin: { components = {} } = {} } = pkg
          resolve(Object.keys(components).reduce((entries, name) =>
            entries.concat({ file: components[name], name })
          , []))
        })
      }),
      new Promise((resolve, reject) => {
        const files = glob.sync(pattern)
        resolve(files.map((file, i) => ({
          file: './' + file,
          name: toPascal(basename(file).split('.')[0])
        })))
      })
    ])
    .then(srcs => {
      const entries = [].concat(...srcs)
      return resolveModulePaths(entries, { browser })
    })
  }

  function resolveModulePaths (entries, { browser }) {
    return Promise.all(entries.map(entry =>
      new Promise((resolve, reject) => {
        resolveModule(entry.file, { basedir: process.cwd() }, (err, res, pkg) => {
          if (err) return reject(err)
          if (!pkg || typeof pkg.browser !== 'string') return resolve(entry)
          const prefix = entry.file.startsWith('./') ? '../' : ''
          const modulePath =
            browser
              ? ((!pkg || typeof pkg.browser !== 'string')
                ? entry.file
                : prefix + join(entry.file, pkg.browser))
              : prefix + relative(process.cwd(), res)
          resolve({
            name: entry.name,
            file: modulePath
          })
        })
      })
    ))
  }
}

function createStreamFactory ({ output }) {
  return () =>
    output === '-'
      ? Object.assign(Object.create(process.stdout), {
        end (data) { if (data) this.write(data) }
      })
      : fs.createWriteStream(output)
}

function createWriter ({ stream, output, pattern, browser }) {
  const symbol = browser ? 'mount' : 'render'
  return entries => {
    // const files = glob.sync(pattern)
    const s = typeof stream === 'function' ? stream() : stream
    s.end(
      entries
        .map(({ file, name }, i) =>
          `export { ${symbol} as ${name} } from '${file}'`
        )
        .join('\n')
    )
    console.error('penguin: ' + output + ' written')
  }
}
<commit_msg>Fix component resolution<commit_after>#!/usr/bin/env node

'use strict'

const fs = require('fs')
const { join, basename, relative } = require('path')
const glob = require('glob')
const toPascal = require('to-pascal-case')
const gaze = require('gaze')
const resolveModule = require('resolve')

module.exports = createComponentMap

if (require.main === module) {
  process.on('unhandledRejection', err => { throw err })
  main(require('minimist')(process.argv.slice(2)))
}

function main (args) {
  const dir = args._[0] || 'components'
  const output = args.output || args.o || '-'
  const browser = args.browser || args.b || false
  const watch = args.watch || args.w || false
  const initial = args.initial || args.i || false

  const pattern = join(dir, '*')
  const writer = createWriter({
    stream: createStreamFactory({ output }),
    pattern,
    output,
    browser
  })
  const resolver = createResolver({ pattern, browser })
  const generator = createGenerator({ resolver, writer })

  if (!watch) {
    generator()
  } else {
    if (initial) writer()
    gaze(pattern, function (err) {
      if (err) throw err
      this.on('added', generator)
      this.on('deleted', generator)
    })
    gaze('package.json', function (err) {
      if (err) throw err
      this.on('changed', generator)
    })
    generator()
  }
}

function createComponentMap ({ pattern = 'components/*', output = '-', browser = false }) {
  const writer = createWriter({
    stream: createStreamFactory({ output }),
    pattern,
    output,
    browser
  })
  const resolver = createResolver({ pattern, browser })
  const generator = createGenerator({ resolver, writer })
  return generator()
}

function createGenerator ({ resolver, writer }) {
  return function generate () {
    return resolver().then(writer)
  }
}

function createResolver ({ pattern, browser }) {
  return function () {
    return Promise.all([
      new Promise((resolve, reject) => {
        resolveModule('./package.json', { basedir: process.cwd() }, (err, res, pkg) => {
          if (err) return reject(err)
          const { penguin: { components = {} } = {} } = pkg
          resolve(Object.keys(components).reduce((entries, name) =>
            entries.concat({ file: components[name], name })
          , []))
        })
      }),
      new Promise((resolve, reject) => {
        const files = glob.sync(pattern)
        resolve(files.map((file, i) => ({
          file: './' + file,
          name: toPascal(basename(file).split('.')[0])
        })))
      })
    ])
    .then(srcs => {
      const entries = [].concat(...srcs)
      return resolveModulePaths(entries, { browser })
    })
  }

  function resolveModulePaths (entries, { browser }) {
    return Promise.all(entries.map(entry =>
      new Promise((resolve, reject) => {
        resolveModule(entry.file, { basedir: process.cwd() }, (err, res, pkg) => {
          if (err) return reject(err)
          if (!pkg || typeof pkg.browser !== 'string') return resolve(entry)
          const prefix = entry.file.startsWith('./') ? './' : ''
          const modulePath =
            browser
              ? ((!pkg || typeof pkg.browser !== 'string')
                ? entry.file
                : prefix + join(entry.file, pkg.browser))
              : prefix + relative(process.cwd(), res)
          resolve({ name: entry.name, file: modulePath })
        })
      })
      .then(entry => ({
        name: entry.name,
        file: entry.file.replace(/^\.\//, '../')
      }))
    ))
  }
}

function createStreamFactory ({ output }) {
  return () =>
    output === '-'
      ? Object.assign(Object.create(process.stdout), {
        end (data) { if (data) this.write(data) }
      })
      : fs.createWriteStream(output)
}

function createWriter ({ stream, output, pattern, browser }) {
  const symbol = browser ? 'mount' : 'render'
  return entries => {
    // const files = glob.sync(pattern)
    const s = typeof stream === 'function' ? stream() : stream
    s.end(
      entries
        .map(({ file, name }, i) =>
          `export { ${symbol} as ${name} } from '${file}'`
        )
        .join('\n')
    )
    console.error('penguin: ' + output + ' written')
  }
}
<|endoftext|>


<commit_before>YUI.add("passbox", function (Y) {

    // Fires pressed button name (pass, x, xx)
    var PassBox = Y.Base.create("passbox", Y.ButtonGroup, [Y.WidgetChild], {

        renderUI: function () {
            this._renderPassBox();
        },

        _renderPassBox: function () {
            this.add([
                { label: "pass", name: "pass" },
                { label: "x", name: "x" },
                { label: "xx", name: "xx" }
            ]);
        },

        syncUI: function () {
            this._syncEnabledButtons(this.get("enabledButtons"));
        },

        _syncEnabledButtons: function (enabledButtons) {
            this.each(function (button) {
                button.set("enabled", enabledButtons[button.get("name")];
            });
        },

        bindUI: function () {
            this.after("button:press", this._afterButtonPress);
            this.after("enabledButtonsChange", this._afterEnabledButtonsChange);
        },

        _afterButtonPress: function (event) {
            this.fire(event.target.get("name"));
        },

        _afterEnabledButtonsChange: function (event) {
            this._syncEnabledButtons(event.newVal);
        }

    }, {

        NAME: "passbox",

        ATTRS: {

            defaultChildType: {
                value: Y.Button
            },

            label: {
                value: ""
            },

            enabledButtons: {
                value: {
                    pass: true,
                    x: false,
                    xx: true
                }
            }

        }

    });

    Y.namespace("Bridge").PassBox = PassBox;

}, "0", { requires: ["gallery-button", "gallery-button-group"] });
<commit_msg>fixed typo - missing parenthesis<commit_after>YUI.add("passbox", function (Y) {

    // Fires pressed button name (pass, x, xx)
    var PassBox = Y.Base.create("passbox", Y.ButtonGroup, [Y.WidgetChild], {

        renderUI: function () {
            this._renderPassBox();
        },

        _renderPassBox: function () {
            this.add([
                { label: "pass", name: "pass" },
                { label: "x", name: "x" },
                { label: "xx", name: "xx" }
            ]);
        },

        syncUI: function () {
            this._syncEnabledButtons(this.get("enabledButtons"));
        },

        _syncEnabledButtons: function (enabledButtons) {
            this.each(function (button) {
                button.set("enabled", enabledButtons[button.get("name")]);
            });
        },

        bindUI: function () {
            this.after("button:press", this._afterButtonPress);
            this.after("enabledButtonsChange", this._afterEnabledButtonsChange);
        },

        _afterButtonPress: function (event) {
            this.fire(event.target.get("name"));
        },

        _afterEnabledButtonsChange: function (event) {
            this._syncEnabledButtons(event.newVal);
        }

    }, {

        NAME: "passbox",

        ATTRS: {

            defaultChildType: {
                value: Y.Button
            },

            label: {
                value: ""
            },

            enabledButtons: {
                value: {
                    pass: true,
                    x: false,
                    xx: true
                }
            }

        }

    });

    Y.namespace("Bridge").PassBox = PassBox;

}, "0", { requires: ["gallery-button", "gallery-button-group"] });
<|endoftext|>


<commit_before>'use strict';

function draw_logic(){
    for(var entity in core_entities){
        canvas_buffer.fillStyle = core_entities[entity]['color'];
        canvas_buffer.fillRect(
          core_entities[entity]['x'],
          core_entities[entity]['y'],
          core_entities[entity]['width'],
          core_entities[entity]['height']
        );
    }
}

function logic(){
    for(var entity in core_entities){
        core_entities[entity]['rotation'] += rotation_rate * (25 - core_entities[entity]['layer']);
        if(core_entities[entity]['rotation'] >= math_tau){
            core_entities[entity]['rotation'] -= math_tau;
        }else if(core_entities[entity]['rotation'] < 0){
            core_entities[entity]['rotation'] += math_tau;
        }

        core_entities[entity]['x'] = canvas_x + core_entities[entity]['layer'] * 10 * Math.cos(core_entities[entity]['rotation']);
        core_entities[entity]['y'] = canvas_y + core_entities[entity]['layer'] * 10 * Math.sin(core_entities[entity]['rotation']);
    }

    core_ui_update({
      'ids': {
        'rotation': rotation_rate_display,
      },
    });
}

function repo_init(){
    core_repo_init({
      'keybinds': {
        65: {
          'todo': function(){
              rotate(-.001);
          },
        },
        68: {
          'todo': function(){
              rotate(.001);
          },
        },
      },
      'title': 'QjnyYap.htm',
      'ui': ' Rotation',
    });
    canvas_init();
}

var rotation_rate = 0;
var rotation_rate_display = '';
<commit_msg>replaced for loop with core_group_modify()<commit_after>'use strict';

function draw_logic(){
    core_group_modify({
      'groups': [
        'canvas',
      ],
      'todo': function(entity){
          canvas_buffer.fillStyle = core_entities[entity]['color'];
          canvas_buffer.fillRect(
            core_entities[entity]['x'],
            core_entities[entity]['y'],
            core_entities[entity]['width'],
            core_entities[entity]['height']
          );
      },
    });
}

function logic(){
    core_group_modify({
      'groups': [
        'canvas',
      ],
      'todo': function(entity){
          core_entities[entity]['rotation'] += rotation_rate * (25 - core_entities[entity]['layer']);
          if(core_entities[entity]['rotation'] >= math_tau){
              core_entities[entity]['rotation'] -= math_tau;
          }else if(core_entities[entity]['rotation'] < 0){
              core_entities[entity]['rotation'] += math_tau;
          }

          core_entities[entity]['x'] = canvas_x + core_entities[entity]['layer'] * 10 * Math.cos(core_entities[entity]['rotation']);
          core_entities[entity]['y'] = canvas_y + core_entities[entity]['layer'] * 10 * Math.sin(core_entities[entity]['rotation']);
      },
    });

    core_ui_update({
      'ids': {
        'rotation': rotation_rate_display,
      },
    });
}

function repo_init(){
    core_repo_init({
      'keybinds': {
        65: {
          'todo': function(){
              rotate(-.001);
          },
        },
        68: {
          'todo': function(){
              rotate(.001);
          },
        },
      },
      'title': 'QjnyYap.htm',
      'ui': ' Rotation',
    });
    canvas_init();
}

var rotation_rate = 0;
var rotation_rate_display = '';
<|endoftext|>


<commit_before>'use strict';

const RED = new Color(255, 0, 0);
const GREEN = new Color(0, 255, 0);
const BLUE = new Color(0, 0, 255);
const WHITE = new Color(255, 255, 255);

class ContourerManager{
    constructor(drawFunc){
        this.viewport = new ScalableViewportManager(
            new Vector(0, 0),
            0.01
        );
        this.zoomSensitivity = 0.3;
        this.contourSpacing = 1.0;
    }
    changeDrawFunc(drawFunc, includeSrc, isAnimated = false){
        const createFieldKernel = coord => {
            const fieldFunc =
`vec2 cPos = (vec2(threadId) * uScale) + uPos;
vec2 res;
` +
            drawFunc.trim() + '\n' +
//`gl_FragData[0] = vec4(
//    res,
//    0.0, 0.0
//);
`gl_FragData[0] = packFloat(res.` + coord + `);
`;
            return this.gpgpuManager.createKernel(
                fieldFunc, [], this.dims, [
                    {
                        type: 'float',
                        name: 'uScale'
                    },
                    {
                        type: 'vec2',
                        name: 'uPos'
                    }
                ].concat(isAnimated ? [
                    {
                        type: 'float',
                        name: 'time'
                    }
                ] : []), 1, GPGPUManager.PACK_FLOAT_INCLUDE + includeSrc.trim() + '\n\n'
            );
        };
        this.fieldKernelX = createFieldKernel('x');
        this.fieldKernelY = createFieldKernel('y');

        this.viewport.scale = 10.0 / this.dims.width;
        this.viewport.pos = new Vector(-this.dims.width, -this.dims.height).divide(2.0).multiply(this.viewport.scale);
        this.contourSpacing = 1.0;

        this.isAnimated = isAnimated;
    }
    useCanvas(canvas){
        this.ctx = GPGPUManager.getCanvasContext(canvas);
        this.gpgpuManager = new GPGPUManager(this.ctx, false);
        this.dims = getCanvasDims(this.ctx);

        this.plotKernel = this.gpgpuManager.createGraphicalKernel(
            ContourerManager.plotFunc, ['uFieldX', 'uFieldY'], this.dims, [
                {
                    type: 'float',
                    name: 'uContourSpacing'
                }
            ], GPGPUManager.PACK_FLOAT_INCLUDE + ContourerManager.FIELD_CHECK_INCLUDE
        );

        const testDims = new Dimensions(5, 1);
        alert(this.gpgpuManager.textureToArray(testDims, this.gpgpuManager.createKernel(
`gl_FragData[0] = packFloat(-1.0 - float(threadId.x) / 5.0);
`, [], testDims, [], 1, GPGPUManager.PACK_FLOAT_INCLUDE).run([], testDims, [], false).textures[0], false).toString());
    }
    destroyContext(){
        this.ctx.canvas.width = 1;
        this.ctx.canvas.height = 1;
    }
    changeZoom(changeAmount, zoomPoint = new Vector(this.dims.width / 2, this.dims.height / 2)){
        this.viewport.scaleAtPoint(
            -changeAmount * this.zoomSensitivity,
            zoomPoint
        );
    }
    changeContourSpacing(changeAmount){
        this.contourSpacing *= Math.exp(changeAmount * this.zoomSensitivity);
    }
    translate(translateAmount){
        this.viewport.translate(translateAmount);
    }
    drawContours(time = 0){
        const uniformAssignments = {
            uScale: this.viewport.scale,
            uPos: this.viewport.pos.toArray()
        };
        if(this.isAnimated){
            uniformAssignments['time'] = time;
        }
        const fieldResultX = this.fieldKernelX.run([], this.dims, uniformAssignments, false);
        const fieldResultY = this.fieldKernelY.run([], this.dims, uniformAssignments, false);
        this.plotKernel.run([fieldResultX.textures[0], fieldResultY.textures[0]], this.dims, {
            uContourSpacing: this.contourSpacing
        });
        fieldResultX.dispose();
        fieldResultY.dispose();
    }
};

ContourerManager.plotFunc =
`ivec2 lineIndex = ivec2(floor(vec2(
    unpackFloat(texture2D(uFieldX, vCoord)),
    unpackFloat(texture2D(uFieldY, vCoord))
) / uContourSpacing));
vec2 cmpField = vec2(lineIndex) * uContourSpacing;
ivec2 drawData = ivec2(greaterThanEqual(
    fieldCheck(threadId, ivec2(0, 1), cmpField) +
    fieldCheck(threadId, ivec2(1, 0), cmpField) +
    fieldCheck(threadId, ivec2(0, -1), cmpField) +
    fieldCheck(threadId, ivec2(-1, 0), cmpField),
    ivec2(1)));
if(all(equal(drawData, ivec2(0)))){
    gl_FragData[0] = vec4(1.0, 1.0, 1.0, 1.0);
}
else{
    vec2 isAxis = vec2(equal(lineIndex, ivec2(0)));
    vec2 lineColor = vec2(drawData) * (1.0 - 0.5 * isAxis);
    gl_FragData[0] = vec4(lineColor.x, 0.5 * dot(vec2(drawData), isAxis), lineColor.y, 1.0);
}
`;

ContourerManager.FIELD_CHECK_INCLUDE =
`vec2 getField(ivec2 pos){
    return vec2(
        unpackFloat(arrGet(uFieldX, pos)),
        unpackFloat(arrGet(uFieldY, pos))
    );
}

ivec2 fieldCheck(ivec2 cPos, ivec2 dir, vec2 cmpField){
    ivec2 oPos = cPos + dir;
    if(all(greaterThanEqual(oPos, ivec2(0))) && all(lessThan(oPos, uDims))){
        return ivec2(lessThan(getField(oPos), cmpField));
    }
    else return ivec2(0);
}

`;

class ContourerAnimationManager{
    constructor(manager, numFrames = 1000){
        this.manager = manager;
        this.isAnimating = false;
        this.numFrames = numFrames;
        this.currentFrame = 0;
        this.onStopCallback = null;
        this.animationLoop = this.animationLoop.bind(this);
    }
    start(startFrame = 0, onDraw = null){
        this.currentFrame = startFrame;
        this.isAnimating = true;
        this.onDraw = onDraw;
        window.requestAnimationFrame(this.animationLoop);
    }
    animationLoop(timestamp){
        if(this.isAnimating){
            this.manager.drawContours(this.currentFrame / this.numFrames);
            if(this.onDraw != null){
                this.onDraw(this.currentFrame);
            }
            this.currentFrame = (this.currentFrame + 1) % this.numFrames;
            window.requestAnimationFrame(this.animationLoop);
        }
        else{
            if(this.onStopCallback != null){
                this.onStopCallback();
            }
        }
    }
    stop(onStopCallback = null){
        if(this.isAnimating){
            this.isAnimating = false;
            this.onStopCallback = onStopCallback;
        }
        else{
            if(onStopCallback != null){
                onStopCallback();
            }
        }
    }
};

function init(){
    const manager = new ContourerManager();
    initRender(manager);
}
<commit_msg>Another mobile bad range test.<commit_after>'use strict';

const RED = new Color(255, 0, 0);
const GREEN = new Color(0, 255, 0);
const BLUE = new Color(0, 0, 255);
const WHITE = new Color(255, 255, 255);

class ContourerManager{
    constructor(drawFunc){
        this.viewport = new ScalableViewportManager(
            new Vector(0, 0),
            0.01
        );
        this.zoomSensitivity = 0.3;
        this.contourSpacing = 1.0;
    }
    changeDrawFunc(drawFunc, includeSrc, isAnimated = false){
        const createFieldKernel = coord => {
            const fieldFunc =
`vec2 cPos = (vec2(threadId) * uScale) + uPos;
vec2 res;
` +
            drawFunc.trim() + '\n' +
//`gl_FragData[0] = vec4(
//    res,
//    0.0, 0.0
//);
`gl_FragData[0] = packFloat(res.` + coord + `);
`;
            return this.gpgpuManager.createKernel(
                fieldFunc, [], this.dims, [
                    {
                        type: 'float',
                        name: 'uScale'
                    },
                    {
                        type: 'vec2',
                        name: 'uPos'
                    }
                ].concat(isAnimated ? [
                    {
                        type: 'float',
                        name: 'time'
                    }
                ] : []), 1, GPGPUManager.PACK_FLOAT_INCLUDE + includeSrc.trim() + '\n\n'
            );
        };
        this.fieldKernelX = createFieldKernel('x');
        this.fieldKernelY = createFieldKernel('y');

        this.viewport.scale = 10.0 / this.dims.width;
        this.viewport.pos = new Vector(-this.dims.width, -this.dims.height).divide(2.0).multiply(this.viewport.scale);
        this.contourSpacing = 1.0;

        this.isAnimated = isAnimated;
    }
    useCanvas(canvas){
        this.ctx = GPGPUManager.getCanvasContext(canvas);
        this.gpgpuManager = new GPGPUManager(this.ctx, false);
        this.dims = getCanvasDims(this.ctx);

        this.plotKernel = this.gpgpuManager.createGraphicalKernel(
            ContourerManager.plotFunc, ['uFieldX', 'uFieldY'], this.dims, [
                {
                    type: 'float',
                    name: 'uContourSpacing'
                }
            ], GPGPUManager.PACK_FLOAT_INCLUDE + ContourerManager.FIELD_CHECK_INCLUDE
        );

        const testDims = new Dimensions(15, 1);
        alert(this.gpgpuManager.textureToArray(testDims, this.gpgpuManager.createKernel(
`gl_FragData[0] = packFloat(- float(threadId.x) / 5.0);
`, [], testDims, [], 1, GPGPUManager.PACK_FLOAT_INCLUDE).run([], testDims, [], false).textures[0], false).toString());
    }
    destroyContext(){
        this.ctx.canvas.width = 1;
        this.ctx.canvas.height = 1;
    }
    changeZoom(changeAmount, zoomPoint = new Vector(this.dims.width / 2, this.dims.height / 2)){
        this.viewport.scaleAtPoint(
            -changeAmount * this.zoomSensitivity,
            zoomPoint
        );
    }
    changeContourSpacing(changeAmount){
        this.contourSpacing *= Math.exp(changeAmount * this.zoomSensitivity);
    }
    translate(translateAmount){
        this.viewport.translate(translateAmount);
    }
    drawContours(time = 0){
        const uniformAssignments = {
            uScale: this.viewport.scale,
            uPos: this.viewport.pos.toArray()
        };
        if(this.isAnimated){
            uniformAssignments['time'] = time;
        }
        const fieldResultX = this.fieldKernelX.run([], this.dims, uniformAssignments, false);
        const fieldResultY = this.fieldKernelY.run([], this.dims, uniformAssignments, false);
        this.plotKernel.run([fieldResultX.textures[0], fieldResultY.textures[0]], this.dims, {
            uContourSpacing: this.contourSpacing
        });
        fieldResultX.dispose();
        fieldResultY.dispose();
    }
};

ContourerManager.plotFunc =
`ivec2 lineIndex = ivec2(floor(vec2(
    unpackFloat(texture2D(uFieldX, vCoord)),
    unpackFloat(texture2D(uFieldY, vCoord))
) / uContourSpacing));
vec2 cmpField = vec2(lineIndex) * uContourSpacing;
ivec2 drawData = ivec2(greaterThanEqual(
    fieldCheck(threadId, ivec2(0, 1), cmpField) +
    fieldCheck(threadId, ivec2(1, 0), cmpField) +
    fieldCheck(threadId, ivec2(0, -1), cmpField) +
    fieldCheck(threadId, ivec2(-1, 0), cmpField),
    ivec2(1)));
if(all(equal(drawData, ivec2(0)))){
    gl_FragData[0] = vec4(1.0, 1.0, 1.0, 1.0);
}
else{
    vec2 isAxis = vec2(equal(lineIndex, ivec2(0)));
    vec2 lineColor = vec2(drawData) * (1.0 - 0.5 * isAxis);
    gl_FragData[0] = vec4(lineColor.x, 0.5 * dot(vec2(drawData), isAxis), lineColor.y, 1.0);
}
`;

ContourerManager.FIELD_CHECK_INCLUDE =
`vec2 getField(ivec2 pos){
    return vec2(
        unpackFloat(arrGet(uFieldX, pos)),
        unpackFloat(arrGet(uFieldY, pos))
    );
}

ivec2 fieldCheck(ivec2 cPos, ivec2 dir, vec2 cmpField){
    ivec2 oPos = cPos + dir;
    if(all(greaterThanEqual(oPos, ivec2(0))) && all(lessThan(oPos, uDims))){
        return ivec2(lessThan(getField(oPos), cmpField));
    }
    else return ivec2(0);
}

`;

class ContourerAnimationManager{
    constructor(manager, numFrames = 1000){
        this.manager = manager;
        this.isAnimating = false;
        this.numFrames = numFrames;
        this.currentFrame = 0;
        this.onStopCallback = null;
        this.animationLoop = this.animationLoop.bind(this);
    }
    start(startFrame = 0, onDraw = null){
        this.currentFrame = startFrame;
        this.isAnimating = true;
        this.onDraw = onDraw;
        window.requestAnimationFrame(this.animationLoop);
    }
    animationLoop(timestamp){
        if(this.isAnimating){
            this.manager.drawContours(this.currentFrame / this.numFrames);
            if(this.onDraw != null){
                this.onDraw(this.currentFrame);
            }
            this.currentFrame = (this.currentFrame + 1) % this.numFrames;
            window.requestAnimationFrame(this.animationLoop);
        }
        else{
            if(this.onStopCallback != null){
                this.onStopCallback();
            }
        }
    }
    stop(onStopCallback = null){
        if(this.isAnimating){
            this.isAnimating = false;
            this.onStopCallback = onStopCallback;
        }
        else{
            if(onStopCallback != null){
                onStopCallback();
            }
        }
    }
};

function init(){
    const manager = new ContourerManager();
    initRender(manager);
}
<|endoftext|>


<commit_before>/*
Copyright 2015, 2016 OpenMarket Ltd

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

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

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

'use strict';

import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import sdk from '../../../index';
import { _t } from '../../../languageHandler';
import MatrixClientPeg from '../../../MatrixClientPeg';
import Modal from "../../../Modal";
import dis from "../../../dispatcher";
import RateLimitedFunc from '../../../ratelimitedfunc';

import * as linkify from 'linkifyjs';
import linkifyElement from 'linkifyjs/element';
import linkifyMatrix from '../../../linkify-matrix';
import AccessibleButton from '../elements/AccessibleButton';
import ManageIntegsButton from '../elements/ManageIntegsButton';
import {CancelButton} from './SimpleRoomHeader';
import SettingsStore from "../../../settings/SettingsStore";
import RoomHeaderButtons from '../right_panel/RoomHeaderButtons';

linkifyMatrix(linkify);

module.exports = React.createClass({
    displayName: 'RoomHeader',

    propTypes: {
        room: PropTypes.object,
        oobData: PropTypes.object,
        editing: PropTypes.bool,
        saving: PropTypes.bool,
        inRoom: PropTypes.bool,
        collapsedRhs: PropTypes.bool,
        onSettingsClick: PropTypes.func,
        onPinnedClick: PropTypes.func,
        onSaveClick: PropTypes.func,
        onSearchClick: PropTypes.func,
        onLeaveClick: PropTypes.func,
        onCancelClick: PropTypes.func,
    },

    getDefaultProps: function() {
        return {
            editing: false,
            inRoom: false,
            onSaveClick: function() {},
            onCancelClick: null,
        };
    },

    componentDidMount: function() {
        const cli = MatrixClientPeg.get();
        cli.on("RoomState.events", this._onRoomStateEvents);
        cli.on("Room.accountData", this._onRoomAccountData);

        // When a room name occurs, RoomState.events is fired *before*
        // room.name is updated. So we have to listen to Room.name as well as
        // RoomState.events.
        if (this.props.room) {
            this.props.room.on("Room.name", this._onRoomNameChange);
        }
    },

    componentDidUpdate: function() {
        if (this.refs.topic) {
            linkifyElement(this.refs.topic, linkifyMatrix.options);
        }
    },

    componentWillUnmount: function() {
        if (this.props.room) {
            this.props.room.removeListener("Room.name", this._onRoomNameChange);
        }
        const cli = MatrixClientPeg.get();
        if (cli) {
            cli.removeListener("RoomState.events", this._onRoomStateEvents);
            cli.removeListener("Room.accountData", this._onRoomAccountData);
        }
    },

    _onRoomStateEvents: function(event, state) {
        if (!this.props.room || event.getRoomId() !== this.props.room.roomId) {
            return;
        }

        // redisplay the room name, topic, etc.
        this._rateLimitedUpdate();
    },

    _onRoomAccountData: function(event, room) {
        if (!this.props.room || room.roomId !== this.props.room.roomId) return;
        if (event.getType() !== "im.vector.room.read_pins") return;

        this._rateLimitedUpdate();
    },

    _rateLimitedUpdate: new RateLimitedFunc(function() {
        /* eslint-disable babel/no-invalid-this */
        this.forceUpdate();
    }, 500),

    _onRoomNameChange: function(room) {
        this.forceUpdate();
    },

    onAvatarPickerClick: function(ev) {
        if (this.refs.file_label) {
            this.refs.file_label.click();
        }
    },

    onAvatarSelected: function(ev) {
        const changeAvatar = this.refs.changeAvatar;
        if (!changeAvatar) {
            console.error("No ChangeAvatar found to upload image to!");
            return;
        }
        changeAvatar.onFileSelected(ev).catch(function(err) {
            const errMsg = (typeof err === "string") ? err : (err.error || "");
            const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
            console.error("Failed to set avatar: " + errMsg);
            Modal.createTrackedDialog('Failed to set avatar', '', ErrorDialog, {
                title: _t("Error"),
                description: _t("Failed to set avatar."),
            });
        }).done();
    },

    onAvatarRemoveClick: function() {
        MatrixClientPeg.get().sendStateEvent(this.props.room.roomId, 'm.room.avatar', {url: null}, '');
    },

    onShowRhsClick: function(ev) {
        dis.dispatch({ action: 'show_right_panel' });
    },

    onShareRoomClick: function(ev) {
        const ShareDialog = sdk.getComponent("dialogs.ShareDialog");
        Modal.createTrackedDialog('share room dialog', '', ShareDialog, {
            target: this.props.room,
        });
    },

    _hasUnreadPins: function() {
        const currentPinEvent = this.props.room.currentState.getStateEvents("m.room.pinned_events", '');
        if (!currentPinEvent) return false;
        if (currentPinEvent.getContent().pinned && currentPinEvent.getContent().pinned.length <= 0) {
            return false; // no pins == nothing to read
        }

        const readPinsEvent = this.props.room.getAccountData("im.vector.room.read_pins");
        if (readPinsEvent && readPinsEvent.getContent()) {
            const readStateEvents = readPinsEvent.getContent().event_ids || [];
            if (readStateEvents) {
                return !readStateEvents.includes(currentPinEvent.getId());
            }
        }

        // There's pins, and we haven't read any of them
        return true;
    },

    _hasPins: function() {
        const currentPinEvent = this.props.room.currentState.getStateEvents("m.room.pinned_events", '');
        if (!currentPinEvent) return false;

        return !(currentPinEvent.getContent().pinned && currentPinEvent.getContent().pinned.length <= 0);
    },

    /**
     * After editing the settings, get the new name for the room
     *
     * @return {?string} newName or undefined if we didn't let the user edit the room name
     */
    getEditedName: function() {
        let newName;
        if (this.refs.nameEditor) {
            newName = this.refs.nameEditor.getRoomName();
        }
        return newName;
    },

    /**
     * After editing the settings, get the new topic for the room
     *
     * @return {?string} newTopic or undefined if we didn't let the user edit the room topic
     */
    getEditedTopic: function() {
        let newTopic;
        if (this.refs.topicEditor) {
            newTopic = this.refs.topicEditor.getTopic();
        }
        return newTopic;
    },

    render: function() {
        const RoomAvatar = sdk.getComponent("avatars.RoomAvatar");
        const ChangeAvatar = sdk.getComponent("settings.ChangeAvatar");
        const TintableSvg = sdk.getComponent("elements.TintableSvg");
        const EmojiText = sdk.getComponent('elements.EmojiText');

        let name = null;
        let searchStatus = null;
        let topicElement = null;
        let cancelButton = null;
        let spinner = null;
        let saveButton = null;
        let settingsButton = null;
        let pinnedEventsButton = null;

        let canSetRoomName;
        let canSetRoomAvatar;
        let canSetRoomTopic;
        if (this.props.editing) {
            // calculate permissions.  XXX: this should be done on mount or something
            const userId = MatrixClientPeg.get().credentials.userId;

            canSetRoomName = this.props.room.currentState.maySendStateEvent('m.room.name', userId);
            canSetRoomAvatar = this.props.room.currentState.maySendStateEvent('m.room.avatar', userId);
            canSetRoomTopic = this.props.room.currentState.maySendStateEvent('m.room.topic', userId);

            saveButton = (
                <AccessibleButton className="mx_RoomHeader_textButton" onClick={this.props.onSaveClick}>
                    { _t("Save") }
                </AccessibleButton>
            );
        }

        if (this.props.onCancelClick) {
            cancelButton = <CancelButton onClick={this.props.onCancelClick} />;
        }

        if (this.props.saving) {
            const Spinner = sdk.getComponent("elements.Spinner");
            spinner =
<Spinner />
;
        }

        if (canSetRoomName) {
            const RoomNameEditor = sdk.getComponent("rooms.RoomNameEditor");
            name = <RoomNameEditor ref="nameEditor" room={this.props.room} />;
        } else {
            // don't display the search count until the search completes and
            // gives us a valid (possibly zero) searchCount.
            if (this.props.searchInfo &&
                this.props.searchInfo.searchCount !== undefined &&
                this.props.searchInfo.searchCount !== null) {
                searchStatus =

                    { _t("(~%(count)s results)", { count: this.props.searchInfo.searchCount }) }

;
            }

            // XXX: this is a bit inefficient - we could just compare room.name for 'Empty room'...
            let settingsHint = false;
            const members = this.props.room ? this.props.room.getJoinedMembers() : undefined;
            if (members) {
                if (members.length === 1 && members[0].userId === MatrixClientPeg.get().credentials.userId) {
                    const nameEvent = this.props.room.currentState.getStateEvents('m.room.name', '');
                    if (!nameEvent || !nameEvent.getContent().name) {
                        settingsHint = true;
                    }
                }
            }

            let roomName = _t("Join Room");
            if (this.props.oobData && this.props.oobData.name) {
                roomName = this.props.oobData.name;
            } else if (this.props.room) {
                roomName = this.props.room.name;
            }

            const emojiTextClasses = classNames('mx_RoomHeader_nametext', { mx_RoomHeader_settingsHint: settingsHint });
            name =

                    <EmojiText dir="auto" element="div" className={emojiTextClasses} title={roomName}>{ roomName }</EmojiText>
                    { searchStatus }

;
        }

        if (canSetRoomTopic) {
            const RoomTopicEditor = sdk.getComponent("rooms.RoomTopicEditor");
            topicElement = <RoomTopicEditor ref="topicEditor" room={this.props.room} />;
        } else {
            let topic;
            if (this.props.room) {
                const ev = this.props.room.currentState.getStateEvents('m.room.topic', '');
                if (ev) {
                    topic = ev.getContent().topic;
                }
            }
            topicElement =

{ topic }
;
        }

        let roomAvatar = null;
        const avatarSize = 28;
        if (canSetRoomAvatar) {
            roomAvatar = (

                        <ChangeAvatar ref="changeAvatar" room={this.props.room} showUploadSection={false} width={avatarSize} height={avatarSize} />

                        <input id="avatarInput" type="file" onChange={this.onAvatarSelected} />

            );
        } else if (this.props.room || (this.props.oobData && this.props.oobData.name)) {
            roomAvatar = (
                <RoomAvatar room={this.props.room} width={avatarSize} height={avatarSize} oobData={this.props.oobData}
                    viewAvatarOnClick={true} />
            );
        }

        if (this.props.onSettingsClick) {
            settingsButton =
                <AccessibleButton className="mx_RoomHeader_button" onClick={this.props.onSettingsClick} title={_t("Settings")}>
                    <TintableSvg src="img/icons-settings-room.svg" width="16" height="16" />
                </AccessibleButton>;
        }

        if (this.props.onPinnedClick && SettingsStore.isFeatureEnabled('feature_pinning')) {
            let pinsIndicator = null;
            if (this._hasUnreadPins()) {
                pinsIndicator = (
);
            } else if (this._hasPins()) {
                pinsIndicator = (
);
            }

            pinnedEventsButton =
                <AccessibleButton className="mx_RoomHeader_button mx_RoomHeader_pinnedButton"
                                  onClick={this.props.onPinnedClick} title={_t("Pinned Messages")}>
                    { pinsIndicator }
                    <TintableSvg src="img/icons-pin.svg" width="16" height="16" />
                </AccessibleButton>;
        }

//        var leave_button;
//        if (this.props.onLeaveClick) {
//            leave_button =
//

//                    <TintableSvg src="img/leave.svg" width="26" height="20"/>
//
;
//        }

        let forgetButton;
        if (this.props.onForgetClick) {
            forgetButton =
                <AccessibleButton className="mx_RoomHeader_button" onClick={this.props.onForgetClick} title={_t("Forget room")}>
                    <TintableSvg src="img/leave.svg" width="26" height="20" />
                </AccessibleButton>;
        }

        let searchButton;
        if (this.props.onSearchClick && this.props.inRoom) {
            searchButton =
                <AccessibleButton className="mx_RoomHeader_button" onClick={this.props.onSearchClick} title={_t("Search")}>
                    <TintableSvg src="img/icons-search.svg" width="16" height="16" />
                </AccessibleButton>;
        }

        let shareRoomButton;
        if (this.props.inRoom) {
            shareRoomButton =
                <AccessibleButton className="mx_RoomHeader_button" onClick={this.onShareRoomClick} title={_t('Share room')}>
                    <TintableSvg src="img/icons-share.svg" width="16" height="16" />
                </AccessibleButton>;
        }

        let rightRow;
        let manageIntegsButton;
        if (this.props.room && this.props.room.roomId && this.props.inRoom) {
            manageIntegsButton = <ManageIntegsButton
                room={this.props.room}
            />;
        }

        if (!this.props.editing) {
            rightRow =

                    { settingsButton }
                    { pinnedEventsButton }
                    { shareRoomButton }
                    { manageIntegsButton }
                    { forgetButton }
                    { searchButton }

;
        }

        return (

{ roomAvatar }

                    { name }
                    { topicElement }
                    { spinner }
                    { saveButton }
                    { cancelButton }
                    { rightRow }
                    <RoomHeaderButtons collapsedRhs={this.props.collapsedRhs} />

        );
    },
});
<commit_msg>remove dead code (collapse button was removed)<commit_after>/*
Copyright 2015, 2016 OpenMarket Ltd

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

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

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

'use strict';

import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import sdk from '../../../index';
import { _t } from '../../../languageHandler';
import MatrixClientPeg from '../../../MatrixClientPeg';
import Modal from "../../../Modal";
import dis from "../../../dispatcher";
import RateLimitedFunc from '../../../ratelimitedfunc';

import * as linkify from 'linkifyjs';
import linkifyElement from 'linkifyjs/element';
import linkifyMatrix from '../../../linkify-matrix';
import AccessibleButton from '../elements/AccessibleButton';
import ManageIntegsButton from '../elements/ManageIntegsButton';
import {CancelButton} from './SimpleRoomHeader';
import SettingsStore from "../../../settings/SettingsStore";
import RoomHeaderButtons from '../right_panel/RoomHeaderButtons';

linkifyMatrix(linkify);

module.exports = React.createClass({
    displayName: 'RoomHeader',

    propTypes: {
        room: PropTypes.object,
        oobData: PropTypes.object,
        editing: PropTypes.bool,
        saving: PropTypes.bool,
        inRoom: PropTypes.bool,
        collapsedRhs: PropTypes.bool,
        onSettingsClick: PropTypes.func,
        onPinnedClick: PropTypes.func,
        onSaveClick: PropTypes.func,
        onSearchClick: PropTypes.func,
        onLeaveClick: PropTypes.func,
        onCancelClick: PropTypes.func,
    },

    getDefaultProps: function() {
        return {
            editing: false,
            inRoom: false,
            onSaveClick: function() {},
            onCancelClick: null,
        };
    },

    componentDidMount: function() {
        const cli = MatrixClientPeg.get();
        cli.on("RoomState.events", this._onRoomStateEvents);
        cli.on("Room.accountData", this._onRoomAccountData);

        // When a room name occurs, RoomState.events is fired *before*
        // room.name is updated. So we have to listen to Room.name as well as
        // RoomState.events.
        if (this.props.room) {
            this.props.room.on("Room.name", this._onRoomNameChange);
        }
    },

    componentDidUpdate: function() {
        if (this.refs.topic) {
            linkifyElement(this.refs.topic, linkifyMatrix.options);
        }
    },

    componentWillUnmount: function() {
        if (this.props.room) {
            this.props.room.removeListener("Room.name", this._onRoomNameChange);
        }
        const cli = MatrixClientPeg.get();
        if (cli) {
            cli.removeListener("RoomState.events", this._onRoomStateEvents);
            cli.removeListener("Room.accountData", this._onRoomAccountData);
        }
    },

    _onRoomStateEvents: function(event, state) {
        if (!this.props.room || event.getRoomId() !== this.props.room.roomId) {
            return;
        }

        // redisplay the room name, topic, etc.
        this._rateLimitedUpdate();
    },

    _onRoomAccountData: function(event, room) {
        if (!this.props.room || room.roomId !== this.props.room.roomId) return;
        if (event.getType() !== "im.vector.room.read_pins") return;

        this._rateLimitedUpdate();
    },

    _rateLimitedUpdate: new RateLimitedFunc(function() {
        /* eslint-disable babel/no-invalid-this */
        this.forceUpdate();
    }, 500),

    _onRoomNameChange: function(room) {
        this.forceUpdate();
    },

    onAvatarPickerClick: function(ev) {
        if (this.refs.file_label) {
            this.refs.file_label.click();
        }
    },

    onAvatarSelected: function(ev) {
        const changeAvatar = this.refs.changeAvatar;
        if (!changeAvatar) {
            console.error("No ChangeAvatar found to upload image to!");
            return;
        }
        changeAvatar.onFileSelected(ev).catch(function(err) {
            const errMsg = (typeof err === "string") ? err : (err.error || "");
            const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
            console.error("Failed to set avatar: " + errMsg);
            Modal.createTrackedDialog('Failed to set avatar', '', ErrorDialog, {
                title: _t("Error"),
                description: _t("Failed to set avatar."),
            });
        }).done();
    },

    onAvatarRemoveClick: function() {
        MatrixClientPeg.get().sendStateEvent(this.props.room.roomId, 'm.room.avatar', {url: null}, '');
    },

    onShareRoomClick: function(ev) {
        const ShareDialog = sdk.getComponent("dialogs.ShareDialog");
        Modal.createTrackedDialog('share room dialog', '', ShareDialog, {
            target: this.props.room,
        });
    },

    _hasUnreadPins: function() {
        const currentPinEvent = this.props.room.currentState.getStateEvents("m.room.pinned_events", '');
        if (!currentPinEvent) return false;
        if (currentPinEvent.getContent().pinned && currentPinEvent.getContent().pinned.length <= 0) {
            return false; // no pins == nothing to read
        }

        const readPinsEvent = this.props.room.getAccountData("im.vector.room.read_pins");
        if (readPinsEvent && readPinsEvent.getContent()) {
            const readStateEvents = readPinsEvent.getContent().event_ids || [];
            if (readStateEvents) {
                return !readStateEvents.includes(currentPinEvent.getId());
            }
        }

        // There's pins, and we haven't read any of them
        return true;
    },

    _hasPins: function() {
        const currentPinEvent = this.props.room.currentState.getStateEvents("m.room.pinned_events", '');
        if (!currentPinEvent) return false;

        return !(currentPinEvent.getContent().pinned && currentPinEvent.getContent().pinned.length <= 0);
    },

    /**
     * After editing the settings, get the new name for the room
     *
     * @return {?string} newName or undefined if we didn't let the user edit the room name
     */
    getEditedName: function() {
        let newName;
        if (this.refs.nameEditor) {
            newName = this.refs.nameEditor.getRoomName();
        }
        return newName;
    },

    /**
     * After editing the settings, get the new topic for the room
     *
     * @return {?string} newTopic or undefined if we didn't let the user edit the room topic
     */
    getEditedTopic: function() {
        let newTopic;
        if (this.refs.topicEditor) {
            newTopic = this.refs.topicEditor.getTopic();
        }
        return newTopic;
    },

    render: function() {
        const RoomAvatar = sdk.getComponent("avatars.RoomAvatar");
        const ChangeAvatar = sdk.getComponent("settings.ChangeAvatar");
        const TintableSvg = sdk.getComponent("elements.TintableSvg");
        const EmojiText = sdk.getComponent('elements.EmojiText');

        let name = null;
        let searchStatus = null;
        let topicElement = null;
        let cancelButton = null;
        let spinner = null;
        let saveButton = null;
        let settingsButton = null;
        let pinnedEventsButton = null;

        let canSetRoomName;
        let canSetRoomAvatar;
        let canSetRoomTopic;
        if (this.props.editing) {
            // calculate permissions.  XXX: this should be done on mount or something
            const userId = MatrixClientPeg.get().credentials.userId;

            canSetRoomName = this.props.room.currentState.maySendStateEvent('m.room.name', userId);
            canSetRoomAvatar = this.props.room.currentState.maySendStateEvent('m.room.avatar', userId);
            canSetRoomTopic = this.props.room.currentState.maySendStateEvent('m.room.topic', userId);

            saveButton = (
                <AccessibleButton className="mx_RoomHeader_textButton" onClick={this.props.onSaveClick}>
                    { _t("Save") }
                </AccessibleButton>
            );
        }

        if (this.props.onCancelClick) {
            cancelButton = <CancelButton onClick={this.props.onCancelClick} />;
        }

        if (this.props.saving) {
            const Spinner = sdk.getComponent("elements.Spinner");
            spinner =
<Spinner />
;
        }

        if (canSetRoomName) {
            const RoomNameEditor = sdk.getComponent("rooms.RoomNameEditor");
            name = <RoomNameEditor ref="nameEditor" room={this.props.room} />;
        } else {
            // don't display the search count until the search completes and
            // gives us a valid (possibly zero) searchCount.
            if (this.props.searchInfo &&
                this.props.searchInfo.searchCount !== undefined &&
                this.props.searchInfo.searchCount !== null) {
                searchStatus =

                    { _t("(~%(count)s results)", { count: this.props.searchInfo.searchCount }) }

;
            }

            // XXX: this is a bit inefficient - we could just compare room.name for 'Empty room'...
            let settingsHint = false;
            const members = this.props.room ? this.props.room.getJoinedMembers() : undefined;
            if (members) {
                if (members.length === 1 && members[0].userId === MatrixClientPeg.get().credentials.userId) {
                    const nameEvent = this.props.room.currentState.getStateEvents('m.room.name', '');
                    if (!nameEvent || !nameEvent.getContent().name) {
                        settingsHint = true;
                    }
                }
            }

            let roomName = _t("Join Room");
            if (this.props.oobData && this.props.oobData.name) {
                roomName = this.props.oobData.name;
            } else if (this.props.room) {
                roomName = this.props.room.name;
            }

            const emojiTextClasses = classNames('mx_RoomHeader_nametext', { mx_RoomHeader_settingsHint: settingsHint });
            name =

                    <EmojiText dir="auto" element="div" className={emojiTextClasses} title={roomName}>{ roomName }</EmojiText>
                    { searchStatus }

;
        }

        if (canSetRoomTopic) {
            const RoomTopicEditor = sdk.getComponent("rooms.RoomTopicEditor");
            topicElement = <RoomTopicEditor ref="topicEditor" room={this.props.room} />;
        } else {
            let topic;
            if (this.props.room) {
                const ev = this.props.room.currentState.getStateEvents('m.room.topic', '');
                if (ev) {
                    topic = ev.getContent().topic;
                }
            }
            topicElement =

{ topic }
;
        }

        let roomAvatar = null;
        const avatarSize = 28;
        if (canSetRoomAvatar) {
            roomAvatar = (

                        <ChangeAvatar ref="changeAvatar" room={this.props.room} showUploadSection={false} width={avatarSize} height={avatarSize} />

                        <input id="avatarInput" type="file" onChange={this.onAvatarSelected} />

            );
        } else if (this.props.room || (this.props.oobData && this.props.oobData.name)) {
            roomAvatar = (
                <RoomAvatar room={this.props.room} width={avatarSize} height={avatarSize} oobData={this.props.oobData}
                    viewAvatarOnClick={true} />
            );
        }

        if (this.props.onSettingsClick) {
            settingsButton =
                <AccessibleButton className="mx_RoomHeader_button" onClick={this.props.onSettingsClick} title={_t("Settings")}>
                    <TintableSvg src="img/icons-settings-room.svg" width="16" height="16" />
                </AccessibleButton>;
        }

        if (this.props.onPinnedClick && SettingsStore.isFeatureEnabled('feature_pinning')) {
            let pinsIndicator = null;
            if (this._hasUnreadPins()) {
                pinsIndicator = (
);
            } else if (this._hasPins()) {
                pinsIndicator = (
);
            }

            pinnedEventsButton =
                <AccessibleButton className="mx_RoomHeader_button mx_RoomHeader_pinnedButton"
                                  onClick={this.props.onPinnedClick} title={_t("Pinned Messages")}>
                    { pinsIndicator }
                    <TintableSvg src="img/icons-pin.svg" width="16" height="16" />
                </AccessibleButton>;
        }

//        var leave_button;
//        if (this.props.onLeaveClick) {
//            leave_button =
//

//                    <TintableSvg src="img/leave.svg" width="26" height="20"/>
//
;
//        }

        let forgetButton;
        if (this.props.onForgetClick) {
            forgetButton =
                <AccessibleButton className="mx_RoomHeader_button" onClick={this.props.onForgetClick} title={_t("Forget room")}>
                    <TintableSvg src="img/leave.svg" width="26" height="20" />
                </AccessibleButton>;
        }

        let searchButton;
        if (this.props.onSearchClick && this.props.inRoom) {
            searchButton =
                <AccessibleButton className="mx_RoomHeader_button" onClick={this.props.onSearchClick} title={_t("Search")}>
                    <TintableSvg src="img/icons-search.svg" width="16" height="16" />
                </AccessibleButton>;
        }

        let shareRoomButton;
        if (this.props.inRoom) {
            shareRoomButton =
                <AccessibleButton className="mx_RoomHeader_button" onClick={this.onShareRoomClick} title={_t('Share room')}>
                    <TintableSvg src="img/icons-share.svg" width="16" height="16" />
                </AccessibleButton>;
        }

        let rightRow;
        let manageIntegsButton;
        if (this.props.room && this.props.room.roomId && this.props.inRoom) {
            manageIntegsButton = <ManageIntegsButton
                room={this.props.room}
            />;
        }

        if (!this.props.editing) {
            rightRow =

                    { settingsButton }
                    { pinnedEventsButton }
                    { shareRoomButton }
                    { manageIntegsButton }
                    { forgetButton }
                    { searchButton }

;
        }

        return (

{ roomAvatar }

                    { name }
                    { topicElement }
                    { spinner }
                    { saveButton }
                    { cancelButton }
                    { rightRow }
                    <RoomHeaderButtons collapsedRhs={this.props.collapsedRhs} />

        );
    },
});
<|endoftext|>


<commit_before>'use strict';

function draw_logic(){
    for(var vertex in vertices){
        canvas_buffer.fillStyle = vertices[vertex]['color'];
        canvas_buffer.fillRect(
          vertices[vertex]['x'],
          vertices[vertex]['y'],
          vertices[vertex]['width'],
          vertices[vertex]['height']
        );
    }

    // Draw rotation_rate_display.
    canvas_buffer.fillStyle = '#fff';
    canvas_buffer.fillText(
      rotation_rate_display,
      0,
      25
    );
}

function logic(){
    for(var vertex in vertices){
        vertices[vertex]['rotation'] += rotation_rate * (25 - vertices[vertex]['layer']);
        if(vertices[vertex]['rotation'] >= math_tau){
            vertices[vertex]['rotation'] -= math_tau;
        }else if(vertices[vertex]['rotation'] < 0){
            vertices[vertex]['rotation'] += math_tau;
        }

        vertices[vertex]['x'] = canvas_x_five + vertices[vertex]['layer'] * 10 * Math.cos(vertices[vertex]['rotation']);
        vertices[vertex]['y'] = canvas_y_five + vertices[vertex]['layer'] * 10 * Math.sin(vertices[vertex]['rotation']);
    }
}

function resize_logic(){
    canvas_x_five = canvas_x - 5;
    canvas_y_five = canvas_y - 5;
}

function rotate(amount){
    rotation_rate += amount;
    rotation_rate_display = (rotation_rate * 1000).toFixed(0);
}

var canvas_x_five = 0;
var canvas_y_five = 0;
var rotation_rate = 0;
var rotation_rate_display = '';
var vertices = [];

window.onload = function(e){
    canvas_init();
    input_init(
      {
        27: {
          'todo': function(){
              rotate(-rotation_rate);
          },
        },
        187: {
          'todo': function(){
              rotate(.001);
          },
        },
        189: {
          'todo': function(){
              rotate(-.001);
          },
        },
      }
    );

    var loop_counter = 23;
    do{
        var inner_counter = loop_counter;
        do{
            vertices.push({
              'color': random_hex(),
              'height': 10,
              'layer': loop_counter + 1,
              'rotation': inner_counter,
              'width': 10,
              'x': 0,
              'y': 0,
            });
        }while(inner_counter--);
    }while(loop_counter--);

    rotate(.005);
};
<commit_msg>switched input.js to args<commit_after>'use strict';

function draw_logic(){
    for(var vertex in vertices){
        canvas_buffer.fillStyle = vertices[vertex]['color'];
        canvas_buffer.fillRect(
          vertices[vertex]['x'],
          vertices[vertex]['y'],
          vertices[vertex]['width'],
          vertices[vertex]['height']
        );
    }

    // Draw rotation_rate_display.
    canvas_buffer.fillStyle = '#fff';
    canvas_buffer.fillText(
      rotation_rate_display,
      0,
      25
    );
}

function logic(){
    for(var vertex in vertices){
        vertices[vertex]['rotation'] += rotation_rate * (25 - vertices[vertex]['layer']);
        if(vertices[vertex]['rotation'] >= math_tau){
            vertices[vertex]['rotation'] -= math_tau;
        }else if(vertices[vertex]['rotation'] < 0){
            vertices[vertex]['rotation'] += math_tau;
        }

        vertices[vertex]['x'] = canvas_x_five + vertices[vertex]['layer'] * 10 * Math.cos(vertices[vertex]['rotation']);
        vertices[vertex]['y'] = canvas_y_five + vertices[vertex]['layer'] * 10 * Math.sin(vertices[vertex]['rotation']);
    }
}

function resize_logic(){
    canvas_x_five = canvas_x - 5;
    canvas_y_five = canvas_y - 5;
}

function rotate(amount){
    rotation_rate += amount;
    rotation_rate_display = (rotation_rate * 1000).toFixed(0);
}

var canvas_x_five = 0;
var canvas_y_five = 0;
var rotation_rate = 0;
var rotation_rate_display = '';
var vertices = [];

window.onload = function(e){
    canvas_init();
    input_init({
      'keybinds': {
        27: {
          'todo': function(){
              rotate(-rotation_rate);
          },
        },
        187: {
          'todo': function(){
              rotate(.001);
          },
        },
        189: {
          'todo': function(){
              rotate(-.001);
          },
        },
      },
    });

    var loop_counter = 23;
    do{
        var inner_counter = loop_counter;
        do{
            vertices.push({
              'color': random_hex(),
              'height': 10,
              'layer': loop_counter + 1,
              'rotation': inner_counter,
              'width': 10,
              'x': 0,
              'y': 0,
            });
        }while(inner_counter--);
    }while(loop_counter--);

    rotate(.005);
};
<|endoftext|>


<commit_before>var Node = require('./Node');

/**
 * The Grid class, which serves as the encapsulation of the layout of the nodes.
 * @constructor
 * @param {number} width Number of columns of the grid.
 * @param {number} height Number of rows of the grid.
 * @param {Array.<Array.<(number|boolean)>>} [matrix] - A 0-1 matrix
 *     representing the walkable status of the nodes(0 or false for walkable).
 *     If the matrix is not supplied, all the nodes will be walkable.  */
function Grid(width, height, matrix) {
    /**
     * The number of columns of the grid.
     * @type number
     */
    this.width = width;
    /**
     * The number of rows of the grid.
     * @type number
     */
    this.height = height;

    /**
     * A 2D array of nodes.
     */
    this.nodes = this._buildNodes(width, height, matrix);
}

/**
 * Build and return the nodes.
 * @private
 * @param {number} width
 * @param {number} height
 * @param {Array.<Array.<number|boolean>>} [matrix] - A 0-1 matrix representing
 *     the walkable status of the nodes.
 * @see Grid
 */
Grid.prototype._buildNodes = function(width, height, matrix) {
    var i, j,
        nodes = new Array(height),
        row;

    for (i = 0; i < height; ++i) {
        nodes[i] = new Array(width);
        for (j = 0; j < width; ++j) {
            nodes[i][j] = new Node(j, i);
        }
    }

    if (matrix === undefined) {
        return nodes;
    }

    if (matrix.length !== height || matrix[0].length !== width) {
        throw new Error('Matrix size does not fit');
    }

    for (i = 0; i < height; ++i) {
        for (j = 0; j < width; ++j) {
            if (matrix[i][j]) {
                // 0, false, null will be walkable
                // while others will be un-walkable
                nodes[i][j].walkable = false;
            }
        }
    }

    return nodes;
};

Grid.prototype.getNodeAt = function(x, y) {
    return this.nodes[y][x];
};

/**
 * Determine whether the node at the given position is walkable.
 * (Also returns false if the position is outside the grid.)
 * @param {number} x - The x coordinate of the node.
 * @param {number} y - The y coordinate of the node.
 * @return {boolean} - The walkability of the node.
 */
Grid.prototype.isWalkableAt = function(x, y) {
    return this.isInside(x, y) && this.nodes[y][x].walkable;
};

/**
 * Determine whether the position is inside the grid.
 * XXX: `grid.isInside(x, y)` is wierd to read.
 * It should be `(x, y) is inside grid`, but I failed to find a better
 * name for this method.
 * @param {number} x
 * @param {number} y
 * @return {boolean}
 */
Grid.prototype.isInside = function(x, y) {
    return (x >= 0 && x < this.width) && (y >= 0 && y < this.height);
};

/**
 * Set whether the node on the given position is walkable.
 * NOTE: throws exception if the coordinate is not inside the grid.
 * @param {number} x - The x coordinate of the node.
 * @param {number} y - The y coordinate of the node.
 * @param {boolean} walkable - Whether the position is walkable.
 */
Grid.prototype.setWalkableAt = function(x, y, walkable) {
    this.nodes[y][x].walkable = walkable;
};

/**
 * Get the neighbors of the given node.
 *
 *     offsets      diagonalOffsets:
 *  +---+---+---+    +---+---+---+
 *  |   | 0 |   |    | 0 |   | 1 |
 *  +---+---+---+    +---+---+---+
 *  | 3 |   | 1 |    |   |   |   |
 *  +---+---+---+    +---+---+---+
 *  |   | 2 |   |    | 3 |   | 2 |
 *  +---+---+---+    +---+---+---+
 *
 *  When allowDiagonal is true, if offsets[i] is valid, then
 *  diagonalOffsets[i] and
 *  diagonalOffsets[(i + 1) % 4] is valid.
 * @param {Node} node
 * @param {boolean} allowDiagonal
 */
Grid.prototype.getNeighbors = function(node, allowDiagonal) {
    var x = node.x,
        y = node.y,
        neighbors = [],
        d0 = false,
        d1 = false,
        d2 = false,
        d3 = false,
        nodes = this.nodes;

    // ↑
    if (this.isWalkableAt(x, y - 1)) {
        neighbors.push(nodes[y - 1][x]);
        d0 = d1 = true;
    }
    // →
    if (this.isWalkableAt(x + 1, y)) {
        neighbors.push(nodes[y][x + 1]);
        d1 = d2 = true;
    }
    // ↓
    if (this.isWalkableAt(x, y + 1)) {
        neighbors.push(nodes[y + 1][x]);
        d2 = d3 = true;
    }
    // ←
    if (this.isWalkableAt(x - 1, y)) {
        neighbors.push(nodes[y][x - 1]);
        d3 = d0 = true;
    }

    if (!allowDiagonal) {
        return neighbors;
    }

    // ↖
    if (d0 && this.isWalkableAt(x - 1, y - 1)) {
        neighbors.push(nodes[y - 1][x - 1]);
    }
    // ↗
    if (d1 && this.isWalkableAt(x + 1, y - 1)) {
        neighbors.push(nodes[y - 1][x + 1]);
    }
    // ↘
    if (d2 && this.isWalkableAt(x + 1, y + 1)) {
        neighbors.push(nodes[y + 1][x + 1]);
    }
    // ↙
    if (d3 && this.isWalkableAt(x - 1, y + 1)) {
        neighbors.push(nodes[y + 1][x - 1]);
    }

    return neighbors;
};

/**
 * Get a clone of this grid.
 * @return {Grid} Cloned grid.
 */
Grid.prototype.clone = function() {
    var i, j,

        width = this.width,
        height = this.height,
        thisNodes = this.nodes,

        newGrid = new Grid(width, height),
        newNodes = new Array(height),
        row;

    for (i = 0; i < height; ++i) {
        newNodes[i] = new Array(width);
        for (j = 0; j < width; ++j) {
            newNodes[i][j] = new Node(j, i, thisNodes[i][j].walkable);
        }
    }

    newGrid.nodes = newNodes;

    return newGrid;
};

module.exports = Grid;
<commit_msg>A mode for not crossing block corners in diagonal movement.<commit_after>var Node = require('./Node');

/**
 * The Grid class, which serves as the encapsulation of the layout of the nodes.
 * @constructor
 * @param {number} width Number of columns of the grid.
 * @param {number} height Number of rows of the grid.
 * @param {Array.<Array.<(number|boolean)>>} [matrix] - A 0-1 matrix
 *     representing the walkable status of the nodes(0 or false for walkable).
 *     If the matrix is not supplied, all the nodes will be walkable.  */
function Grid(width, height, matrix) {
    /**
     * The number of columns of the grid.
     * @type number
     */
    this.width = width;
    /**
     * The number of rows of the grid.
     * @type number
     */
    this.height = height;

    /**
     * A 2D array of nodes.
     */
    this.nodes = this._buildNodes(width, height, matrix);
}

/**
 * Build and return the nodes.
 * @private
 * @param {number} width
 * @param {number} height
 * @param {Array.<Array.<number|boolean>>} [matrix] - A 0-1 matrix representing
 *     the walkable status of the nodes.
 * @see Grid
 */
Grid.prototype._buildNodes = function(width, height, matrix) {
    var i, j,
        nodes = new Array(height),
        row;

    for (i = 0; i < height; ++i) {
        nodes[i] = new Array(width);
        for (j = 0; j < width; ++j) {
            nodes[i][j] = new Node(j, i);
        }
    }

    if (matrix === undefined) {
        return nodes;
    }

    if (matrix.length !== height || matrix[0].length !== width) {
        throw new Error('Matrix size does not fit');
    }

    for (i = 0; i < height; ++i) {
        for (j = 0; j < width; ++j) {
            if (matrix[i][j]) {
                // 0, false, null will be walkable
                // while others will be un-walkable
                nodes[i][j].walkable = false;
            }
        }
    }

    return nodes;
};

Grid.prototype.getNodeAt = function(x, y) {
    return this.nodes[y][x];
};

/**
 * Determine whether the node at the given position is walkable.
 * (Also returns false if the position is outside the grid.)
 * @param {number} x - The x coordinate of the node.
 * @param {number} y - The y coordinate of the node.
 * @return {boolean} - The walkability of the node.
 */
Grid.prototype.isWalkableAt = function(x, y) {
    return this.isInside(x, y) && this.nodes[y][x].walkable;
};

/**
 * Determine whether the position is inside the grid.
 * XXX: `grid.isInside(x, y)` is wierd to read.
 * It should be `(x, y) is inside grid`, but I failed to find a better
 * name for this method.
 * @param {number} x
 * @param {number} y
 * @return {boolean}
 */
Grid.prototype.isInside = function(x, y) {
    return (x >= 0 && x < this.width) && (y >= 0 && y < this.height);
};

/**
 * Set whether the node on the given position is walkable.
 * NOTE: throws exception if the coordinate is not inside the grid.
 * @param {number} x - The x coordinate of the node.
 * @param {number} y - The y coordinate of the node.
 * @param {boolean} walkable - Whether the position is walkable.
 */
Grid.prototype.setWalkableAt = function(x, y, walkable) {
    this.nodes[y][x].walkable = walkable;
};

/**
 * Get the neighbors of the given node.
 *
 *     offsets      diagonalOffsets:
 *  +---+---+---+    +---+---+---+
 *  |   | 0 |   |    | 0 |   | 1 |
 *  +---+---+---+    +---+---+---+
 *  | 3 |   | 1 |    |   |   |   |
 *  +---+---+---+    +---+---+---+
 *  |   | 2 |   |    | 3 |   | 2 |
 *  +---+---+---+    +---+---+---+
 *
 *  When allowDiagonal is true, if offsets[i] is valid, then
 *  diagonalOffsets[i] and
 *  diagonalOffsets[(i + 1) % 4] is valid.
 * @param {Node} node
 * @param {boolean} allowDiagonal
 * @param {boolean} dontCrossCorners
 */
Grid.prototype.getNeighbors = function(node, allowDiagonal, dontCrossCorners) {
    var x = node.x,
        y = node.y,
        neighbors = [],
        s0 = false, d0 = false,
        s1 = false, d1 = false,
        s2 = false, d2 = false,
        s3 = false, d3 = false,
        nodes = this.nodes;

    // ↑
    if (this.isWalkableAt(x, y - 1)) {
        neighbors.push(nodes[y - 1][x]);
        s0 = true;
    }
    // →
    if (this.isWalkableAt(x + 1, y)) {
        neighbors.push(nodes[y][x + 1]);
        s1 = true;
    }
    // ↓
    if (this.isWalkableAt(x, y + 1)) {
        neighbors.push(nodes[y + 1][x]);
        s2 = true;
    }
    // ←
    if (this.isWalkableAt(x - 1, y)) {
        neighbors.push(nodes[y][x - 1]);
        s3 = true;
    }

    if (!allowDiagonal) {
        return neighbors;
    }

    if (dontCrossCorners) {
        d0 = s3 && s0;
        d1 = s0 && s1;
        d2 = s1 && s2;
        d3 = s2 && s3;
    } else {
        d0 = s3 || s0;
        d1 = s0 || s1;
        d2 = s1 || s2;
        d3 = s2 || s3;
    }

    // ↖
    if (d0 && this.isWalkableAt(x - 1, y - 1)) {
        neighbors.push(nodes[y - 1][x - 1]);
    }
    // ↗
    if (d1 && this.isWalkableAt(x + 1, y - 1)) {
        neighbors.push(nodes[y - 1][x + 1]);
    }
    // ↘
    if (d2 && this.isWalkableAt(x + 1, y + 1)) {
        neighbors.push(nodes[y + 1][x + 1]);
    }
    // ↙
    if (d3 && this.isWalkableAt(x - 1, y + 1)) {
        neighbors.push(nodes[y + 1][x - 1]);
    }

    return neighbors;
};

/**
 * Get a clone of this grid.
 * @return {Grid} Cloned grid.
 */
Grid.prototype.clone = function() {
    var i, j,

        width = this.width,
        height = this.height,
        thisNodes = this.nodes,

        newGrid = new Grid(width, height),
        newNodes = new Array(height),
        row;

    for (i = 0; i < height; ++i) {
        newNodes[i] = new Array(width);
        for (j = 0; j < width; ++j) {
            newNodes[i][j] = new Node(j, i, thisNodes[i][j].walkable);
        }
    }

    newGrid.nodes = newNodes;

    return newGrid;
};

module.exports = Grid;
<|endoftext|>


<commit_before>/*
Copyright 2015 OpenMarket Ltd

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

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

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

var React = require("react");

module.exports = {
    propTypes: {
        title: React.PropTypes.string,
        description: React.PropTypes.string,
        button: React.PropTypes.string,
        focus: React.PropTypes.bool,
        onFinished: React.PropTypes.func.isRequired,
    },

    getDefaultProps: function() {
        return {
            title: "Error",
            description: "An error has occurred.",
            button: "OK",
            focus: true,
        };
    },
};
<commit_msg>you don't have to pass a description, and if you do, it could be JSX or a string<commit_after>/*
Copyright 2015 OpenMarket Ltd

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

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

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

var React = require("react");

module.exports = {
    propTypes: {
        title: React.PropTypes.string,
        button: React.PropTypes.string,
        focus: React.PropTypes.bool,
        onFinished: React.PropTypes.func.isRequired,
    },

    getDefaultProps: function() {
        return {
            title: "Error",
            description: "An error has occurred.",
            button: "OK",
            focus: true,
        };
    },
};
<|endoftext|>


<commit_before>'use strict';

/** @jsx React.DOM */
var PureRenderMixin = require('React/addons').addons.PureRenderMixin;

var safeStringify = require('../../util/util').safeStringify;

var ParseTreeView = React.createClass({
  mixins: [PureRenderMixin],
  render: function () {

    var preStyle = {
      maxHeight: 175,
      width: '100%',
      fontSize: 11
    };

    var parserDebugger = this.props.parserDebugger || [];

    var text = parserDebugger.map(function (step) {
      var res = '';
      if (step.action === 'reduce') {
        res += ' --> ';
      }
      res += step.action + ': ' + safeStringify(step.text);
      return res;
    }).join('\n');
    return (

Parse tree

{text}

    );
  }
});

module.exports = ParseTreeView;

<commit_msg>display nonterminals/terminals<commit_after>'use strict';

/** @jsx React.DOM */
var PureRenderMixin = require('React/addons').addons.PureRenderMixin;

var safeStringify = require('../../util/util').safeStringify;

var ParseTreeView = React.createClass({
  mixins: [PureRenderMixin],
  render: function () {

    var preStyle = {
      maxHeight: 175,
      width: '100%',
      fontSize: 11
    };

    var parserDebugger = this.props.parserDebugger || [];

    var text = parserDebugger.map(function (step) {
      var res = '';
      if (step.action === 'reduce') {
        res += ' --> ';
      }
      res += step.action + ': ' + safeStringify(step.text);
      if (step.action === 'reduce') {
        res += ' (' + step.nonterminal + ')';
      } else if (step.action === 'shift') {
        res += ' (' + step.terminal + ')';
      }
      return res;
    }).join('\n');
    return (

Parse tree

{text}

    );
  }
});

module.exports = ParseTreeView;

<|endoftext|>


<commit_before>// rawdata.js
// Raw level and model data. Ideally this is loaded from the server
// but...oh well. No time to waste!
// Models are stored in objects of this form:
// {
//   name: ,
//   layers:
// }
// Worlds are stored in objects of this form:
// {
//   name: ,
//   playerStartX: ,
//   playerStartY: ,
//   playerStartZ: ,
//   modelInstances: [{name: ,x: ,y: ,z: }],
//   entities: [{type: ,x: ,y: ,z: ,entityArgs: }]
// }

game.rawdata = {};

game.rawdata.RAW_MODEL_DATA = [
    {
        name: "player",
        layers: [
            [[100]]
        ]
    },
    {
        name: "plus",
        layers: [
            [[0,0,0],
             [0,101,0],
             [0,0,0]],
            [[0,3,0],
             [3,3,3],
             [0,3,0]],
            [[0,0,0],
             [0,3,0],
             [0,0,0]]
        ]
    },
];

game.rawdata.RAW_WORLD_DATA = [
    {
        name: "main",
        playerStartX: 16,
        playerStartY: 16,
        playerStartZ: 3,
        bottomZ: 20,
        modelInstances: [
            { name: "plus", x: 5, y: 5, z: 3},
            { name: "plus", x: 20, y: 7, z: 2},
            { name: "plus", x: 9, y: 14, z: 5},
            { name: "plus", x: 2, y: 19, z: 4},
            { name: "plus", x: 25, y: 25, z: 1},
            { name: "plus", x: 15, y: 15, z: 7},
        ],
        entities: [
            { type: "player", x: 0, y: 0, z: 0, args: {} }
        ]
    },
];<commit_msg>made the pluses more forgiving...<commit_after>// rawdata.js
// Raw level and model data. Ideally this is loaded from the server
// but...oh well. No time to waste!
// Models are stored in objects of this form:
// {
//   name: ,
//   layers:
// }
// Worlds are stored in objects of this form:
// {
//   name: ,
//   playerStartX: ,
//   playerStartY: ,
//   playerStartZ: ,
//   modelInstances: [{name: ,x: ,y: ,z: }],
//   entities: [{type: ,x: ,y: ,z: ,entityArgs: }]
// }

game.rawdata = {};

game.rawdata.RAW_MODEL_DATA = [
    {
        name: "player",
        layers: [
            [[100]]
        ]
    },
    {
        name: "plus",
        layers: [
            [[0,0,0,0],
             [0,101,101,0],
             [0,101,101,0],
             [0,0,0,0]],
            [[0,3,3,0],
             [3,3,3,3],
             [3,3,3,3],
             [0,3,3,0]],
            [[0,3,3,0],
             [3,3,3,3],
             [3,3,3,3],
             [0,3,3,0]],
            [[0,0,0,0],
             [0,3,3,0],
             [0,3,3,0],
             [0,0,0,0]],
        ]
    },
];

game.rawdata.RAW_WORLD_DATA = [
    {
        name: "main",
        playerStartX: 16,
        playerStartY: 16,
        playerStartZ: 3,
        bottomZ: 20,
        modelInstances: [
            { name: "plus", x: 5, y: 5, z: 3},
            { name: "plus", x: 20, y: 7, z: 2},
            { name: "plus", x: 9, y: 14, z: 5},
            { name: "plus", x: 2, y: 19, z: 4},
            { name: "plus", x: 25, y: 25, z: 1},
            { name: "plus", x: 15, y: 15, z: 7},
        ],
        entities: [
            { type: "player", x: 0, y: 0, z: 0, args: {} }
        ]
    },
];<|endoftext|>